@@ -312,23 +312,27 @@ BignumPointer BignumPointer::clone() {
312312}
313313
314314int BignumPointer::isPrime (int nchecks,
315- BignumPointer::PrimeCheckCallback innerCb) const {
315+ BignumPointer::PrimeCheckCallback innerCb) const {
316316 BignumCtxPointer ctx (BN_CTX_new ());
317317 BignumGenCallbackPointer cb (nullptr );
318318 if (innerCb != nullptr ) {
319319 cb = BignumGenCallbackPointer (BN_GENCB_new ());
320- if (!cb) [[unlikely]] return -1 ;
321- BN_GENCB_set (cb.get (), [](int a, int b, BN_GENCB* ctx) mutable -> int {
322- PrimeCheckCallback& ptr =
323- *static_cast <PrimeCheckCallback*>(BN_GENCB_get_arg (ctx));
324- return ptr (a, b) ? 1 : 0 ;
325- }, &innerCb);
320+ if (!cb) [[unlikely]]
321+ return -1 ;
322+ BN_GENCB_set (
323+ cb.get (),
324+ [](int a, int b, BN_GENCB* ctx) mutable -> int {
325+ PrimeCheckCallback& ptr =
326+ *static_cast <PrimeCheckCallback*>(BN_GENCB_get_arg (ctx));
327+ return ptr (a, b) ? 1 : 0 ;
328+ },
329+ &innerCb);
326330 }
327331 return BN_is_prime_ex (get (), nchecks, ctx.get (), cb.get ());
328332}
329333
330334BignumPointer BignumPointer::NewPrime (const PrimeConfig& params,
331- PrimeCheckCallback cb) {
335+ PrimeCheckCallback cb) {
332336 BignumPointer prime (BN_new ());
333337 if (!prime || !prime.generate (params, std::move (cb))) {
334338 return {};
@@ -337,27 +341,30 @@ BignumPointer BignumPointer::NewPrime(const PrimeConfig& params,
337341}
338342
339343bool BignumPointer::generate (const PrimeConfig& params,
340- PrimeCheckCallback innerCb) const {
344+ PrimeCheckCallback innerCb) const {
341345 // BN_generate_prime_ex() calls RAND_bytes_ex() internally.
342346 // Make sure the CSPRNG is properly seeded.
343347 CSPRNG (nullptr , 0 );
344348 BignumGenCallbackPointer cb (nullptr );
345349 if (innerCb != nullptr ) {
346350 cb = BignumGenCallbackPointer (BN_GENCB_new ());
347- if (!cb) [[unlikely]] return -1 ;
348- BN_GENCB_set (cb.get (), [](int a, int b, BN_GENCB* ctx) mutable -> int {
349- PrimeCheckCallback& ptr =
350- *static_cast <PrimeCheckCallback*>(BN_GENCB_get_arg (ctx));
351- return ptr (a, b) ? 1 : 0 ;
352- }, &innerCb);
353- }
354- if (BN_generate_prime_ex (
355- get (),
356- params.bits ,
357- params.safe ? 1 : 0 ,
358- params.add .get (),
359- params.rem .get (),
360- cb.get ()) == 0 ) {
351+ if (!cb) [[unlikely]]
352+ return -1 ;
353+ BN_GENCB_set (
354+ cb.get (),
355+ [](int a, int b, BN_GENCB* ctx) mutable -> int {
356+ PrimeCheckCallback& ptr =
357+ *static_cast <PrimeCheckCallback*>(BN_GENCB_get_arg (ctx));
358+ return ptr (a, b) ? 1 : 0 ;
359+ },
360+ &innerCb);
361+ }
362+ if (BN_generate_prime_ex (get (),
363+ params.bits ,
364+ params.safe ? 1 : 0 ,
365+ params.add .get (),
366+ params.rem .get (),
367+ cb.get ()) == 0 ) {
361368 return false ;
362369 }
363370
@@ -2228,13 +2235,11 @@ void SSLPointer::getCiphers(
22282235 // document them, but since there are only 5, easier to just add them manually
22292236 // and not have to explain their absence in the API docs. They are lower-cased
22302237 // because the docs say they will be.
2231- static const char * TLS13_CIPHERS[] = {
2232- " tls_aes_256_gcm_sha384" ,
2233- " tls_chacha20_poly1305_sha256" ,
2234- " tls_aes_128_gcm_sha256" ,
2235- " tls_aes_128_ccm_8_sha256" ,
2236- " tls_aes_128_ccm_sha256"
2237- };
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" };
22382243
22392244 const int n = sk_SSL_CIPHER_num (ciphers);
22402245
@@ -2259,7 +2264,7 @@ bool SSLPointer::setSniContext(const SSLCtxPointer& ctx) const {
22592264 auto x509 = ncrypto::X509View::From (ctx);
22602265 if (!x509) return false ;
22612266 EVP_PKEY* pkey = SSL_CTX_get0_privatekey (ctx.get ());
2262- STACK_OF (X509)* chain;
2267+ STACK_OF (X509) * chain;
22632268
22642269 int err = SSL_CTX_get0_chain_certs (ctx.get (), &chain);
22652270 if (err == 1 ) err = SSL_use_certificate (get (), x509);
@@ -2281,7 +2286,7 @@ std::optional<uint32_t> SSLPointer::verifyPeerCertificate() const {
22812286 // looks like session resumption.
22822287 if (SSL_CIPHER_get_auth_nid (curr_cipher) == NID_auth_psk ||
22832288 (SSL_SESSION_get_protocol_version (sess) == TLS1_3_VERSION &&
2284- SSL_session_reused (get ()))) {
2289+ SSL_session_reused (get ()))) {
22852290 return X509_V_OK;
22862291 }
22872292
@@ -2314,26 +2319,20 @@ const std::string_view SSLPointer::getClientHelloServerName() const {
23142319 size_t len;
23152320 size_t rem;
23162321
2317- if (!SSL_client_hello_get0_ext (
2318- get (),
2319- TLSEXT_TYPE_server_name,
2320- &buf,
2321- &rem) || rem <= 2 ) {
2322+ if (!SSL_client_hello_get0_ext (get (), TLSEXT_TYPE_server_name, &buf, &rem) ||
2323+ rem <= 2 ) {
23222324 return nullptr ;
23232325 }
23242326
23252327 len = (*buf << 8 ) | *(buf + 1 );
2326- if (len + 2 != rem)
2327- return nullptr ;
2328+ if (len + 2 != rem) return nullptr ;
23282329 rem = len;
23292330
23302331 if (rem == 0 || *(buf + 2 ) != TLSEXT_NAMETYPE_host_name) return nullptr ;
23312332 rem--;
2332- if (rem <= 2 )
2333- return nullptr ;
2333+ if (rem <= 2 ) return nullptr ;
23342334 len = (*(buf + 3 ) << 8 ) | *(buf + 4 );
2335- if (len + 2 > rem)
2336- return nullptr ;
2335+ if (len + 2 > rem) return nullptr ;
23372336 return reinterpret_cast <const char *>(buf + 5 );
23382337}
23392338
@@ -2383,7 +2382,9 @@ SSLCtxPointer& SSLCtxPointer::operator=(SSLCtxPointer&& other) noexcept {
23832382 return *new (this ) SSLCtxPointer (std::move (other));
23842383}
23852384
2386- SSLCtxPointer::~SSLCtxPointer () { reset (); }
2385+ SSLCtxPointer::~SSLCtxPointer () {
2386+ reset ();
2387+ }
23872388
23882389void SSLCtxPointer::reset (SSL_CTX* ctx) {
23892390 ctx_.reset (ctx);
@@ -2413,4 +2414,94 @@ bool SSLCtxPointer::setGroups(const char* groups) {
24132414 return SSL_CTX_set1_groups_list (get (), groups) == 1 ;
24142415}
24152416
2417+ // ============================================================================
2418+
2419+ const Cipher Cipher::FromName (const char * name) {
2420+ return Cipher (EVP_get_cipherbyname (name));
2421+ }
2422+
2423+ const Cipher Cipher::FromNid (int nid) {
2424+ return Cipher (EVP_get_cipherbynid (nid));
2425+ }
2426+
2427+ const Cipher Cipher::FromCtx (const CipherCtxPointer& ctx) {
2428+ return Cipher (EVP_CIPHER_CTX_cipher (ctx.get ()));
2429+ }
2430+
2431+ int Cipher::getMode () const {
2432+ if (!cipher_) return 0 ;
2433+ return EVP_CIPHER_mode (cipher_);
2434+ }
2435+
2436+ int Cipher::getIvLength () const {
2437+ if (!cipher_) return 0 ;
2438+ return EVP_CIPHER_iv_length (cipher_);
2439+ }
2440+
2441+ int Cipher::getKeyLength () const {
2442+ if (!cipher_) return 0 ;
2443+ return EVP_CIPHER_key_length (cipher_);
2444+ }
2445+
2446+ int Cipher::getBlockSize () const {
2447+ if (!cipher_) return 0 ;
2448+ return EVP_CIPHER_block_size (cipher_);
2449+ }
2450+
2451+ int Cipher::getNid () const {
2452+ if (!cipher_) return 0 ;
2453+ return EVP_CIPHER_nid (cipher_);
2454+ }
2455+
2456+ const std::string_view Cipher::getModeLabel () const {
2457+ if (!cipher_) return {};
2458+ switch (getMode ()) {
2459+ case EVP_CIPH_CCM_MODE:
2460+ return " ccm" ;
2461+ case EVP_CIPH_CFB_MODE:
2462+ return " cfb" ;
2463+ case EVP_CIPH_CBC_MODE:
2464+ return " cbc" ;
2465+ case EVP_CIPH_CTR_MODE:
2466+ return " ctr" ;
2467+ case EVP_CIPH_ECB_MODE:
2468+ return " ecb" ;
2469+ case EVP_CIPH_GCM_MODE:
2470+ return " gcm" ;
2471+ case EVP_CIPH_OCB_MODE:
2472+ return " ocb" ;
2473+ case EVP_CIPH_OFB_MODE:
2474+ return " ofb" ;
2475+ case EVP_CIPH_WRAP_MODE:
2476+ return " wrap" ;
2477+ case EVP_CIPH_XTS_MODE:
2478+ return " xts" ;
2479+ case EVP_CIPH_STREAM_CIPHER:
2480+ return " stream" ;
2481+ }
2482+ return " {unknown}" ;
2483+ }
2484+
2485+ const std::string_view Cipher::getName () const {
2486+ if (!cipher_) return {};
2487+ // OBJ_nid2sn(EVP_CIPHER_nid(cipher)) is used here instead of
2488+ // EVP_CIPHER_name(cipher) for compatibility with BoringSSL.
2489+ return OBJ_nid2sn (getNid ());
2490+ }
2491+
2492+ bool Cipher::isSupportedAuthenticatedMode () const {
2493+ switch (getMode ()) {
2494+ case EVP_CIPH_CCM_MODE:
2495+ case EVP_CIPH_GCM_MODE:
2496+ #ifndef OPENSSL_NO_OCB
2497+ case EVP_CIPH_OCB_MODE:
2498+ #endif
2499+ return true ;
2500+ case EVP_CIPH_STREAM_CIPHER:
2501+ return getNid () == NID_chacha20_poly1305;
2502+ default :
2503+ return false ;
2504+ }
2505+ }
2506+
24162507} // namespace ncrypto
0 commit comments