Add detailed comment explaining OpenSSL v3 default digest behavior

This commit adds comprehensive documentation in the code explaining:
- How OpenSSL v3 provides SHA256 as the default digest for RSA keys
- The exact source code locations in OpenSSL where this happens
- Why BoringSSL behaves differently (no automatic default)
- Why this fix is necessary for Node.js compatibility

The comment includes specific file paths and line numbers from OpenSSL v3
source code for future reference and maintenance.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude Bot
2025-09-02 08:42:16 +00:00
parent d2dc8db8ed
commit a2550bee45

View File

@@ -350,11 +350,47 @@ std::optional<SignJobCtx> SignJobCtx::fromJS(JSGlobalObject* globalObject, Throw
return {};
}
} else {
// When no algorithm is specified, use a default for RSA keys
// Ed25519/Ed448 (one-shot variants) don't need a digest
// OpenSSL v3 Default Digest Behavior for RSA Keys
// ================================================
// When Node.js calls crypto.sign() or crypto.verify() with a null/undefined algorithm,
// it passes NULL to OpenSSL's EVP_DigestSignInit/EVP_DigestVerifyInit functions.
//
// OpenSSL v3 then automatically provides a default digest for RSA keys through the
// following mechanism:
//
// 1. In crypto/evp/m_sigver.c:215-220 (do_sigver_init function):
// When mdname is NULL and type is NULL, OpenSSL calls:
// evp_keymgmt_util_get_deflt_digest_name(tmp_keymgmt, provkey, locmdname, sizeof(locmdname))
//
// 2. In crypto/evp/keymgmt_lib.c:533-571 (evp_keymgmt_util_get_deflt_digest_name function):
// This queries the key management provider for OSSL_PKEY_PARAM_DEFAULT_DIGEST
//
// 3. In providers/implementations/keymgmt/rsa_kmgmt.c:
// - Line 54: #define RSA_DEFAULT_MD "SHA256"
// - Lines 351-355: For RSA keys (non-PSS), it returns RSA_DEFAULT_MD ("SHA256")
// if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
// && (rsa_type != RSA_FLAG_TYPE_RSASSAPSS
// || ossl_rsa_pss_params_30_is_unrestricted(pss_params))) {
// if (!OSSL_PARAM_set_utf8_string(p, RSA_DEFAULT_MD))
// return 0;
// }
//
// BoringSSL Difference:
// =====================
// BoringSSL (used by Bun) does not have this automatic default mechanism.
// When NULL is passed as the digest to EVP_DigestVerifyInit for RSA keys,
// BoringSSL returns error 0x06000077 (NO_DEFAULT_DIGEST).
//
// This Fix:
// =========
// To achieve Node.js/OpenSSL compatibility, we explicitly set SHA256 as the
// default digest for RSA keys when no algorithm is specified, matching the
// OpenSSL behavior documented above.
//
// For Ed25519/Ed448 keys (one-shot variants), we intentionally leave digest
// as null since these algorithms perform their own hashing internally and
// don't require a separate digest algorithm.
if (keyObject.asymmetricKey().isRsaVariant()) {
// Use SHA256 as default for RSA keys when no algorithm is specified
// This matches Node.js behavior for crypto.verify with null algorithm
digest = Digest::FromName("SHA256"_s);
}
}