src: add mutex to ManagedEVPPKey class by danbev · Pull Request #36825 · nodejs/node · GitHub
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/crypto/crypto_dsa.cc
20 changes: 12 additions & 8 deletions src/crypto/crypto_ec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -601,9 +601,11 @@ WebCryptoKeyExportStatus EC_Raw_Export(
KeyObjectData* key_data,
const ECKeyExportConfig& params,
ByteSource* out) {
CHECK(key_data->GetAsymmetricKey());
ManagedEVPPKey m_pkey = key_data->GetAsymmetricKey();
CHECK(m_pkey);
Mutex::ScopedLock lock(*m_pkey.mutex());

EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key_data->GetAsymmetricKey().get());
EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(m_pkey.get());

unsigned char* data;
size_t len = 0;
Expand Down Expand Up @@ -688,10 +690,11 @@ Maybe<bool> ExportJWKEcKey(
Environment* env,
std::shared_ptr<KeyObjectData> key,
Local<Object> target) {
ManagedEVPPKey pkey = key->GetAsymmetricKey();
CHECK_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_EC);
ManagedEVPPKey m_pkey = key->GetAsymmetricKey();
Mutex::ScopedLock lock(*m_pkey.mutex());
CHECK_EQ(EVP_PKEY_id(m_pkey.get()), EVP_PKEY_EC);

EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey.get());
EC_KEY* ec = EVP_PKEY_get0_EC_KEY(m_pkey.get());
CHECK_NOT_NULL(ec);

const EC_POINT* pub = EC_KEY_get0_public_key(ec);
Expand Down Expand Up @@ -893,10 +896,11 @@ Maybe<bool> GetEcKeyDetail(
Environment* env,
std::shared_ptr<KeyObjectData> key,
Local<Object> target) {
ManagedEVPPKey pkey = key->GetAsymmetricKey();
CHECK_EQ(EVP_PKEY_id(pkey.get()), EVP_PKEY_EC);
ManagedEVPPKey m_pkey = key->GetAsymmetricKey();
Mutex::ScopedLock lock(*m_pkey.mutex());
CHECK_EQ(EVP_PKEY_id(m_pkey.get()), EVP_PKEY_EC);

EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey.get());
EC_KEY* ec = EVP_PKEY_get0_EC_KEY(m_pkey.get());
CHECK_NOT_NULL(ec);

const EC_GROUP* group = EC_KEY_get0_group(ec);
Expand Down
18 changes: 15 additions & 3 deletions src/crypto/crypto_keys.cc
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,8 @@ Maybe<bool> GetAsymmetricKeyDetail(
}
} // namespace

ManagedEVPPKey::ManagedEVPPKey(EVPKeyPointer&& pkey) : pkey_(std::move(pkey)) {}
ManagedEVPPKey::ManagedEVPPKey(EVPKeyPointer&& pkey) : pkey_(std::move(pkey)),
mutex_(std::make_shared<Mutex>()) {}

