@@ -321,6 +321,8 @@ int BignumPointer::isPrime(int nchecks,
321
321
return -1 ;
322
322
BN_GENCB_set (
323
323
cb.get (),
324
+ // TODO(@jasnell): This could be refactored to allow inlining.
325
+ // Not too important right now tho.
324
326
[](int a, int b, BN_GENCB* ctx) mutable -> int {
325
327
PrimeCheckCallback& ptr =
326
328
*static_cast <PrimeCheckCallback*>(BN_GENCB_get_arg (ctx));
@@ -374,6 +376,7 @@ bool BignumPointer::generate(const PrimeConfig& params,
374
376
BignumPointer BignumPointer::NewSub (const BignumPointer& a,
375
377
const BignumPointer& b) {
376
378
BignumPointer res = New ();
379
+ if (!res) return {};
377
380
if (!BN_sub (res.get (), a.get (), b.get ())) {
378
381
return {};
379
382
}
@@ -382,6 +385,7 @@ BignumPointer BignumPointer::NewSub(const BignumPointer& a,
382
385
383
386
BignumPointer BignumPointer::NewLShift (size_t length) {
384
387
BignumPointer res = New ();
388
+ if (!res) return {};
385
389
if (!BN_lshift (res.get (), One (), length)) {
386
390
return {};
387
391
}
@@ -1192,8 +1196,8 @@ std::string_view X509Pointer::ErrorCode(int32_t err) { // NOLINT(runtime/int)
1192
1196
return " UNSPECIFIED" ;
1193
1197
}
1194
1198
1195
- std::string_view X509Pointer::ErrorReason (int32_t err) {
1196
- if (err == X509_V_OK) return " " ;
1199
+ std::optional<std:: string_view> X509Pointer::ErrorReason (int32_t err) {
1200
+ if (err == X509_V_OK) return std::nullopt ;
1197
1201
return X509_verify_cert_error_string (err);
1198
1202
}
1199
1203
@@ -2235,11 +2239,12 @@ void SSLPointer::getCiphers(
2235
2239
// document them, but since there are only 5, easier to just add them manually
2236
2240
// and not have to explain their absence in the API docs. They are lower-cased
2237
2241
// because the docs say they will be.
2238
- static const char * TLS13_CIPHERS[] = {" tls_aes_256_gcm_sha384" ,
2239
- " tls_chacha20_poly1305_sha256" ,
2240
- " tls_aes_128_gcm_sha256" ,
2241
- " tls_aes_128_ccm_8_sha256" ,
2242
- " tls_aes_128_ccm_sha256" };
2242
+ static constexpr const char * TLS13_CIPHERS[] = {
2243
+ " tls_aes_256_gcm_sha384" ,
2244
+ " tls_chacha20_poly1305_sha256" ,
2245
+ " tls_aes_128_gcm_sha256" ,
2246
+ " tls_aes_128_ccm_8_sha256" ,
2247
+ " tls_aes_128_ccm_sha256" };
2243
2248
2244
2249
const int n = sk_SSL_CIPHER_num (ciphers);
2245
2250
@@ -2249,8 +2254,7 @@ void SSLPointer::getCiphers(
2249
2254
}
2250
2255
2251
2256
for (unsigned i = 0 ; i < 5 ; ++i) {
2252
- const char * name = TLS13_CIPHERS[i];
2253
- cb (name);
2257
+ cb (TLS13_CIPHERS[i]);
2254
2258
}
2255
2259
}
2256
2260
@@ -2265,7 +2269,6 @@ bool SSLPointer::setSniContext(const SSLCtxPointer& ctx) const {
2265
2269
if (!x509) return false ;
2266
2270
EVP_PKEY* pkey = SSL_CTX_get0_privatekey (ctx.get ());
2267
2271
STACK_OF (X509) * chain;
2268
-
2269
2272
int err = SSL_CTX_get0_chain_certs (ctx.get (), &chain);
2270
2273
if (err == 1 ) err = SSL_use_certificate (get (), x509);
2271
2274
if (err == 1 ) err = SSL_use_PrivateKey (get (), pkey);
@@ -2294,7 +2297,7 @@ std::optional<uint32_t> SSLPointer::verifyPeerCertificate() const {
2294
2297
}
2295
2298
2296
2299
const std::string_view SSLPointer::getClientHelloAlpn () const {
2297
- if (ssl_ == nullptr ) return std::string_view () ;
2300
+ if (ssl_ == nullptr ) return {} ;
2298
2301
const unsigned char * buf;
2299
2302
size_t len;
2300
2303
size_t rem;
@@ -2305,34 +2308,34 @@ const std::string_view SSLPointer::getClientHelloAlpn() const {
2305
2308
&buf,
2306
2309
&rem) ||
2307
2310
rem < 2 ) {
2308
- return nullptr ;
2311
+ return {} ;
2309
2312
}
2310
2313
2311
2314
len = (buf[0 ] << 8 ) | buf[1 ];
2312
- if (len + 2 != rem) return nullptr ;
2315
+ if (len + 2 != rem) return {} ;
2313
2316
return reinterpret_cast <const char *>(buf + 3 );
2314
2317
}
2315
2318
2316
2319
const std::string_view SSLPointer::getClientHelloServerName () const {
2317
- if (ssl_ == nullptr ) return std::string_view () ;
2320
+ if (ssl_ == nullptr ) return {} ;
2318
2321
const unsigned char * buf;
2319
2322
size_t len;
2320
2323
size_t rem;
2321
2324
2322
2325
if (!SSL_client_hello_get0_ext (get (), TLSEXT_TYPE_server_name, &buf, &rem) ||
2323
2326
rem <= 2 ) {
2324
- return nullptr ;
2327
+ return {} ;
2325
2328
}
2326
2329
2327
2330
len = (*buf << 8 ) | *(buf + 1 );
2328
- if (len + 2 != rem) return nullptr ;
2331
+ if (len + 2 != rem) return {} ;
2329
2332
rem = len;
2330
2333
2331
- if (rem == 0 || *(buf + 2 ) != TLSEXT_NAMETYPE_host_name) return nullptr ;
2334
+ if (rem == 0 || *(buf + 2 ) != TLSEXT_NAMETYPE_host_name) return {} ;
2332
2335
rem--;
2333
- if (rem <= 2 ) return nullptr ;
2336
+ if (rem <= 2 ) return {} ;
2334
2337
len = (*(buf + 3 ) << 8 ) | *(buf + 4 );
2335
- if (len + 2 > rem) return nullptr ;
2338
+ if (len + 2 > rem) return {} ;
2336
2339
return reinterpret_cast <const char *>(buf + 5 );
2337
2340
}
2338
2341
@@ -2453,7 +2456,7 @@ int Cipher::getNid() const {
2453
2456
return EVP_CIPHER_nid (cipher_);
2454
2457
}
2455
2458
2456
- const std::string_view Cipher::getModeLabel () const {
2459
+ std::string_view Cipher::getModeLabel () const {
2457
2460
if (!cipher_) return {};
2458
2461
switch (getMode ()) {
2459
2462
case EVP_CIPH_CCM_MODE:
@@ -2482,7 +2485,7 @@ const std::string_view Cipher::getModeLabel() const {
2482
2485
return " {unknown}" ;
2483
2486
}
2484
2487
2485
- const std::string_view Cipher::getName () const {
2488
+ std::string_view Cipher::getName () const {
2486
2489
if (!cipher_) return {};
2487
2490
// OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
2488
2491
// EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
@@ -2504,4 +2507,110 @@ bool Cipher::isSupportedAuthenticatedMode() const {
2504
2507
}
2505
2508
}
2506
2509
2510
+ // ============================================================================
2511
+
2512
+ CipherCtxPointer CipherCtxPointer::New () {
2513
+ auto ret = CipherCtxPointer (EVP_CIPHER_CTX_new ());
2514
+ if (!ret) return {};
2515
+ EVP_CIPHER_CTX_init (ret.get ());
2516
+ return ret;
2517
+ }
2518
+
2519
+ CipherCtxPointer::CipherCtxPointer (EVP_CIPHER_CTX* ctx) : ctx_(ctx) {}
2520
+
2521
+ CipherCtxPointer::CipherCtxPointer (CipherCtxPointer&& other) noexcept
2522
+ : ctx_(other.release()) {}
2523
+
2524
+ CipherCtxPointer& CipherCtxPointer::operator =(
2525
+ CipherCtxPointer&& other) noexcept {
2526
+ if (this == &other) return *this ;
2527
+ this ->~CipherCtxPointer ();
2528
+ return *new (this ) CipherCtxPointer (std::move (other));
2529
+ }
2530
+
2531
+ CipherCtxPointer::~CipherCtxPointer () {
2532
+ reset ();
2533
+ }
2534
+
2535
+ void CipherCtxPointer::reset (EVP_CIPHER_CTX* ctx) {
2536
+ ctx_.reset (ctx);
2537
+ }
2538
+
2539
+ EVP_CIPHER_CTX* CipherCtxPointer::release () {
2540
+ return ctx_.release ();
2541
+ }
2542
+
2543
+ void CipherCtxPointer::setFlags (int flags) {
2544
+ if (!ctx_) return ;
2545
+ EVP_CIPHER_CTX_set_flags (ctx_.get (), flags);
2546
+ }
2547
+
2548
+ bool CipherCtxPointer::setKeyLength (size_t length) {
2549
+ if (!ctx_) return false ;
2550
+ return EVP_CIPHER_CTX_set_key_length (ctx_.get (), length);
2551
+ }
2552
+
2553
+ bool CipherCtxPointer::setIvLength (size_t length) {
2554
+ if (!ctx_) return false ;
2555
+ return EVP_CIPHER_CTX_ctrl (
2556
+ ctx_.get (), EVP_CTRL_AEAD_SET_IVLEN, length, nullptr );
2557
+ }
2558
+
2559
+ bool CipherCtxPointer::setAeadTag (const Buffer<const char >& tag) {
2560
+ if (!ctx_) return false ;
2561
+ return EVP_CIPHER_CTX_ctrl (
2562
+ ctx_.get (), EVP_CTRL_AEAD_SET_TAG, tag.len , const_cast <char *>(tag.data ));
2563
+ }
2564
+
2565
+ bool CipherCtxPointer::setAeadTagLength (size_t length) {
2566
+ if (!ctx_) return false ;
2567
+ return EVP_CIPHER_CTX_ctrl (
2568
+ ctx_.get (), EVP_CTRL_AEAD_SET_TAG, length, nullptr );
2569
+ }
2570
+
2571
+ bool CipherCtxPointer::setPadding (bool padding) {
2572
+ if (!ctx_) return false ;
2573
+ return EVP_CIPHER_CTX_set_padding (ctx_.get (), padding);
2574
+ }
2575
+
2576
+ int CipherCtxPointer::getBlockSize () const {
2577
+ if (!ctx_) return 0 ;
2578
+ return EVP_CIPHER_CTX_block_size (ctx_.get ());
2579
+ }
2580
+
2581
+ int CipherCtxPointer::getMode () const {
2582
+ if (!ctx_) return 0 ;
2583
+ return EVP_CIPHER_CTX_mode (ctx_.get ());
2584
+ }
2585
+
2586
+ int CipherCtxPointer::getNid () const {
2587
+ if (!ctx_) return 0 ;
2588
+ return EVP_CIPHER_CTX_nid (ctx_.get ());
2589
+ }
2590
+
2591
+ bool CipherCtxPointer::init (const Cipher& cipher,
2592
+ bool encrypt,
2593
+ const unsigned char * key,
2594
+ const unsigned char * iv) {
2595
+ if (!ctx_) return false ;
2596
+ return EVP_CipherInit_ex (
2597
+ ctx_.get (), cipher, nullptr , key, iv, encrypt ? 1 : 0 ) == 1 ;
2598
+ }
2599
+
2600
+ bool CipherCtxPointer::update (const Buffer<const unsigned char >& in,
2601
+ unsigned char * out,
2602
+ int * out_len,
2603
+ bool finalize) {
2604
+ if (!ctx_) return false ;
2605
+ if (!finalize) {
2606
+ return EVP_CipherUpdate (ctx_.get (), out, out_len, in.data , in.len ) == 1 ;
2607
+ }
2608
+ return EVP_CipherFinal_ex (ctx_.get (), out, out_len) == 1 ;
2609
+ }
2610
+
2611
+ bool CipherCtxPointer::getAeadTag (size_t len, unsigned char * out) {
2612
+ if (!ctx_) return false ;
2613
+ return EVP_CIPHER_CTX_ctrl (ctx_.get (), EVP_CTRL_AEAD_GET_TAG, len, out);
2614
+ }
2615
+
2507
2616
} // namespace ncrypto
0 commit comments