fileserver/lib/Botan-3.2.0/doc/migration_guide.rst

450 lines
18 KiB
ReStructuredText
Raw Normal View History

Botan 2.x to 3.x Migration
==============================
This is a guide on migrating applications from Botan 2.x to 3.0.
This guide attempts to be, but is not, complete. If you run into a problem while
converting code that does not seem to be described here, please open an issue on
Github.
Headers
--------
Many headers have been removed from the public API.
In some cases, such as ``datastor.h`` or ``tls_blocking.h``, the functionality
presented was entirely deprecated, in which case it has been removed.
In other cases (such as ``loadstor.h`` or ``rotate.h``) the header was really an
implementation header of the library and not intended to be consumed as a public
API. In these cases the header is still used internally, but not installed for
application use.
However in most cases there is a better way of performing the same operations,
which usually works in both 2.x and 3.x. For example, in 3.0 all of the
algorithm headers (such as ``aes.h``) have been removed. Instead you should
create objects via the factory methods (in the case of AES,
``BlockCipher::create``) which works in both 2.x and 3.0
Build Artifacts
---------------
For consistency with other platforms the DLL is now suffixed with the library's
major version on Windows as well.
TLS
---
Starting with Botan 3.0 TLS 1.3 is supported.
This development required a number of backward-incompatible changes to
accomodate the protocol differences to TLS 1.2, which is still supported.
Build modules
^^^^^^^^^^^^^
The build module ``tls`` is now internal and contains common TLS helpers. Users
have to explicitly enable ``tls12`` and/or ``tls13``. Note that for Botan 3.0 it
is not (yet) possible to exclusively enable TLS 1.3 at build time.
Removed Functionality
^^^^^^^^^^^^^^^^^^^^^
Functionality removed from the TLS implementation includes
* TLS 1.0, 1.1 and DTLS 1.0
* DSA ciphersuites
* anonymous ciphersuites
* SRP ciphersuites
* SEED ciphersuites
* Camellia CBC ciphersuites
* AES-128 OCB ciphersuites
* DHE_PSK ciphersuites
* CECPQ1 ciphersuites
enum classes
^^^^^^^^^^^^
The publicly available C++ enums in the TLS namespace are now `enum class` and
their member naming scheme was converted from `SHOUTING_SNAKE_CASE` to
`CamelCase`.
Callbacks
^^^^^^^^^
A number of new callbacks were added with TLS 1.3. None of those new callbacks
is mandatory to implement by applications, though. Additionally there are a few
backward incompatible changes in callbacks that might require attention by some
applications:
tls_record_received() / tls_emit_data()
"""""""""""""""""""""""""""""""""""""""
Those callbacks now take `std::span<const uint8_t>` instead of `const uint8_t*`
with a `size_t` buffer length.
tls_session_established()
"""""""""""""""""""""""""
This callback provides a summary of the just-negotiated connection. It used to
have a bool return value letting an application decide to store or discard the
connection's resumption information. This use case is now provided via:
`tls_should_persist_resumption_information()` which might be called more than
once for a single TLS 1.3 connection.
`tls_session_established` is not a mandatory callback anymore but still allows
applications to abort a connection given a summary of the negotiated
characteristics. Note that this summary is not a persistable `Session` anymore.
tls_verify_cert_chain()
"""""""""""""""""""""""
The parameter `ocsp_responses`, which was previously
`std::shared_ptr<OCSP::Response>`, is now `std::optional<OCSP::Response>`.
tls_modify_extensions() / tls_examine_extensions()
""""""""""""""""""""""""""""""""""""""""""""""""""
These callbacks now have an additional parameter of type `Handshake_Type` that
identify the TLS handshake message the extensions in question are residing in.
TLS 1.3 makes much heavier use of such extensions in a wider range of messages
to implement core protocol functionality.
tls_dh_agree() / tls_ecdh_agree() / tls_decode_group_param()
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
These callbacks were used as customization points for the TLS 1.2 key exchange
in the TLS client. To allow similar (and more) customizations with the
introduction of TLS 1.3, these callbacks were replaced with a more generic
approach.
Key agreement is split into two callbacks, namely `tls_generate_ephemeral_key()`
and `tls_ephemeral_key_agreement()`. Those are used in both clients and servers
and in all protocol versions. `tls_decode_group_param()` is removed as it became
obsolete by the replacement of the other two callbacks.
Policy
^^^^^^
choose_key_exchange_group()
"""""""""""""""""""""""""""
The new parameter `offered_by_peer` identifies the key exchange groups a peer
has sent public exchange offerings for (in TLS 1.3 handshakes only).
Choosing a key exchange group that is not listed is legal but will result in an
additional network round trip (cf. "Hello Retry Request").
In TLS 1.2, this vector is always empty and can be ignored.
session_ticket_lifetime()
"""""""""""""""""""""""""
Now returns `std::chrono::seconds` rather than a bare `uint32_t`.
Credentials Manager
^^^^^^^^^^^^^^^^^^^
find_cert_chain(), cert_chain() and cert_chain_single_type()
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
These methods now have a `cert_signature_schemes` parameter that identifies
a list of signature schemes the peer is willing to accept for signatures
in certificates.
Notably, this *does not necessarily* mean that the leaf certificate must feature
a public key type able to generate one of those schemes.
private_key_for()
"""""""""""""""""
Applications must now provide a `std::shared_ptr<>` to the requested private key
object instead of a raw pointer to better communicate the implementation's
life-time expectations of this private key object.
.. _tls_session_manager_migration:
Session and Ticket Handling
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Old (pre-Botan 3.0) sessions won't load in Botan 3.0 anymore and should be
discarded.
For applications using `Session_Manager_SQL` or `Session_Manager_SQLite`
discarding happens automatically on first access after the update.
With Botan 3.0 the session manager now is responsible for stateful session
handling (backed by a database) and creation and management of stateless session
tickets.
The latter was previously handled transparently by the TLS implementation itself.
Therefore, TLS server applications that relied on Botan's default session
management implementations (most notably `Session_Manager_SQLite` or
`Session_Manager_In_Memory`) are advised to re-evaluate their choice.
Have a look at `Session_Manager_Hybrid` to retain support for both stateful and
stateless TLS sessions.
TLS client applications may safely keep relying on the above-mentioned default
implementations.
Applications implementing their own `Session_Manager` will need to adapt to the
new base class API.
New API of Session Manager
""""""""""""""""""""""""""
TLS 1.3 removed the legacy resumption procedures based on session IDs or session
tickets and combined them under the protocol's Pre-Shared Key mechanism.
This new approach allows TLS servers to handle sessions both stateless (as
self-contained encrypted and authenticated tickets) and stateful (identified
with unique database handles).
To accomodates this flexibility the `Session_Manager` base class API has changed
drastically and is now responsible for creation, storage and management of both
stateful sessions and stateless session tickets.
Sub-classes therefore gain full control over the session ticket's structure and
content.
API details are documented in the class' doxygen comments.
The Session Object and its Handle
"""""""""""""""""""""""""""""""""
Objects of class `Session` are not aware of their "session ID" or their "session
ticket" anymore.
Instead, the new class `Session_Handle` encapsulates the session's identifier or
ticket and accompanies the `Session` object where necessary.
Algorithms Removed
-------------------
The algorithms CAST-256, MISTY1, Kasumi, DESX, XTEA, PBKDF1, MCEIES, CBC-MAC,
Tiger, CECPQ1, and NewHope have been removed.
Certificate API shared_ptr
----------------------------
Previously the certificate store used ``shared_ptr<X509_Certificate>`` in
various APIs. However starting in 2.4.0, ``X509_Certificate`` itself is a pimpl
to a ``shared_ptr``, making the outer shared pointer pointless. In 3.0 the
certificate interfaces have changed to just consume and return ``X509_Certificate``.
All Or Nothing Package Transform
----------------------------------
This code was deprecated and has been removed.
Exception Changes
-------------------
Several exceptions, mostly ones not used by the library, were removed.
A few others that were very specific (such as Illegal_Point) were replaced
by throws of their immediate base class exception type.
The base class of Encoding_Error and Decoding_Error changed from
Invalid_Argument to Exception. If you are explicitly catching Invalid_Argument,
verify that you do not need to now also explicitly catch Encoding_Error and/or
Decoding_Error.
X.509 Certificate Info Access
-------------------------------
Previously ``X509_Certificate::subject_info`` and ``issuer_info`` could be used
to query information about extensions. This is not longer the case; instead you
should either call a specific function on ``X509_Certificate`` which returns the
same information, or lacking that, iterate over the result of
``X509_Certificate::v3_extensions``.
OCSP Response Validation
------------------------
After mitigating CVE-2022-43705 the OCSP response signature validation was refactored.
This led to the removal of the `OCSP::Response::check_signature()` method. If you
must validate OCSP responses directly in your application please use the new method
`OCSP::Response::find_signing_certificate()` and `OCSP::Response::verify_signature()`.
Use of ``enum class``
--------------------------------
Several enumerations where modified to become ``enum class``, including
``DL_Group::Format``, ``CRL_Code``, ``EC_Group_Encoding``, ``Signature_Format``,
``Cipher_Dir``, ``TLS::Extension_Code``, ``TLS::Connection_Side``,
``TLS::Record_Type``, and ``TLS::Handshake_Type``
In many cases the enumeration values were renamed from ``SHOUTING_CASE`` to
``CamelCase``. In some cases where the enumeration was commonly used by
applications (for example ``Signature_Format`` and ``Cipher_Dir``) the old
enumeration names are retained as deprecated variants.
ASN.1 enums
---------------
The enum ``ASN1_Tag`` has been split into ``ASN1_Type`` and ``ASN1_Class``.
Unlike ``ASN1_Tag``, these new enums are ``enum class``. The members of the
enums have changed from ``SHOUTING_CASE`` to ``CamelCase``, eg ``CONSTRUCTED``
is now ``Constructed``.
Also an important change related to ``ASN1_Tag::PRIVATE``. This enum value was
incorrect, and actually was used for explicitly tagged context specific values.
Now, ``ASN1_Class::Private`` refers to the correct class, but would lead to a
different encoding vs 2.x's ``ASN1_Tag::PRIVATE``. The correct value to use in
3.0 to match ``ASN1_Tag::PRIVATE`` is ``ASN1_Class::ExplicitContextSpecific``.
Cipher Mode Granularity
-------------------------
Previously Cipher_Mode::update_granularity specified the minimum buffer size
that must be provided during processing. However the value returned was often
much larger than what was strictly required. In particular some modes can easily
accept inputs as small as 1 byte, but their update_granularity was much larger
to encourage best performance.
Now update_granularity returns the true minimum value, and the new
Cipher_Mode::ideal_granularity returns a value which is a multiple of
update_granularity sized for good performance.
If you are sizing buffers on the basis of update_granularity consider
using ideal_granularity instead. Otherwise you may encounter performance
regressions due to creating and processing very small buffers.
"SHA-160" and "SHA1"
---------------------
Previously the library accepted "SHA-160" and "SHA1" alternative names
for "SHA-1". This is no longer the case, you must use "SHA-1". Botan
2.x also recognizes "SHA-1".
PointGFp
------------
This type is now named ``EC_Point``
X509::load_key
-------------------
Previously these functions returned a raw pointer. They now return
a std::unique_ptr
PKCS11_Request::subject_public_key and X509_Certificate::subject_public_key
-----------------------------------------------------------------------------
These functions now return a unique_ptr
choose_sig_format removed
---------------------------
The freestanding functions choose_sig_format have been removed.
Use X509_Object::choose_sig_format
DLIES Constructors
--------------------
Previously the constructors to the DLIES classes took raw pointers,
and retained ownership of them. They now consume std::unique_ptrs
Credentials_Manager::private_key_for
-------------------------------------
Previously this function returned a raw pointer, which the Credentials_Manager
implementation had to keep alive "forever", since there was no way for it to
know when or if the TLS layer had completed using the returned key.
Now this function returns std::shared_ptr<Private_Key>
OID operator+
------------------------
OID operator+ allowed concatenating new fields onto an object identifier. This
was not used at all within the library or the tests, and seems of marginal
value, so it was removed.
If necessary in your application, this can be done by retrieving the
vector of components from your source OID, push the new element onto the vector
and create an OID from the result.
RSA with "EMSA1" padding
-------------------------
EMSA1 indicates that effectively the plain hash is signed, with no other
padding. It is typically used for algorithms like ECSDA, but was allowed for
RSA. This is now no longer implemented.
If you must generate such signatures for some horrible reason, you can pre-hash
the message using a hash function as usual, and then sign using a "Raw" padding,
which will allow you to sign any arbitrary bits with no preprocessing.
ECDSA/DSA with "EMSA1" padding
---------------------------------
Previous versions of Botan required using a hash specifier like "EMSA1(SHA-256)"
when generating or verifying ECDSA/DSA signatures, with the specified hash. The
"EMSA1" was a reference to a now obsolete IEEE standard.
In Botan 3 the "EMSA1" notation is still accepted, but now also it is possible
to simply use the name of the hash, eg "EMSA1(SHA-256)" becomes "SHA-256".
Signature Algorithm OIDs
-----------------------------
In line with the previous entries, previously Botan used a string like
"ECDSA/EMSA1(SHA-256)" to identify the OID 1.2.840.10045.4.3.2. Now it
uses the string "ECDSA/SHA-256" instead, and does not recognize the
EMSA1 variant at all (for example in ``OID::from_string``).
Public Key Signature Padding
-----------------------------
In previous versions Botan was somewhat lenient about allowing the application
to specify using a hash which was in fact incompatible with the algorithm. For
example, Ed25519 signatures are *always* generated using SHA-512; there is no
choice in the matter. In the past, requesting using some other hash, say
SHA-256, would be silently ignored. Now an exception is thrown, indicating the
desired hash is not compatible with the algorithm.
In previous versions, various APIs required that the application specify the
hash function to be used. In most cases this can now be omitted (passing an
empty string) and a suitable default will be chosen.
Discrete Logarithm Key Changes
--------------------------------
Keys based on the discrete logarithm problem no longer derive from the
DL_Scheme_PrivateKey and DL_Scheme_PublicKey classes; these classes
have been removed.
Functions to access DL algorithm internal fields (such as the integer value of
the private key using ``get_x``) have been removed. If you need access to this
information you can use the new ``get_int_field`` function.
The constructors of the DL scheme private keys have changed. Previously, loading
and creating a key used the same constructor, namely one taking arguments
``(DL_Group, RandomNumberGenerator&, BigInt x = 0)`` and then the behavior of
the constructor depend on if ``x`` was zero (in which case a new key was
created) or otherwise if ``x`` was non-zero then it was taken as the private
key. Now there are two constructors, one taking a random number generator and a
group, which generates a new key, and a second taking a group and an integer,
which loads an existing key.
XMSS Signature Changes
------------------------
The logic to derive WOTS+ private keys from the seed contained in the XMSS
private key has been updated according to the recommendations in
NIST SP 800-208. While signatures created with old private keys are still valid using
the old public key, new valid signatures cannot be created. To still support legacy
private XMSS keys, they can be used by passing ``WOTS_Derivation_Method::Botan2x`` to
the constructor of the ``XMSS_PrivateKey``.
Private XMSS keys created this way use the old derivation logic and can therefore
generate new valid signatures. It is recommended to use
``WOTS_Derivation_Method::NIST_SP800_208`` (default) when creating new XMSS keys.
Random Number Generator
-----------------------
Fetching a large number of bytes via `randomize_with_input()` from a stateful
RNG will now incorporate the provided "input" data in the first request to the
underlying DRBG only. This applies to such DRBGs that pose a limit on the number
of bytes per request (most notable ``HMAC_DRBG`` with a 64kB default). Botan 2.x
(erroneously) applied the input to *all* underlying DRBG requests in such cases.
Applications that rely on a static seed for deterministic RNG output might
observe a different byte stream in such cases. As a workaround, users are
advised to "mimick" the legacy behaviour by manually pulling from the RNG in
"byte limit"-sized chunks and provide the "input" with each invocation.