ManagedEVPPKey::ManagedEVPPKey(const ManagedEVPPKey& that) {
*this = that;
Expand All @@ -564,6 +565,8 @@ ManagedEVPPKey& ManagedEVPPKey::operator=(const ManagedEVPPKey& that) {
if (pkey_)
EVP_PKEY_up_ref(pkey_.get());

mutex_ = that.mutex_;

return *this;
}

Expand All @@ -575,6 +578,10 @@ EVP_PKEY* ManagedEVPPKey::get() const {
return pkey_.get();
}

Mutex* ManagedEVPPKey::mutex() const {
return mutex_.get();
}

void ManagedEVPPKey::MemoryInfo(MemoryTracker* tracker) const {
tracker->TrackFieldWithSize("pkey",
!pkey_ ? 0 : kSizeOf_EVP_PKEY +
Expand Down Expand Up @@ -1326,8 +1333,10 @@ WebCryptoKeyExportStatus PKEY_SPKI_Export(
KeyObjectData* key_data,
ByteSource* out) {
CHECK_EQ(key_data->GetKeyType(), kKeyTypePublic);
ManagedEVPPKey m_pkey = key_data->GetAsymmetricKey();
Mutex::ScopedLock lock(*m_pkey.mutex());
BIOPointer bio(BIO_new(BIO_s_mem()));
if (!i2d_PUBKEY_bio(bio.get(), key_data->GetAsymmetricKey().get()))
if (!i2d_PUBKEY_bio(bio.get(), m_pkey.get()))
return WebCryptoKeyExportStatus::FAILED;

*out = ByteSource::FromBIO(bio);
Expand All @@ -1338,8 +1347,11 @@ WebCryptoKeyExportStatus PKEY_PKCS8_Export(
KeyObjectData* key_data,
ByteSource* out) {
CHECK_EQ(key_data->GetKeyType(), kKeyTypePrivate);
ManagedEVPPKey m_pkey = key_data->GetAsymmetricKey();
Mutex::ScopedLock lock(*m_pkey.mutex());

BIOPointer bio(BIO_new(BIO_s_mem()));
PKCS8Pointer p8inf(EVP_PKEY2PKCS8(key_data->GetAsymmetricKey().get()));
PKCS8Pointer p8inf(EVP_PKEY2PKCS8(m_pkey.get()));
if (!i2d_PKCS8_PRIV_KEY_INFO_bio(bio.get(), p8inf.get()))
return WebCryptoKeyExportStatus::FAILED;

Expand Down
2 changes: 2 additions & 0 deletions src/crypto/crypto_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class ManagedEVPPKey : public MemoryRetainer {

operator bool() const;
EVP_PKEY* get() const;
Mutex* mutex() const;

void MemoryInfo(MemoryTracker* tracker) const override;
SET_MEMORY_INFO_NAME(ManagedEVPPKey)
Expand Down Expand Up @@ -127,6 +128,7 @@ class ManagedEVPPKey : public MemoryRetainer {
size_t size_of_public_key() const;

EVPKeyPointer pkey_;
std::shared_ptr<Mutex> mutex_;
};

// Objects of this class can safely be shared among threads.
Expand Down
23 changes: 13 additions & 10 deletions src/crypto/crypto_rsa.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,10 @@ WebCryptoCipherStatus RSA_Cipher(
const ByteSource& in,
ByteSource* out) {
CHECK_NE(key_data->GetKeyType(), kKeyTypeSecret);
ManagedEVPPKey m_pkey = key_data->GetAsymmetricKey();
Mutex::ScopedLock lock(*m_pkey.mutex());

EVPKeyCtxPointer ctx(
EVP_PKEY_CTX_new(key_data->GetAsymmetricKey().get(), nullptr));
EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(m_pkey.get(), nullptr));

if (!ctx || init(ctx.get()) <= 0)
return WebCryptoCipherStatus::FAILED;
Expand Down Expand Up @@ -363,17 +364,18 @@ Maybe<bool> ExportJWKRsaKey(
Environment* env,
std::shared_ptr<KeyObjectData> key,
Local<Object> target) {
ManagedEVPPKey pkey = key->GetAsymmetricKey();
int type = EVP_PKEY_id(pkey.get());
ManagedEVPPKey m_pkey = key->GetAsymmetricKey();
Mutex::ScopedLock lock(*m_pkey.mutex());
int type = EVP_PKEY_id(m_pkey.get());
CHECK(type == EVP_PKEY_RSA || type == EVP_PKEY_RSA_PSS);

// TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL
// versions older than 1.1.1e via FIPS / dynamic linking.
RSA* rsa;
if (OpenSSL_version_num() >= 0x1010105fL) {
rsa = EVP_PKEY_get0_RSA(pkey.get());
rsa = EVP_PKEY_get0_RSA(m_pkey.get());
} else {
rsa = static_cast<RSA*>(EVP_PKEY_get0(pkey.get()));
rsa = static_cast<RSA*>(EVP_PKEY_get0(m_pkey.get()));
}
CHECK_NOT_NULL(rsa);

Expand Down Expand Up @@ -511,17 +513,18 @@ Maybe<bool> GetRsaKeyDetail(
const BIGNUM* e; // Public Exponent
const BIGNUM* n; // Modulus

ManagedEVPPKey pkey = key->GetAsymmetricKey();
int type = EVP_PKEY_id(pkey.get());
ManagedEVPPKey m_pkey = key->GetAsymmetricKey();
Mutex::ScopedLock lock(*m_pkey.mutex());
int type = EVP_PKEY_id(m_pkey.get());
CHECK(type == EVP_PKEY_RSA || type == EVP_PKEY_RSA_PSS);

// TODO(tniessen): Remove the "else" branch once we drop support for OpenSSL
// versions older than 1.1.1e via FIPS / dynamic linking.
RSA* rsa;
if (OpenSSL_version_num() >= 0x1010105fL) {
rsa = EVP_PKEY_get0_RSA(pkey.get());
rsa = EVP_PKEY_get0_RSA(m_pkey.get());
} else {
rsa = static_cast<RSA*>(EVP_PKEY_get0(pkey.get()));
rsa = static_cast<RSA*>(EVP_PKEY_get0(m_pkey.get()));
}
CHECK_NOT_NULL(rsa);

Expand Down
24 changes: 13 additions & 11 deletions src/crypto/crypto_sig.cc