@@ -75,6 +75,7 @@ namespace {
7575using BignumCtxPointer = DeleteFnPtr<BN_CTX , BN_CTX_free>;
7676using BignumGenCallbackPointer = DeleteFnPtr<BN_GENCB , BN_GENCB_free>;
7777using NetscapeSPKIPointer = DeleteFnPtr<NETSCAPE_SPKI , NETSCAPE_SPKI_free>;
78+ using X509PubKeyPointer = DeleteFnPtr<X509_PUBKEY , X509_PUBKEY_free>;
7879
7980static constexpr int kX509NameFlagsRFC2253WithinUtf8JSON =
8081 XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB & ~ASN1_STRFLGS_ESC_CTRL ;
@@ -2755,6 +2756,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePrivateKey(
27552756#else
27562757 RSA * rsa = EVP_PKEY_get0_RSA (get ());
27572758#endif
2759+ if (rsa == nullptr ) return Result<BIOPointer, bool >(false );
2760+
27582761 switch (config.format ) {
27592762 case PKFormatType::PEM : {
27602763 err = PEM_write_bio_RSAPrivateKey (
@@ -2818,6 +2821,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePrivateKey(
28182821#else
28192822 EC_KEY * ec = EVP_PKEY_get0_EC_KEY (get ());
28202823#endif
2824+ if (ec == nullptr ) return Result<BIOPointer, bool >(false );
2825+
28212826 switch (config.format ) {
28222827 case PKFormatType::PEM : {
28232828 err = PEM_write_bio_ECPrivateKey (
@@ -2871,6 +2876,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePublicKey(
28712876#else
28722877 RSA * rsa = EVP_PKEY_get0_RSA (get ());
28732878#endif
2879+ if (rsa == nullptr ) return Result<BIOPointer, bool >(false );
2880+
28742881 if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM ) {
28752882 // Encode PKCS#1 as PEM.
28762883 if (PEM_write_bio_RSAPublicKey (bio.get (), rsa) != 1 ) {
@@ -2890,7 +2897,14 @@ Result<BIOPointer, bool> EVPKeyPointer::writePublicKey(
28902897
28912898 if (config.format == ncrypto::EVPKeyPointer::PKFormatType::PEM ) {
28922899 // Encode SPKI as PEM.
2893- if (PEM_write_bio_PUBKEY (bio.get (), get ()) != 1 ) {
2900+ X509_PUBKEY * pubkey = nullptr ;
2901+ if (X509_PUBKEY_set (&pubkey, get ()) != 1 ) {
2902+ X509_PUBKEY_free (pubkey);
2903+ return Result<BIOPointer, bool >(false ,
2904+ mark_pop_error_on_return.peekError ());
2905+ }
2906+ X509PubKeyPointer pubkey_ptr (pubkey);
2907+ if (PEM_write_bio_X509_PUBKEY (bio.get (), pubkey_ptr.get ()) != 1 ) {
28942908 return Result<BIOPointer, bool >(false ,
28952909 mark_pop_error_on_return.peekError ());
28962910 }
@@ -2959,14 +2973,45 @@ std::optional<uint32_t> EVPKeyPointer::getBytesOfRS() const {
29592973
29602974 if (id == EVP_PKEY_DSA ) {
29612975 const DSA * dsa_key = EVP_PKEY_get0_DSA (get ());
2976+ bool has_bits = false ;
29622977 // Both r and s are computed mod q, so their width is limited by that of q.
2963- bits = BignumPointer::GetBitCount (DSA_get0_q (dsa_key));
2978+ if (dsa_key != nullptr ) {
2979+ const BIGNUM * q = DSA_get0_q (dsa_key);
2980+ if (q != nullptr ) {
2981+ bits = BignumPointer::GetBitCount (q);
2982+ has_bits = true ;
2983+ }
2984+ }
2985+ #if OPENSSL_VERSION_MAJOR >= 3 && !defined(OPENSSL_IS_BORINGSSL)
2986+ if (!has_bits &&
2987+ EVP_PKEY_get_int_param (get (), OSSL_PKEY_PARAM_FFC_QBITS , &bits) == 1 ) {
2988+ has_bits = true ;
2989+ }
2990+ #endif
2991+ if (!has_bits) return std::nullopt ;
29642992 } else if (id == EVP_PKEY_EC ) {
2965- bits = EC_GROUP_order_bits (ECKeyPointer::GetGroup (*this ));
2993+ const EC_KEY * ec_key = EVP_PKEY_get0_EC_KEY (get ());
2994+ bool has_bits = false ;
2995+ if (ec_key != nullptr ) {
2996+ const EC_GROUP * group = ECKeyPointer::GetGroup (ec_key);
2997+ if (group != nullptr ) {
2998+ bits = EC_GROUP_order_bits (group);
2999+ has_bits = true ;
3000+ }
3001+ }
3002+ #if OPENSSL_VERSION_MAJOR >= 3 && !defined(OPENSSL_IS_BORINGSSL)
3003+ if (!has_bits &&
3004+ EVP_PKEY_get_int_param (get (), OSSL_PKEY_PARAM_BITS , &bits) == 1 ) {
3005+ has_bits = true ;
3006+ }
3007+ #endif
3008+ if (!has_bits) return std::nullopt ;
29663009 } else {
29673010 return std::nullopt ;
29683011 }
29693012
3013+ if (bits <= 0 ) return std::nullopt ;
3014+
29703015 return (bits + 7 ) / 8 ;
29713016}
29723017
@@ -2997,16 +3042,18 @@ EVPKeyPointer::operator Dsa() const {
29973042
29983043bool EVPKeyPointer::validateDsaParameters () const {
29993044 if (!pkey_) return false ;
3000- /* Validate DSA2 parameters from FIPS 186-4 */
3045+ /* Validate DSA2 parameters from FIPS 186-4 */
30013046#if OPENSSL_VERSION_MAJOR >= 3
30023047 if (EVP_default_properties_is_fips_enabled (nullptr ) && EVP_PKEY_DSA == id ()) {
30033048#else
30043049 if (FIPS_mode () && EVP_PKEY_DSA == id ()) {
30053050#endif
30063051 const DSA * dsa = EVP_PKEY_get0_DSA (pkey_.get ());
3052+ if (dsa == nullptr ) return false ;
30073053 const BIGNUM * p;
30083054 const BIGNUM * q;
30093055 DSA_get0_pqg (dsa, &p, &q, nullptr );
3056+ if (p == nullptr || q == nullptr ) return false ;
30103057 int L = BignumPointer::GetBitCount (p);
30113058 int N = BignumPointer::GetBitCount (q);
30123059
0 commit comments