An `std::string_view v` is a `const char* v.data()` along with an
`std::size_t v.size()` that guarantees that `v.size()` contiguous
elements of type `char` can be accessed relative to the pointer
`v.data()`.
One of the main reasons behind the existence of `std::string_view` is
the ability to operate on `char` sequences without requiring null
termination, which otherwise often requires expensive copies of strings
to be made. As a consequence, it is generally incorrect to assume that
`v.data()` points to a null-terminated sequence of `char`, and the only
way to obtain a null-terminated string from an `std::string_view` is to
make a copy. It is not even possible to check if the sequence pointed to
by `v.data()` is null-terminated because the null character would be at
position `v.data() + v.size()`, which is outside of the range that `v`
guarantees safe access to. (A default-constructed `std::string_view`
even sets its own data pointer to a `nullptr`, which is fine because it
only needs to guarantee safe access to zero elements, i.e., to no
elements).
In `deps/ncrypto` and `src/crypto`, there are various APIs that consume
`std::string_view v` arguments but then ignore `v.size()` and treat
`v.data()` as a C-style string of type `const char*`. However, that is
not what call sites would expect from functions that explicitly ask for
`std::string_view` arguments, since it makes assumptions beyond the
guarantees provided by `std::string_view` and leads to undefined
behavior unless the given view either contains an embedded null
character or the `char` at address `v.data() + v.size()` is a null
character. This is not a reasonable assumption for `std::string_view` in
general, and it also defeats the purpose of `std::string_view` for the
most part since, when `v.size()` is being ignored, it is essentially
just a `const char*`.
Constructing an `std::string_view` from a `const char*` is also not
"free" but requires computing the length of the C-style string (unless
the length can be computed at compile time, e.g., because the value is
just a string literal). Repeated conversion between `const char*` as
used by OpenSSL and `std::string_view` as used by ncrypto thus incurs
the additional overhead of computing the length of the string whenever
an `std::string_view` is constructed from a `const char*`. (This seems
negligible compared to the safety argument though.)
Similarly, returning a `const char*` pointer to a C-style string as an
`std::string_view` has two downsides: the function must compute the
length of the string in order to construct the view, and the caller
can no longer assume that the return value is null-terminated and thus
cannot pass the returned view to functions that require their arguments
to be null terminated. (And, for the reasons explained above, the caller
also cannot check if the value is null-terminated without potentially
invoking undefined behavior.)
C++20 unfortunately does not have a type similar to Rust's `CStr` or
GSL `czstring`. Therefore, this commit changes many occurrences of
`std::string_view` back to `const char*`, which is conventional for
null-terminated C-style strings and does not require computing the
length of strings.
There are _a lot_ of occurrences of `std::string_view` in ncrypto and
for each one, we need to evaluate if it is safe and a good abstraction.
I tried to do so, but I might have changed too few or too many, so
please feel free to give feedback on individual occurrences.
PR-URL: https://github.com/nodejs/node/pull/57816
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
The `CipherBase` class assumes that any authentication tag will fit into
`EVP_GCM_TLS_TAG_LEN` bytes, which is true because Node.js only supports
GCM with AES as the blocker cipher, and the block size of AES happens to
be 16 bytes, which coincidentally is also the output size of the
Poly1305 construction used by ChaCha20-Poly1305 as well as the maximum
size of authentication tags produced by AES in CCM or OCB mode.
This commit adds a new constant `ncrypto::Cipher::MAX_AUTH_TAG_LENGTH`
which is the maximum length of authentication tags produced by
algorithms that Node.js supports and replaces some constants in
`CipherBase` with semantically more meaningful named constants.
The OpenSSL team is debating whether a constant like
`MAX_AUTH_TAG_LENGTH` (`EVP_MAX_AEAD_TAG_LENGTH`) should exist at all
since its value necessarily depends on the set of AEAD algorithms
supported, but I do believe that, for Node.js, this is a step in the
right direction. It certainly makes more sense than to use the AES-GCM
tag size as defined by TLS.
PR-URL: https://github.com/nodejs/node/pull/57803
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/57023
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
* Use ncrypto APIs where appropriate
* Remove obsolete no-longer used functions
* Improve error handling a bit
* move secure heap handling to ncrypto
To simplify handling of boringssl/openssl, move secure
heap impl to ncrypto. Overall the reduces the complexity
of the code in crypto_util by eliminating additional
ifdef branches.
* simplify CryptoErrorStore::ToException a bit
* simplify error handling in crypto_common
* move curve utility methods to ncrypto
* verify that released DataPointers aren't on secure heap
The ByteSource does not currently know how to free a DataPointer
allocated on the secure heap, so just verify.
DataPointers on the secure heap are not something that users can
allocate on their own. Their use is rare. Eventually ByteSource
is going to be refactored around ncrypto APIs so these additional
checks should be temporary.
* simplify some ifdefs that are covered by ncrypto
* cleanup some obsolete includes in crypto_util
PR-URL: https://github.com/nodejs/node/pull/57323
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
An eventual goal for ncrypto is to completely abstract away
details of working directly with openssl in order to make it
easier to work with multiple different openssl/boringssl versions.
As part of that we want to move away from direct reliance on
specific openssl APIs in the runtime and instead go through
the ncrypto abstractions. Not only does this help other
runtimes trying to be compatible with Node.js, but it helps
Node.js also by reducing the complexity of the crypto code
in Node.js itself.
PR-URL: https://github.com/nodejs/node/pull/57300
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
PR-URL: https://github.com/nodejs/node/pull/56527
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
* remove obsolete LogSecret function
* move StackOfX509 decl to ncrypto
* colocate GetSSLOCSPResponse with callsite
* move x509 error code and reason to ncrypto
* simplify X509Pointer/X509View pointer derefs a bit
* move prime gen and checks to ncrypto
* move BN_* methods into ncrypto
* move SSLPointer impl to ncrypto
* move SSLCtxPointer impl to ncrypto
* move EVP_CIPHER methods to ncrypto
* move CipherCtx methods to ncrypto
PR-URL: https://github.com/nodejs/node/pull/56421
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
PR-URL: https://github.com/nodejs/node/pull/55425
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Added equivalent fields to `X509Certificate` in Date form.
PR-URL: https://github.com/nodejs/node/pull/54159
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
Start moving src/crypto functionality out to a separate dep that
can be shared with other projects that need to emulate Node.js
crypto behavior.
PR-URL: https://github.com/nodejs/node/pull/53803
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>