Skip to content

Commit

Permalink
src: move crypto bio stuff to ncrypto
Browse files Browse the repository at this point in the history
  • Loading branch information
jasnell committed Aug 11, 2024
1 parent 9f5f3a9 commit b43b4d6
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 36 deletions.
14 changes: 13 additions & 1 deletion deps/ncrypto/ncrypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,11 @@ void BIOPointer::reset(BIO* bio) { bio_.reset(bio); }

BIO* BIOPointer::release() { return bio_.release(); }

bool BIOPointer::resetBio() const {
if (!bio_) return 0;
return BIO_reset(bio_.get()) == 1;
}

BIOPointer BIOPointer::NewMem() {
return BIOPointer(BIO_new(BIO_s_mem()));
}
Expand All @@ -742,7 +747,14 @@ BIOPointer BIOPointer::NewFile(std::string_view filename, std::string_view mode)
return BIOPointer(BIO_new_file(filename.data(), mode.data()));
}

BIOPointer BIOPointer::NewFd(int fd, int close_flag) {
BIOPointer BIOPointer::NewFp(FILE* fd, int close_flag) {
return BIOPointer(BIO_new_fp(fd, close_flag));
}

int BIOPointer::Write(BIOPointer* bio, std::string_view message) {
if (bio == nullptr || !*bio) return 0;
return BIO_write(bio->get(), message.data(), message.size());
}


} // namespace ncrypto
27 changes: 24 additions & 3 deletions deps/ncrypto/ncrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#include <optional>
#include <string>
#include <string_view>
#include "openssl/bn.h"
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/x509.h>
#include <openssl/dh.h>
#include <openssl/dsa.h>
Expand Down Expand Up @@ -250,9 +251,10 @@ class BIOPointer final {
static BIOPointer New(const BIO_METHOD* method);
static BIOPointer New(const void* data, size_t len);
static BIOPointer NewFile(std::string_view filename, std::string_view mode);
static BIOPointer NewFd(int fd, int flags);
static BIOPointer NewFp(FILE* fd, int flags);

BIOPointer() = default;
BIOPointer(std::nullptr_t) : bio_(nullptr) {}
explicit BIOPointer(BIO* bio);
BIOPointer(BIOPointer&& other) noexcept;
BIOPointer& operator=(BIOPointer&& other) noexcept;
Expand All @@ -263,11 +265,30 @@ class BIOPointer final {
inline operator bool() const { return bio_ != nullptr; }
inline BIO* get() const noexcept { return bio_.get(); }

inline operator BUF_MEM*() const {
BUF_MEM* mem = nullptr;
if (!bio_) return mem;
BIO_get_mem_ptr(bio_.get(), &mem);
return mem;
}

inline operator BIO*() const { return bio_.get(); }

void reset(BIO* bio = nullptr);
BIO* release();

bool resetBio() const;

static int Write(BIOPointer* bio, std::string_view message);

template <typename...Args>
static void Printf(BIOPointer* bio, const char* format, Args...args) {
if (bio == nullptr || !*bio) return;
BIO_printf(bio->get(), format, std::forward<Args...>(args...));
}

private:
DeleteFnPtr<BIO, BIO_free_all> bio_;
mutable DeleteFnPtr<BIO, BIO_free_all> bio_;
};

class BignumPointer final {
Expand Down
6 changes: 3 additions & 3 deletions src/crypto/crypto_bio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ BIOPointer NodeBIO::New(Environment* env) {
BIOPointer NodeBIO::NewFixed(const char* data, size_t len, Environment* env) {
BIOPointer bio = New(env);

if (!bio ||
len > INT_MAX ||
BIO_write(bio.get(), data, len) != static_cast<int>(len) ||
if (!bio || len > INT_MAX ||
BIOPointer::Write(&bio, std::string_view(data, len)) !=
static_cast<int>(len) ||
BIO_set_mem_eof_return(bio.get(), 0) != 1) {
return BIOPointer();
}
Expand Down
16 changes: 8 additions & 8 deletions src/crypto/crypto_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,14 @@ MaybeLocal<Value> GetCert(Environment* env, const SSLPointer& ssl) {
}

Local<Value> ToV8Value(Environment* env, const BIOPointer& bio) {
BUF_MEM* mem;
BIO_get_mem_ptr(bio.get(), &mem);
BUF_MEM* mem = bio;
MaybeLocal<String> ret =
String::NewFromUtf8(
env->isolate(),
mem->data,
NewStringType::kNormal,
mem->length);
CHECK_EQ(BIO_reset(bio.get()), 1);
CHECK(bio.resetBio());
return ret.FromMaybe(Local<Value>());
}

Expand Down Expand Up @@ -467,7 +466,8 @@ MaybeLocal<Value> GetExponentString(
const BIOPointer& bio,
const BIGNUM* e) {
uint64_t exponent_word = static_cast<uint64_t>(BignumPointer::GetWord(e));
BIO_printf(bio.get(), "0x%" PRIx64, exponent_word);
BIOPointer::Printf(
const_cast<BIOPointer*>(&bio), "0x%" PRIx64, exponent_word);
return ToV8Value(env, bio);
}

Expand Down Expand Up @@ -588,7 +588,7 @@ v8::MaybeLocal<v8::Value> GetSubjectAltNameString(Environment* env,
CHECK_NOT_NULL(ext);

if (!ncrypto::SafeX509SubjectAltNamePrint(bio, ext)) {
CHECK_EQ(BIO_reset(bio.get()), 1);
CHECK(bio.resetBio());
return v8::Null(env->isolate());
}

Expand All @@ -606,7 +606,7 @@ v8::MaybeLocal<v8::Value> GetInfoAccessString(Environment* env,
CHECK_NOT_NULL(ext);

if (!ncrypto::SafeX509InfoAccessPrint(bio, ext)) {
CHECK_EQ(BIO_reset(bio.get()), 1);
CHECK(bio.resetBio());
return v8::Null(env->isolate());
}

Expand All @@ -622,7 +622,7 @@ MaybeLocal<Value> GetIssuerString(Environment* env,
issuer_name,
0,
kX509NameFlagsMultiline) <= 0) {
CHECK_EQ(BIO_reset(bio.get()), 1);
CHECK(bio.resetBio());
return Undefined(env->isolate());
}

Expand All @@ -637,7 +637,7 @@ MaybeLocal<Value> GetSubject(Environment* env,
X509_get_subject_name(cert),
0,
kX509NameFlagsMultiline) <= 0) {
CHECK_EQ(BIO_reset(bio.get()), 1);
CHECK(bio.resetBio());
return Undefined(env->isolate());
}

Expand Down
8 changes: 4 additions & 4 deletions src/crypto/crypto_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,13 @@ BIOPointer LoadBIO(Environment* env, Local<Value> v) {
if (!bio) return {};
ByteSource bsrc = ByteSource::FromStringOrBuffer(env, v);
if (bsrc.size() > INT_MAX) return {};
int written = BIO_write(bio.get(), bsrc.data<char>(), bsrc.size());
int written = BIOPointer::Write(
&bio, std::string_view(bsrc.data<char>(), bsrc.size()));
if (written < 0) return {};
if (static_cast<size_t>(written) != bsrc.size()) return {};
return bio;
}
return nullptr;
return {};
}

namespace {
Expand Down Expand Up @@ -1012,7 +1013,6 @@ void SecureContext::SetSessionIdContext(
if (SSL_CTX_set_session_id_context(sc->ctx_.get(), sid_ctx, sid_ctx_len) == 1)
return;

BUF_MEM* mem;
Local<String> message;

auto bio = BIOPointer::NewMem();
Expand All @@ -1021,7 +1021,7 @@ void SecureContext::SetSessionIdContext(
"SSL_CTX_set_session_id_context error");
} else {
ERR_print_errors(bio.get());
BIO_get_mem_ptr(bio.get(), &mem);
BUF_MEM* mem = bio;
message = OneByteString(env->isolate(), mem->data, mem->length);
}

Expand Down
18 changes: 8 additions & 10 deletions src/crypto/crypto_keys.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ ParseKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
return ret;

// Maybe it is PKCS#1.
CHECK(BIO_reset(bp.get()));
CHECK(bp.resetBio());
ret = TryParsePublicKey(pkey, bp, "RSA PUBLIC KEY",
[](const unsigned char** p, long l) { // NOLINT(runtime/int)
return d2i_PublicKey(EVP_PKEY_RSA, nullptr, p, l);
Expand All @@ -128,7 +128,7 @@ ParseKeyResult ParsePublicKeyPEM(EVPKeyPointer* pkey,
return ret;

// X.509 fallback.
CHECK(BIO_reset(bp.get()));
CHECK(bp.resetBio());
return TryParsePublicKey(pkey, bp, "CERTIFICATE",
[](const unsigned char** p, long l) { // NOLINT(runtime/int)
X509Pointer x509(d2i_X509(nullptr, p, l));
Expand Down Expand Up @@ -270,12 +270,10 @@ ParseKeyResult ParsePrivateKey(EVPKeyPointer* pkey,
return ParseKeyResult::kParseKeyFailed;
}

MaybeLocal<Value> BIOToStringOrBuffer(
Environment* env,
BIO* bio,
PKFormatType format) {
BUF_MEM* bptr;
BIO_get_mem_ptr(bio, &bptr);
MaybeLocal<Value> BIOToStringOrBuffer(Environment* env,
const BIOPointer& bio,
PKFormatType format) {
BUF_MEM* bptr = bio;
if (format == kKeyFormatPEM) {
// PEM is an ASCII format, so we will return it as a string.
return String::NewFromUtf8(env->isolate(), bptr->data,
Expand Down Expand Up @@ -388,7 +386,7 @@ MaybeLocal<Value> WritePrivateKey(Environment* env,
ThrowCryptoError(env, ERR_get_error(), "Failed to encode private key");
return MaybeLocal<Value>();
}
return BIOToStringOrBuffer(env, bio.get(), config.format_);
return BIOToStringOrBuffer(env, bio, config.format_);
}

bool WritePublicKeyInner(OSSL3_CONST EVP_PKEY* pkey,
Expand Down Expand Up @@ -429,7 +427,7 @@ MaybeLocal<Value> WritePublicKey(Environment* env,
ThrowCryptoError(env, ERR_get_error(), "Failed to encode public key");
return MaybeLocal<Value>();
}
return BIOToStringOrBuffer(env, bio.get(), config.format_);
return BIOToStringOrBuffer(env, bio, config.format_);
}

Maybe<void> ExportJWKSecretKey(Environment* env,
Expand Down
11 changes: 6 additions & 5 deletions src/crypto/crypto_tls.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "crypto/crypto_tls.h"
#include "crypto/crypto_context.h"
#include "crypto/crypto_common.h"
#include "crypto/crypto_util.h"
#include <cstdio>
#include "async_wrap-inl.h"
#include "crypto/crypto_bio.h"
#include "crypto/crypto_clienthello-inl.h"
#include "async_wrap-inl.h"
#include "crypto/crypto_common.h"
#include "crypto/crypto_context.h"
#include "crypto/crypto_util.h"
#include "debug_utils-inl.h"
#include "memory_tracker-inl.h"
#include "node_buffer.h"
Expand Down Expand Up @@ -1244,7 +1245,7 @@ void TLSWrap::EnableTrace(const FunctionCallbackInfo<Value>& args) {

#if HAVE_SSL_TRACE
if (wrap->ssl_) {
wrap->bio_trace_ = BIOPointer::NewFd(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
wrap->bio_trace_ = BIOPointer::NewFp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
SSL_set_msg_callback(wrap->ssl_.get(), [](int write_p, int version, int
content_type, const void* buf, size_t len, SSL* ssl, void* arg)
-> void {
Expand Down
3 changes: 1 addition & 2 deletions src/crypto/crypto_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,7 @@ MaybeLocal<Uint8Array> ByteSource::ToBuffer(Environment* env) {

ByteSource ByteSource::FromBIO(const BIOPointer& bio) {
CHECK(bio);
BUF_MEM* bptr;
BIO_get_mem_ptr(bio.get(), &bptr);
BUF_MEM* bptr = bio;
ByteSource::Builder out(bptr->length);
memcpy(out.data<void>(), bptr->data, bptr->length);
return std::move(out).release();
Expand Down

0 comments on commit b43b4d6

Please sign in to comment.