@@ -321,6 +321,8 @@ int BignumPointer::isPrime(int nchecks,
321321 return -1 ;
322322 BN_GENCB_set (
323323 cb.get (),
324+ // TODO(@jasnell): This could be refactored to allow inlining.
325+ // Not too important right now tho.
324326 [](int a, int b, BN_GENCB* ctx) mutable -> int {
325327 PrimeCheckCallback& ptr =
326328 *static_cast <PrimeCheckCallback*>(BN_GENCB_get_arg (ctx));
@@ -374,6 +376,7 @@ bool BignumPointer::generate(const PrimeConfig& params,
374376BignumPointer BignumPointer::NewSub (const BignumPointer& a,
375377 const BignumPointer& b) {
376378 BignumPointer res = New ();
379+ if (!res) return {};
377380 if (!BN_sub (res.get (), a.get (), b.get ())) {
378381 return {};
379382 }
@@ -382,6 +385,7 @@ BignumPointer BignumPointer::NewSub(const BignumPointer& a,
382385
383386BignumPointer BignumPointer::NewLShift (size_t length) {
384387 BignumPointer res = New ();
388+ if (!res) return {};
385389 if (!BN_lshift (res.get (), One (), length)) {
386390 return {};
387391 }
@@ -1192,8 +1196,8 @@ std::string_view X509Pointer::ErrorCode(int32_t err) { // NOLINT(runtime/int)
11921196 return " UNSPECIFIED" ;
11931197}
11941198
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 ;
11971201 return X509_verify_cert_error_string (err);
11981202}
11991203
@@ -2235,11 +2239,12 @@ void SSLPointer::getCiphers(
22352239 // document them, but since there are only 5, easier to just add them manually
22362240 // and not have to explain their absence in the API docs. They are lower-cased
22372241 // 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" };
22432248
22442249 const int n = sk_SSL_CIPHER_num (ciphers);
22452250
@@ -2249,8 +2254,7 @@ void SSLPointer::getCiphers(
22492254 }
22502255
22512256 for (unsigned i = 0 ; i < 5 ; ++i) {
2252- const char * name = TLS13_CIPHERS[i];
2253- cb (name);
2257+ cb (TLS13_CIPHERS[i]);
22542258 }
22552259}
22562260
@@ -2265,7 +2269,6 @@ bool SSLPointer::setSniContext(const SSLCtxPointer& ctx) const {
22652269 if (!x509) return false ;
22662270 EVP_PKEY* pkey = SSL_CTX_get0_privatekey (ctx.get ());
22672271 STACK_OF (X509) * chain;
2268-
22692272 int err = SSL_CTX_get0_chain_certs (ctx.get (), &chain);
22702273 if (err == 1 ) err = SSL_use_certificate (get (), x509);
22712274 if (err == 1 ) err = SSL_use_PrivateKey (get (), pkey);
@@ -2294,7 +2297,7 @@ std::optional<uint32_t> SSLPointer::verifyPeerCertificate() const {
22942297}
22952298
22962299const std::string_view SSLPointer::getClientHelloAlpn () const {
2297- if (ssl_ == nullptr ) return std::string_view () ;
2300+ if (ssl_ == nullptr ) return {} ;
22982301 const unsigned char * buf;
22992302 size_t len;
23002303 size_t rem;
@@ -2305,34 +2308,34 @@ const std::string_view SSLPointer::getClientHelloAlpn() const {
23052308 &buf,
23062309 &rem) ||
23072310 rem < 2 ) {
2308- return nullptr ;
2311+ return {} ;
23092312 }
23102313
23112314 len = (buf[0 ] << 8 ) | buf[1 ];
2312- if (len + 2 != rem) return nullptr ;
2315+ if (len + 2 != rem) return {} ;
23132316 return reinterpret_cast <const char *>(buf + 3 );
23142317}
23152318
23162319const std::string_view SSLPointer::getClientHelloServerName () const {
2317- if (ssl_ == nullptr ) return std::string_view () ;
2320+ if (ssl_ == nullptr ) return {} ;
23182321 const unsigned char * buf;
23192322 size_t len;
23202323 size_t rem;
23212324
23222325 if (!SSL_client_hello_get0_ext (get (), TLSEXT_TYPE_server_name, &buf, &rem) ||
23232326 rem <= 2 ) {
2324- return nullptr ;
2327+ return {} ;
23252328 }
23262329
23272330 len = (*buf << 8 ) | *(buf + 1 );
2328- if (len + 2 != rem) return nullptr ;
2331+ if (len + 2 != rem) return {} ;
23292332 rem = len;
23302333
2331- if (rem == 0 || *(buf + 2 ) != TLSEXT_NAMETYPE_host_name) return nullptr ;
2334+ if (rem == 0 || *(buf + 2 ) != TLSEXT_NAMETYPE_host_name) return {} ;
23322335 rem--;
2333- if (rem <= 2 ) return nullptr ;
2336+ if (rem <= 2 ) return {} ;
23342337 len = (*(buf + 3 ) << 8 ) | *(buf + 4 );
2335- if (len + 2 > rem) return nullptr ;
2338+ if (len + 2 > rem) return {} ;
23362339 return reinterpret_cast <const char *>(buf + 5 );
23372340}
23382341
@@ -2453,7 +2456,7 @@ int Cipher::getNid() const {
24532456 return EVP_CIPHER_nid (cipher_);
24542457}
24552458
2456- const std::string_view Cipher::getModeLabel () const {
2459+ std::string_view Cipher::getModeLabel () const {
24572460 if (!cipher_) return {};
24582461 switch (getMode ()) {
24592462 case EVP_CIPH_CCM_MODE:
@@ -2482,7 +2485,7 @@ const std::string_view Cipher::getModeLabel() const {
24822485 return " {unknown}" ;
24832486}
24842487
2485- const std::string_view Cipher::getName () const {
2488+ std::string_view Cipher::getName () const {
24862489 if (!cipher_) return {};
24872490 // OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
24882491 // EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
@@ -2504,4 +2507,110 @@ bool Cipher::isSupportedAuthenticatedMode() const {
25042507 }
25052508}
25062509
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+
25072616} // namespace ncrypto
0 commit comments