@@ -1164,7 +1164,7 @@ X509View X509View::From(const SSLCtxPointer& ctx) {
1164
1164
}
1165
1165
1166
1166
std::optional<std::string> X509View::getFingerprint (
1167
- const EVP_MD* method) const {
1167
+ const Digest& method) const {
1168
1168
unsigned int md_size;
1169
1169
unsigned char md[EVP_MAX_MD_SIZE];
1170
1170
static constexpr char hex[] = " 0123456789ABCDEF" ;
@@ -1669,17 +1669,17 @@ const EVP_CIPHER* getCipherByName(const std::string_view name) {
1669
1669
return EVP_get_cipherbyname (name.data ());
1670
1670
}
1671
1671
1672
- bool checkHkdfLength (const EVP_MD* md, size_t length) {
1672
+ bool checkHkdfLength (const Digest& md, size_t length) {
1673
1673
// HKDF-Expand computes up to 255 HMAC blocks, each having as many bits as
1674
1674
// the output of the hash function. 255 is a hard limit because HKDF appends
1675
1675
// an 8-bit counter to each HMAC'd message, starting at 1.
1676
1676
static constexpr size_t kMaxDigestMultiplier = 255 ;
1677
- size_t max_length = EVP_MD_size (md ) * kMaxDigestMultiplier ;
1677
+ size_t max_length = md. size ( ) * kMaxDigestMultiplier ;
1678
1678
if (length > max_length) return false ;
1679
1679
return true ;
1680
1680
}
1681
1681
1682
- DataPointer hkdf (const EVP_MD* md,
1682
+ DataPointer hkdf (const Digest& md,
1683
1683
const Buffer<const unsigned char >& key,
1684
1684
const Buffer<const unsigned char >& info,
1685
1685
const Buffer<const unsigned char >& salt,
@@ -1692,8 +1692,11 @@ DataPointer hkdf(const EVP_MD* md,
1692
1692
}
1693
1693
1694
1694
auto ctx = EVPKeyCtxPointer::NewFromID (EVP_PKEY_HKDF);
1695
+ // OpenSSL < 3.0.0 accepted only a void* as the argument of
1696
+ // EVP_PKEY_CTX_set_hkdf_md.
1697
+ const EVP_MD* md_ptr = md;
1695
1698
if (!ctx || !EVP_PKEY_derive_init (ctx.get ()) ||
1696
- !EVP_PKEY_CTX_set_hkdf_md (ctx.get (), md ) ||
1699
+ !EVP_PKEY_CTX_set_hkdf_md (ctx.get (), md_ptr ) ||
1697
1700
!EVP_PKEY_CTX_add1_hkdf_info (ctx.get (), info.data , info.len )) {
1698
1701
return {};
1699
1702
}
@@ -1703,7 +1706,7 @@ DataPointer hkdf(const EVP_MD* md,
1703
1706
if (salt.len > 0 ) {
1704
1707
actual_salt = {reinterpret_cast <const char *>(salt.data ), salt.len };
1705
1708
} else {
1706
- actual_salt = {default_salt, static_cast <unsigned >(EVP_MD_size (md ))};
1709
+ actual_salt = {default_salt, static_cast <unsigned >(md. size ( ))};
1707
1710
}
1708
1711
1709
1712
// We do not use EVP_PKEY_HKDF_MODE_EXTRACT_AND_EXPAND because and instead
@@ -1776,7 +1779,7 @@ DataPointer scrypt(const Buffer<const char>& pass,
1776
1779
return {};
1777
1780
}
1778
1781
1779
- DataPointer pbkdf2 (const EVP_MD* md,
1782
+ DataPointer pbkdf2 (const Digest& md,
1780
1783
const Buffer<const char >& pass,
1781
1784
const Buffer<const unsigned char >& salt,
1782
1785
uint32_t iterations,
@@ -1788,12 +1791,13 @@ DataPointer pbkdf2(const EVP_MD* md,
1788
1791
}
1789
1792
1790
1793
auto dp = DataPointer::Alloc (length);
1794
+ const EVP_MD* md_ptr = md;
1791
1795
if (dp && PKCS5_PBKDF2_HMAC (pass.data ,
1792
1796
pass.len ,
1793
1797
salt.data ,
1794
1798
salt.len ,
1795
1799
iterations,
1796
- md ,
1800
+ md_ptr ,
1797
1801
length,
1798
1802
reinterpret_cast <unsigned char *>(dp.get ()))) {
1799
1803
return dp;
@@ -2728,6 +2732,17 @@ bool SSLCtxPointer::setGroups(const char* groups) {
2728
2732
return SSL_CTX_set1_groups_list (get (), groups) == 1 ;
2729
2733
}
2730
2734
2735
+ bool SSLCtxPointer::setCipherSuites (std::string_view ciphers) {
2736
+ #ifndef OPENSSL_IS_BORINGSSL
2737
+ if (!ctx_) return false ;
2738
+ return SSL_CTX_set_ciphersuites (ctx_.get (), ciphers.data ());
2739
+ #else
2740
+ // BoringSSL does not allow API config of TLS 1.3 cipher suites.
2741
+ // We treat this as a non-op.
2742
+ return true ;
2743
+ #endif
2744
+ }
2745
+
2731
2746
// ============================================================================
2732
2747
2733
2748
const Cipher Cipher::FromName (std::string_view name) {
@@ -2742,6 +2757,55 @@ const Cipher Cipher::FromCtx(const CipherCtxPointer& ctx) {
2742
2757
return Cipher (EVP_CIPHER_CTX_cipher (ctx.get ()));
2743
2758
}
2744
2759
2760
+ const Cipher Cipher::EMPTY = Cipher ();
2761
+ const Cipher Cipher::AES_128_CBC = Cipher::FromNid (NID_aes_128_cbc);
2762
+ const Cipher Cipher::AES_192_CBC = Cipher::FromNid (NID_aes_192_cbc);
2763
+ const Cipher Cipher::AES_256_CBC = Cipher::FromNid (NID_aes_256_cbc);
2764
+ const Cipher Cipher::AES_128_CTR = Cipher::FromNid (NID_aes_128_ctr);
2765
+ const Cipher Cipher::AES_192_CTR = Cipher::FromNid (NID_aes_192_ctr);
2766
+ const Cipher Cipher::AES_256_CTR = Cipher::FromNid (NID_aes_256_ctr);
2767
+ const Cipher Cipher::AES_128_GCM = Cipher::FromNid (NID_aes_128_gcm);
2768
+ const Cipher Cipher::AES_192_GCM = Cipher::FromNid (NID_aes_192_gcm);
2769
+ const Cipher Cipher::AES_256_GCM = Cipher::FromNid (NID_aes_256_gcm);
2770
+ const Cipher Cipher::AES_128_KW = Cipher::FromNid (NID_id_aes128_wrap);
2771
+ const Cipher Cipher::AES_192_KW = Cipher::FromNid (NID_id_aes192_wrap);
2772
+ const Cipher Cipher::AES_256_KW = Cipher::FromNid (NID_id_aes256_wrap);
2773
+
2774
+ bool Cipher::isGcmMode () const {
2775
+ if (!cipher_) return false ;
2776
+ return getMode () == EVP_CIPH_GCM_MODE;
2777
+ }
2778
+
2779
+ bool Cipher::isWrapMode () const {
2780
+ if (!cipher_) return false ;
2781
+ return getMode () == EVP_CIPH_WRAP_MODE;
2782
+ }
2783
+
2784
+ bool Cipher::isCtrMode () const {
2785
+ if (!cipher_) return false ;
2786
+ return getMode () == EVP_CIPH_CTR_MODE;
2787
+ }
2788
+
2789
+ bool Cipher::isCcmMode () const {
2790
+ if (!cipher_) return false ;
2791
+ return getMode () == EVP_CIPH_CCM_MODE;
2792
+ }
2793
+
2794
+ bool Cipher::isOcbMode () const {
2795
+ if (!cipher_) return false ;
2796
+ return getMode () == EVP_CIPH_OCB_MODE;
2797
+ }
2798
+
2799
+ bool Cipher::isStreamMode () const {
2800
+ if (!cipher_) return false ;
2801
+ return getMode () == EVP_CIPH_STREAM_CIPHER;
2802
+ }
2803
+
2804
+ bool Cipher::isChaCha20Poly1305 () const {
2805
+ if (!cipher_) return false ;
2806
+ return getNid () == NID_chacha20_poly1305;
2807
+ }
2808
+
2745
2809
int Cipher::getMode () const {
2746
2810
if (!cipher_) return 0 ;
2747
2811
return EVP_CIPHER_mode (cipher_);
@@ -2818,6 +2882,14 @@ bool Cipher::isSupportedAuthenticatedMode() const {
2818
2882
}
2819
2883
}
2820
2884
2885
+ int Cipher::bytesToKey (const Digest& digest,
2886
+ const Buffer<const unsigned char >& input,
2887
+ unsigned char * key,
2888
+ unsigned char * iv) const {
2889
+ return EVP_BytesToKey (
2890
+ *this , Digest::MD5, nullptr , input.data , input.len , 1 , key, iv);
2891
+ }
2892
+
2821
2893
// ============================================================================
2822
2894
2823
2895
CipherCtxPointer CipherCtxPointer::New () {
@@ -2851,9 +2923,9 @@ EVP_CIPHER_CTX* CipherCtxPointer::release() {
2851
2923
return ctx_.release ();
2852
2924
}
2853
2925
2854
- void CipherCtxPointer::setFlags ( int flags ) {
2926
+ void CipherCtxPointer::setAllowWrap ( ) {
2855
2927
if (!ctx_) return ;
2856
- EVP_CIPHER_CTX_set_flags (ctx_.get (), flags );
2928
+ EVP_CIPHER_CTX_set_flags (ctx_.get (), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW );
2857
2929
}
2858
2930
2859
2931
bool CipherCtxPointer::setKeyLength (size_t length) {
@@ -2894,6 +2966,26 @@ int CipherCtxPointer::getMode() const {
2894
2966
return EVP_CIPHER_CTX_mode (ctx_.get ());
2895
2967
}
2896
2968
2969
+ bool CipherCtxPointer::isGcmMode () const {
2970
+ if (!ctx_) return false ;
2971
+ return getMode () == EVP_CIPH_GCM_MODE;
2972
+ }
2973
+
2974
+ bool CipherCtxPointer::isCcmMode () const {
2975
+ if (!ctx_) return false ;
2976
+ return getMode () == EVP_CIPH_CCM_MODE;
2977
+ }
2978
+
2979
+ bool CipherCtxPointer::isWrapMode () const {
2980
+ if (!ctx_) return false ;
2981
+ return getMode () == EVP_CIPH_WRAP_MODE;
2982
+ }
2983
+
2984
+ bool CipherCtxPointer::isChaCha20Poly1305 () const {
2985
+ if (!ctx_) return false ;
2986
+ return getNid () == NID_chacha20_poly1305;
2987
+ }
2988
+
2897
2989
int CipherCtxPointer::getNid () const {
2898
2990
if (!ctx_) return 0 ;
2899
2991
return EVP_CIPHER_CTX_nid (ctx_.get ());
@@ -3258,14 +3350,16 @@ bool EVPKeyCtxPointer::setEcParameters(int curve, int encoding) {
3258
3350
EVP_PKEY_CTX_set_ec_param_enc (ctx_.get (), encoding) == 1 ;
3259
3351
}
3260
3352
3261
- bool EVPKeyCtxPointer::setRsaOaepMd (const EVP_MD* md) {
3262
- if (md == nullptr || !ctx_) return false ;
3263
- return EVP_PKEY_CTX_set_rsa_oaep_md (ctx_.get (), md) > 0 ;
3353
+ bool EVPKeyCtxPointer::setRsaOaepMd (const Digest& md) {
3354
+ if (!md || !ctx_) return false ;
3355
+ const EVP_MD* md_ptr = md;
3356
+ return EVP_PKEY_CTX_set_rsa_oaep_md (ctx_.get (), md_ptr) > 0 ;
3264
3357
}
3265
3358
3266
- bool EVPKeyCtxPointer::setRsaMgf1Md (const EVP_MD* md) {
3267
- if (md == nullptr || !ctx_) return false ;
3268
- return EVP_PKEY_CTX_set_rsa_mgf1_md (ctx_.get (), md) > 0 ;
3359
+ bool EVPKeyCtxPointer::setRsaMgf1Md (const Digest& md) {
3360
+ if (!md || !ctx_) return false ;
3361
+ const EVP_MD* md_ptr = md;
3362
+ return EVP_PKEY_CTX_set_rsa_mgf1_md (ctx_.get (), md_ptr) > 0 ;
3269
3363
}
3270
3364
3271
3365
bool EVPKeyCtxPointer::setRsaPadding (int padding) {
@@ -3300,14 +3394,17 @@ bool EVPKeyCtxPointer::setRsaKeygenPubExp(BignumPointer&& e) {
3300
3394
return false ;
3301
3395
}
3302
3396
3303
- bool EVPKeyCtxPointer::setRsaPssKeygenMd (const EVP_MD* md) {
3304
- if (md == nullptr || !ctx_) return false ;
3305
- return EVP_PKEY_CTX_set_rsa_pss_keygen_md (ctx_.get (), md) > 0 ;
3397
+ bool EVPKeyCtxPointer::setRsaPssKeygenMd (const Digest& md) {
3398
+ if (!md || !ctx_) return false ;
3399
+ // OpenSSL < 3 accepts a void* for the md parameter.
3400
+ const EVP_MD* md_ptr = md;
3401
+ return EVP_PKEY_CTX_set_rsa_pss_keygen_md (ctx_.get (), md_ptr) > 0 ;
3306
3402
}
3307
3403
3308
- bool EVPKeyCtxPointer::setRsaPssKeygenMgf1Md (const EVP_MD* md) {
3309
- if (md == nullptr || !ctx_) return false ;
3310
- return EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md (ctx_.get (), md) > 0 ;
3404
+ bool EVPKeyCtxPointer::setRsaPssKeygenMgf1Md (const Digest& md) {
3405
+ if (!md || !ctx_) return false ;
3406
+ const EVP_MD* md_ptr = md;
3407
+ return EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md (ctx_.get (), md_ptr) > 0 ;
3311
3408
}
3312
3409
3313
3410
bool EVPKeyCtxPointer::setRsaPssSaltlen (int salt_len) {
@@ -3673,6 +3770,74 @@ DataPointer Cipher::recover(const EVPKeyPointer& key,
3673
3770
key, params, in);
3674
3771
}
3675
3772
3773
+ namespace {
3774
+ struct CipherCallbackContext {
3775
+ Cipher::CipherNameCallback cb;
3776
+ void operator ()(std::string_view name) { cb (name); }
3777
+ };
3778
+
3779
+ #if OPENSSL_VERSION_MAJOR >= 3
3780
+ template <class TypeName ,
3781
+ TypeName* fetch_type (OSSL_LIB_CTX*, const char *, const char *),
3782
+ void free_type(TypeName*),
3783
+ const TypeName* getbyname(const char *),
3784
+ const char* getname(const TypeName*)>
3785
+ void array_push_back(const TypeName* evp_ref,
3786
+ const char * from,
3787
+ const char * to,
3788
+ void * arg) {
3789
+ if (from == nullptr ) return ;
3790
+
3791
+ const TypeName* real_instance = getbyname (from);
3792
+ if (!real_instance) return ;
3793
+
3794
+ const char * real_name = getname (real_instance);
3795
+ if (!real_name) return ;
3796
+
3797
+ // EVP_*_fetch() does not support alias names, so we need to pass it the
3798
+ // real/original algorithm name.
3799
+ // We use EVP_*_fetch() as a filter here because it will only return an
3800
+ // instance if the algorithm is supported by the public OpenSSL APIs (some
3801
+ // algorithms are used internally by OpenSSL and are also passed to this
3802
+ // callback).
3803
+ TypeName* fetched = fetch_type (nullptr , real_name, nullptr );
3804
+ if (fetched == nullptr ) return ;
3805
+
3806
+ free_type (fetched);
3807
+ auto & cb = *(static_cast <CipherCallbackContext*>(arg));
3808
+ cb (from);
3809
+ }
3810
+ #else
3811
+ template <class TypeName >
3812
+ void array_push_back (const TypeName* evp_ref,
3813
+ const char * from,
3814
+ const char * to,
3815
+ void * arg) {
3816
+ if (!from) return ;
3817
+ auto & cb = *(static_cast <CipherCallbackContext*>(arg));
3818
+ cb (from);
3819
+ }
3820
+ #endif
3821
+ } // namespace
3822
+
3823
+ void Cipher::ForEach (Cipher::CipherNameCallback callback) {
3824
+ ClearErrorOnReturn clearErrorOnReturn;
3825
+ CipherCallbackContext context;
3826
+ context.cb = std::move (callback);
3827
+
3828
+ EVP_CIPHER_do_all_sorted (
3829
+ #if OPENSSL_VERSION_MAJOR >= 3
3830
+ array_push_back<EVP_CIPHER,
3831
+ EVP_CIPHER_fetch,
3832
+ EVP_CIPHER_free,
3833
+ EVP_get_cipherbyname,
3834
+ EVP_CIPHER_get0_name>,
3835
+ #else
3836
+ array_push_back<EVP_CIPHER>,
3837
+ #endif
3838
+ &context);
3839
+ }
3840
+
3676
3841
// ============================================================================
3677
3842
3678
3843
Ec::Ec () : ec_ (nullptr ) {}
@@ -3713,7 +3878,7 @@ EVP_MD_CTX* EVPMDCtxPointer::release() {
3713
3878
return ctx_.release ();
3714
3879
}
3715
3880
3716
- bool EVPMDCtxPointer::digestInit (const EVP_MD* digest) {
3881
+ bool EVPMDCtxPointer::digestInit (const Digest& digest) {
3717
3882
if (!ctx_) return false ;
3718
3883
return EVP_DigestInit_ex (ctx_.get (), digest, nullptr ) > 0 ;
3719
3884
}
@@ -3779,7 +3944,7 @@ bool EVPMDCtxPointer::copyTo(const EVPMDCtxPointer& other) const {
3779
3944
}
3780
3945
3781
3946
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInit (const EVPKeyPointer& key,
3782
- const EVP_MD* digest) {
3947
+ const Digest& digest) {
3783
3948
EVP_PKEY_CTX* ctx = nullptr ;
3784
3949
if (!EVP_DigestSignInit (ctx_.get (), &ctx, digest, nullptr , key.get ())) {
3785
3950
return std::nullopt;
@@ -3788,7 +3953,7 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInit(const EVPKeyPointer& key,
3788
3953
}
3789
3954
3790
3955
std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInit (
3791
- const EVPKeyPointer& key, const EVP_MD* digest) {
3956
+ const EVPKeyPointer& key, const Digest& digest) {
3792
3957
EVP_PKEY_CTX* ctx = nullptr ;
3793
3958
if (!EVP_DigestVerifyInit (ctx_.get (), &ctx, digest, nullptr , key.get ())) {
3794
3959
return std::nullopt;
@@ -3885,9 +4050,10 @@ HMAC_CTX* HMACCtxPointer::release() {
3885
4050
return ctx_.release ();
3886
4051
}
3887
4052
3888
- bool HMACCtxPointer::init (const Buffer<const void >& buf, const EVP_MD* md) {
4053
+ bool HMACCtxPointer::init (const Buffer<const void >& buf, const Digest& md) {
3889
4054
if (!ctx_) return false ;
3890
- return HMAC_Init_ex (ctx_.get (), buf.data , buf.len , md, nullptr ) == 1 ;
4055
+ const EVP_MD* md_ptr = md;
4056
+ return HMAC_Init_ex (ctx_.get (), buf.data , buf.len , md_ptr, nullptr ) == 1 ;
3891
4057
}
3892
4058
3893
4059
bool HMACCtxPointer::update (const Buffer<const void >& buf) {
@@ -4029,4 +4195,21 @@ size_t Dsa::getDivisorLength() const {
4029
4195
return BignumPointer::GetBitCount (getQ ());
4030
4196
}
4031
4197
4198
+ // ============================================================================
4199
+
4200
+ size_t Digest::size () const {
4201
+ if (md_ == nullptr ) return 0 ;
4202
+ return EVP_MD_size (md_);
4203
+ }
4204
+
4205
+ const Digest Digest::MD5 = Digest (EVP_md5 ());
4206
+ const Digest Digest::SHA1 = Digest (EVP_sha1 ());
4207
+ const Digest Digest::SHA256 = Digest (EVP_sha256 ());
4208
+ const Digest Digest::SHA384 = Digest (EVP_sha384 ());
4209
+ const Digest Digest::SHA512 = Digest (EVP_sha512 ());
4210
+
4211
+ const Digest Digest::FromName (std::string_view name) {
4212
+ return ncrypto::getDigestByName (name);
4213
+ }
4214
+
4032
4215
} // namespace ncrypto
0 commit comments