This allows to move ASN1 logic from inside the `SECPxxxr1` curve
itself to the data structures. It makes more sense to have dedicated and
explicit methods to handle transformation between formats.
C++ will jovially select the implicit conversion operator, even if it's
complete bogus, such as for unknown-size types or non-destructible
types. Therefore, all such conversions (which incur a copy) must
(unfortunately) be explicit so that non-copyable types continue to work.
NOTE: We make an exception for trivially copyable types, since they
are, well, trivially copyable.
Co-authored-by: kleines Filmröllchen <filmroellchen@serenityos.org>
Replicate what we are doing with RSA and parse both the private and
public key when parsing the ASN1.
The only thing that changed in the tests is the error message.
The decoding inside `RSA::parse_rsa_key` is quite complex because it
tries to understand if it's decoding PKCS#8 or PKCS#1. Simplify the code
by moving the burden to the PEM decoder.
I have divided ANS1 constants by length so that they don't have
trailing zeros that need to be removed.
Also moved OIDs lists to the only place they are used for clarity.
Fixed a couple of WPT tests by adding SECP521r1 to the list of known
curves.
Parse and store the `ECPrivateKey` extracted from the
`privateKeyAlgorithm` field of the ASN.1 `PrivateKeyInfo` sequence when
the algorithm identifier is `ec_public_key_encryption`.
The parsing function returns `ErrorOr` instead of an "empty" key, like
`parse_rsa_key` does. To me, this seemed better in terms of reliability.
As mentioned in the previous commit, there is room for improvement.
Added basic EC private and public key definitions as well as ASN.1
encoding and decoding.
A lot of refactoring can be made around the ASN.1 processing (here and
in other parts of the codebase) by utilizing what is available
in `LibCrypto::Certificate` as macros, but I think it's outside the
scope of implementing ECDH support for WebCryptoAPI.
It looks like the `SECPxxxr1` was made mainly to work with the TLS
implementation which requires everything to be bytes. This is not always
the case and a loss of generality.
I have added some methods that take and return `UnsignedBigInteger`s
for better interoperability with ASN.1 stuff. I would like to remove
the old methods relying on bytes, but I haven't made my mind around how
to generalize it for all curves.
Add support for encoding parameters in `wrap_in_private_key_info` and
`wrap_in_subject_public_key_info` as well as turn `Span<int>` into
`Span<int const>`.
By moving `Certificate` to `LibCrypto` it is possible to reuse a bunch
of code from in `LibCrypto` itself. It also moves some constants
and pieces of code to a more appropriate place than `LibTLS`.
This also makes future work on WebCryptoAPI easier.
These changes are arbitrarily divided into multiple commits to make it
easier to find potentially introduced bugs with git bisect.
The modifications in this commit were automatically made using the
following command:
find . -name '*.h' -exec sed -i -E 's/dbg\(\) << ("[^"{]*");/dbgln\(\1\);/' {} \;
These changes are arbitrarily divided into multiple commits to make it
easier to find potentially introduced bugs with git bisect.Everything:
The modifications in this commit were automatically made using the
following command:
find . -name '*.cpp' -exec sed -i -E 's/dbg\(\) << ("[^"{]*");/dbgln\(\1\);/' {} \;
Problem:
- `constexpr` functions are decorated with the `inline` specifier
keyword. This is redundant because `constexpr` functions are
implicitly `inline`.
- [dcl.constexpr], §7.1.5/2 in the C++11 standard): "constexpr
functions and constexpr constructors are implicitly inline (7.1.2)".
Solution:
- Remove the redundant `inline` keyword.
Before, when the actually passed key was too long, the extra bytes were silently
ignored. This can lead to all sorts of trouble, so ... don't do that.
The original intention was maybe to support non-integer amounts of key bytes.
But that doesn't happen anyway with AES.
Any (future) program that includes this header would fail to compile, because the
private symbol 'kind_name' is defined, along with a bunch of code, but unused.
A good way to see this is by #include'ing LibCrypto/ASN1/ASN1.h in an unrelated
.cpp-file, for example Userland/md.cpp.
No other headers seem to have this problem.