@@ -111,20 +111,64 @@ DataPointer DataPointer::Alloc(size_t len) {
111
111
#endif
112
112
}
113
113
114
+ DataPointer DataPointer::SecureAlloc (size_t len) {
115
+ #ifndef OPENSSL_IS_BORINGSSL
116
+ auto ptr = OPENSSL_secure_zalloc (len);
117
+ if (ptr == nullptr ) return {};
118
+ return DataPointer (ptr, len, true );
119
+ #else
120
+ // BoringSSL does not implement the OPENSSL_secure_zalloc API.
121
+ auto ptr = OPENSSL_malloc (len);
122
+ if (ptr == nullptr ) return {};
123
+ memset (ptr, 0 , len);
124
+ return DataPointer (ptr, len);
125
+ #endif
126
+ }
127
+
128
+ size_t DataPointer::GetSecureHeapUsed () {
129
+ #ifndef OPENSSL_IS_BORINGSSL
130
+ return CRYPTO_secure_malloc_initialized () ? CRYPTO_secure_used () : 0 ;
131
+ #else
132
+ // BoringSSL does not have the secure heap and therefore
133
+ // will always return 0.
134
+ return 0 ;
135
+ #endif
136
+ }
137
+
138
+ DataPointer::InitSecureHeapResult DataPointer::TryInitSecureHeap (size_t amount,
139
+ size_t min) {
140
+ #ifndef OPENSSL_IS_BORINGSSL
141
+ switch (CRYPTO_secure_malloc_init (amount, min)) {
142
+ case 0 :
143
+ return InitSecureHeapResult::FAILED;
144
+ case 2 :
145
+ return InitSecureHeapResult::UNABLE_TO_MEMORY_MAP;
146
+ case 1 :
147
+ return InitSecureHeapResult::OK;
148
+ default :
149
+ return InitSecureHeapResult::FAILED;
150
+ }
151
+ #else
152
+ // BoringSSL does not actually support the secure heap
153
+ return InitSecureHeapResult::FAILED;
154
+ #endif
155
+ }
156
+
114
157
DataPointer DataPointer::Copy (const Buffer<const void >& buffer) {
115
158
return DataPointer (OPENSSL_memdup (buffer.data , buffer.len ), buffer.len );
116
159
}
117
160
118
- DataPointer::DataPointer (void * data, size_t length)
119
- : data_(data), len_(length) {}
161
+ DataPointer::DataPointer (void * data, size_t length, bool secure )
162
+ : data_(data), len_(length), secure_(secure) {}
120
163
121
- DataPointer::DataPointer (const Buffer<void >& buffer)
122
- : data_(buffer.data), len_(buffer.len) {}
164
+ DataPointer::DataPointer (const Buffer<void >& buffer, bool secure )
165
+ : data_(buffer.data), len_(buffer.len), secure_(secure) {}
123
166
124
167
DataPointer::DataPointer (DataPointer&& other) noexcept
125
- : data_(other.data_), len_(other.len_) {
168
+ : data_(other.data_), len_(other.len_), secure_(other.secure_) {
126
169
other.data_ = nullptr ;
127
170
other.len_ = 0 ;
171
+ other.secure_ = false ;
128
172
}
129
173
130
174
DataPointer& DataPointer::operator =(DataPointer&& other) noexcept {
@@ -144,7 +188,11 @@ void DataPointer::zero() {
144
188
145
189
void DataPointer::reset (void * data, size_t length) {
146
190
if (data_ != nullptr ) {
147
- OPENSSL_clear_free (data_, len_);
191
+ if (secure_) {
192
+ OPENSSL_secure_clear_free (data_, len_);
193
+ } else {
194
+ OPENSSL_clear_free (data_, len_);
195
+ }
148
196
}
149
197
data_ = data;
150
198
len_ = length;
@@ -175,6 +223,7 @@ DataPointer DataPointer::resize(size_t len) {
175
223
176
224
// ============================================================================
177
225
bool isFipsEnabled () {
226
+ ClearErrorOnReturn clear_error_on_return;
178
227
#if OPENSSL_VERSION_MAJOR >= 3
179
228
return EVP_default_properties_is_fips_enabled (nullptr ) == 1 ;
180
229
#else
@@ -186,30 +235,31 @@ bool setFipsEnabled(bool enable, CryptoErrorList* errors) {
186
235
if (isFipsEnabled () == enable) return true ;
187
236
ClearErrorOnReturn clearErrorOnReturn (errors);
188
237
#if OPENSSL_VERSION_MAJOR >= 3
189
- return EVP_default_properties_enable_fips (nullptr , enable ? 1 : 0 ) == 1 ;
238
+ return EVP_default_properties_enable_fips (nullptr , enable ? 1 : 0 ) == 1 &&
239
+ EVP_default_properties_is_fips_enabled (nullptr );
190
240
#else
191
241
return FIPS_mode_set (enable ? 1 : 0 ) == 1 ;
192
242
#endif
193
243
}
194
244
195
245
bool testFipsEnabled () {
246
+ ClearErrorOnReturn clear_error_on_return;
196
247
#if OPENSSL_VERSION_MAJOR >= 3
197
248
OSSL_PROVIDER* fips_provider = nullptr ;
198
249
if (OSSL_PROVIDER_available (nullptr , " fips" )) {
199
250
fips_provider = OSSL_PROVIDER_load (nullptr , " fips" );
200
251
}
201
- const auto enabled = fips_provider == nullptr ? 0
202
- : OSSL_PROVIDER_self_test (fips_provider) ? 1
203
- : 0 ;
252
+ if (fips_provider == nullptr ) return false ;
253
+ int result = OSSL_PROVIDER_self_test (fips_provider);
254
+ OSSL_PROVIDER_unload (fips_provider);
255
+ return result;
204
256
#else
205
257
#ifdef OPENSSL_FIPS
206
- const auto enabled = FIPS_selftest () ? 1 : 0 ;
258
+ return FIPS_selftest ();
207
259
#else // OPENSSL_FIPS
208
- const auto enabled = 0 ;
260
+ return false ;
209
261
#endif // OPENSSL_FIPS
210
262
#endif
211
-
212
- return enabled;
213
263
}
214
264
215
265
// ============================================================================
@@ -2689,6 +2739,21 @@ std::optional<std::string_view> SSLPointer::getCipherVersion() const {
2689
2739
return SSL_CIPHER_get_version (cipher);
2690
2740
}
2691
2741
2742
+ std::optional<int > SSLPointer::getSecurityLevel () {
2743
+ #ifndef OPENSSL_IS_BORINGSSL
2744
+ auto ctx = SSLCtxPointer::New ();
2745
+ if (!ctx) return std::nullopt;
2746
+
2747
+ auto ssl = SSLPointer::New (ctx);
2748
+ if (!ssl) return std::nullopt;
2749
+
2750
+ return SSL_get_security_level (ssl);
2751
+ #else
2752
+ // for BoringSSL assume the same as the default
2753
+ return OPENSSL_TLS_SECURITY_LEVEL;
2754
+ #endif // OPENSSL_IS_BORINGSSL
2755
+ }
2756
+
2692
2757
SSLCtxPointer::SSLCtxPointer (SSL_CTX* ctx) : ctx_ (ctx) {}
2693
2758
2694
2759
SSLCtxPointer::SSLCtxPointer (SSLCtxPointer&& other) noexcept
@@ -3290,6 +3355,10 @@ EVPKeyCtxPointer EVPKeyCtxPointer::New(const EVPKeyPointer& key) {
3290
3355
}
3291
3356
3292
3357
EVPKeyCtxPointer EVPKeyCtxPointer::NewFromID (int id) {
3358
+ #ifdef OPENSSL_IS_BORINGSSL
3359
+ // DSA keys are not supported with BoringSSL
3360
+ if (id == EVP_PKEY_DSA) return {};
3361
+ #endif
3293
3362
return EVPKeyCtxPointer (EVP_PKEY_CTX_new_id (id, nullptr ));
3294
3363
}
3295
3364
@@ -3852,6 +3921,26 @@ int Ec::getCurve() const {
3852
3921
return EC_GROUP_get_curve_name (getGroup ());
3853
3922
}
3854
3923
3924
+ int Ec::GetCurveIdFromName (std::string_view name) {
3925
+ int nid = EC_curve_nist2nid (name.data ());
3926
+ if (nid == NID_undef) {
3927
+ nid = OBJ_sn2nid (name.data ());
3928
+ }
3929
+ return nid;
3930
+ }
3931
+
3932
+ bool Ec::GetCurves (Ec::GetCurveCallback callback) {
3933
+ const size_t count = EC_get_builtin_curves (nullptr , 0 );
3934
+ std::vector<EC_builtin_curve> curves (count);
3935
+ if (EC_get_builtin_curves (curves.data (), count) != count) {
3936
+ return false ;
3937
+ }
3938
+ for (auto curve : curves) {
3939
+ if (!callback (OBJ_nid2sn (curve.nid ))) return false ;
3940
+ }
3941
+ return true ;
3942
+ }
3943
+
3855
3944
// ============================================================================
3856
3945
3857
3946
EVPMDCtxPointer::EVPMDCtxPointer () : ctx_ (nullptr ) {}
0 commit comments