diff options
69 files changed, 492 insertions, 1009 deletions
diff --git a/doc/api_ref/tls.rst b/doc/api_ref/tls.rst index fdffeda26..e4d497a1a 100644 --- a/doc/api_ref/tls.rst +++ b/doc/api_ref/tls.rst @@ -282,11 +282,9 @@ available: .. cpp:function:: std::vector<X509_Certificate> peer_cert_chain() Returns the certificate chain of the counterparty. When acting - as a client, this value will be non-empty unless the client's - policy allowed anonymous connections and the server then chose - an anonymous ciphersuite. Acting as a server, this value will - ordinarily be empty, unless the server requested a certificate - and the client responded with one. + as a client, this value will be non-empty. Acting as a server, + this value will ordinarily be empty, unless the server requested + a certificate and the client responded with one. .. cpp:function:: SymmetricKey key_material_export( \ const std::string& label, \ @@ -335,8 +333,8 @@ TLS Clients :ref:`tls_session_managers` for more about session managers. The *credentials_manager* is an interface that will be called to - retrieve any certificates, secret keys, pre-shared keys, or SRP - information; see :doc:`credentials_manager` for more information. + retrieve any certificates, private keys, or pre-shared keys; see + :doc:`credentials_manager` for more information. Use the optional *server_info* to specify the DNS name of the server you are attempting to connect to, if you know it. This helps @@ -698,11 +696,6 @@ information about that session: Returns the certificate chain of the peer - .. cpp:function:: std::string srp_identifier() const - - If an SRP ciphersuite was used, then this is the identifier - that was used for authentication. - .. cpp:function:: bool secure_renegotiation() const Returns ``true`` if the connection was negotiated with the @@ -861,8 +854,7 @@ policy settings from a file. Also allowed: "AES-256", "AES-128", "AES-256/CCM", "AES-128/CCM", "AES-256/CCM(8)", "AES-128/CCM(8)", - "Camellia-256/GCM", "Camellia-128/GCM", "ARIA-256/GCM", "ARIA-128/GCM", - "Camellia-256", "Camellia-128" + "Camellia-256/GCM", "Camellia-128/GCM", "ARIA-256/GCM", "ARIA-128/GCM" Also allowed (though currently experimental): "AES-128/OCB(12)", "AES-256/OCB(12)" @@ -870,7 +862,7 @@ policy settings from a file. In versions up to 2.8.0, the CBC and CCM ciphersuites "AES-256", "AES-128", "AES-256/CCM" and "AES-128/CCM" were enabled by default. - Also allowed (although **not recommended**): "SEED", "3DES" + Also allowed (although **not recommended**): "3DES" .. note:: @@ -884,7 +876,7 @@ policy settings from a file. .. note:: - SEED and 3DES are deprecated and will be removed in a future release. + All CBC ciphersuites are deprecated and will be removed in a future release. .. cpp:function:: std::vector<std::string> allowed_macs() const @@ -924,7 +916,7 @@ policy settings from a file. the benefit of post quantum security) so if CECPQ1 is being disabled for traffic overhead reasons, DH should also be avoided. - Also allowed: "RSA", "SRP_SHA", "ECDHE_PSK", "DHE_PSK", "PSK" + Also allowed: "RSA", "ECDHE_PSK", "DHE_PSK", "PSK" .. note:: @@ -936,7 +928,7 @@ policy settings from a file. .. note:: - In order to enable RSA, SRP, or PSK ciphersuites one must also enable + In order to enable RSA or PSK ciphersuites one must also enable authentication method "IMPLICIT", see :cpp:func:`allowed_signature_methods`. .. cpp:function:: std::vector<std::string> allowed_signature_hashes() const @@ -958,19 +950,11 @@ policy settings from a file. Default: "ECDSA", "RSA" - Also allowed (disabled by default): "DSA", "IMPLICIT", "ANONYMOUS" + Also allowed (disabled by default): "IMPLICIT" "IMPLICIT" enables ciphersuites which are authenticated not by a signature but through a side-effect of the key exchange. In particular this setting - is required to enable PSK, SRP, and static RSA ciphersuites. - - "ANONYMOUS" allows purely anonymous DH/ECDH key exchanges. **Enabling this - is not recommended** - - .. note:: - - Both DSA authentication and anonymous DH ciphersuites are deprecated, - and will be removed in a future release. + is required to enable PSK and static RSA ciphersuites. .. cpp:function:: std::vector<Group_Params> key_exchange_groups() const @@ -1132,7 +1116,7 @@ policy settings from a file. .. cpp:function:: bool hide_unknown_users() const - The SRP and PSK suites work using an identifier along with a + The PSK suites work using an identifier along with a shared secret. If this function returns true, when an identifier that the server does not recognize is provided by a client, a random shared secret will be generated in such a way that a diff --git a/doc/api_ref/x509.rst b/doc/api_ref/x509.rst index cbf3d531e..a6c62a207 100644 --- a/doc/api_ref/x509.rst +++ b/doc/api_ref/x509.rst @@ -317,7 +317,7 @@ store would be one that looked up the certificates in a SQL database, or by contacting a CGI script running on a HTTP server. There are currently three mechanisms for looking up a certificate, and one for retrieving CRLs. By default, most of these mechanisms will return an -empty ``std::shared_ptr`` of ``X509_Certificate``. This storage mechanism +empty ``std::optional`` of ``X509_Certificate``. This storage mechanism is *only* queried when doing certificate validation: it allows you to distribute only the root key with an application, and let some online method handle getting all the other certificates that are needed to @@ -334,15 +334,24 @@ mandatory to implement. Finally, there is a method for finding a CRL, called ``find_crl_for``, that takes an ``X509_Certificate`` object, and returns a -``std::shared_ptr`` of ``X509_CRL``. The ``std::shared_ptr`` return -type makes it easy to return no CRLs by returning ``nullptr`` +``std::optional`` of ``X509_CRL``. The ``std::optional`` return +type makes it easy to return no CRLs by returning ``nullopt`` (eg, if the certificate store doesn't support retrieving CRLs). Implementing the function is optional, and by default will return -``nullptr``. +``nullopt``. Certificate stores are used in the :doc:`tls` module to store a list of trusted certificate authorities. +.. note:: + + In the 2.x library, the certificate store interface relied on + ``shared_ptr<X509_Certificate>`` to avoid copies. However since + 2.4.0, the ``X509_Certificate`` was internally shared, and thus the + outer ``shared_ptr`` was just a cause of needless runtime overhead + and API complexity. Starting in version 3.0, the certificate store + interface is defined in terms of plain ``X509_Certificate``. + In Memory Certificate Store ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -369,17 +378,25 @@ later. Add a certificate to the store - .. cpp:function:: void add_certificate(std::shared_ptr<const X509_Certificate> cert) - - Add a certificate already in a shared_ptr to the store - .. cpp:function:: void add_crl(const X509_CRL& crl) Add a certificate revocation list (CRL) to the store. - .. cpp:function:: void add_crl(std::shared_ptr<const X509_CRL> crl) +System Certificate Stores +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +An interface to use the system provided certificate stores is available for +Unix, macOS and Windows systems, ``System_Certificate_Store`` + +Flatfile Certificate Stores +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +``Flatfile_Certificate_Store`` is an implementation of certificate store that +reads certificates as files from a directory. This is also used as the +implementation of the Unix/Linux system certificate store. - Add a certificate revocation list (CRL) to the store as a shared_ptr +The constructor takes a path to the directory to read, along with an optional +boolean indicating if non-CA certificates should be ignored. SQL-backed Certificate Stores ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -410,8 +427,7 @@ certificates. Returns the private key for "cert" or an empty shared_ptr if none was found - .. cpp:function:: std::vector<std::shared_ptr<const X509_Certificate>> \ - find_certs_for_key(const Private_Key& key) const + .. cpp:function:: std::vector<X509_Certificate> find_certs_for_key(const Private_Key& key) const Returns all certificates for private key ``key`` @@ -465,7 +481,7 @@ set of functions in ``x509path.h`` named ``x509_path_validate``: Usage_Type usage = Usage_Type::UNSPECIFIED, \ std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), \ std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), \ - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp = std::vector<std::shared_ptr<const OCSP::Response>>()) + const std::vector<std::optional<OCSP::Response>>& ocsp_resp = std::vector<std::optional<OCSP::Response>>()) The last five parameters are optional. ``hostname`` specifies a hostname which is matched against the subject DN in ``end_cert`` according to RFC 6125. @@ -838,7 +854,7 @@ for certificate status information. .. cpp:function:: Certificate_Status_Code check_signature( \ const std::vector<Certificate_Store*>& trust_roots, \ - const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path = const std::vector<std::shared<const X509_Certificate>>()) const + const std::vector<X509_Certificate>& cert_path = const std::vector<X509_Certificate>()) const Find the issuing certificate of the OCSP response, and check the signature. diff --git a/doc/building.rst b/doc/building.rst index 93652f266..7e54479a7 100644 --- a/doc/building.rst +++ b/doc/building.rst @@ -232,8 +232,11 @@ For Android --------------------- Modern versions of Android NDK use Clang and support C++17. Simply -configure using the appropriate NDK compiler:: +configure using the appropriate NDK compiler and ``ar`` (``ar`` only +needed if building the static library). Here we build for Aarch64 +targeting Android API 28:: + $ export AR=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar $ export CXX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android28-clang++ $ ./configure.py --os=android --cc=clang --cpu=arm64 diff --git a/doc/deprecated.rst b/doc/deprecated.rst index 0d16e5f9a..0ac159692 100644 --- a/doc/deprecated.rst +++ b/doc/deprecated.rst @@ -34,18 +34,12 @@ in a future major release: - All CBC mode ciphersuites. This includes all available 3DES and SEED ciphersuites. This implies also removing Encrypt-then-MAC extension. -- All ciphersuites using DH key exchange (DHE-DSS, DHE-RSA, DHE-PSK, anon DH) +- All ciphersuites using DH key exchange (DHE-RSA, DHE-PSK) - Support for renegotiation in TLS v1.2 - All ciphersuites using static RSA key exchange -- SRP ciphersuites. This is implied by the removal of CBC mode, since - all available SRP ciphersuites use CBC. To avoid use of obsolete - ciphers, it would be better to instead perform a standard TLS - negotiation, then a PAKE authentication within (and bound to) the - TLS channel. - - OCB ciphersuites using 128-bit keys Deprecated Functionality @@ -16,12 +16,16 @@ Version 3.0.0, Not Yet Released DESX, XTEA, PBKDF1, MCEIES, CBC-MAC and Tiger (GH #2434) * Remove several deprecated features in TLS including DSA ciphersuites (GH #2505), - anonymous ciphersuites (GH #2497) + anonymous ciphersuites (GH #2497), SRP ciphersuites (GH #2506), + SEED ciphersuites (GH #2509), Camellia CBC ciphersuites (GH #2509) * Resolve an issue in the modular square root function which could cause a near-infinite loop if used with a composite modulus of a certain form where finding a quadratic non-residue is hard. (GH #2478 #2476) +* Remove use of ``shared_ptr`` from certificate store API as since + 2.4.0 ``X509_Certificate`` is internally a ``shared_ptr``. (GH #2484) + * Add new ``X509_DN::DER_encode`` function. (GH #2472) * Re-enable support for CLMUL instruction on Visual C++, which was accidentally diff --git a/src/bogo_shim/bogo_shim.cpp b/src/bogo_shim/bogo_shim.cpp index c62bc8e67..350623854 100644 --- a/src/bogo_shim/bogo_shim.cpp +++ b/src/bogo_shim/bogo_shim.cpp @@ -1009,8 +1009,7 @@ class Shim_Policy final : public Botan::TLS::Policy return true; } - std::vector<uint16_t> ciphersuite_list(Botan::TLS::Protocol_Version version, - bool have_srp) const override; + std::vector<uint16_t> ciphersuite_list(Botan::TLS::Protocol_Version version) const override; size_t dtls_default_mtu() const override { @@ -1044,8 +1043,7 @@ class Shim_Policy final : public Botan::TLS::Policy size_t m_sessions; }; -std::vector<uint16_t> Shim_Policy::ciphersuite_list(Botan::TLS::Protocol_Version version, - bool have_srp) const +std::vector<uint16_t> Shim_Policy::ciphersuite_list(Botan::TLS::Protocol_Version version) const { std::vector<uint16_t> ciphersuite_codes; @@ -1080,10 +1078,6 @@ std::vector<uint16_t> Shim_Policy::ciphersuite_list(Botan::TLS::Protocol_Version if(suite.valid() == false) continue; - // Are we doing SRP? - if(!have_srp && suite.kex_method() == Botan::TLS::Kex_Algo::SRP_SHA) - continue; - if(cipher_limit != "") { if(cipher_limit == "DEFAULT:!AES") @@ -1324,7 +1318,7 @@ class Shim_Callbacks final : public Botan::TLS::Callbacks } void tls_verify_cert_chain(const std::vector<Botan::X509_Certificate>& /*cert_chain*/, - const std::vector<std::shared_ptr<const Botan::OCSP::Response>>& /*ocsp_responses*/, + const std::vector<std::optional<Botan::OCSP::Response>>& /*ocsp_responses*/, const std::vector<Botan::Certificate_Store*>& /*trusted_roots*/, Botan::Usage_Type /*usage*/, const std::string& /*hostname*/, diff --git a/src/cli/tls_client.cpp b/src/cli/tls_client.cpp index 3ef7195dd..eee97a4c0 100644 --- a/src/cli/tls_client.cpp +++ b/src/cli/tls_client.cpp @@ -308,7 +308,7 @@ class TLS_Client final : public Command, public Botan::TLS::Callbacks void tls_verify_cert_chain( const std::vector<Botan::X509_Certificate>& cert_chain, - const std::vector<std::shared_ptr<const Botan::OCSP::Response>>& ocsp, + const std::vector<std::optional<Botan::OCSP::Response>>& ocsp, const std::vector<Botan::Certificate_Store*>& trusted_roots, Botan::Usage_Type usage, const std::string& hostname, diff --git a/src/cli/tls_helpers.h b/src/cli/tls_helpers.h index 653a106e0..f23a70798 100644 --- a/src/cli/tls_helpers.h +++ b/src/cli/tls_helpers.h @@ -182,7 +182,7 @@ class TLS_All_Policy final : public Botan::TLS::Policy std::vector<std::string> allowed_key_exchange_methods() const override { - return { "SRP_SHA", "ECDHE_PSK", "DHE_PSK", "PSK", "CECPQ1", "ECDH", "DH", "RSA" }; + return { "ECDHE_PSK", "DHE_PSK", "PSK", "CECPQ1", "ECDH", "DH", "RSA" }; } std::vector<std::string> allowed_signature_methods() const override diff --git a/src/cli/tls_utils.cpp b/src/cli/tls_utils.cpp index b7340c404..698c625e1 100644 --- a/src/cli/tls_utils.cpp +++ b/src/cli/tls_utils.cpp @@ -67,7 +67,6 @@ class TLS_Ciphersuites final : public Command { const std::string policy_type = get_arg("policy"); const Botan::TLS::Protocol_Version version(tls_version_from_str(get_arg("version"))); - const bool with_srp = false; // fixme auto policy = load_tls_policy(policy_type); @@ -77,7 +76,7 @@ class TLS_Ciphersuites final : public Command return; } - for(uint16_t suite_id : policy->ciphersuite_list(version, with_srp)) + for(uint16_t suite_id : policy->ciphersuite_list(version)) { const Botan::TLS::Ciphersuite suite(Botan::TLS::Ciphersuite::by_id(suite_id)); output() << suite.to_string() << "\n"; diff --git a/src/cli/x509.cpp b/src/cli/x509.cpp index f5691b8d5..64e66366e 100644 --- a/src/cli/x509.cpp +++ b/src/cli/x509.cpp @@ -67,9 +67,9 @@ class Trust_Root_Info final : public Command output() << "# " << dn << "\n"; if(flag_set("display")) - output() << cert->to_string() << "\n"; + output() << cert.to_string() << "\n"; - output() << cert->PEM_encode() << "\n"; + output() << cert.PEM_encode() << "\n"; } } diff --git a/src/fuzzer/tls_client.cpp b/src/fuzzer/tls_client.cpp index c8e5839f4..2adc6b350 100644 --- a/src/fuzzer/tls_client.cpp +++ b/src/fuzzer/tls_client.cpp @@ -21,8 +21,7 @@ class Fuzzer_TLS_Client_Creds : public Botan::Credentials_Manager class Fuzzer_TLS_Policy : public Botan::TLS::Policy { public: - std::vector<uint16_t> ciphersuite_list(Botan::TLS::Protocol_Version version, - bool have_srp) const override + std::vector<uint16_t> ciphersuite_list(Botan::TLS::Protocol_Version version) const override { std::vector<uint16_t> ciphersuites; @@ -31,10 +30,6 @@ class Fuzzer_TLS_Policy : public Botan::TLS::Policy if(suite.valid() == false) continue; - // Are we doing SRP? - if(!have_srp && suite.kex_method() == Botan::TLS::Kex_Algo::SRP_SHA) - continue; - if(!version.supports_aead_modes()) { // Are we doing AEAD in a non-AEAD version? @@ -78,7 +73,7 @@ class Fuzzer_TLS_Client_Callbacks : public Botan::TLS::Callbacks void tls_verify_cert_chain( const std::vector<Botan::X509_Certificate>& cert_chain, - const std::vector<std::shared_ptr<const Botan::OCSP::Response>>& ocsp_responses, + const std::vector<std::optional<Botan::OCSP::Response>>& ocsp_responses, const std::vector<Botan::Certificate_Store*>& trusted_roots, Botan::Usage_Type usage, const std::string& hostname, diff --git a/src/fuzzer/tls_server.cpp b/src/fuzzer/tls_server.cpp index 9df6151a7..f251a9df1 100644 --- a/src/fuzzer/tls_server.cpp +++ b/src/fuzzer/tls_server.cpp @@ -112,8 +112,7 @@ class Fuzzer_TLS_Server_Creds : public Botan::Credentials_Manager class Fuzzer_TLS_Policy : public Botan::TLS::Policy { public: - std::vector<uint16_t> ciphersuite_list(Botan::TLS::Protocol_Version version, - bool have_srp) const override + std::vector<uint16_t> ciphersuite_list(Botan::TLS::Protocol_Version version) const override { std::vector<uint16_t> ciphersuites; @@ -122,10 +121,6 @@ class Fuzzer_TLS_Policy : public Botan::TLS::Policy if(suite.valid() == false) continue; - // Are we doing SRP? - if(!have_srp && suite.kex_method() == Botan::TLS::Kex_Algo::SRP_SHA) - continue; - if(!version.supports_aead_modes()) { // Are we doing AEAD in a non-AEAD version? @@ -177,7 +172,7 @@ class Fuzzer_TLS_Server_Callbacks : public Botan::TLS::Callbacks void tls_verify_cert_chain( const std::vector<Botan::X509_Certificate>& cert_chain, - const std::vector<std::shared_ptr<const Botan::OCSP::Response>>& ocsp_responses, + const std::vector<std::optional<Botan::OCSP::Response>>& ocsp_responses, const std::vector<Botan::Certificate_Store*>& trusted_roots, Botan::Usage_Type usage, const std::string& hostname, diff --git a/src/lib/tls/asio/asio_stream.h b/src/lib/tls/asio/asio_stream.h index f1ffa67f2..42cb65a1e 100644 --- a/src/lib/tls/asio/asio_stream.h +++ b/src/lib/tls/asio/asio_stream.h @@ -621,7 +621,7 @@ class Stream void tls_verify_cert_chain( const std::vector<X509_Certificate>& cert_chain, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, + const std::vector<std::optional<OCSP::Response>>& ocsp_responses, const std::vector<Certificate_Store*>& trusted_roots, Usage_Type usage, const std::string& hostname, diff --git a/src/lib/tls/credentials_manager.cpp b/src/lib/tls/credentials_manager.cpp index 0c5ae9718..aca751d00 100644 --- a/src/lib/tls/credentials_manager.cpp +++ b/src/lib/tls/credentials_manager.cpp @@ -30,36 +30,6 @@ SymmetricKey Credentials_Manager::psk(const std::string&, throw Internal_Error("No PSK set for identity " + identity); } -bool Credentials_Manager::attempt_srp(const std::string&, - const std::string&) - { - return false; - } - -std::string Credentials_Manager::srp_identifier(const std::string&, - const std::string&) - { - return ""; - } - -std::string Credentials_Manager::srp_password(const std::string&, - const std::string&, - const std::string&) - { - return ""; - } - -bool Credentials_Manager::srp_verifier(const std::string&, - const std::string&, - const std::string&, - std::string&, - BigInt&, - std::vector<uint8_t>&, - bool) - { - return false; - } - std::vector<X509_Certificate> Credentials_Manager::find_cert_chain( const std::vector<std::string>& key_types, const std::vector<X509_DN>&, diff --git a/src/lib/tls/credentials_manager.h b/src/lib/tls/credentials_manager.h index 627894a87..d036a1524 100644 --- a/src/lib/tls/credentials_manager.h +++ b/src/lib/tls/credentials_manager.h @@ -121,48 +121,6 @@ class BOTAN_PUBLIC_API(2,0) Credentials_Manager /** * @param type specifies the type of operation occurring * @param context specifies a context relative to type. - * @return true if we should attempt SRP authentication - */ - virtual bool attempt_srp(const std::string& type, - const std::string& context); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. - * @return identifier for client-side SRP auth, if available - for this type/context. Should return empty string - if password auth not desired/available. - */ - virtual std::string srp_identifier(const std::string& type, - const std::string& context); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. - * @param identifier specifies what identifier we want the - * password for. This will be a value previously returned - * by srp_identifier. - * @return password for client-side SRP auth, if available - for this identifier/type/context. - */ - virtual std::string srp_password(const std::string& type, - const std::string& context, - const std::string& identifier); - - /** - * Retrieve SRP verifier parameters - */ - virtual bool srp_verifier(const std::string& type, - const std::string& context, - const std::string& identifier, - std::string& group_name, - BigInt& verifier, - std::vector<uint8_t>& salt, - bool generate_fake_on_unknown); - - /** - * @param type specifies the type of operation occurring - * @param context specifies a context relative to type. * @return the PSK identity hint for this type/context */ virtual std::string psk_identity_hint(const std::string& type, diff --git a/src/lib/tls/msg_client_hello.cpp b/src/lib/tls/msg_client_hello.cpp index 149f3f0d4..3eee06e69 100644 --- a/src/lib/tls/msg_client_hello.cpp +++ b/src/lib/tls/msg_client_hello.cpp @@ -89,7 +89,7 @@ Client_Hello::Client_Hello(Handshake_IO& io, const std::vector<std::string>& next_protocols) : m_version(client_settings.protocol_version()), m_random(make_hello_random(rng, policy)), - m_suites(policy.ciphersuite_list(m_version, !client_settings.srp_identifier().empty())), + m_suites(policy.ciphersuite_list(m_version)), m_comp_methods(1) { if(!policy.acceptable_protocol_version(m_version)) @@ -125,15 +125,6 @@ Client_Hello::Client_Hello(Handshake_IO& io, if(m_version.is_datagram_protocol()) m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles())); -#if defined(BOTAN_HAS_SRP6) - m_extensions.add(new SRP_Identifier(client_settings.srp_identifier())); -#else - if(!client_settings.srp_identifier().empty()) - { - throw Invalid_State("Attempting to initiate SRP session but TLS-SRP support disabled"); - } -#endif - std::unique_ptr<Supported_Groups> supported_groups(new Supported_Groups(policy.key_exchange_groups())); if(supported_groups->ec_groups().size() > 0) @@ -165,7 +156,7 @@ Client_Hello::Client_Hello(Handshake_IO& io, m_version(session.version()), m_session_id(session.session_id()), m_random(make_hello_random(rng, policy)), - m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))), + m_suites(policy.ciphersuite_list(m_version)), m_comp_methods(1) { if(!policy.acceptable_protocol_version(m_version)) @@ -201,15 +192,6 @@ Client_Hello::Client_Hello(Handshake_IO& io, if(session.supports_encrypt_then_mac()) m_extensions.add(new Encrypt_then_MAC); -#if defined(BOTAN_HAS_SRP6) - m_extensions.add(new SRP_Identifier(session.srp_identifier())); -#else - if(!session.srp_identifier().empty()) - { - throw Invalid_State("Attempting to resume SRP session but TLS-SRP support disabled"); - } -#endif - if(m_version.supports_negotiable_signature_algorithms()) m_extensions.add(new Signature_Algorithms(policy.allowed_signature_schemes())); @@ -380,15 +362,6 @@ std::string Client_Hello::sni_hostname() const return ""; } -#if defined(BOTAN_HAS_SRP6) -std::string Client_Hello::srp_identifier() const - { - if(SRP_Identifier* srp = m_extensions.get<SRP_Identifier>()) - return srp->identifier(); - return ""; - } -#endif - bool Client_Hello::secure_renegotiation() const { return m_extensions.has<Renegotiation_Extension>(); diff --git a/src/lib/tls/msg_client_kex.cpp b/src/lib/tls/msg_client_kex.cpp index 39266962b..beeede31f 100644 --- a/src/lib/tls/msg_client_kex.cpp +++ b/src/lib/tls/msg_client_kex.cpp @@ -23,10 +23,6 @@ #include <botan/cecpq1.h> #endif -#if defined(BOTAN_HAS_SRP6) - #include <botan/srp6.h> -#endif - namespace Botan { namespace TLS { @@ -146,36 +142,6 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_key_material, ecdh_result.second, 1); } -#if defined(BOTAN_HAS_SRP6) - else if(kex_algo == Kex_Algo::SRP_SHA) - { - const BigInt N = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535)); - const BigInt g = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535)); - std::vector<uint8_t> salt = reader.get_range<uint8_t>(1, 1, 255); - const BigInt B = BigInt::decode(reader.get_range<uint8_t>(2, 1, 65535)); - - const std::string srp_group = srp6_group_identifier(N, g); - - const std::string srp_identifier = - creds.srp_identifier("tls-client", hostname); - - const std::string srp_password = - creds.srp_password("tls-client", hostname, srp_identifier); - - std::pair<BigInt, SymmetricKey> srp_vals = - srp6_client_agree(srp_identifier, - srp_password, - srp_group, - "SHA-1", - salt, - B, - rng); - - append_tls_length_value(m_key_material, BigInt::encode(srp_vals.first), 2); - m_pre_master = srp_vals.second.bits_of(); - } -#endif - #if defined(BOTAN_HAS_CECPQ1) else if(kex_algo == Kex_Algo::CECPQ1) { @@ -313,14 +279,6 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<uint8_t>& contents, append_tls_length_value(m_pre_master, zeros, 2); append_tls_length_value(m_pre_master, psk.bits_of(), 2); } -#if defined(BOTAN_HAS_SRP6) - else if(kex_algo == Kex_Algo::SRP_SHA) - { - SRP6_Server_Session& srp = state.server_kex()->server_srp_params(); - - m_pre_master = srp.step2(BigInt::decode(reader.get_range<uint8_t>(2, 0, 65535))).bits_of(); - } -#endif #if defined(BOTAN_HAS_CECPQ1) else if(kex_algo == Kex_Algo::CECPQ1) { diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp index cefb88904..35bd94d1b 100644 --- a/src/lib/tls/msg_server_kex.cpp +++ b/src/lib/tls/msg_server_kex.cpp @@ -26,10 +26,6 @@ #include <botan/cecpq1.h> #endif -#if defined(BOTAN_HAS_SRP6) - #include <botan/srp6.h> -#endif - namespace Botan { namespace TLS { @@ -137,37 +133,6 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io, append_tls_length_value(m_params, ecdh_public_val, 1); } -#if defined(BOTAN_HAS_SRP6) - else if(kex_algo == Kex_Algo::SRP_SHA) - { - const std::string srp_identifier = state.client_hello()->srp_identifier(); - - std::string group_id; - BigInt v; - std::vector<uint8_t> salt; - - const bool found = creds.srp_verifier("tls-server", hostname, - srp_identifier, - group_id, v, salt, - policy.hide_unknown_users()); - - if(!found) - throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY, - "Unknown SRP user " + srp_identifier); - - m_srp_params.reset(new SRP6_Server_Session); - - BigInt B = m_srp_params->step1(v, group_id, - "SHA-1", rng); - - DL_Group group(group_id); - - append_tls_length_value(m_params, BigInt::encode(group.get_p()), 2); - append_tls_length_value(m_params, BigInt::encode(group.get_g()), 2); - append_tls_length_value(m_params, salt, 1); - append_tls_length_value(m_params, BigInt::encode(B), 2); - } -#endif #if defined(BOTAN_HAS_CECPQ1) else if(kex_algo == Kex_Algo::CECPQ1) { @@ -239,15 +204,6 @@ Server_Key_Exchange::Server_Key_Exchange(const std::vector<uint8_t>& buf, reader.get_uint16_t(); // curve id reader.get_range<uint8_t>(1, 1, 255); // public key } - else if(kex_algo == Kex_Algo::SRP_SHA) - { - // 2 bigints (N,g) then salt, then server B - - reader.get_range<uint8_t>(2, 1, 65535); - reader.get_range<uint8_t>(2, 1, 65535); - reader.get_range<uint8_t>(1, 1, 255); - reader.get_range<uint8_t>(2, 1, 65535); - } else if(kex_algo == Kex_Algo::CECPQ1) { // u16 blob diff --git a/src/lib/tls/tls_algos.cpp b/src/lib/tls/tls_algos.cpp index 5c383807b..cdd6cc1b9 100644 --- a/src/lib/tls/tls_algos.cpp +++ b/src/lib/tls/tls_algos.cpp @@ -38,8 +38,6 @@ std::string kex_method_to_string(Kex_Algo method) return "ECDH"; case Kex_Algo::CECPQ1: return "CECPQ1"; - case Kex_Algo::SRP_SHA: - return "SRP_SHA"; case Kex_Algo::PSK: return "PSK"; case Kex_Algo::DHE_PSK: @@ -65,9 +63,6 @@ Kex_Algo kex_method_from_string(const std::string& str) if(str == "CECPQ1") return Kex_Algo::CECPQ1; - if(str == "SRP_SHA") - return Kex_Algo::SRP_SHA; - if(str == "PSK") return Kex_Algo::PSK; diff --git a/src/lib/tls/tls_algos.h b/src/lib/tls/tls_algos.h index 0d3a02304..6f99574ce 100644 --- a/src/lib/tls/tls_algos.h +++ b/src/lib/tls/tls_algos.h @@ -20,35 +20,30 @@ namespace TLS { enum class Cipher_Algo { CHACHA20_POLY1305, - AES_128_CBC_HMAC_SHA1 = 100, - AES_128_CBC_HMAC_SHA256, - AES_128_CCM, - AES_128_CCM_8, AES_128_GCM, - AES_128_OCB, - - AES_256_CBC_HMAC_SHA1 = 200, - AES_256_CBC_HMAC_SHA256, - AES_256_CBC_HMAC_SHA384, - AES_256_CCM, - AES_256_CCM_8, AES_256_GCM, + + AES_128_OCB, AES_256_OCB, - CAMELLIA_128_CBC_HMAC_SHA1 = 300, - CAMELLIA_128_CBC_HMAC_SHA256, CAMELLIA_128_GCM, - - CAMELLIA_256_CBC_HMAC_SHA1 = 400, - CAMELLIA_256_CBC_HMAC_SHA256, - CAMELLIA_256_CBC_HMAC_SHA384, CAMELLIA_256_GCM, - ARIA_128_GCM = 500, + ARIA_128_GCM, ARIA_256_GCM, - DES_EDE_CBC_HMAC_SHA1 = 1000, - SEED_CBC_HMAC_SHA1, + AES_128_CCM, + AES_256_CCM, + AES_128_CCM_8, + AES_256_CCM_8, + + AES_128_CBC_HMAC_SHA1, + AES_128_CBC_HMAC_SHA256, + AES_256_CBC_HMAC_SHA1, + AES_256_CBC_HMAC_SHA256, + AES_256_CBC_HMAC_SHA384, + + DES_EDE_CBC_HMAC_SHA1, }; enum class KDF_Algo { @@ -141,7 +136,6 @@ enum class Kex_Algo { DH, ECDH, CECPQ1, - SRP_SHA, PSK, DHE_PSK, ECDHE_PSK, diff --git a/src/lib/tls/tls_callbacks.cpp b/src/lib/tls/tls_callbacks.cpp index 0dd758b75..4b43359eb 100644 --- a/src/lib/tls/tls_callbacks.cpp +++ b/src/lib/tls/tls_callbacks.cpp @@ -52,7 +52,7 @@ std::string TLS::Callbacks::tls_decode_group_param(Group_Params group_param) void TLS::Callbacks::tls_verify_cert_chain( const std::vector<X509_Certificate>& cert_chain, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, + const std::vector<std::optional<OCSP::Response>>& ocsp_responses, const std::vector<Certificate_Store*>& trusted_roots, Usage_Type usage, const std::string& hostname, diff --git a/src/lib/tls/tls_callbacks.h b/src/lib/tls/tls_callbacks.h index 795663e22..5c81e2f93 100644 --- a/src/lib/tls/tls_callbacks.h +++ b/src/lib/tls/tls_callbacks.h @@ -13,7 +13,7 @@ #include <botan/tls_session.h> #include <botan/tls_alert.h> #include <botan/pubkey.h> -#include <functional> +#include <optional> namespace Botan { @@ -128,7 +128,7 @@ class BOTAN_PUBLIC_API(2,0) Callbacks */ virtual void tls_verify_cert_chain( const std::vector<X509_Certificate>& cert_chain, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, + const std::vector<std::optional<OCSP::Response>>& ocsp_responses, const std::vector<Certificate_Store*>& trusted_roots, Usage_Type usage, const std::string& hostname, diff --git a/src/lib/tls/tls_ciphersuite.cpp b/src/lib/tls/tls_ciphersuite.cpp index 738be110b..3e54bcb89 100644 --- a/src/lib/tls/tls_ciphersuite.cpp +++ b/src/lib/tls/tls_ciphersuite.cpp @@ -199,13 +199,7 @@ bool Ciphersuite::is_usable() const return false; } - if(kex_method() == Kex_Algo::SRP_SHA) - { -#if !defined(BOTAN_HAS_SRP6) - return false; -#endif - } - else if(kex_method() == Kex_Algo::ECDH || kex_method() == Kex_Algo::ECDHE_PSK) + if(kex_method() == Kex_Algo::ECDH || kex_method() == Kex_Algo::ECDHE_PSK) { #if !defined(BOTAN_HAS_ECDH) return false; diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp index 091e649a9..117dfcabe 100644 --- a/src/lib/tls/tls_client.cpp +++ b/src/lib/tls/tls_client.cpp @@ -75,11 +75,8 @@ Client::Client(Callbacks& callbacks, m_creds(creds), m_info(info) { - const std::string srp_identifier = m_creds.srp_identifier("tls-client", m_info.hostname()); - Handshake_State& state = create_handshake_state(offer_version); - send_client_hello(state, false, offer_version, - srp_identifier, next_protocols); + send_client_hello(state, false, offer_version, next_protocols); } Handshake_State* Client::new_handshake_state(Handshake_IO* io) @@ -113,7 +110,6 @@ void Client::initiate_handshake(Handshake_State& state, void Client::send_client_hello(Handshake_State& state_base, bool force_full_renegotiation, Protocol_Version version, - const std::string& srp_identifier, const std::vector<std::string>& next_protocols) { Client_Handshake_State& state = dynamic_cast<Client_Handshake_State&>(state_base); @@ -140,27 +136,24 @@ void Client::send_client_hello(Handshake_State& state_base, if(policy().acceptable_ciphersuite(session_info->ciphersuite()) && session_version_ok) { - if(srp_identifier == "" || session_info->srp_identifier() == srp_identifier) - { - state.client_hello( - new Client_Hello(state.handshake_io(), - state.hash(), - policy(), - callbacks(), - rng(), - secure_renegotiation_data_for_client_hello(), - *session_info, - next_protocols)); - - state.resumed_session = std::move(session_info); - } + state.client_hello( + new Client_Hello(state.handshake_io(), + state.hash(), + policy(), + callbacks(), + rng(), + secure_renegotiation_data_for_client_hello(), + *session_info, + next_protocols)); + + state.resumed_session = std::move(session_info); } } } if(!state.client_hello()) // not resuming { - Client_Hello::Settings client_settings(version, m_info.hostname(), srp_identifier); + Client_Hello::Settings client_settings(version, m_info.hostname()); state.client_hello(new Client_Hello( state.handshake_io(), state.hash(), @@ -578,11 +571,11 @@ void Client::process_handshake_msg(const Handshake_State* active_state, { auto trusted_CAs = m_creds.trusted_certificate_authorities("tls-client", m_info.hostname()); - std::vector<std::shared_ptr<const OCSP::Response>> ocsp; + std::vector<std::optional<OCSP::Response>> ocsp; if(state.server_cert_status() != nullptr) { try { - ocsp.push_back(std::make_shared<OCSP::Response>(state.server_cert_status()->response())); + ocsp.push_back(OCSP::Response(state.server_cert_status()->response())); } catch(Decoding_Error&) { @@ -709,7 +702,6 @@ void Client::process_handshake_msg(const Handshake_State* active_state, get_peer_cert_chain(state), session_ticket, m_info, - "", state.server_hello()->srtp_profile() ); diff --git a/src/lib/tls/tls_client.h b/src/lib/tls/tls_client.h index 7440e59ef..8528491ce 100644 --- a/src/lib/tls/tls_client.h +++ b/src/lib/tls/tls_client.h @@ -75,7 +75,6 @@ class BOTAN_PUBLIC_API(2,0) Client final : public Channel void send_client_hello(Handshake_State& state, bool force_full_renegotiation, Protocol_Version version, - const std::string& srp_identifier = "", const std::vector<std::string>& next_protocols = {}); void process_handshake_msg(const Handshake_State* active_state, diff --git a/src/lib/tls/tls_extensions.cpp b/src/lib/tls/tls_extensions.cpp index 631868703..ce067d7c0 100644 --- a/src/lib/tls/tls_extensions.cpp +++ b/src/lib/tls/tls_extensions.cpp @@ -24,11 +24,6 @@ Extension* make_extension(TLS_Data_Reader& reader, uint16_t code, uint16_t size, case TLSEXT_SERVER_NAME_INDICATION: return new Server_Name_Indicator(reader, size); -#if defined(BOTAN_HAS_SRP6) - case TLSEXT_SRP_IDENTIFIER: - return new SRP_Identifier(reader, size); -#endif - case TLSEXT_SUPPORTED_GROUPS: return new Supported_Groups(reader, size); @@ -213,27 +208,6 @@ std::vector<uint8_t> Server_Name_Indicator::serialize(Connection_Side /*whoami*/ return buf; } -#if defined(BOTAN_HAS_SRP6) - -SRP_Identifier::SRP_Identifier(TLS_Data_Reader& reader, - uint16_t extension_size) : m_srp_identifier(reader.get_string(1, 1, 255)) - { - if(m_srp_identifier.size() + 1 != extension_size) - throw Decoding_Error("Bad encoding for SRP identifier extension"); - } - -std::vector<uint8_t> SRP_Identifier::serialize(Connection_Side /*whoami*/) const - { - std::vector<uint8_t> buf; - - const uint8_t* srp_bytes = cast_char_ptr_to_uint8(m_srp_identifier.data()); - append_tls_length_value(buf, srp_bytes, m_srp_identifier.size(), 1); - - return buf; - } - -#endif - Renegotiation_Extension::Renegotiation_Extension(TLS_Data_Reader& reader, uint16_t extension_size) : m_reneg_data(reader.get_range<uint8_t>(1, 0, 255)) { diff --git a/src/lib/tls/tls_extensions.h b/src/lib/tls/tls_extensions.h index a426c8e56..fefa8af77 100644 --- a/src/lib/tls/tls_extensions.h +++ b/src/lib/tls/tls_extensions.h @@ -36,7 +36,6 @@ enum Handshake_Extension_Type { TLSEXT_CERTIFICATE_TYPES = 9, TLSEXT_SUPPORTED_GROUPS = 10, TLSEXT_EC_POINT_FORMATS = 11, - TLSEXT_SRP_IDENTIFIER = 12, TLSEXT_SIGNATURE_ALGORITHMS = 13, TLSEXT_USE_SRTP = 14, TLSEXT_ALPN = 16, @@ -101,34 +100,6 @@ class BOTAN_UNSTABLE_API Server_Name_Indicator final : public Extension std::string m_sni_host_name; }; -#if defined(BOTAN_HAS_SRP6) -/** -* SRP identifier extension (RFC 5054) -*/ -class BOTAN_UNSTABLE_API SRP_Identifier final : public Extension - { - public: - static Handshake_Extension_Type static_type() - { return TLSEXT_SRP_IDENTIFIER; } - - Handshake_Extension_Type type() const override { return static_type(); } - - explicit SRP_Identifier(const std::string& identifier) : - m_srp_identifier(identifier) {} - - SRP_Identifier(TLS_Data_Reader& reader, - uint16_t extension_size); - - std::string identifier() const { return m_srp_identifier; } - - std::vector<uint8_t> serialize(Connection_Side whoami) const override; - - bool empty() const override { return m_srp_identifier.empty(); } - private: - std::string m_srp_identifier; - }; -#endif - /** * Renegotiation Indication Extension (RFC 5746) */ diff --git a/src/lib/tls/tls_handshake_state.cpp b/src/lib/tls/tls_handshake_state.cpp index 7c1264511..ee54000f7 100644 --- a/src/lib/tls/tls_handshake_state.cpp +++ b/src/lib/tls/tls_handshake_state.cpp @@ -359,18 +359,6 @@ Handshake_State::get_next_handshake_msg() return m_handshake_io->get_next_record(expecting_ccs); } -std::string Handshake_State::srp_identifier() const - { -#if defined(BOTAN_HAS_SRP6) - // Authenticated via the successful key exchange - if(ciphersuite().valid() && ciphersuite().kex_method() == Kex_Algo::SRP_SHA) - return client_hello()->srp_identifier(); -#endif - - return ""; - } - - std::vector<uint8_t> Handshake_State::session_ticket() const { if(new_session_ticket() && !new_session_ticket()->ticket().empty()) diff --git a/src/lib/tls/tls_handshake_state.h b/src/lib/tls/tls_handshake_state.h index 3321a6210..0238ebd2b 100644 --- a/src/lib/tls/tls_handshake_state.h +++ b/src/lib/tls/tls_handshake_state.h @@ -93,8 +93,6 @@ class Handshake_State bool for_client_auth, const Policy& policy) const; - std::string srp_identifier() const; - KDF* protocol_specific_prf() const; Protocol_Version version() const { return m_version; } diff --git a/src/lib/tls/tls_messages.h b/src/lib/tls/tls_messages.h index fc95a1c02..5de15f0a2 100644 --- a/src/lib/tls/tls_messages.h +++ b/src/lib/tls/tls_messages.h @@ -25,10 +25,6 @@ #include <botan/cecpq1.h> #endif -#if defined(BOTAN_HAS_SRP6) - #include <botan/srp6.h> -#endif - namespace Botan { class Public_Key; @@ -74,20 +70,16 @@ class BOTAN_UNSTABLE_API Client_Hello final : public Handshake_Message { public: Settings(const Protocol_Version version, - const std::string& hostname = "", - const std::string& srp_identifier = "") : + const std::string& hostname = "") : m_new_session_version(version), - m_hostname(hostname), - m_srp_identifier(srp_identifier) {} + m_hostname(hostname) {} const Protocol_Version protocol_version() const { return m_new_session_version; } const std::string& hostname() const { return m_hostname; } - const std::string& srp_identifier() const { return m_srp_identifier; } private: const Protocol_Version m_new_session_version; const std::string m_hostname; - const std::string m_srp_identifier; }; Handshake_Type type() const override { return CLIENT_HELLO; } @@ -118,10 +110,6 @@ class BOTAN_UNSTABLE_API Client_Hello final : public Handshake_Message std::string sni_hostname() const; -#if defined(BOTAN_HAS_SRP6) - std::string srp_identifier() const; -#endif - bool secure_renegotiation() const; std::vector<uint8_t> renegotiation_info() const; @@ -543,15 +531,6 @@ class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message // Only valid for certain kex types const Private_Key& server_kex_key() const; -#if defined(BOTAN_HAS_SRP6) - // Only valid for SRP negotiation - SRP6_Server_Session& server_srp_params() const - { - BOTAN_ASSERT_NONNULL(m_srp_params); - return *m_srp_params; - } -#endif - #if defined(BOTAN_HAS_CECPQ1) // Only valid for CECPQ1 negotiation const CECPQ1_key& cecpq1_key() const @@ -577,10 +556,6 @@ class BOTAN_UNSTABLE_API Server_Key_Exchange final : public Handshake_Message private: std::vector<uint8_t> serialize() const override; -#if defined(BOTAN_HAS_SRP6) - std::unique_ptr<SRP6_Server_Session> m_srp_params; -#endif - #if defined(BOTAN_HAS_CECPQ1) std::unique_ptr<CECPQ1_key> m_cecpq1_key; #endif diff --git a/src/lib/tls/tls_policy.cpp b/src/lib/tls/tls_policy.cpp index a63c73101..723ba4350 100644 --- a/src/lib/tls/tls_policy.cpp +++ b/src/lib/tls/tls_policy.cpp @@ -57,9 +57,6 @@ std::vector<std::string> Policy::allowed_ciphers() const //"ARIA-128/GCM", //"AES-256", //"AES-128", - //"Camellia-256", - //"Camellia-128", - //"SEED", //"3DES", }; } @@ -92,7 +89,6 @@ std::vector<std::string> Policy::allowed_macs() const std::vector<std::string> Policy::allowed_key_exchange_methods() const { return { - //"SRP_SHA", //"ECDHE_PSK", //"DHE_PSK", //"PSK", @@ -428,8 +424,7 @@ class Ciphersuite_Preference_Ordering final } -std::vector<uint16_t> Policy::ciphersuite_list(Protocol_Version version, - bool have_srp) const +std::vector<uint16_t> Policy::ciphersuite_list(Protocol_Version version) const { const std::vector<std::string> ciphers = allowed_ciphers(); const std::vector<std::string> macs = allowed_macs(); @@ -452,10 +447,6 @@ std::vector<uint16_t> Policy::ciphersuite_list(Protocol_Version version, if(!this->acceptable_ciphersuite(suite)) continue; - // Are we doing SRP? - if(!have_srp && suite.kex_method() == Kex_Algo::SRP_SHA) - continue; - if(!value_exists(kex, suite.kex_algo())) continue; // unsupported key exchange diff --git a/src/lib/tls/tls_policy.h b/src/lib/tls/tls_policy.h index c0f618e0f..209e814c2 100644 --- a/src/lib/tls/tls_policy.h +++ b/src/lib/tls/tls_policy.h @@ -205,7 +205,7 @@ class BOTAN_PUBLIC_API(2,0) Policy virtual void check_peer_key_acceptable(const Public_Key& public_key) const; /** - * If this function returns false, unknown SRP/PSK identifiers + * If this function returns false, unknown PSK identifiers * will be rejected with an unknown_psk_identifier alert as soon * as the non-existence is identified. Otherwise, a false * identifier value will be used and the protocol allowed to @@ -295,8 +295,7 @@ class BOTAN_PUBLIC_API(2,0) Policy /** * Return allowed ciphersuites, in order of preference */ - virtual std::vector<uint16_t> ciphersuite_list(Protocol_Version version, - bool have_srp) const; + virtual std::vector<uint16_t> ciphersuite_list(Protocol_Version version) const; /** * @return the default MTU for DTLS diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp index 3fd4565fd..c62053857 100644 --- a/src/lib/tls/tls_server.cpp +++ b/src/lib/tls/tls_server.cpp @@ -104,15 +104,6 @@ bool check_for_resume(Session& session_info, session_info.ciphersuite_code())) return false; -#if defined(BOTAN_HAS_SRP6) - // client sent a different SRP identity - if(client_hello->srp_identifier() != "") - { - if(client_hello->srp_identifier() != session_info.srp_identifier()) - return false; - } -#endif - // client sent a different SNI hostname if(client_hello->sni_hostname() != "") { @@ -158,14 +149,12 @@ bool check_for_resume(Session& session_info, uint16_t choose_ciphersuite( const Policy& policy, Protocol_Version version, - Credentials_Manager& creds, const std::map<std::string, std::vector<X509_Certificate>>& cert_chains, const Client_Hello& client_hello) { const bool our_choice = policy.server_uses_own_ciphersuite_preferences(); - const bool have_srp = creds.attempt_srp("tls-server", client_hello.sni_hostname()); const std::vector<uint16_t> client_suites = client_hello.ciphersuites(); - const std::vector<uint16_t> server_suites = policy.ciphersuite_list(version, have_srp); + const std::vector<uint16_t> server_suites = policy.ciphersuite_list(version); if(server_suites.empty()) throw TLS_Exception(Alert::HANDSHAKE_FAILURE, @@ -248,20 +237,6 @@ uint16_t choose_ciphersuite( } } -#if defined(BOTAN_HAS_SRP6) - /* - The client may offer SRP cipher suites in the hello message but - omit the SRP extension. If the server would like to select an - SRP cipher suite in this case, the server SHOULD return a fatal - "unknown_psk_identity" alert immediately after processing the - client hello message. - - RFC 5054 section 2.5.1.2 - */ - if(suite.kex_method() == Kex_Algo::SRP_SHA && client_hello.srp_identifier() == "") - throw TLS_Exception(Alert::UNKNOWN_PSK_IDENTITY, - "Client wanted SRP but did not send username"); -#endif - return suite_id; } @@ -686,7 +661,6 @@ void Server::process_finished_msg(Server_Handshake_State& pending_state, get_peer_cert_chain(pending_state), std::vector<uint8_t>(), Server_Information(pending_state.client_hello()->sni_hostname()), - pending_state.srp_identifier(), pending_state.server_hello()->srtp_profile()); if(save_session(session_info)) @@ -871,7 +845,7 @@ void Server::session_create(Server_Handshake_State& pending_state, } const uint16_t ciphersuite = choose_ciphersuite(policy(), pending_state.version(), - m_creds, cert_chains, + cert_chains, *pending_state.client_hello()); Server_Hello::Settings srv_settings( diff --git a/src/lib/tls/tls_session.cpp b/src/lib/tls/tls_session.cpp index bd817687c..de118f778 100644 --- a/src/lib/tls/tls_session.cpp +++ b/src/lib/tls/tls_session.cpp @@ -29,7 +29,6 @@ Session::Session(const std::vector<uint8_t>& session_identifier, const std::vector<X509_Certificate>& certs, const std::vector<uint8_t>& ticket, const Server_Information& server_info, - const std::string& srp_identifier, uint16_t srtp_profile) : m_start_time(std::chrono::system_clock::now()), m_identifier(session_identifier), @@ -42,8 +41,7 @@ Session::Session(const std::vector<uint8_t>& session_identifier, m_extended_master_secret(extended_master_secret), m_encrypt_then_mac(encrypt_then_mac), m_peer_certs(certs), - m_server_info(server_info), - m_srp_identifier(srp_identifier) + m_server_info(server_info) { } @@ -124,8 +122,6 @@ Session::Session(const uint8_t ber[], size_t ber_len) server_service.value(), static_cast<uint16_t>(server_port)); - m_srp_identifier = srp_identifier_str.value(); - if(!peer_cert_bits.empty()) { DataSource_Memory certs(peer_cert_bits.data(), peer_cert_bits.size()); @@ -160,7 +156,7 @@ secure_vector<uint8_t> Session::DER_encode() const .encode(ASN1_String(m_server_info.hostname(), UTF8_STRING)) .encode(ASN1_String(m_server_info.service(), UTF8_STRING)) .encode(static_cast<size_t>(m_server_info.port())) - .encode(ASN1_String(m_srp_identifier, UTF8_STRING)) + .encode(ASN1_String("", UTF8_STRING)) // old srp identifier .encode(static_cast<size_t>(m_srtp_profile)) .end_cons() .get_contents(); diff --git a/src/lib/tls/tls_session.h b/src/lib/tls/tls_session.h index 5a75e6a32..5cb1f44be 100644 --- a/src/lib/tls/tls_session.h +++ b/src/lib/tls/tls_session.h @@ -54,7 +54,6 @@ class BOTAN_PUBLIC_API(2,0) Session final const std::vector<X509_Certificate>& peer_certs, const std::vector<uint8_t>& session_ticket, const Server_Information& server_info, - const std::string& srp_identifier, uint16_t srtp_profile); /** @@ -134,11 +133,6 @@ class BOTAN_PUBLIC_API(2,0) Session final Connection_Side side() const { return m_connection_side; } /** - * Get the SRP identity (if sent by the client in the initial handshake) - */ - const std::string& srp_identifier() const { return m_srp_identifier; } - - /** * Get the saved master secret */ const secure_vector<uint8_t>& master_secret() const { return m_master_secret; } @@ -200,7 +194,6 @@ class BOTAN_PUBLIC_API(2,0) Session final std::vector<X509_Certificate> m_peer_certs; Server_Information m_server_info; // optional - std::string m_srp_identifier; // optional }; } diff --git a/src/lib/tls/tls_suite_info.cpp b/src/lib/tls/tls_suite_info.cpp index 4c49f72ad..0f3e0527d 100644 --- a/src/lib/tls/tls_suite_info.cpp +++ b/src/lib/tls/tls_suite_info.cpp @@ -3,7 +3,7 @@ * * This file was automatically generated from the IANA assignments * (tls-parameters.txt sha256 6412d7a966151d409d463681e5427e706cd9066f13d34ca7a89f8cc2f7dff4b2) -* by ./src/scripts/tls_suite_info.py on 2020-11-17 +* by ./src/scripts/tls_suite_info.py on 2020-11-23 * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -25,20 +25,14 @@ const std::vector<Ciphersuite>& Ciphersuite::all_known_ciphersuites() Ciphersuite(0x0039, "DHE_RSA_WITH_AES_256_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x003C, "RSA_WITH_AES_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), Ciphersuite(0x003D, "RSA_WITH_AES_256_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0x0041, "RSA_WITH_CAMELLIA_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0x0045, "DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "Camellia-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x0067, "DHE_RSA_WITH_AES_128_CBC_SHA256", Auth_Method::RSA, Kex_Algo::DH, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), Ciphersuite(0x006B, "DHE_RSA_WITH_AES_256_CBC_SHA256", Auth_Method::RSA, Kex_Algo::DH, "AES-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0x0084, "RSA_WITH_CAMELLIA_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0x0088, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "Camellia-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x008B, "PSK_WITH_3DES_EDE_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::PSK, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x008C, "PSK_WITH_AES_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x008D, "PSK_WITH_AES_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x008F, "DHE_PSK_WITH_3DES_EDE_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x0090, "DHE_PSK_WITH_AES_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x0091, "DHE_PSK_WITH_AES_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0x0096, "RSA_WITH_SEED_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "SEED", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0x009A, "DHE_RSA_WITH_SEED_CBC_SHA", Auth_Method::RSA, Kex_Algo::DH, "SEED", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0x009C, "RSA_WITH_AES_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0x009D, "RSA_WITH_AES_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0x009E, "DHE_RSA_WITH_AES_128_GCM_SHA256", Auth_Method::RSA, Kex_Algo::DH, "AES-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), @@ -51,10 +45,6 @@ const std::vector<Ciphersuite>& Ciphersuite::all_known_ciphersuites() Ciphersuite(0x00AF, "PSK_WITH_AES_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "AES-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), Ciphersuite(0x00B2, "DHE_PSK_WITH_AES_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), Ciphersuite(0x00B3, "DHE_PSK_WITH_AES_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "AES-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), - Ciphersuite(0x00BA, "RSA_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0x00BE, "DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::RSA, Kex_Algo::DH, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0x00C0, "RSA_WITH_CAMELLIA_256_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0x00C4, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", Auth_Method::RSA, Kex_Algo::DH, "Camellia-256", 32, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), Ciphersuite(0x16B7, "CECPQ1_RSA_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::RSA, Kex_Algo::CECPQ1, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), Ciphersuite(0x16B8, "CECPQ1_ECDSA_WITH_CHACHA20_POLY1305_SHA256", Auth_Method::ECDSA, Kex_Algo::CECPQ1, "ChaCha20Poly1305", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_XOR_12), Ciphersuite(0x16B9, "CECPQ1_RSA_WITH_AES_256_GCM_SHA384", Auth_Method::RSA, Kex_Algo::CECPQ1, "AES-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), @@ -65,12 +55,6 @@ const std::vector<Ciphersuite>& Ciphersuite::all_known_ciphersuites() Ciphersuite(0xC012, "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", Auth_Method::RSA, Kex_Algo::ECDH, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0xC013, "ECDHE_RSA_WITH_AES_128_CBC_SHA", Auth_Method::RSA, Kex_Algo::ECDH, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0xC014, "ECDHE_RSA_WITH_AES_256_CBC_SHA", Auth_Method::RSA, Kex_Algo::ECDH, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0xC01A, "SRP_SHA_WITH_3DES_EDE_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::SRP_SHA, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0xC01B, "SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", Auth_Method::RSA, Kex_Algo::SRP_SHA, "3DES", 24, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0xC01D, "SRP_SHA_WITH_AES_128_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::SRP_SHA, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0xC01E, "SRP_SHA_RSA_WITH_AES_128_CBC_SHA", Auth_Method::RSA, Kex_Algo::SRP_SHA, "AES-128", 16, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0xC020, "SRP_SHA_WITH_AES_256_CBC_SHA", Auth_Method::IMPLICIT, Kex_Algo::SRP_SHA, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), - Ciphersuite(0xC021, "SRP_SHA_RSA_WITH_AES_256_CBC_SHA", Auth_Method::RSA, Kex_Algo::SRP_SHA, "AES-256", 32, "SHA-1", 20, KDF_Algo::SHA_1, Nonce_Format::CBC_MODE), Ciphersuite(0xC023, "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), Ciphersuite(0xC024, "ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", Auth_Method::ECDSA, Kex_Algo::ECDH, "AES-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), Ciphersuite(0xC027, "ECDHE_RSA_WITH_AES_128_CBC_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "AES-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), @@ -96,10 +80,6 @@ const std::vector<Ciphersuite>& Ciphersuite::all_known_ciphersuites() Ciphersuite(0xC06B, "PSK_WITH_ARIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0xC06C, "DHE_PSK_WITH_ARIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "ARIA-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0xC06D, "DHE_PSK_WITH_ARIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "ARIA-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), - Ciphersuite(0xC072, "ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::ECDSA, Kex_Algo::ECDH, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0xC073, "ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::ECDSA, Kex_Algo::ECDH, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), - Ciphersuite(0xC076, "ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::RSA, Kex_Algo::ECDH, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0xC077, "ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::RSA, Kex_Algo::ECDH, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), Ciphersuite(0xC07A, "RSA_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0xC07B, "RSA_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0xC07C, "DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::RSA, Kex_Algo::DH, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), @@ -112,12 +92,6 @@ const std::vector<Ciphersuite>& Ciphersuite::all_known_ciphersuites() Ciphersuite(0xC08F, "PSK_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0xC090, "DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "Camellia-128/GCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0xC091, "DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "Camellia-256/GCM", 32, "AEAD", 0, KDF_Algo::SHA_384, Nonce_Format::AEAD_IMPLICIT_4), - Ciphersuite(0xC094, "PSK_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::PSK, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0xC095, "PSK_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::PSK, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), - Ciphersuite(0xC096, "DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0xC097, "DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::DHE_PSK, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), - Ciphersuite(0xC09A, "ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "Camellia-128", 16, "SHA-256", 32, KDF_Algo::SHA_256, Nonce_Format::CBC_MODE), - Ciphersuite(0xC09B, "ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", Auth_Method::IMPLICIT, Kex_Algo::ECDHE_PSK, "Camellia-256", 32, "SHA-384", 48, KDF_Algo::SHA_384, Nonce_Format::CBC_MODE), Ciphersuite(0xC09C, "RSA_WITH_AES_128_CCM", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-128/CCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0xC09D, "RSA_WITH_AES_256_CCM", Auth_Method::IMPLICIT, Kex_Algo::STATIC_RSA, "AES-256/CCM", 32, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), Ciphersuite(0xC09E, "DHE_RSA_WITH_AES_128_CCM", Auth_Method::RSA, Kex_Algo::DH, "AES-128/CCM", 16, "AEAD", 0, KDF_Algo::SHA_256, Nonce_Format::AEAD_IMPLICIT_4), diff --git a/src/lib/x509/certstor.cpp b/src/lib/x509/certstor.cpp index a066f208d..9bec24f64 100644 --- a/src/lib/x509/certstor.cpp +++ b/src/lib/x509/certstor.cpp @@ -16,38 +16,29 @@ namespace Botan { Certificate_Store::~Certificate_Store() {} -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store::find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { const auto certs = find_all_certs(subject_dn, key_id); if(certs.empty()) { - return nullptr; // certificate not found + return std::nullopt; } // `count` might be greater than 1, but we'll just select the first match return certs.front(); } -std::shared_ptr<const X509_CRL> Certificate_Store::find_crl_for(const X509_Certificate&) const +std::optional<X509_CRL> Certificate_Store::find_crl_for(const X509_Certificate&) const { - return {}; + return std::nullopt; } void Certificate_Store_In_Memory::add_certificate(const X509_Certificate& cert) { for(const auto& c : m_certs) - if(*c == cert) - return; - - m_certs.push_back(std::make_shared<const X509_Certificate>(cert)); - } - -void Certificate_Store_In_Memory::add_certificate(std::shared_ptr<const X509_Certificate> cert) - { - for(const auto& c : m_certs) - if(*c == *cert) + if(c == cert) return; m_certs.push_back(cert); @@ -57,11 +48,11 @@ std::vector<X509_DN> Certificate_Store_In_Memory::all_subjects() const { std::vector<X509_DN> subjects; for(const auto& cert : m_certs) - subjects.push_back(cert->subject_dn()); + subjects.push_back(cert.subject_dn()); return subjects; } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_In_Memory::find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { @@ -70,43 +61,43 @@ Certificate_Store_In_Memory::find_cert(const X509_DN& subject_dn, // Only compare key ids if set in both call and in the cert if(key_id.size()) { - std::vector<uint8_t> skid = cert->subject_key_id(); + std::vector<uint8_t> skid = cert.subject_key_id(); if(skid.size() && skid != key_id) // no match continue; } - if(cert->subject_dn() == subject_dn) + if(cert.subject_dn() == subject_dn) return cert; } - return nullptr; + return std::nullopt; } -std::vector<std::shared_ptr<const X509_Certificate>> Certificate_Store_In_Memory::find_all_certs( +std::vector<X509_Certificate> Certificate_Store_In_Memory::find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { - std::vector<std::shared_ptr<const X509_Certificate>> matches; + std::vector<X509_Certificate> matches; for(const auto& cert : m_certs) { if(key_id.size()) { - std::vector<uint8_t> skid = cert->subject_key_id(); + std::vector<uint8_t> skid = cert.subject_key_id(); if(skid.size() && skid != key_id) // no match continue; } - if(cert->subject_dn() == subject_dn) + if(cert.subject_dn() == subject_dn) matches.push_back(cert); } return matches; } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_In_Memory::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const { if(key_hash.size() != 20) @@ -115,15 +106,15 @@ Certificate_Store_In_Memory::find_cert_by_pubkey_sha1(const std::vector<uint8_t> std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-1")); for(const auto& cert : m_certs){ - hash->update(cert->subject_public_key_bitstring()); + hash->update(cert.subject_public_key_bitstring()); if(key_hash == hash->final_stdvec()) //final_stdvec also clears the hash to initial state return cert; } - return nullptr; + return std::nullopt; } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_In_Memory::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const { if(subject_hash.size() != 32) @@ -132,30 +123,24 @@ Certificate_Store_In_Memory::find_cert_by_raw_subject_dn_sha256(const std::vecto std::unique_ptr<HashFunction> hash(HashFunction::create("SHA-256")); for(const auto& cert : m_certs){ - hash->update(cert->raw_subject_dn()); + hash->update(cert.raw_subject_dn()); if(subject_hash == hash->final_stdvec()) //final_stdvec also clears the hash to initial state return cert; } - return nullptr; + return std::nullopt; } void Certificate_Store_In_Memory::add_crl(const X509_CRL& crl) { - std::shared_ptr<const X509_CRL> crl_s = std::make_shared<const X509_CRL>(crl); - return add_crl(crl_s); - } - -void Certificate_Store_In_Memory::add_crl(std::shared_ptr<const X509_CRL> crl) - { - X509_DN crl_issuer = crl->issuer_dn(); + X509_DN crl_issuer = crl.issuer_dn(); for(auto& c : m_crls) { // Found an update of a previously existing one; replace it - if(c->issuer_dn() == crl_issuer) + if(c.issuer_dn() == crl_issuer) { - if(c->this_update() <= crl->this_update()) + if(c.this_update() <= crl.this_update()) c = crl; return; } @@ -165,7 +150,7 @@ void Certificate_Store_In_Memory::add_crl(std::shared_ptr<const X509_CRL> crl) m_crls.push_back(crl); } -std::shared_ptr<const X509_CRL> Certificate_Store_In_Memory::find_crl_for(const X509_Certificate& subject) const +std::optional<X509_CRL> Certificate_Store_In_Memory::find_crl_for(const X509_Certificate& subject) const { const std::vector<uint8_t>& key_id = subject.authority_key_id(); @@ -174,13 +159,13 @@ std::shared_ptr<const X509_CRL> Certificate_Store_In_Memory::find_crl_for(const // Only compare key ids if set in both call and in the CRL if(key_id.size()) { - std::vector<uint8_t> akid = c->authority_key_id(); + std::vector<uint8_t> akid = c.authority_key_id(); if(akid.size() && akid != key_id) // no match continue; } - if(c->issuer_dn() == subject.issuer_dn()) + if(c.issuer_dn() == subject.issuer_dn()) return c; } @@ -214,7 +199,8 @@ Certificate_Store_In_Memory::Certificate_Store_In_Memory(const std::string& dir) { try { - m_certs.push_back(std::make_shared<X509_Certificate>(src)); + X509_Certificate cert(src); + m_certs.push_back(cert); } catch(std::exception&) { diff --git a/src/lib/x509/certstor.h b/src/lib/x509/certstor.h index 6901589d2..0752e908f 100644 --- a/src/lib/x509/certstor.h +++ b/src/lib/x509/certstor.h @@ -10,6 +10,7 @@ #include <botan/x509cert.h> #include <botan/x509_crl.h> +#include <optional> namespace Botan { @@ -25,18 +26,18 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store * Find a certificate by Subject DN and (optionally) key identifier * @param subject_dn the subject's distinguished name * @param key_id an optional key id - * @return a matching certificate or nullptr otherwise + * @return a matching certificate or nullopt otherwise * If more than one certificate in the certificate store matches, then * a single value is selected arbitrarily. */ - virtual std::shared_ptr<const X509_Certificate> + virtual std::optional<X509_Certificate> find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const; /** * Find all certificates with a given Subject DN. * Subject DN and even the key identifier might not be unique. */ - virtual std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs( + virtual std::vector<X509_Certificate> find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const = 0; @@ -44,26 +45,26 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store * Find a certificate by searching for one with a matching SHA-1 hash of * public key. Used for OCSP. * @param key_hash SHA-1 hash of the subject's public key - * @return a matching certificate or nullptr otherwise + * @return a matching certificate or nullopt otherwise */ - virtual std::shared_ptr<const X509_Certificate> + virtual std::optional<X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const = 0; /** * Find a certificate by searching for one with a matching SHA-256 hash of * raw subject name. Used for OCSP. * @param subject_hash SHA-256 hash of the subject's raw name - * @return a matching certificate or nullptr otherwise + * @return a matching certificate or nullopt otherwise */ - virtual std::shared_ptr<const X509_Certificate> + virtual std::optional<X509_Certificate> find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const = 0; /** * Finds a CRL for the given certificate * @param subject the subject certificate - * @return the CRL for subject or nullptr otherwise + * @return the CRL for subject or nullopt otherwise */ - virtual std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const; + virtual std::optional<X509_CRL> find_crl_for(const X509_Certificate& subject) const; /** * @return whether the certificate is known @@ -71,7 +72,7 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store */ bool certificate_known(const X509_Certificate& cert) const { - return find_cert(cert.subject_dn(), cert.subject_key_id()) != nullptr; + return find_cert(cert.subject_dn(), cert.subject_key_id()).has_value(); } // remove this (used by TLS::Server) @@ -107,24 +108,12 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_Memory final : public Certifica void add_certificate(const X509_Certificate& cert); /** - * Add a certificate already in a shared_ptr to the store. - * @param cert certificate to be added - */ - void add_certificate(std::shared_ptr<const X509_Certificate> cert); - - /** * Add a certificate revocation list (CRL) to the store. * @param crl CRL to be added */ void add_crl(const X509_CRL& crl); /** - * Add a certificate revocation list (CRL) to the store as a shared_ptr - * @param crl CRL to be added - */ - void add_crl(std::shared_ptr<const X509_CRL> crl); - - /** * @return DNs for all certificates managed by the store */ std::vector<X509_DN> all_subjects() const override; @@ -133,7 +122,7 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_Memory final : public Certifica * Find a certificate by Subject DN and (optionally) key identifier * @return the first certificate that matches */ - std::shared_ptr<const X509_Certificate> find_cert( + std::optional<X509_Certificate> find_cert( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; @@ -141,23 +130,23 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_Memory final : public Certifica * Find all certificates with a given Subject DN. * Subject DN and even the key identifier might not be unique. */ - std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs( + std::vector<X509_Certificate> find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override; - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override; /** * Finds a CRL for the given certificate */ - std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override; + std::optional<X509_CRL> find_crl_for(const X509_Certificate& subject) const override; private: // TODO: Add indexing on the DN and key id to avoid linear search - std::vector<std::shared_ptr<const X509_Certificate>> m_certs; - std::vector<std::shared_ptr<const X509_CRL>> m_crls; + std::vector<X509_Certificate> m_certs; + std::vector<X509_CRL> m_crls; }; } diff --git a/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp b/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp index 9804759b9..74837cd1e 100644 --- a/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp +++ b/src/lib/x509/certstor_flatfile/certstor_flatfile.cpp @@ -49,7 +49,7 @@ Flatfile_Certificate_Store::Flatfile_Certificate_Store(const std::string& file, for(const std::vector<uint8_t>& der : decode_all_certificates(file_stream)) { - std::shared_ptr<const X509_Certificate> cert = std::make_shared<const X509_Certificate>(der.data(), der.size()); + X509_Certificate cert(der); /* * Various weird or misconfigured system roots include intermediate certificates, @@ -57,16 +57,16 @@ Flatfile_Certificate_Store::Flatfile_Certificate_Store(const std::string& file, * Previously this code would error on such cases as an obvious misconfiguration, * but we cannot fix the trust store. So instead just ignore any such certificate. */ - if(cert->is_self_signed() && cert->is_CA_cert()) + if(cert.is_self_signed() && cert.is_CA_cert()) { - m_all_subjects.push_back(cert->subject_dn()); - m_dn_to_cert[cert->subject_dn()].push_back(cert); - m_pubkey_sha1_to_cert.emplace(cert->subject_public_key_bitstring_sha1(), cert); - m_subject_dn_sha256_to_cert.emplace(cert->raw_subject_dn_sha256(), cert); + m_all_subjects.push_back(cert.subject_dn()); + m_dn_to_cert[cert.subject_dn()].push_back(cert); + m_pubkey_sha1_to_cert.emplace(cert.subject_public_key_bitstring_sha1(), cert); + m_subject_dn_sha256_to_cert.emplace(cert.raw_subject_dn_sha256(), cert); } else if(!ignore_non_ca) { - throw Invalid_Argument("Flatfile_Certificate_Store received non CA cert " + cert->subject_dn().to_string()); + throw Invalid_Argument("Flatfile_Certificate_Store received non CA cert " + cert.subject_dn().to_string()); } } @@ -81,18 +81,18 @@ std::vector<X509_DN> Flatfile_Certificate_Store::all_subjects() const return m_all_subjects; } -std::vector<std::shared_ptr<const X509_Certificate>> Flatfile_Certificate_Store::find_all_certs( +std::vector<X509_Certificate> Flatfile_Certificate_Store::find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { - std::vector<std::shared_ptr<const X509_Certificate>> found_certs; + std::vector<X509_Certificate> found_certs; try { const auto certs = m_dn_to_cert.at(subject_dn); for(auto cert : certs) { - if(key_id.empty() || key_id == cert->subject_key_id()) + if(key_id.empty() || key_id == cert.subject_key_id()) { found_certs.push_back(cert); } @@ -106,7 +106,7 @@ std::vector<std::shared_ptr<const X509_Certificate>> Flatfile_Certificate_Store: return found_certs; } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Flatfile_Certificate_Store::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const { if(key_hash.size() != 20) @@ -121,10 +121,10 @@ Flatfile_Certificate_Store::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& return found_cert->second; } - return nullptr; + return std::nullopt; } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Flatfile_Certificate_Store::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const { if(subject_hash.size() != 32) @@ -137,10 +137,10 @@ Flatfile_Certificate_Store::find_cert_by_raw_subject_dn_sha256(const std::vector return found_cert->second; } - return nullptr; + return std::nullopt; } -std::shared_ptr<const X509_CRL> Flatfile_Certificate_Store::find_crl_for(const X509_Certificate& subject) const +std::optional<X509_CRL> Flatfile_Certificate_Store::find_crl_for(const X509_Certificate& subject) const { BOTAN_UNUSED(subject); return {}; diff --git a/src/lib/x509/certstor_flatfile/certstor_flatfile.h b/src/lib/x509/certstor_flatfile/certstor_flatfile.h index 1608aaa11..fba14382a 100644 --- a/src/lib/x509/certstor_flatfile/certstor_flatfile.h +++ b/src/lib/x509/certstor_flatfile/certstor_flatfile.h @@ -46,7 +46,7 @@ class BOTAN_PUBLIC_API(2, 11) Flatfile_Certificate_Store final : public Certific * Find all certificates with a given Subject DN. * Subject DN and even the key identifier might not be unique. */ - std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs( + std::vector<X509_Certificate> find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; /** @@ -54,23 +54,23 @@ class BOTAN_PUBLIC_API(2, 11) Flatfile_Certificate_Store final : public Certific * public key. * @return a matching certificate or nullptr otherwise */ - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override; - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override; /** * Fetching CRLs is not supported by this certificate store. This will * always return an empty list. */ - std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override; + std::optional<X509_CRL> find_crl_for(const X509_Certificate& subject) const override; private: std::vector<X509_DN> m_all_subjects; - std::map<X509_DN, std::vector<std::shared_ptr<const X509_Certificate>>> m_dn_to_cert; - std::map<std::vector<uint8_t>, std::shared_ptr<const X509_Certificate>> m_pubkey_sha1_to_cert; - std::map<std::vector<uint8_t>, std::shared_ptr<const X509_Certificate>> m_subject_dn_sha256_to_cert; + std::map<X509_DN, std::vector<X509_Certificate>> m_dn_to_cert; + std::map<std::vector<uint8_t>, std::optional<X509_Certificate>> m_pubkey_sha1_to_cert; + std::map<std::vector<uint8_t>, std::optional<X509_Certificate>> m_subject_dn_sha256_to_cert; }; } diff --git a/src/lib/x509/certstor_sql/certstor_sql.cpp b/src/lib/x509/certstor_sql/certstor_sql.cpp index ab4b8e64a..deab7abdd 100644 --- a/src/lib/x509/certstor_sql/certstor_sql.cpp +++ b/src/lib/x509/certstor_sql/certstor_sql.cpp @@ -44,7 +44,7 @@ Certificate_Store_In_SQL::Certificate_Store_In_SQL(std::shared_ptr<SQL_Database> } // Certificate handling -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_In_SQL::find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { std::shared_ptr<SQL_Database::Statement> stmt; @@ -67,16 +67,16 @@ Certificate_Store_In_SQL::find_cert(const X509_DN& subject_dn, const std::vector while(stmt->step()) { auto blob = stmt->get_blob(0); - return std::make_shared<X509_Certificate>(std::vector<uint8_t>(blob.first, blob.first + blob.second)); + return X509_Certificate(blob.first, blob.second); } - return std::shared_ptr<const X509_Certificate>(); + return std::optional<X509_Certificate>(); } -std::vector<std::shared_ptr<const X509_Certificate>> +std::vector<X509_Certificate> Certificate_Store_In_SQL::find_all_certs(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { - std::vector<std::shared_ptr<const X509_Certificate>> certs; + std::vector<X509_Certificate> certs; std::shared_ptr<SQL_Database::Statement> stmt; @@ -95,30 +95,29 @@ Certificate_Store_In_SQL::find_all_certs(const X509_DN& subject_dn, const std::v stmt->bind(2, key_id); } - std::shared_ptr<const X509_Certificate> cert; + std::optional<X509_Certificate> cert; while(stmt->step()) { auto blob = stmt->get_blob(0); - certs.push_back(std::make_shared<X509_Certificate>( - std::vector<uint8_t>(blob.first,blob.first + blob.second))); + certs.push_back(X509_Certificate(blob.first, blob.second)); } return certs; } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_In_SQL::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& /*key_hash*/) const { throw Not_Implemented("Certificate_Store_In_SQL::find_cert_by_pubkey_sha1"); } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_In_SQL::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& /*subject_hash*/) const { throw Not_Implemented("Certificate_Store_In_SQL::find_cert_by_raw_subject_dn_sha256"); } -std::shared_ptr<const X509_CRL> +std::optional<X509_CRL> Certificate_Store_In_SQL::find_crl_for(const X509_Certificate& subject) const { auto all_crls = generate_crls(); @@ -126,10 +125,10 @@ Certificate_Store_In_SQL::find_crl_for(const X509_Certificate& subject) const for(auto crl: all_crls) { if(!crl.get_revoked().empty() && crl.issuer_dn() == subject.issuer_dn()) - return std::shared_ptr<X509_CRL>(new X509_CRL(crl)); + return crl; } - return std::shared_ptr<X509_CRL>(); + return std::optional<X509_CRL>(); } std::vector<X509_DN> Certificate_Store_In_SQL::all_subjects() const @@ -209,7 +208,7 @@ std::shared_ptr<const Private_Key> Certificate_Store_In_SQL::find_key(const X509 return key; } -std::vector<std::shared_ptr<const X509_Certificate>> +std::vector<X509_Certificate> Certificate_Store_In_SQL::find_certs_for_key(const Private_Key& key) const { auto fpr = key.fingerprint_private("SHA-256"); @@ -217,12 +216,11 @@ Certificate_Store_In_SQL::find_certs_for_key(const Private_Key& key) const stmt->bind(1,fpr); - std::vector<std::shared_ptr<const X509_Certificate>> certs; + std::vector<X509_Certificate> certs; while(stmt->step()) { auto blob = stmt->get_blob(0); - certs.push_back(std::make_shared<X509_Certificate>( - std::vector<uint8_t>(blob.first,blob.first + blob.second))); + certs.push_back(X509_Certificate(blob.first, blob.second)); } return certs; diff --git a/src/lib/x509/certstor_sql/certstor_sql.h b/src/lib/x509/certstor_sql/certstor_sql.h index fd80eb191..05bb2c561 100644 --- a/src/lib/x509/certstor_sql/certstor_sql.h +++ b/src/lib/x509/certstor_sql/certstor_sql.h @@ -40,20 +40,20 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_SQL : public Certificate_Store /** * Returns the first certificate with matching subject DN and optional key ID. */ - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; /* * Find all certificates with a given Subject DN. * Subject DN and even the key identifier might not be unique. */ - std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs( + std::vector<X509_Certificate> find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override; - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override; /** @@ -77,7 +77,7 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_SQL : public Certificate_Store std::shared_ptr<const Private_Key> find_key(const X509_Certificate&) const; /// Returns all certificates for private key "key". - std::vector<std::shared_ptr<const X509_Certificate>> + std::vector<X509_Certificate> find_certs_for_key(const Private_Key& key) const; /** @@ -104,7 +104,7 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Store_In_SQL : public Certificate_Store /** * Generates a CRL for all certificates issued by the given issuer. */ - std::shared_ptr<const X509_CRL> + std::optional<X509_CRL> find_crl_for(const X509_Certificate& issuer) const override; private: diff --git a/src/lib/x509/certstor_system/certstor_system.cpp b/src/lib/x509/certstor_system/certstor_system.cpp index 0fca1a975..234979cab 100644 --- a/src/lib/x509/certstor_system/certstor_system.cpp +++ b/src/lib/x509/certstor_system/certstor_system.cpp @@ -31,32 +31,32 @@ System_Certificate_Store::System_Certificate_Store() #endif } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> System_Certificate_Store::find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { return m_system_store->find_cert(subject_dn, key_id); } -std::vector<std::shared_ptr<const X509_Certificate>> +std::vector<X509_Certificate> System_Certificate_Store::find_all_certs(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { return m_system_store->find_all_certs(subject_dn, key_id); } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> System_Certificate_Store::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const { return m_system_store->find_cert_by_pubkey_sha1(key_hash); } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> System_Certificate_Store::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const { return m_system_store->find_cert_by_raw_subject_dn_sha256(subject_hash); } -std::shared_ptr<const X509_CRL> +std::optional<X509_CRL> System_Certificate_Store::find_crl_for(const X509_Certificate& subject) const { return m_system_store->find_crl_for(subject); diff --git a/src/lib/x509/certstor_system/certstor_system.h b/src/lib/x509/certstor_system/certstor_system.h index 3a0fc6153..a2be72738 100644 --- a/src/lib/x509/certstor_system/certstor_system.h +++ b/src/lib/x509/certstor_system/certstor_system.h @@ -17,19 +17,19 @@ class BOTAN_PUBLIC_API(2,11) System_Certificate_Store final : public Certificate System_Certificate_Store(); - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; - std::vector<std::shared_ptr<const X509_Certificate>> + std::vector<X509_Certificate> find_all_certs(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override; - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override; - std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override; + std::optional<X509_CRL> find_crl_for(const X509_Certificate& subject) const override; std::vector<X509_DN> all_subjects() const override; diff --git a/src/lib/x509/certstor_system_macos/certstor_macos.cpp b/src/lib/x509/certstor_system_macos/certstor_macos.cpp index 12a907b2b..9885e33a8 100644 --- a/src/lib/x509/certstor_system_macos/certstor_macos.cpp +++ b/src/lib/x509/certstor_system_macos/certstor_macos.cpp @@ -288,24 +288,27 @@ class Certificate_Store_MacOS_Impl check_notnull(m_keychains, "initialize keychain array"); } - std::shared_ptr<const X509_Certificate> findOne(Query query) const + std::optional<X509_Certificate> findOne(Query query) const { query.addParameter(kSecMatchLimit, kSecMatchLimitOne); scoped_CFType<CFTypeRef> result(nullptr); search(std::move(query), &result.get()); - return (result) ? readCertificate(result.get()) : nullptr; + if(result) + return readCertificate(result.get()); + else + return std::nullopt; } - std::vector<std::shared_ptr<const X509_Certificate>> findAll(Query query) const + std::vector<X509_Certificate> findAll(Query query) const { query.addParameter(kSecMatchLimit, kSecMatchLimitAll); scoped_CFType<CFArrayRef> result(nullptr); search(std::move(query), (CFTypeRef*)&result.get()); - std::vector<std::shared_ptr<const X509_Certificate>> output; + std::vector<X509_Certificate> output; if(result) { @@ -341,7 +344,7 @@ class Certificate_Store_MacOS_Impl /** * Convert a CFTypeRef object into a Botan::X509_Certificate */ - std::shared_ptr<const X509_Certificate> readCertificate(CFTypeRef object) const + X509_Certificate readCertificate(CFTypeRef object) const { if(!object || CFGetTypeID(object) != SecCertificateGetTypeID()) { @@ -357,7 +360,7 @@ class Certificate_Store_MacOS_Impl const auto length = CFDataGetLength(derData.get()); DataSource_Memory ds(data, length); - return std::make_shared<Botan::X509_Certificate>(ds); + return X509_Certificate(ds); } CFArrayRef keychains() const { return m_keychains.get(); } @@ -395,7 +398,7 @@ std::vector<X509_DN> Certificate_Store_MacOS::all_subjects() const std::vector<X509_DN> output; std::transform(certificates.cbegin(), certificates.cend(), std::back_inserter(output), - [](const std::shared_ptr<const X509_Certificate> cert) + [](const std::optional<X509_Certificate> cert) { return cert->subject_dn(); }); @@ -403,7 +406,7 @@ std::vector<X509_DN> Certificate_Store_MacOS::all_subjects() const return output; } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_MacOS::find_cert(const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { @@ -418,7 +421,7 @@ Certificate_Store_MacOS::find_cert(const X509_DN& subject_dn, return m_impl->findOne(std::move(query)); } -std::vector<std::shared_ptr<const X509_Certificate>> Certificate_Store_MacOS::find_all_certs( +std::vector<X509_Certificate> Certificate_Store_MacOS::find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { @@ -433,7 +436,7 @@ std::vector<std::shared_ptr<const X509_Certificate>> Certificate_Store_MacOS::fi return m_impl->findAll(std::move(query)); } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_MacOS::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const { if(key_hash.size() != 20) @@ -447,14 +450,14 @@ Certificate_Store_MacOS::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& ke return m_impl->findOne(std::move(query)); } -std::shared_ptr<const X509_Certificate> +std::optional<X509_Certificate> Certificate_Store_MacOS::find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const { BOTAN_UNUSED(subject_hash); throw Not_Implemented("Certificate_Store_MacOS::find_cert_by_raw_subject_dn_sha256"); } -std::shared_ptr<const X509_CRL> Certificate_Store_MacOS::find_crl_for(const X509_Certificate& subject) const +std::optional<X509_CRL> Certificate_Store_MacOS::find_crl_for(const X509_Certificate& subject) const { BOTAN_UNUSED(subject); return {}; diff --git a/src/lib/x509/certstor_system_macos/certstor_macos.h b/src/lib/x509/certstor_system_macos/certstor_macos.h index e7416e631..3c983dc2e 100644 --- a/src/lib/x509/certstor_system_macos/certstor_macos.h +++ b/src/lib/x509/certstor_system_macos/certstor_macos.h @@ -41,7 +41,7 @@ class BOTAN_PUBLIC_API(2, 10) Certificate_Store_MacOS final : public Certificate * Find a certificate by Subject DN and (optionally) key identifier * @return the first certificate that matches */ - std::shared_ptr<const X509_Certificate> find_cert( + std::optional<X509_Certificate> find_cert( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; @@ -49,7 +49,7 @@ class BOTAN_PUBLIC_API(2, 10) Certificate_Store_MacOS final : public Certificate * Find all certificates with a given Subject DN. * Subject DN and even the key identifier might not be unique. */ - std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs( + std::vector<X509_Certificate> find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; /** @@ -57,20 +57,20 @@ class BOTAN_PUBLIC_API(2, 10) Certificate_Store_MacOS final : public Certificate * public key. * @return a matching certificate or nullptr otherwise */ - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override; /** * @throws Botan::Not_Implemented */ - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override; /** * Fetching CRLs is not supported by the keychain on macOS. This will * always return an empty list. */ - std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override; + std::optional<X509_CRL> find_crl_for(const X509_Certificate& subject) const override; private: std::shared_ptr<Certificate_Store_MacOS_Impl> m_impl; diff --git a/src/lib/x509/certstor_system_windows/certstor_windows.cpp b/src/lib/x509/certstor_system_windows/certstor_windows.cpp index ba202b48c..d112047db 100644 --- a/src/lib/x509/certstor_system_windows/certstor_windows.cpp +++ b/src/lib/x509/certstor_system_windows/certstor_windows.cpp @@ -23,8 +23,6 @@ namespace Botan { namespace { -using Cert_Pointer = std::shared_ptr<const Botan::X509_Certificate>; -using Cert_Vector = std::vector<Cert_Pointer>; const std::array<const char*, 2> cert_store_names{"Root", "CA"}; /** @@ -119,11 +117,12 @@ HCERTSTORE open_cert_store(const char* cert_store_name) return store; } -Cert_Vector search_cert_stores(const _CRYPTOAPI_BLOB& blob, const DWORD& find_type, - std::function<bool(const Cert_Vector& certs, Cert_Pointer cert)> filter, - bool return_on_first_found) +std::vector<X509_Certificate> search_cert_stores( + const _CRYPTOAPI_BLOB& blob, const DWORD& find_type, + std::function<bool (const std::vector<X509_Certificate>& certs, const X509_Certificate& cert)> filter, + bool return_on_first_found) { - Cert_Vector certs; + std::vector<X509_Certificate> certs; for(const auto store_name : cert_store_names) { Handle_Guard<HCERTSTORE> windows_cert_store = open_cert_store(store_name); @@ -133,7 +132,7 @@ Cert_Vector search_cert_stores(const _CRYPTOAPI_BLOB& blob, const DWORD& find_ty WINCRYPT_UNUSED_PARAM, find_type, &blob, cert_context.get()))) { - auto cert = std::make_shared<X509_Certificate>(cert_context->pbCertEncoded, cert_context->cbCertEncoded); + X509_Certificate cert(cert_context->pbCertEncoded, cert_context->cbCertEncoded); if(filter(certs, cert)) { if(return_on_first_found) @@ -148,15 +147,15 @@ Cert_Vector search_cert_stores(const _CRYPTOAPI_BLOB& blob, const DWORD& find_ty return certs; } -bool already_contains_certificate(const Cert_Vector& certs, Cert_Pointer cert) +bool already_contains_certificate(const std::vector<X509_Certificate>& certs, X509_Certificate cert) { - return std::any_of(certs.begin(), certs.end(), [&](std::shared_ptr<const Botan::X509_Certificate> c) + return std::any_of(certs.begin(), certs.end(), [&](const X509_Certificate& c) { - return *c == *cert; + return c == cert; }); } -Cert_Vector find_cert_by_dn_and_key_id(const Botan::X509_DN& subject_dn, +std::vector<X509_Certificate> find_cert_by_dn_and_key_id(const Botan::X509_DN& subject_dn, const std::vector<uint8_t>& key_id, bool return_on_first_found) { @@ -179,9 +178,9 @@ Cert_Vector find_cert_by_dn_and_key_id(const Botan::X509_DN& subject_dn, blob.pbData = const_cast<BYTE*>(key_id.data()); } - auto filter = [&](const Cert_Vector& certs, Cert_Pointer cert) + auto filter = [&](const std::vector<X509_Certificate>& certs, const X509_Certificate& cert) { - return !already_contains_certificate(certs, cert) && (key_id.empty() || cert->subject_dn() == subject_dn); + return !already_contains_certificate(certs, cert) && (key_id.empty() || cert.subject_dn() == subject_dn); }; return search_cert_stores(blob, find_type, filter, return_on_first_found); @@ -210,21 +209,26 @@ std::vector<X509_DN> Certificate_Store_Windows::all_subjects() const return subject_dns; } -Cert_Pointer Certificate_Store_Windows::find_cert(const Botan::X509_DN& subject_dn, - const std::vector<uint8_t>& key_id) const +std::optional<X509_Certificate> +Certificate_Store_Windows::find_cert(const Botan::X509_DN& subject_dn, + const std::vector<uint8_t>& key_id) const { const auto certs = find_cert_by_dn_and_key_id(subject_dn, key_id, true); - return certs.empty() ? nullptr : certs.front(); + if(certs.empty()) + return std::nullopt; + else + return certs.front(); } -Cert_Vector Certificate_Store_Windows::find_all_certs( +std::vector<X509_Certificate> Certificate_Store_Windows::find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const { return find_cert_by_dn_and_key_id(subject_dn, key_id, false); } -Cert_Pointer Certificate_Store_Windows::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const +std::optional<X509_Certificate> +Certificate_Store_Windows::find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const { if(key_hash.size() != 20) { @@ -235,23 +239,27 @@ Cert_Pointer Certificate_Store_Windows::find_cert_by_pubkey_sha1(const std::vect blob.cbData = static_cast<DWORD>(key_hash.size()); blob.pbData = const_cast<BYTE*>(key_hash.data()); - auto filter = [](const Cert_Vector&, Cert_Pointer) { return true; }; + auto filter = [&](const std::vector<X509_Certificate>&, const X509_Certificate&) { return true; }; const auto certs = search_cert_stores(blob, CERT_FIND_KEY_IDENTIFIER, filter, true); - return certs.empty() ? nullptr : certs.front(); + if(certs.empty()) + return std::nullopt; + else + return certs.front(); } -Cert_Pointer Certificate_Store_Windows::find_cert_by_raw_subject_dn_sha256( +std::optional<X509_Certificate> +Certificate_Store_Windows::find_cert_by_raw_subject_dn_sha256( const std::vector<uint8_t>& subject_hash) const { BOTAN_UNUSED(subject_hash); throw Not_Implemented("Certificate_Store_Windows::find_cert_by_raw_subject_dn_sha256"); } -std::shared_ptr<const X509_CRL> Certificate_Store_Windows::find_crl_for(const X509_Certificate& subject) const +std::optional<X509_CRL> Certificate_Store_Windows::find_crl_for(const X509_Certificate& subject) const { // TODO: this could be implemented by using the CertFindCRLInStore function BOTAN_UNUSED(subject); - return {}; + return std::nullopt; } } diff --git a/src/lib/x509/certstor_system_windows/certstor_windows.h b/src/lib/x509/certstor_system_windows/certstor_windows.h index f47e718c8..890920ac9 100644 --- a/src/lib/x509/certstor_system_windows/certstor_windows.h +++ b/src/lib/x509/certstor_system_windows/certstor_windows.h @@ -34,7 +34,7 @@ class BOTAN_PUBLIC_API(2, 11) Certificate_Store_Windows final : public Certifica * Find a certificate by Subject DN and (optionally) key identifier * @return the first certificate that matches */ - std::shared_ptr<const X509_Certificate> find_cert( + std::optional<X509_Certificate> find_cert( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; @@ -42,7 +42,7 @@ class BOTAN_PUBLIC_API(2, 11) Certificate_Store_Windows final : public Certifica * Find all certificates with a given Subject DN. * Subject DN and even the key identifier might not be unique. */ - std::vector<std::shared_ptr<const X509_Certificate>> find_all_certs( + std::vector<X509_Certificate> find_all_certs( const X509_DN& subject_dn, const std::vector<uint8_t>& key_id) const override; /** @@ -50,20 +50,20 @@ class BOTAN_PUBLIC_API(2, 11) Certificate_Store_Windows final : public Certifica * public key. * @return a matching certificate or nullptr otherwise */ - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_pubkey_sha1(const std::vector<uint8_t>& key_hash) const override; /** * @throws Botan::Not_Implemented */ - std::shared_ptr<const X509_Certificate> + std::optional<X509_Certificate> find_cert_by_raw_subject_dn_sha256(const std::vector<uint8_t>& subject_hash) const override; /** * Not Yet Implemented * @return nullptr; */ - std::shared_ptr<const X509_CRL> find_crl_for(const X509_Certificate& subject) const override; + std::optional<X509_CRL> find_crl_for(const X509_Certificate& subject) const override; }; } diff --git a/src/lib/x509/ocsp.cpp b/src/lib/x509/ocsp.cpp index f4d934526..69d216ad0 100644 --- a/src/lib/x509/ocsp.cpp +++ b/src/lib/x509/ocsp.cpp @@ -186,12 +186,12 @@ Certificate_Status_Code Response::verify_signature(const X509_Certificate& issue } Certificate_Status_Code Response::check_signature(const std::vector<Certificate_Store*>& trusted_roots, - const std::vector<std::shared_ptr<const X509_Certificate>>& ee_cert_path) const + const std::vector<X509_Certificate>& ee_cert_path) const { if (m_responses.empty()) return m_dummy_response_status; - std::shared_ptr<const X509_Certificate> signing_cert; + std::optional<X509_Certificate> signing_cert; for(size_t i = 0; i != trusted_roots.size(); ++i) { @@ -223,13 +223,13 @@ Certificate_Status_Code Response::check_signature(const std::vector<Certificate_ for(size_t i = 1; i < ee_cert_path.size(); ++i) { // Check all CA certificates in the (assumed validated) EE cert path - if(!m_signer_name.empty() && ee_cert_path[i]->subject_dn() == m_signer_name) + if(!m_signer_name.empty() && ee_cert_path[i].subject_dn() == m_signer_name) { signing_cert = ee_cert_path[i]; break; } - if(m_key_hash.size() > 0 && ee_cert_path[i]->subject_public_key_bitstring_sha1() == m_key_hash) + if(m_key_hash.size() > 0 && ee_cert_path[i].subject_public_key_bitstring_sha1() == m_key_hash) { signing_cert = ee_cert_path[i]; break; @@ -244,13 +244,13 @@ Certificate_Status_Code Response::check_signature(const std::vector<Certificate_ // Check all CA certificates in the (assumed validated) EE cert path if(!m_signer_name.empty() && m_certs[i].subject_dn() == m_signer_name) { - signing_cert = std::make_shared<const X509_Certificate>(m_certs[i]); + signing_cert = m_certs[i]; break; } if(m_key_hash.size() > 0 && m_certs[i].subject_public_key_bitstring_sha1() == m_key_hash) { - signing_cert = std::make_shared<const X509_Certificate>(m_certs[i]); + signing_cert = m_certs[i]; break; } } diff --git a/src/lib/x509/ocsp.h b/src/lib/x509/ocsp.h index 552245644..139bd6c77 100644 --- a/src/lib/x509/ocsp.h +++ b/src/lib/x509/ocsp.h @@ -168,7 +168,7 @@ class BOTAN_PUBLIC_API(2,0) Response final * some cases. */ Certificate_Status_Code check_signature(const std::vector<Certificate_Store*>& trust_roots, - const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path = {}) const; + const std::vector<X509_Certificate>& cert_path = {}) const; /** * Verify that issuer's key signed this response diff --git a/src/lib/x509/pkix_types.h b/src/lib/x509/pkix_types.h index 221c67c25..64c746308 100644 --- a/src/lib/x509/pkix_types.h +++ b/src/lib/x509/pkix_types.h @@ -384,7 +384,7 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Extension * @param pos Position of subject certificate in cert_path */ virtual void validate(const X509_Certificate& subject, const X509_Certificate& issuer, - const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<X509_Certificate>& cert_path, std::vector<std::set<Certificate_Status_Code>>& cert_status, size_t pos); diff --git a/src/lib/x509/x509_ext.cpp b/src/lib/x509/x509_ext.cpp index 18fcaea44..e000b2f11 100644 --- a/src/lib/x509/x509_ext.cpp +++ b/src/lib/x509/x509_ext.cpp @@ -110,7 +110,7 @@ Extensions::create_extn_obj(const OID& oid, * Validate the extension (the default implementation is a NOP) */ void Certificate_Extension::validate(const X509_Certificate&, const X509_Certificate&, - const std::vector<std::shared_ptr<const X509_Certificate>>&, + const std::vector<X509_Certificate>&, std::vector<std::set<Certificate_Status_Code>>&, size_t) { @@ -555,7 +555,7 @@ void Name_Constraints::decode_inner(const std::vector<uint8_t>& in) } void Name_Constraints::validate(const X509_Certificate& subject, const X509_Certificate& issuer, - const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<X509_Certificate>& cert_path, std::vector<std::set<Certificate_Status_Code>>& cert_status, size_t pos) { @@ -580,7 +580,7 @@ void Name_Constraints::validate(const X509_Certificate& subject, const X509_Cert for(auto c: m_name_constraints.permitted()) { - switch(c.base().matches(*cert_path.at(j))) + switch(c.base().matches(cert_path.at(j))) { case GeneralName::MatchResult::NotFound: case GeneralName::MatchResult::All: @@ -597,7 +597,7 @@ void Name_Constraints::validate(const X509_Certificate& subject, const X509_Cert for(auto c: m_name_constraints.excluded()) { - switch(c.base().matches(*cert_path.at(j))) + switch(c.base().matches(cert_path.at(j))) { case GeneralName::MatchResult::All: case GeneralName::MatchResult::Some: @@ -687,7 +687,7 @@ void Certificate_Policies::decode_inner(const std::vector<uint8_t>& in) void Certificate_Policies::validate( const X509_Certificate& /*subject*/, const X509_Certificate& /*issuer*/, - const std::vector<std::shared_ptr<const X509_Certificate>>& /*cert_path*/, + const std::vector<X509_Certificate>& /*cert_path*/, std::vector<std::set<Certificate_Status_Code>>& cert_status, size_t pos) { diff --git a/src/lib/x509/x509_ext.h b/src/lib/x509/x509_ext.h index bdb8ebd20..58fd0b35a 100644 --- a/src/lib/x509/x509_ext.h +++ b/src/lib/x509/x509_ext.h @@ -229,7 +229,7 @@ class BOTAN_PUBLIC_API(2,0) Name_Constraints final : public Certificate_Extensio Name_Constraints(const NameConstraints &nc) : m_name_constraints(nc) {} void validate(const X509_Certificate& subject, const X509_Certificate& issuer, - const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<X509_Certificate>& cert_path, std::vector<std::set<Certificate_Status_Code>>& cert_status, size_t pos) override; @@ -267,7 +267,7 @@ class BOTAN_PUBLIC_API(2,0) Certificate_Policies final : public Certificate_Exte OID oid_of() const override { return static_oid(); } void validate(const X509_Certificate& subject, const X509_Certificate& issuer, - const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, + const std::vector<X509_Certificate>& cert_path, std::vector<std::set<Certificate_Status_Code>>& cert_status, size_t pos) override; private: @@ -481,7 +481,7 @@ class BOTAN_PUBLIC_API(2,4) Unknown_Extension final : public Certificate_Extensi bool is_critical_extension() const { return m_critical; } void validate(const X509_Certificate&, const X509_Certificate&, - const std::vector<std::shared_ptr<const X509_Certificate>>&, + const std::vector<X509_Certificate>&, std::vector<std::set<Certificate_Status_Code>>& cert_status, size_t pos) override { diff --git a/src/lib/x509/x509path.cpp b/src/lib/x509/x509path.cpp index b5cdc27c2..840e8f3bf 100644 --- a/src/lib/x509/x509path.cpp +++ b/src/lib/x509/x509path.cpp @@ -29,7 +29,7 @@ namespace Botan { * PKIX path validation */ CertificatePathStatusCodes -PKIX::check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +PKIX::check_chain(const std::vector<X509_Certificate>& cert_path, std::chrono::system_clock::time_point ref_time, const std::string& hostname, Usage_Type usage, @@ -45,14 +45,14 @@ PKIX::check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& ce CertificatePathStatusCodes cert_status(cert_path.size()); - if(!hostname.empty() && !cert_path[0]->matches_dns_name(hostname)) + if(!hostname.empty() && !cert_path[0].matches_dns_name(hostname)) cert_status[0].insert(Certificate_Status_Code::CERT_NAME_NOMATCH); - if(!cert_path[0]->allowed_usage(usage)) + if(!cert_path[0].allowed_usage(usage)) cert_status[0].insert(Certificate_Status_Code::INVALID_USAGE); - if(cert_path[0]->is_CA_cert() == false && - cert_path[0]->has_constraints(KEY_CERT_SIGN)) + if(cert_path[0].is_CA_cert() == false && + cert_path[0].has_constraints(KEY_CERT_SIGN)) { /* "If the keyCertSign bit is asserted, then the cA bit in the @@ -71,9 +71,9 @@ PKIX::check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& ce const bool at_self_signed_root = (i == cert_path.size() - 1); - const std::shared_ptr<const X509_Certificate>& subject = cert_path[i]; + const std::optional<X509_Certificate>& subject = cert_path[i]; - const std::shared_ptr<const X509_Certificate>& issuer = cert_path[at_self_signed_root ? (i) : (i + 1)]; + const std::optional<X509_Certificate>& issuer = cert_path[at_self_signed_root ? (i) : (i + 1)]; if(at_self_signed_root && (issuer->is_self_signed() == false)) { @@ -179,7 +179,7 @@ PKIX::check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& ce for(size_t i = cert_path.size() - 1; i > 0 ; --i) { std::set<Certificate_Status_Code>& status = cert_status.at(i); - const std::shared_ptr<const X509_Certificate>& subject = cert_path[i]; + const std::optional<X509_Certificate>& subject = cert_path[i]; /* * If the certificate was not self-issued, verify that max_path_length is @@ -211,8 +211,8 @@ PKIX::check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& ce } CertificatePathStatusCodes -PKIX::check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, +PKIX::check_ocsp(const std::vector<X509_Certificate>& cert_path, + const std::vector<std::optional<OCSP::Response>>& ocsp_responses, const std::vector<Certificate_Store*>& trusted_certstores, std::chrono::system_clock::time_point ref_time, std::chrono::seconds max_ocsp_age) @@ -226,10 +226,10 @@ PKIX::check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cer { std::set<Certificate_Status_Code>& status = cert_status.at(i); - std::shared_ptr<const X509_Certificate> subject = cert_path.at(i); - std::shared_ptr<const X509_Certificate> ca = cert_path.at(i+1); + std::optional<X509_Certificate> subject = cert_path.at(i); + std::optional<X509_Certificate> ca = cert_path.at(i+1); - if(i < ocsp_responses.size() && (ocsp_responses.at(i) != nullptr) + if(i < ocsp_responses.size() && (ocsp_responses.at(i) != std::nullopt) && (ocsp_responses.at(i)->status() == OCSP::Response_Status_Code::Successful)) { try @@ -262,8 +262,8 @@ PKIX::check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cer } CertificatePathStatusCodes -PKIX::check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<std::shared_ptr<const X509_CRL>>& crls, +PKIX::check_crl(const std::vector<X509_Certificate>& cert_path, + const std::vector<std::optional<X509_CRL>>& crls, std::chrono::system_clock::time_point ref_time) { if(cert_path.empty()) @@ -276,10 +276,10 @@ PKIX::check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert { std::set<Certificate_Status_Code>& status = cert_status.at(i); - if(i < crls.size() && crls.at(i)) + if(i < crls.size() && crls[i].has_value()) { - std::shared_ptr<const X509_Certificate> subject = cert_path.at(i); - std::shared_ptr<const X509_Certificate> ca = cert_path.at(i+1); + std::optional<X509_Certificate> subject = cert_path.at(i); + std::optional<X509_Certificate> ca = cert_path.at(i+1); if(!ca->allowed_usage(CRL_SIGN)) status.insert(Certificate_Status_Code::CA_CERT_NOT_FOR_CRL_ISSUER); @@ -332,7 +332,7 @@ PKIX::check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert } CertificatePathStatusCodes -PKIX::check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +PKIX::check_crl(const std::vector<X509_Certificate>& cert_path, const std::vector<Certificate_Store*>& certstores, std::chrono::system_clock::time_point ref_time) { @@ -342,14 +342,13 @@ PKIX::check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert if(certstores.empty()) throw Invalid_Argument("PKIX::check_crl certstores empty"); - std::vector<std::shared_ptr<const X509_CRL>> crls(cert_path.size()); + std::vector<std::optional<X509_CRL>> crls(cert_path.size()); for(size_t i = 0; i != cert_path.size(); ++i) { - BOTAN_ASSERT_NONNULL(cert_path[i]); for(size_t c = 0; c != certstores.size(); ++c) { - crls[i] = certstores[c]->find_crl_for(*cert_path[i]); + crls[i] = certstores[c]->find_crl_for(cert_path[i]); if(crls[i]) break; } @@ -361,7 +360,7 @@ PKIX::check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert #if defined(BOTAN_HAS_ONLINE_REVOCATION_CHECKS) CertificatePathStatusCodes -PKIX::check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +PKIX::check_ocsp_online(const std::vector<X509_Certificate>& cert_path, const std::vector<Certificate_Store*>& trusted_certstores, std::chrono::system_clock::time_point ref_time, std::chrono::milliseconds timeout, @@ -371,7 +370,7 @@ PKIX::check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate if(cert_path.empty()) throw Invalid_Argument("PKIX::check_ocsp_online cert_path empty"); - std::vector<std::future<std::shared_ptr<const OCSP::Response>>> ocsp_response_futures; + std::vector<std::future<std::optional<OCSP::Response>>> ocsp_response_futures; size_t to_ocsp = 1; @@ -382,18 +381,18 @@ PKIX::check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate for(size_t i = 0; i < to_ocsp; ++i) { - const std::shared_ptr<const X509_Certificate>& subject = cert_path.at(i); - const std::shared_ptr<const X509_Certificate>& issuer = cert_path.at(i+1); + const std::optional<X509_Certificate>& subject = cert_path.at(i); + const std::optional<X509_Certificate>& issuer = cert_path.at(i+1); if(subject->ocsp_responder() == "") { - ocsp_response_futures.emplace_back(std::async(std::launch::deferred, [&]() -> std::shared_ptr<const OCSP::Response> { - return std::make_shared<const OCSP::Response>(Certificate_Status_Code::OCSP_NO_REVOCATION_URL); + ocsp_response_futures.emplace_back(std::async(std::launch::deferred, [&]() -> std::optional<OCSP::Response> { + return OCSP::Response(Certificate_Status_Code::OCSP_NO_REVOCATION_URL); })); } else { - ocsp_response_futures.emplace_back(std::async(std::launch::async, [&]() -> std::shared_ptr<const OCSP::Response> { + ocsp_response_futures.emplace_back(std::async(std::launch::async, [&]() -> std::optional<OCSP::Response> { OCSP::Request req(*issuer, BigInt::decode(subject->serial_number())); HTTP::Response http; @@ -410,15 +409,15 @@ PKIX::check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate // log e.what() ? } if (http.status_code() != 200) - return std::make_shared<const OCSP::Response>(Certificate_Status_Code::OCSP_SERVER_NOT_AVAILABLE); + return OCSP::Response(Certificate_Status_Code::OCSP_SERVER_NOT_AVAILABLE); // Check the MIME type? - return std::make_shared<const OCSP::Response>(http.body()); + return OCSP::Response(http.body()); })); } } - std::vector<std::shared_ptr<const OCSP::Response>> ocsp_responses; + std::vector<std::optional<OCSP::Response>> ocsp_responses; for(size_t i = 0; i < ocsp_response_futures.size(); ++i) { @@ -429,7 +428,7 @@ PKIX::check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate } CertificatePathStatusCodes -PKIX::check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +PKIX::check_crl_online(const std::vector<X509_Certificate>& cert_path, const std::vector<Certificate_Store*>& certstores, Certificate_Store_In_Memory* crl_store, std::chrono::system_clock::time_point ref_time, @@ -440,16 +439,16 @@ PKIX::check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate> if(certstores.empty()) throw Invalid_Argument("PKIX::check_crl_online certstores empty"); - std::vector<std::future<std::shared_ptr<const X509_CRL>>> future_crls; - std::vector<std::shared_ptr<const X509_CRL>> crls(cert_path.size()); + std::vector<std::future<std::optional<X509_CRL>>> future_crls; + std::vector<std::optional<X509_CRL>> crls(cert_path.size()); for(size_t i = 0; i != cert_path.size(); ++i) { - const std::shared_ptr<const X509_Certificate>& cert = cert_path.at(i); + const std::optional<X509_Certificate>& cert = cert_path.at(i); for(size_t c = 0; c != certstores.size(); ++c) { crls[i] = certstores[c]->find_crl_for(*cert); - if(crls[i]) + if(crls[i].has_value()) break; } @@ -462,24 +461,24 @@ PKIX::check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate> We already have a CRL, so just insert this empty one to hold a place in the vector so that indexes match up */ - future_crls.emplace_back(std::future<std::shared_ptr<const X509_CRL>>()); + future_crls.emplace_back(std::future<std::optional<X509_CRL>>()); } else if(cert->crl_distribution_point() == "") { // Avoid creating a thread for this case - future_crls.emplace_back(std::async(std::launch::deferred, [&]() -> std::shared_ptr<const X509_CRL> { + future_crls.emplace_back(std::async(std::launch::deferred, [&]() -> std::optional<X509_CRL> { throw Not_Implemented("No CRL distribution point for this certificate"); })); } else { - future_crls.emplace_back(std::async(std::launch::async, [&]() -> std::shared_ptr<const X509_CRL> { + future_crls.emplace_back(std::async(std::launch::async, [&]() -> std::optional<X509_CRL> { auto http = HTTP::GET_sync(cert->crl_distribution_point(), /*redirects*/ 1, timeout); http.throw_unless_ok(); // check the mime type? - return std::make_shared<const X509_CRL>(http.body()); + return X509_CRL(http.body()); })); } } @@ -509,8 +508,8 @@ PKIX::check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate> if(crl_status[i].count(Certificate_Status_Code::VALID_CRL_CHECKED)) { // better be non-null, we supposedly validated it - BOTAN_ASSERT_NONNULL(crls[i]); - crl_store->add_crl(crls[i]); + BOTAN_ASSERT_NOMSG(crls[i].has_value()); + crl_store->add_crl(*crls[i]); } } } @@ -521,12 +520,12 @@ PKIX::check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate> #endif Certificate_Status_Code -PKIX::build_certificate_path(std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +PKIX::build_certificate_path(std::vector<X509_Certificate>& cert_path, const std::vector<Certificate_Store*>& trusted_certstores, - const std::shared_ptr<const X509_Certificate>& end_entity, - const std::vector<std::shared_ptr<const X509_Certificate>>& end_entity_extra) + const X509_Certificate& end_entity, + const std::vector<X509_Certificate>& end_entity_extra) { - if(end_entity->is_self_signed()) + if(end_entity.is_self_signed()) { return Certificate_Status_Code::CANNOT_ESTABLISH_TRUST; } @@ -540,7 +539,7 @@ PKIX::build_certificate_path(std::vector<std::shared_ptr<const X509_Certificate> std::set<std::string> certs_seen; cert_path.push_back(end_entity); - certs_seen.insert(end_entity->fingerprint("SHA-256")); + certs_seen.insert(end_entity.fingerprint("SHA-256")); Certificate_Store_In_Memory ee_extras; for(size_t i = 0; i != end_entity_extra.size(); ++i) @@ -549,11 +548,11 @@ PKIX::build_certificate_path(std::vector<std::shared_ptr<const X509_Certificate> // iterate until we reach a root or cannot find the issuer for(;;) { - const X509_Certificate& last = *cert_path.back(); + const X509_Certificate& last = cert_path.back(); const X509_DN issuer_dn = last.issuer_dn(); const std::vector<uint8_t> auth_key_id = last.authority_key_id(); - std::shared_ptr<const X509_Certificate> issuer; + std::optional<X509_Certificate> issuer; bool trusted_issuer = false; for(Certificate_Store* store : trusted_certstores) @@ -583,7 +582,7 @@ PKIX::build_certificate_path(std::vector<std::shared_ptr<const X509_Certificate> } certs_seen.insert(fprint); - cert_path.push_back(issuer); + cert_path.push_back(*issuer); if(issuer->is_self_signed()) { @@ -605,7 +604,7 @@ PKIX::build_certificate_path(std::vector<std::shared_ptr<const X509_Certificate> namespace { // <certificate, trusted?> -using cert_maybe_trusted = std::pair<std::shared_ptr<const X509_Certificate>,bool>; +using cert_maybe_trusted = std::pair<std::optional<X509_Certificate>,bool>; } /** @@ -626,10 +625,10 @@ using cert_maybe_trusted = std::pair<std::shared_ptr<const X509_Certificate>,boo * */ Certificate_Status_Code -PKIX::build_all_certificate_paths(std::vector<std::vector<std::shared_ptr<const X509_Certificate>>>& cert_paths_out, +PKIX::build_all_certificate_paths(std::vector<std::vector<X509_Certificate>>& cert_paths_out, const std::vector<Certificate_Store*>& trusted_certstores, - const std::shared_ptr<const X509_Certificate>& end_entity, - const std::vector<std::shared_ptr<const X509_Certificate>>& end_entity_extra) + const std::optional<X509_Certificate>& end_entity, + const std::vector<X509_Certificate>& end_entity_extra) { if(!cert_paths_out.empty()) { @@ -662,26 +661,26 @@ PKIX::build_all_certificate_paths(std::vector<std::vector<std::shared_ptr<const // new certs are added and removed from the path during the DFS // it is copied into cert_paths_out when we encounter a trusted root - std::vector<std::shared_ptr<const X509_Certificate>> path_so_far; + std::vector<X509_Certificate> path_so_far; // todo can we assume that the end certificate is not trusted? std::vector<cert_maybe_trusted> stack = { {end_entity, false} }; while(!stack.empty()) { + std::optional<X509_Certificate> last = stack.back().first; // found a deletion marker that guides the DFS, backtracing - if(stack.back().first == nullptr) + if(last == std::nullopt) { stack.pop_back(); - std::string fprint = path_so_far.back()->fingerprint("SHA-256"); + std::string fprint = path_so_far.back().fingerprint("SHA-256"); certs_seen.erase(fprint); path_so_far.pop_back(); } // process next cert on the path else { - std::shared_ptr<const X509_Certificate> last = stack.back().first; - bool trusted = stack.back().second; + const bool trusted = stack.back().second; stack.pop_back(); // certificate already seen? @@ -700,7 +699,7 @@ PKIX::build_all_certificate_paths(std::vector<std::vector<std::shared_ptr<const if(trusted) { cert_paths_out.push_back(path_so_far); - cert_paths_out.back().push_back(last); + cert_paths_out.back().push_back(*last); continue; } @@ -716,7 +715,7 @@ PKIX::build_all_certificate_paths(std::vector<std::vector<std::shared_ptr<const const std::vector<uint8_t> auth_key_id = last->authority_key_id(); // search for trusted issuers - std::vector<std::shared_ptr<const X509_Certificate>> trusted_issuers; + std::vector<X509_Certificate> trusted_issuers; for(Certificate_Store* store : trusted_certstores) { auto new_issuers = store->find_all_certs(issuer_dn, auth_key_id); @@ -724,7 +723,7 @@ PKIX::build_all_certificate_paths(std::vector<std::vector<std::shared_ptr<const } // search the supplemental certs - std::vector<std::shared_ptr<const X509_Certificate>> misc_issuers = + std::vector<X509_Certificate> misc_issuers = ee_extras.find_all_certs(issuer_dn, auth_key_id); // if we could not find any issuers, the current path ends here @@ -735,11 +734,11 @@ PKIX::build_all_certificate_paths(std::vector<std::vector<std::shared_ptr<const } // push the latest certificate onto the path_so_far - path_so_far.push_back(last); + path_so_far.push_back(*last); certs_seen.emplace(fprint); // push a deletion marker on the stack for backtracing later - stack.push_back({std::shared_ptr<const X509_Certificate>(nullptr),false}); + stack.push_back({std::optional<X509_Certificate>(), false}); for(const auto& trusted_cert : trusted_issuers) { @@ -851,21 +850,21 @@ Path_Validation_Result x509_path_validate( Usage_Type usage, std::chrono::system_clock::time_point ref_time, std::chrono::milliseconds ocsp_timeout, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp) + const std::vector<std::optional<OCSP::Response>>& ocsp_resp) { if(end_certs.empty()) { throw Invalid_Argument("x509_path_validate called with no subjects"); } - std::shared_ptr<const X509_Certificate> end_entity(std::make_shared<const X509_Certificate>(end_certs[0])); - std::vector<std::shared_ptr<const X509_Certificate>> end_entity_extra; + X509_Certificate end_entity = end_certs[0]; + std::vector<X509_Certificate> end_entity_extra; for(size_t i = 1; i < end_certs.size(); ++i) { - end_entity_extra.push_back(std::make_shared<const X509_Certificate>(end_certs[i])); + end_entity_extra.push_back(end_certs[i]); } - std::vector<std::vector<std::shared_ptr<const X509_Certificate>>> cert_paths; + std::vector<std::vector<X509_Certificate>> cert_paths; Certificate_Status_Code path_building_result = PKIX::build_all_certificate_paths(cert_paths, trusted_roots, end_entity, end_entity_extra); // If we cannot successfully build a chain to a trusted self-signed root, stop now @@ -930,7 +929,7 @@ Path_Validation_Result x509_path_validate( Usage_Type usage, std::chrono::system_clock::time_point when, std::chrono::milliseconds ocsp_timeout, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp) + const std::vector<std::optional<OCSP::Response>>& ocsp_resp) { std::vector<X509_Certificate> certs; certs.push_back(end_cert); @@ -945,7 +944,7 @@ Path_Validation_Result x509_path_validate( Usage_Type usage, std::chrono::system_clock::time_point when, std::chrono::milliseconds ocsp_timeout, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp) + const std::vector<std::optional<OCSP::Response>>& ocsp_resp) { std::vector<Certificate_Store*> trusted_roots; trusted_roots.push_back(const_cast<Certificate_Store*>(&store)); @@ -961,7 +960,7 @@ Path_Validation_Result x509_path_validate( Usage_Type usage, std::chrono::system_clock::time_point when, std::chrono::milliseconds ocsp_timeout, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp) + const std::vector<std::optional<OCSP::Response>>& ocsp_resp) { std::vector<X509_Certificate> certs; certs.push_back(end_cert); @@ -1012,7 +1011,7 @@ CertificatePathStatusCodes find_warnings(const CertificatePathStatusCodes& all_s } Path_Validation_Result::Path_Validation_Result(CertificatePathStatusCodes status, - std::vector<std::shared_ptr<const X509_Certificate>>&& cert_chain) : + std::vector<X509_Certificate>&& cert_chain) : m_all_status(status), m_warnings(find_warnings(m_all_status)), m_cert_path(cert_chain), @@ -1027,14 +1026,14 @@ const X509_Certificate& Path_Validation_Result::trust_root() const if(result() != Certificate_Status_Code::VERIFIED) throw Invalid_State("Path_Validation_Result::trust_root meaningless with invalid status"); - return *m_cert_path[m_cert_path.size()-1]; + return m_cert_path[m_cert_path.size()-1]; } std::set<std::string> Path_Validation_Result::trusted_hashes() const { std::set<std::string> hashes; for(size_t i = 0; i != m_cert_path.size(); ++i) - hashes.insert(m_cert_path[i]->hash_used_for_signature()); + hashes.insert(m_cert_path[i].hash_used_for_signature()); return hashes; } diff --git a/src/lib/x509/x509path.h b/src/lib/x509/x509path.h index c8575fd32..9aee14973 100644 --- a/src/lib/x509/x509path.h +++ b/src/lib/x509/x509path.h @@ -143,7 +143,7 @@ class BOTAN_PUBLIC_API(2,0) Path_Validation_Result final * @return the full path from subject to trust root * This path may be empty */ - const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path() const { return m_cert_path; } + const std::vector<X509_Certificate>& cert_path() const { return m_cert_path; } /** * @return true iff the validation was successful @@ -193,7 +193,7 @@ class BOTAN_PUBLIC_API(2,0) Path_Validation_Result final * @param cert_chain the certificate chain that was validated */ Path_Validation_Result(CertificatePathStatusCodes status, - std::vector<std::shared_ptr<const X509_Certificate>>&& cert_chain); + std::vector<X509_Certificate>&& cert_chain); /** * Create a Path_Validation_Result @@ -204,7 +204,7 @@ class BOTAN_PUBLIC_API(2,0) Path_Validation_Result final private: CertificatePathStatusCodes m_all_status; CertificatePathStatusCodes m_warnings; - std::vector<std::shared_ptr<const X509_Certificate>> m_cert_path; + std::vector<X509_Certificate> m_cert_path; Certificate_Status_Code m_overall; }; @@ -231,7 +231,7 @@ Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( Usage_Type usage = Usage_Type::UNSPECIFIED, std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp = {}); + const std::vector<std::optional<OCSP::Response>>& ocsp_resp = {}); /** * PKIX Path Validation @@ -253,7 +253,7 @@ Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( Usage_Type usage = Usage_Type::UNSPECIFIED, std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp = {}); + const std::vector<std::optional<OCSP::Response>>& ocsp_resp = {}); /** * PKIX Path Validation @@ -275,7 +275,7 @@ Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( Usage_Type usage = Usage_Type::UNSPECIFIED, std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp = {}); + const std::vector<std::optional<OCSP::Response>>& ocsp_resp = {}); /** * PKIX Path Validation @@ -297,7 +297,7 @@ Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( Usage_Type usage = Usage_Type::UNSPECIFIED, std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_resp = {}); + const std::vector<std::optional<OCSP::Response>>& ocsp_resp = {}); /** @@ -309,10 +309,10 @@ Path_Validation_Result BOTAN_PUBLIC_API(2,0) x509_path_validate( namespace PKIX { Certificate_Status_Code -build_all_certificate_paths(std::vector<std::vector<std::shared_ptr<const X509_Certificate>>>& cert_paths, +build_all_certificate_paths(std::vector<std::vector<X509_Certificate>>& cert_paths, const std::vector<Certificate_Store*>& trusted_certstores, - const std::shared_ptr<const X509_Certificate>& end_entity, - const std::vector<std::shared_ptr<const X509_Certificate>>& end_entity_extra); + const std::optional<X509_Certificate>& end_entity, + const std::vector<X509_Certificate>& end_entity_extra); /** @@ -324,10 +324,10 @@ build_all_certificate_paths(std::vector<std::vector<std::shared_ptr<const X509_C * @return result of the path building operation (OK or error) */ Certificate_Status_Code -BOTAN_PUBLIC_API(2,0) build_certificate_path(std::vector<std::shared_ptr<const X509_Certificate>>& cert_path_out, +BOTAN_PUBLIC_API(2,0) build_certificate_path(std::vector<X509_Certificate>& cert_path_out, const std::vector<Certificate_Store*>& trusted_certstores, - const std::shared_ptr<const X509_Certificate>& end_entity, - const std::vector<std::shared_ptr<const X509_Certificate>>& end_entity_extra); + const X509_Certificate& end_entity, + const std::vector<X509_Certificate>& end_entity_extra); /** * Check the certificate chain, but not any revocation data @@ -347,7 +347,7 @@ BOTAN_PUBLIC_API(2,0) build_certificate_path(std::vector<std::shared_ptr<const X * then the result for that certificate is successful. If all results are */ CertificatePathStatusCodes -BOTAN_PUBLIC_API(2,0) check_chain(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +BOTAN_PUBLIC_API(2,0) check_chain(const std::vector<X509_Certificate>& cert_path, std::chrono::system_clock::time_point ref_time, const std::string& hostname, Usage_Type usage, @@ -366,8 +366,8 @@ BOTAN_PUBLIC_API(2,0) check_chain(const std::vector<std::shared_ptr<const X509_C * @return revocation status */ CertificatePathStatusCodes -BOTAN_PUBLIC_API(2, 0) check_ocsp(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<std::shared_ptr<const OCSP::Response>>& ocsp_responses, +BOTAN_PUBLIC_API(2, 0) check_ocsp(const std::vector<X509_Certificate>& cert_path, + const std::vector<std::optional<OCSP::Response>>& ocsp_responses, const std::vector<Certificate_Store*>& certstores, std::chrono::system_clock::time_point ref_time, std::chrono::seconds max_ocsp_age = std::chrono::seconds::zero()); @@ -382,9 +382,9 @@ BOTAN_PUBLIC_API(2, 0) check_ocsp(const std::vector<std::shared_ptr<const X509_C * @return revocation status */ CertificatePathStatusCodes -BOTAN_PUBLIC_API(2,0) check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, - const std::vector<std::shared_ptr<const X509_CRL>>& crls, - std::chrono::system_clock::time_point ref_time); +BOTAN_PUBLIC_API(2,0) check_crl(const std::vector<X509_Certificate>& cert_path, + const std::vector<std::optional<X509_CRL>>& crls, + std::chrono::system_clock::time_point ref_time); /** * Check CRLs for revocation information @@ -395,7 +395,7 @@ BOTAN_PUBLIC_API(2,0) check_crl(const std::vector<std::shared_ptr<const X509_Cer * @return revocation status */ CertificatePathStatusCodes -BOTAN_PUBLIC_API(2,0) check_crl(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +BOTAN_PUBLIC_API(2,0) check_crl(const std::vector<X509_Certificate>& cert_path, const std::vector<Certificate_Store*>& certstores, std::chrono::system_clock::time_point ref_time); @@ -418,7 +418,7 @@ BOTAN_PUBLIC_API(2,0) check_crl(const std::vector<std::shared_ptr<const X509_Cer * @return revocation status */ CertificatePathStatusCodes -BOTAN_PUBLIC_API(2, 0) check_ocsp_online(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +BOTAN_PUBLIC_API(2, 0) check_ocsp_online(const std::vector<X509_Certificate>& cert_path, const std::vector<Certificate_Store*>& trusted_certstores, std::chrono::system_clock::time_point ref_time, std::chrono::milliseconds timeout, @@ -440,7 +440,7 @@ BOTAN_PUBLIC_API(2, 0) check_ocsp_online(const std::vector<std::shared_ptr<const * @return revocation status */ CertificatePathStatusCodes -BOTAN_PUBLIC_API(2,0) check_crl_online(const std::vector<std::shared_ptr<const X509_Certificate>>& cert_path, +BOTAN_PUBLIC_API(2,0) check_crl_online(const std::vector<X509_Certificate>& cert_path, const std::vector<Certificate_Store*>& trusted_certstores, Certificate_Store_In_Memory* certstore_to_recv_crls, std::chrono::system_clock::time_point ref_time, diff --git a/src/scripts/ci/setup_gh_actions.sh b/src/scripts/ci/setup_gh_actions.sh index 43007bd79..636b7ead1 100755 --- a/src/scripts/ci/setup_gh_actions.sh +++ b/src/scripts/ci/setup_gh_actions.sh @@ -56,7 +56,7 @@ if type -p "apt-get"; then elif [ "$TARGET" = "coverage" ]; then sudo apt-get -qq install g++-8 softhsm2 libtspi-dev lcov python-coverage libboost-all-dev gdb pip install --user codecov - echo "$HOME/.local/bin" >> $GITHUB_PATH + echo "$HOME/.local/bin" >> "$GITHUB_PATH" git clone --depth 1 --branch runner-changes https://github.com/randombit/boringssl.git @@ -64,7 +64,7 @@ if type -p "apt-get"; then sudo chmod g+w /var/lib/softhsm/tokens softhsm2-util --init-token --free --label test --pin 123456 --so-pin 12345678 - echo "PKCS11_LIB=/usr/lib/softhsm/libsofthsm2.so" >> $GITHUB_ENV + echo "PKCS11_LIB=/usr/lib/softhsm/libsofthsm2.so" >> "$GITHUB_ENV" elif [ "$TARGET" = "docs" ]; then sudo apt-get -qq install doxygen python-docutils python3-sphinx diff --git a/src/scripts/ci/travis.yml b/src/scripts/ci/travis.yml index 46736d0ff..1337cc95c 100644 --- a/src/scripts/ci/travis.yml +++ b/src/scripts/ci/travis.yml @@ -10,6 +10,11 @@ jobs: env: - TARGET="shared" + - name: Linux arm64 (GCC) + arch: arm64 + env: + - TARGET="shared" + install: - ./src/scripts/ci/setup_travis.sh diff --git a/src/scripts/ci_build.py b/src/scripts/ci_build.py index 03ef0f97c..f6010c389 100755 --- a/src/scripts/ci_build.py +++ b/src/scripts/ci_build.py @@ -74,12 +74,6 @@ def determine_flags(target, target_os, target_cpu, target_cc, cc_bin, test_prefix = [] test_cmd = [os.path.join(root_dir, 'botan-test')] - essential_tests = ['block', 'aead', 'hash', 'stream', 'mac', 'modes', 'kdf', - 'hmac_drbg', 'hmac_drbg_unit', 'tls', - 'rsa_sign', 'rsa_verify', 'dh_kat', - 'ecc_randomized', 'ecdh_kat', 'ecdsa_sign', 'curve25519_scalar', - 'cpuid', 'simd_32', 'os_utils', 'util', 'util_dates'] - install_prefix = os.path.join(tempfile.gettempdir(), 'botan-install') flags = ['--prefix=%s' % (install_prefix), @@ -118,13 +112,21 @@ def determine_flags(target, target_os, target_cpu, target_cc, cc_bin, flags += ['--with-coverage-info', '--with-debug-info', '--test-mode'] if target == 'valgrind': - # valgrind in 16.04 has a bug with rdrand handling - flags += ['--with-valgrind', '--disable-rdrand'] + flags += ['--with-valgrind'] test_prefix = ['valgrind', '--error-exitcode=9', '-v', '--leak-check=full', '--show-reachable=yes'] # valgrind is single threaded anyway test_cmd += ['--test-threads=1'] # valgrind is slow - test_cmd += essential_tests + slow_tests = [ + 'cryptobox', 'dh_invalid', 'dh_kat', 'dh_keygen', + 'dl_group_gen', 'dlies', 'dsa_param', 'ecc_basemul', + 'ecdsa_verify_wycheproof', 'mce_keygen', 'passhash9', + 'rsa_encrypt', 'rsa_pss', 'rsa_pss_raw', 'scrypt', + 'srp6_kat', 'x509_path_bsi', 'xmss_keygen', 'xmss_sign', + 'pbkdf', 'argon2', 'bcrypt', 'bcrypt_pbkdf', 'compression', + 'ed25519_sign', 'elgamal_keygen', 'x509_path_rsa_pss'] + + test_cmd += ['--skip-tests=%s' % (','.join(slow_tests))] if target == 'fuzzers': flags += ['--unsafe-fuzzer-mode'] @@ -195,9 +197,6 @@ def determine_flags(target, target_os, target_cpu, target_cc, cc_bin, test_cmd = [os.path.join(root_dir, 'botan-test.exe')] + test_cmd[1:] test_prefix = ['wine'] else: - # Build everything but restrict what is run - test_cmd += essential_tests - if target == 'cross-arm32': flags += ['--cpu=armv7'] cc_bin = 'arm-linux-gnueabihf-g++' diff --git a/src/scripts/tls_suite_info.py b/src/scripts/tls_suite_info.py index 3e3c40307..77a6b6bed 100755 --- a/src/scripts/tls_suite_info.py +++ b/src/scripts/tls_suite_info.py @@ -176,11 +176,6 @@ def process_command_line(args): parser.add_option('--without-cecpq1', action='store_false', dest='with_cecpq1', help='disable CECPQ1 suites') - parser.add_option('--with-srp-aead', action='store_true', default=False, - help='add SRP AEAD suites') - parser.add_option('--without-srp-aead', action='store_false', dest='with_srp_aead', - help='disable SRP AEAD suites') - parser.add_option('--save-download', action='store_true', default=False, help='save downloaded tls-parameters.txt to cwd') @@ -194,11 +189,12 @@ def main(args = None): if args is None: args = sys.argv - weak_crypto = ['EXPORT', 'RC2', 'IDEA', 'RC4', '_DES_', 'WITH_NULL', 'GOST', '_anon_', '_DSS_'] + weak_crypto = ['EXPORT', 'RC2', 'IDEA', 'RC4', '_DES_', 'WITH_NULL', 'GOST', '_anon_'] static_dh = ['ECDH_ECDSA', 'ECDH_RSA', 'DH_DSS', 'DH_RSA'] # not supported + removed_algos = ['_DSS_', 'SRP_', 'SEED', 'CAMELLIA_128_CBC', 'CAMELLIA_256_CBC'] protocol_goop = ['SCSV', 'KRB5'] maybe_someday = ['RSA_PSK', 'ECCPWD'] - not_supported = weak_crypto + static_dh + protocol_goop + maybe_someday + not_supported = weak_crypto + static_dh + protocol_goop + maybe_someday + removed_algos (options, args) = process_command_line(args) @@ -269,19 +265,6 @@ def main(args = None): define_custom_ciphersuite('CECPQ1_ECDSA_WITH_AES_256_OCB_SHA256', 'FFCD') #define_custom_ciphersuite('CECPQ1_PSK_WITH_AES_256_OCB_SHA256', 'FFCE') - if options.with_srp_aead: - # SRP using GCM or OCB - Botan extension - define_custom_ciphersuite('SRP_SHA_WITH_AES_256_GCM_SHA384', 'FFA0') - define_custom_ciphersuite('SRP_SHA_RSA_WITH_AES_256_GCM_SHA384', 'FFA1') - define_custom_ciphersuite('SRP_SHA_DSS_WITH_AES_256_GCM_SHA384', 'FFA2') - define_custom_ciphersuite('SRP_SHA_ECDSA_WITH_AES_256_GCM_SHA384', 'FFA3') - - if options.with_ocb: - define_custom_ciphersuite('SRP_SHA_WITH_AES_256_OCB_SHA256', 'FFA4') - define_custom_ciphersuite('SRP_SHA_RSA_WITH_AES_256_OCB_SHA256', 'FFA5') - define_custom_ciphersuite('SRP_SHA_DSS_WITH_AES_256_OCB_SHA256', 'FFA6') - define_custom_ciphersuite('SRP_SHA_ECDSA_WITH_AES_256_OCB_SHA256', 'FFA7') - suite_info = '' def header(): diff --git a/src/tests/test_certstor.cpp b/src/tests/test_certstor.cpp index 6359944f1..681b323ca 100644 --- a/src/tests/test_certstor.cpp +++ b/src/tests/test_certstor.cpp @@ -88,8 +88,8 @@ Test::Result test_certstor_sqlite3_insert_find_remove_test(const std::vector<Cer } else { - const bool found = std::any_of(rev_certs.begin(), - rev_certs.end(), [&](std::shared_ptr<const Botan::X509_Certificate> c) { return c->fingerprint() == cert.fingerprint(); }); + const bool found = std::any_of(rev_certs.begin(), rev_certs.end(), + [&](const Botan::X509_Certificate& c) { return c.fingerprint() == cert.fingerprint(); }); result.test_eq("Got wrong/no certificate", found, true); } @@ -247,7 +247,7 @@ Test::Result test_certstor_sqlite3_find_all_certs_test(const std::vector<Certifi std::stringstream a_ss; a_ss << a.certificate.subject_dn(); std::stringstream res_ss; - res_ss << res_vec.at(0)->subject_dn(); + res_ss << res_vec.at(0).subject_dn(); result.test_eq("Check subject " + a_ss.str(), a_ss.str(), res_ss.str()); } } @@ -271,10 +271,10 @@ Test::Result test_certstor_sqlite3_find_all_certs_test(const std::vector<Certifi std::stringstream cert_ss; cert_ss << same_dn_1.subject_dn(); std::stringstream res_ss; - res_ss << res_vec.at(0)->subject_dn(); + res_ss << res_vec.at(0).subject_dn(); result.test_eq("Check subject " + cert_ss.str(), cert_ss.str(), res_ss.str()); res_ss.str(""); - res_ss << res_vec.at(1)->subject_dn(); + res_ss << res_vec.at(1).subject_dn(); result.test_eq("Check subject " + cert_ss.str(), cert_ss.str(), res_ss.str()); } } @@ -349,8 +349,8 @@ Test::Result test_certstor_load_allcert() Botan::X509_Certificate root_cert(Test::data_dir() + "/x509/x509test/root.pem"); Botan::X509_Certificate valid_cert(Test::data_dir() + "/x509/x509test/ValidCert.pem"); std::vector<uint8_t> key_id; - result.confirm("Root cert found", store.find_cert(root_cert.subject_dn(), key_id) != nullptr); - result.confirm("ValidCert found", store.find_cert(valid_cert.subject_dn(), key_id) != nullptr); + result.confirm("Root cert found", store.find_cert(root_cert.subject_dn(), key_id) != std::nullopt); + result.confirm("ValidCert found", store.find_cert(valid_cert.subject_dn(), key_id) != std::nullopt); return result; } catch(std::exception& e) diff --git a/src/tests/test_certstor_flatfile.cpp b/src/tests/test_certstor_flatfile.cpp index 213c6d390..3c8177653 100644 --- a/src/tests/test_certstor_flatfile.cpp +++ b/src/tests/test_certstor_flatfile.cpp @@ -61,7 +61,7 @@ Test::Result find_certificate_by_pubkey_sha1() auto cert = certstore.find_cert_by_pubkey_sha1(get_key_id()); result.end_timer(); - if(result.test_not_null("found certificate", cert.get())) + if(result.test_not_nullopt("found certificate", cert)) { auto cns = cert->subject_dn().get_attribute("CN"); result.test_int_eq("exactly one CN", cns.size(), 1); @@ -95,7 +95,7 @@ Test::Result find_cert_by_subject_dn() auto cert = certstore.find_cert(dn, std::vector<uint8_t>()); result.end_timer(); - if(result.test_not_null("found certificate", cert.get())) + if(result.test_not_nullopt("found certificate", cert)) { auto cns = cert->subject_dn().get_attribute("CN"); result.test_int_eq("exactly one CN", cns.size(), 1); @@ -124,7 +124,7 @@ Test::Result find_cert_by_utf8_subject_dn() result.end_timer(); - if(result.test_not_null("found certificate", cert.get())) + if(result.test_not_nullopt("found certificate", cert)) { auto cns = cert->subject_dn().get_attribute("CN"); result.test_is_eq("exactly one CN", cns.size(), size_t(1)); @@ -152,7 +152,7 @@ Test::Result find_cert_by_subject_dn_and_key_id() auto cert = certstore.find_cert(dn, get_key_id()); result.end_timer(); - if(result.test_not_null("found certificate", cert.get())) + if(result.test_not_nullopt("found certificate", cert)) { auto cns = cert->subject_dn().get_attribute("CN"); result.test_int_eq("exactly one CN", cns.size(), 1); @@ -183,7 +183,7 @@ Test::Result find_certs_by_subject_dn_and_key_id() if(result.confirm("result not empty", !certs.empty()) && result.test_eq("exactly one certificate", certs.size(), 1)) { - auto cns = certs.front()->subject_dn().get_attribute("CN"); + auto cns = certs.front().subject_dn().get_attribute("CN"); result.test_int_eq("exactly one CN", cns.size(), 1); result.test_eq("CN", cns.front(), "DST Root CA X3"); } diff --git a/src/tests/test_certstor_system.cpp b/src/tests/test_certstor_system.cpp index ff254f11e..b0cd80b03 100644 --- a/src/tests/test_certstor_system.cpp +++ b/src/tests/test_certstor_system.cpp @@ -29,7 +29,7 @@ Test::Result find_certificate_by_pubkey_sha1(Botan::Certificate_Store& certstore auto cert = certstore.find_cert_by_pubkey_sha1(get_key_id()); result.end_timer(); - if(result.test_not_null("found certificate", cert.get())) + if(result.test_not_nullopt("found certificate", cert)) { auto cns = cert->subject_dn().get_attribute("CN"); result.test_is_eq("exactly one CN", cns.size(), size_t(1)); @@ -61,7 +61,7 @@ Test::Result find_cert_by_subject_dn(Botan::Certificate_Store& certstore) auto cert = certstore.find_cert(dn, std::vector<uint8_t>()); result.end_timer(); - if(result.test_not_null("found certificate", cert.get())) + if(result.test_not_nullopt("found certificate", cert)) { auto cns = cert->subject_dn().get_attribute("CN"); result.test_is_eq("exactly one CN", cns.size(), size_t(1)); @@ -94,7 +94,7 @@ Test::Result find_cert_by_utf8_subject_dn(Botan::Certificate_Store& certstore) auto cert = certstore.find_cert(dn, std::vector<uint8_t>()); result.end_timer(); - if(result.test_not_null("found certificate", cert.get())) + if(result.test_not_nullopt("found certificate", cert)) { auto cns = cert->subject_dn().get_attribute("CN"); result.test_is_eq("exactly one CN", cns.size(), size_t(1)); @@ -122,7 +122,7 @@ Test::Result find_cert_by_subject_dn_and_key_id(Botan::Certificate_Store& certst auto cert = certstore.find_cert(dn, get_key_id()); result.end_timer(); - if(result.test_not_null("found certificate", cert.get())) + if(result.test_not_nullopt("found certificate", cert)) { auto cns = cert->subject_dn().get_attribute("CN"); result.test_is_eq("exactly one CN", cns.size(), size_t(1)); @@ -152,7 +152,7 @@ Test::Result find_certs_by_subject_dn_and_key_id(Botan::Certificate_Store& certs if(result.confirm("result not empty", !certs.empty()) && result.test_eq("exactly one certificate", certs.size(), 1)) { - auto cns = certs.front()->subject_dn().get_attribute("CN"); + auto cns = certs.front().subject_dn().get_attribute("CN"); result.test_is_eq("exactly one CN", cns.size(), size_t(1)); result.test_eq("CN", cns.front(), "DST Root CA X3"); } @@ -189,7 +189,7 @@ Test::Result find_all_certs_by_subject_dn(Botan::Certificate_Store& certstore) if(result.confirm("result not empty", !certs.empty())) { - auto cns = certs.front()->subject_dn().get_attribute("CN"); + auto cns = certs.front().subject_dn().get_attribute("CN"); result.test_gte("at least one CN", cns.size(), size_t(1)); result.test_eq("CN", cns.front(), "DST Root CA X3"); } @@ -279,9 +279,9 @@ Test::Result certificate_matching_with_dn_normalization(Botan::Certificate_Store result.end_timer(); if(result.confirm("find_all_certs did find the skewed DN", !certs.empty()) && - result.confirm("find_cert did find the skewed DN", cert != nullptr)) + result.confirm("find_cert did find the skewed DN", cert.has_value())) { - result.test_eq("it is the correct cert", certs.front()->subject_dn().get_first_attribute("CN"), "DST Root CA X3"); + result.test_eq("it is the correct cert", certs.front().subject_dn().get_first_attribute("CN"), "DST Root CA X3"); result.test_eq("it is the correct cert", cert->subject_dn().get_first_attribute("CN"), "DST Root CA X3"); } } diff --git a/src/tests/test_compression.cpp b/src/tests/test_compression.cpp index fdc2ddd35..7f503d538 100644 --- a/src/tests/test_compression.cpp +++ b/src/tests/test_compression.cpp @@ -66,6 +66,8 @@ class Compression_Tests final : public Test { Test::Result result(algo + " compression"); + result.start_timer(); + std::unique_ptr<Botan::Compression_Algorithm> c(Botan::make_compressor(algo)); std::unique_ptr<Botan::Decompression_Algorithm> d(Botan::make_decompressor(algo)); @@ -108,6 +110,8 @@ class Compression_Tests final : public Test result.test_lt("Zeros compresses much better than text", c1_z / 8, c1_t); result.test_lt("Text compresses much better than random", c1_t / 2, c1_r); + result.end_timer(); + results.emplace_back(result); } catch(std::exception& e) diff --git a/src/tests/test_ocsp.cpp b/src/tests/test_ocsp.cpp index 443f79aba..5d6c98b47 100644 --- a/src/tests/test_ocsp.cpp +++ b/src/tests/test_ocsp.cpp @@ -21,14 +21,14 @@ namespace Botan_Tests { class OCSP_Tests final : public Test { private: - std::shared_ptr<const Botan::X509_Certificate> load_test_X509_cert(const std::string& path) + Botan::X509_Certificate load_test_X509_cert(const std::string& path) { - return std::make_shared<const Botan::X509_Certificate>(Test::data_file(path)); + return Botan::X509_Certificate(Test::data_file(path)); } - std::shared_ptr<const Botan::OCSP::Response> load_test_OCSP_resp(const std::string& path) + Botan::OCSP::Response load_test_OCSP_resp(const std::string& path) { - return std::make_shared<const Botan::OCSP::Response>(Test::read_binary_data_file(path)); + return Botan::OCSP::Response(Test::read_binary_data_file(path)); } Test::Result test_response_parsing() @@ -131,13 +131,13 @@ class OCSP_Tests final : public Test { Test::Result result("OCSP request check with next_update w/o max_age"); - std::shared_ptr<const Botan::X509_Certificate> ee = load_test_X509_cert("x509/ocsp/randombit.pem"); - std::shared_ptr<const Botan::X509_Certificate> ca = load_test_X509_cert("x509/ocsp/letsencrypt.pem"); - std::shared_ptr<const Botan::X509_Certificate> trust_root = load_test_X509_cert("x509/ocsp/geotrust.pem"); + auto ee = load_test_X509_cert("x509/ocsp/randombit.pem"); + auto ca = load_test_X509_cert("x509/ocsp/letsencrypt.pem"); + auto trust_root = load_test_X509_cert("x509/ocsp/geotrust.pem"); - const std::vector<std::shared_ptr<const Botan::X509_Certificate>> cert_path = { ee, ca, trust_root }; + const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/randombit_ocsp.der"); + auto ocsp = load_test_OCSP_resp("x509/ocsp/randombit_ocsp.der"); Botan::Certificate_Store_In_Memory certstore; certstore.add_certificate(trust_root); @@ -169,13 +169,13 @@ class OCSP_Tests final : public Test { Test::Result result("OCSP request check with next_update with max_age"); - std::shared_ptr<const Botan::X509_Certificate> ee = load_test_X509_cert("x509/ocsp/randombit.pem"); - std::shared_ptr<const Botan::X509_Certificate> ca = load_test_X509_cert("x509/ocsp/letsencrypt.pem"); - std::shared_ptr<const Botan::X509_Certificate> trust_root = load_test_X509_cert("x509/ocsp/geotrust.pem"); + auto ee = load_test_X509_cert("x509/ocsp/randombit.pem"); + auto ca = load_test_X509_cert("x509/ocsp/letsencrypt.pem"); + auto trust_root = load_test_X509_cert("x509/ocsp/geotrust.pem"); - const std::vector<std::shared_ptr<const Botan::X509_Certificate>> cert_path = { ee, ca, trust_root }; + const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/randombit_ocsp.der"); + auto ocsp = load_test_OCSP_resp("x509/ocsp/randombit_ocsp.der"); Botan::Certificate_Store_In_Memory certstore; certstore.add_certificate(trust_root); @@ -210,13 +210,13 @@ class OCSP_Tests final : public Test { Test::Result result("OCSP request check w/o next_update with max_age"); - std::shared_ptr<const Botan::X509_Certificate> ee = load_test_X509_cert("x509/ocsp/patrickschmidt.pem"); - std::shared_ptr<const Botan::X509_Certificate> ca = load_test_X509_cert("x509/ocsp/bdrive_encryption.pem"); - std::shared_ptr<const Botan::X509_Certificate> trust_root = load_test_X509_cert("x509/ocsp/bdrive_root.pem"); + auto ee = load_test_X509_cert("x509/ocsp/patrickschmidt.pem"); + auto ca = load_test_X509_cert("x509/ocsp/bdrive_encryption.pem"); + auto trust_root = load_test_X509_cert("x509/ocsp/bdrive_root.pem"); - const std::vector<std::shared_ptr<const Botan::X509_Certificate>> cert_path = { ee, ca, trust_root }; + const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/patrickschmidt_ocsp.der"); + auto ocsp = load_test_OCSP_resp("x509/ocsp/patrickschmidt_ocsp.der"); Botan::Certificate_Store_In_Memory certstore; certstore.add_certificate(trust_root); @@ -249,13 +249,13 @@ class OCSP_Tests final : public Test { Test::Result result("OCSP request check w/o next_update w/o max_age"); - std::shared_ptr<const Botan::X509_Certificate> ee = load_test_X509_cert("x509/ocsp/patrickschmidt.pem"); - std::shared_ptr<const Botan::X509_Certificate> ca = load_test_X509_cert("x509/ocsp/bdrive_encryption.pem"); - std::shared_ptr<const Botan::X509_Certificate> trust_root = load_test_X509_cert("x509/ocsp/bdrive_root.pem"); + auto ee = load_test_X509_cert("x509/ocsp/patrickschmidt.pem"); + auto ca = load_test_X509_cert("x509/ocsp/bdrive_encryption.pem"); + auto trust_root = load_test_X509_cert("x509/ocsp/bdrive_root.pem"); - const std::vector<std::shared_ptr<const Botan::X509_Certificate>> cert_path = { ee, ca, trust_root }; + const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/patrickschmidt_ocsp.der"); + auto ocsp = load_test_OCSP_resp("x509/ocsp/patrickschmidt_ocsp.der"); Botan::Certificate_Store_In_Memory certstore; certstore.add_certificate(trust_root); @@ -285,14 +285,13 @@ class OCSP_Tests final : public Test { Test::Result result("OCSP request softfail check"); - std::shared_ptr<const Botan::X509_Certificate> ee = load_test_X509_cert("x509/ocsp/randombit.pem"); - std::shared_ptr<const Botan::X509_Certificate> ca = load_test_X509_cert("x509/ocsp/letsencrypt.pem"); - std::shared_ptr<const Botan::X509_Certificate> trust_root = load_test_X509_cert("x509/ocsp/geotrust.pem"); + auto ee = load_test_X509_cert("x509/ocsp/randombit.pem"); + auto ca = load_test_X509_cert("x509/ocsp/letsencrypt.pem"); + auto trust_root = load_test_X509_cert("x509/ocsp/geotrust.pem"); - const std::vector<std::shared_ptr<const Botan::X509_Certificate>> cert_path = { ee, ca, trust_root }; + const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = - std::make_shared<const Botan::OCSP::Response>(Botan::Certificate_Status_Code::OCSP_NO_REVOCATION_URL); + Botan::OCSP::Response ocsp(Botan::Certificate_Status_Code::OCSP_NO_REVOCATION_URL); Botan::Certificate_Store_In_Memory certstore; certstore.add_certificate(trust_root); @@ -318,10 +317,10 @@ class OCSP_Tests final : public Test Test::Result result("OCSP online check"); // Expired end-entity certificate: - std::shared_ptr<const Botan::X509_Certificate> ca = load_test_X509_cert("x509/ocsp/letsencrypt.pem"); - std::shared_ptr<const Botan::X509_Certificate> trust_root = load_test_X509_cert("x509/ocsp/identrust.pem"); + auto ca = load_test_X509_cert("x509/ocsp/letsencrypt.pem"); + auto trust_root = load_test_X509_cert("x509/ocsp/identrust.pem"); - const std::vector<std::shared_ptr<const Botan::X509_Certificate>> cert_path = { ca, trust_root }; + const std::vector<Botan::X509_Certificate> cert_path = { ca, trust_root }; Botan::Certificate_Store_In_Memory certstore; certstore.add_certificate(trust_root); diff --git a/src/tests/test_tls.cpp b/src/tests/test_tls.cpp index 454388d0a..69cbf2095 100644 --- a/src/tests/test_tls.cpp +++ b/src/tests/test_tls.cpp @@ -50,7 +50,6 @@ class TLS_Session_Tests final : public Test std::vector<Botan::X509_Certificate>(), std::vector<uint8_t>(), Botan::TLS::Server_Information("server"), - "SRP username", 0x0000); const std::string pem = session.PEM_encode(); @@ -73,7 +72,6 @@ class TLS_Session_Tests final : public Test ctext2.data(), 12, expected_hdr.data(), 12); Botan::TLS::Session dsession = Botan::TLS::Session::decrypt(ctext1.data(), ctext1.size(), key); - result.test_eq("Decrypted session access works", dsession.srp_identifier(), "SRP username"); Fixed_Output_RNG frng1("00112233445566778899AABBCCDDEEFF802802802802802802802802"); const std::vector<uint8_t> ctextf1 = session.encrypt(key, frng1); @@ -466,7 +464,6 @@ class Test_TLS_Algo_Strings : public Test Botan::TLS::Kex_Algo::DH, Botan::TLS::Kex_Algo::ECDH, Botan::TLS::Kex_Algo::CECPQ1, - Botan::TLS::Kex_Algo::SRP_SHA, Botan::TLS::Kex_Algo::PSK, Botan::TLS::Kex_Algo::DHE_PSK, Botan::TLS::Kex_Algo::ECDHE_PSK diff --git a/src/tests/test_tls_stream_integration.cpp b/src/tests/test_tls_stream_integration.cpp index f11f134f3..084d2c08a 100644 --- a/src/tests/test_tls_stream_integration.cpp +++ b/src/tests/test_tls_stream_integration.cpp @@ -292,7 +292,7 @@ class Client : public Side { static void accept_all( const std::vector<Botan::X509_Certificate>&, - const std::vector<std::shared_ptr<const Botan::OCSP::Response>>&, + const std::vector<std::optional<Botan::OCSP::Response>>&, const std::vector<Botan::Certificate_Store*>&, Botan::Usage_Type, const std::string&, const Botan::TLS::Policy&) {} diff --git a/src/tests/test_x509_path.cpp b/src/tests/test_x509_path.cpp index 0b07231e1..bd113a6f4 100644 --- a/src/tests/test_x509_path.cpp +++ b/src/tests/test_x509_path.cpp @@ -412,38 +412,41 @@ std::vector<Test::Result> PSS_Path_Validation_Tests::run() continue; } - std::shared_ptr<Botan::X509_CRL> crl; - std::shared_ptr<Botan::X509_Certificate> end; - std::shared_ptr<Botan::X509_Certificate> root; + std::optional<Botan::X509_CRL> crl; + std::optional<Botan::X509_Certificate> end; + std::optional<Botan::X509_Certificate> root; Botan::Certificate_Store_In_Memory store; - std::shared_ptr<Botan::PKCS10_Request> csr; - auto validation_time = Botan::calendar_point(std::atoi((validation_times_iter++)->second.c_str()), 0, 0, 0, 0, - 0).to_std_timepoint(); + std::optional<Botan::PKCS10_Request> csr; + + auto validation_time = Botan::calendar_point( + std::atoi((validation_times_iter++)->second.c_str()), + 0, 0, 0, 0, 0).to_std_timepoint(); + for(auto const& file : all_files) { if(file.find("end.crt") != std::string::npos) { - end.reset(new Botan::X509_Certificate(file)); + end = Botan::X509_Certificate(file); } else if(file.find("root.crt") != std::string::npos) { - root.reset(new Botan::X509_Certificate(file)); + root = Botan::X509_Certificate(file); store.add_certificate(*root); } else if(file.find(".crl") != std::string::npos) { - crl.reset(new Botan::X509_CRL(file)); + crl = Botan::X509_CRL(file); } else if(file.find(".csr") != std::string::npos) { - csr.reset(new Botan::PKCS10_Request(file)); + csr = Botan::PKCS10_Request(file); } } if(end && crl && root) // CRL tests { - const std::vector<std::shared_ptr<const Botan::X509_Certificate>> cert_path = { end, root }; - const std::vector<std::shared_ptr<const Botan::X509_CRL>> crls = { crl }; + const std::vector<Botan::X509_Certificate> cert_path = { *end, *root }; + const std::vector<std::optional<Botan::X509_CRL>> crls = { crl }; auto crl_status = Botan::PKIX::check_crl(cert_path, crls, validation_time); // alternatively we could just call crl.check_signature( root_pubkey ) @@ -823,9 +826,9 @@ class Path_Validation_With_OCSP_Tests final : public Test return Botan::X509_Certificate(Test::data_file(path)); } - std::shared_ptr<const Botan::OCSP::Response> load_test_OCSP_resp(const std::string& path) + std::optional<Botan::OCSP::Response> load_test_OCSP_resp(const std::string& path) { - return std::make_shared<const Botan::OCSP::Response>(Test::read_binary_data_file(path)); + return Botan::OCSP::Response(Test::read_binary_data_file(path)); } Test::Result validate_with_ocsp_with_next_update_without_max_age() @@ -842,7 +845,7 @@ class Path_Validation_With_OCSP_Tests final : public Test const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/randombit_ocsp.der"); + std::optional<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/randombit_ocsp.der"); auto check_path = [&](const std::chrono::system_clock::time_point valid_time, const Botan::Certificate_Status_Code expected) @@ -882,7 +885,7 @@ class Path_Validation_With_OCSP_Tests final : public Test const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/randombit_ocsp.der"); + auto ocsp = load_test_OCSP_resp("x509/ocsp/randombit_ocsp.der"); auto check_path = [&](const std::chrono::system_clock::time_point valid_time, const Botan::Certificate_Status_Code expected) @@ -922,7 +925,7 @@ class Path_Validation_With_OCSP_Tests final : public Test const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/patrickschmidt_ocsp.der"); + auto ocsp = load_test_OCSP_resp("x509/ocsp/patrickschmidt_ocsp.der"); auto check_path = [&](const std::chrono::system_clock::time_point valid_time, const Botan::Certificate_Status_Code expected) @@ -961,7 +964,7 @@ class Path_Validation_With_OCSP_Tests final : public Test const std::vector<Botan::X509_Certificate> cert_path = { ee, ca, trust_root }; - std::shared_ptr<const Botan::OCSP::Response> ocsp = load_test_OCSP_resp("x509/ocsp/patrickschmidt_ocsp.der"); + auto ocsp = load_test_OCSP_resp("x509/ocsp/patrickschmidt_ocsp.der"); auto check_path = [&](const std::chrono::system_clock::time_point valid_time, const Botan::Certificate_Status_Code expected) @@ -1068,8 +1071,7 @@ class XMSS_Path_Validation_Tests final : public Test Botan::Path_Validation_Restrictions restrictions; auto self_signed = Botan::X509_Certificate(Test::data_dir() + "/x509/xmss/" + file); - auto cert_path = std::vector<std::shared_ptr<const Botan::X509_Certificate>>{ - std::make_shared<const Botan::X509_Certificate>(self_signed)}; + auto cert_path = std::vector<Botan::X509_Certificate>{self_signed}; auto valid_time = Botan::calendar_point(2019, 10, 8, 4, 45, 0).to_std_timepoint(); auto status = Botan::PKIX::overall_status(Botan::PKIX::check_chain(cert_path, valid_time, diff --git a/src/tests/tests.h b/src/tests/tests.h index 694779ac5..159c61400 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -21,6 +21,7 @@ #include <string> #include <unordered_map> #include <vector> +#include <optional> namespace Botan { @@ -271,6 +272,15 @@ class Test return test_success(what + " was not null"); } + template<typename T> + bool test_not_nullopt(const std::string& what, std::optional<T> val) + { + if(val == std::nullopt) + return test_failure(what + " was nullopt"); + else + return test_success(what + " was not nullopt"); + } + bool test_eq(const std::string& what, const char* produced, const char* expected); bool test_is_nonempty(const std::string& what_is_it, const std::string& to_examine); diff --git a/src/tests/unit_tls.cpp b/src/tests/unit_tls.cpp index 8ecd305e9..9b2322e2a 100644 --- a/src/tests/unit_tls.cpp +++ b/src/tests/unit_tls.cpp @@ -28,10 +28,6 @@ #include <botan/x509_ca.h> #include <botan/x509self.h> - #if defined(BOTAN_HAS_SRP6) - #include <botan/srp6.h> - #endif - #if defined(BOTAN_HAS_TLS_SQLITE3_SESSION_MANAGER) #include <botan/tls_session_manager_sqlite.h> #endif @@ -237,88 +233,6 @@ create_creds(Botan::RandomNumberGenerator& rng, return cmt; } -#if defined(BOTAN_HAS_SRP6) -Botan::Credentials_Manager* -create_srp6_creds(Botan::RandomNumberGenerator& rng) - { - class Credentials_Manager_SRP6 : public Botan::Credentials_Manager - { - public: - Credentials_Manager_SRP6(Botan::RandomNumberGenerator& rng) - { - m_group_id = "modp/srp/1024"; - m_username = "srp6_username"; - m_password = "srp6_password"; - m_salt.resize(16); - rng.randomize(m_salt.data(), m_salt.size()); - - m_verifier = Botan::generate_srp6_verifier(m_username, - m_password, - m_salt, - m_group_id, - "SHA-1"); - } - - bool attempt_srp(const std::string& /*type*/, - const std::string& /*context*/) override - { - return true; - } - - std::string srp_identifier(const std::string& /*type*/, - const std::string& /*context*/) override - { - return m_username; - } - - std::string srp_password(const std::string& /*type*/, - const std::string& /*context*/, - const std::string& identifier) override - { - if(identifier == m_username) - return m_password; - return ""; - } - - bool srp_verifier(const std::string& /*type*/, - const std::string& /*context*/, - const std::string& identifier, - std::string& group_name, - Botan::BigInt& verifier, - std::vector<uint8_t>& salt, - bool generate_fake_on_unknown) override - { - // FIXME test generate_fake_on_unknown behavior - if(identifier == m_username) - { - group_name = m_group_id; - verifier = m_verifier; - salt = m_salt; - return true; - } - else if(generate_fake_on_unknown) - { - group_name = m_group_id; - verifier = m_verifier + 1; - salt = m_salt; - return true; - } - else - return false; - } - - std::string m_username; - std::string m_password; - std::vector<uint8_t> m_salt; - std::string m_group_id; - Botan::BigInt m_verifier; - }; - - return new Credentials_Manager_SRP6(rng); - } -#endif - - class TLS_Handshake_Test final { public: @@ -783,7 +697,7 @@ class TLS_Unit_Tests final : public Test policy.set("allow_dtls10", "true"); policy.set("allow_dtls12", "true"); - if(kex_policy.find("RSA") != std::string::npos || kex_policy.find("SRP") != std::string::npos) + if(kex_policy.find("RSA") != std::string::npos) { policy.set("signature_methods", "IMPLICIT"); } @@ -886,33 +800,17 @@ class TLS_Unit_Tests final : public Test test_all_versions("AES-128 RSA", results, *client_ses, *server_ses, *creds, "RSA", "AES-128", "SHA-256 SHA-1", etm_setting); test_all_versions("AES-128 ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "AES-128", "SHA-256 SHA-1", etm_setting); -#if defined(BOTAN_HAS_CAMELLIA) && defined(BOTAN_HAS_TLS_CBC) - test_all_versions("Camellia-128 RSA", results, *client_ses, *server_ses, - *creds, "RSA", "Camellia-128", "SHA-256 SHA-1", etm_setting); - test_all_versions("Camellia-256 RSA SHA-2", results, *client_ses, *server_ses, - *creds, "RSA", "Camellia-256", "SHA-256 SHA-384 SHA-1", etm_setting); -#endif - #if defined(BOTAN_HAS_DES) test_all_versions("3DES RSA", results, *client_ses, *server_ses, *creds, "RSA", "3DES", "SHA-1", etm_setting); test_all_versions("3DES ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "3DES", "SHA-1", etm_setting); #endif -#if defined(BOTAN_HAS_SEED) - test_all_versions("SEED RSA", results, *client_ses, *server_ses, *creds, "RSA", "SEED", "SHA-1", etm_setting); -#endif - server_ses->remove_all(); } client_ses->remove_all(); test_modern_versions("AES-128 DH", results, *client_ses, *server_ses, *creds, "DH", "AES-128", "SHA-256"); -#if defined(BOTAN_HAS_SRP6) - std::unique_ptr<Botan::Credentials_Manager> srp6_creds(create_srp6_creds(rng)); - test_all_versions("SRP6 AES", results, *client_ses, *server_ses, *srp6_creds, "SRP_SHA", "AES-128", "SHA-1", "false"); -#endif - #endif Botan::TLS::Strict_Policy strict_policy; @@ -939,15 +837,12 @@ class TLS_Unit_Tests final : public Test client_ses->remove_all(); -#if defined(BOTAN_HAS_CAMELLIA) && defined(BOTAN_HAS_TLS_CBC) - test_modern_versions("Camellia-256 SHA-2", results, *client_ses, *server_ses, *creds, "RSA", "Camellia-256", "SHA-384 SHA-256"); -#endif #if defined(BOTAN_HAS_CAMELLIA) && defined(BOTAN_HAS_AEAD_GCM) test_modern_versions("Camellia-128/GCM ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "Camellia-128/GCM", "AEAD"); #endif #if defined(BOTAN_HAS_ARIA) - test_modern_versions("ARIA ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "ARIA-128/GCM", "AEAD"); + test_modern_versions("ARIA/GCM ECDH", results, *client_ses, *server_ses, *creds, "ECDH", "ARIA-128/GCM", "AEAD"); #endif #if defined(BOTAN_HAS_CECPQ1) |