1313#include < openssl/ssl.h>
1414#include < openssl/x509.h>
1515#include < cstddef>
16+ #include < functional>
1617#include < list>
1718#include < memory>
1819#include < optional>
@@ -195,7 +196,7 @@ template <typename T, void (*function)(T*)>
195196using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;
196197
197198using BignumCtxPointer = DeleteFnPtr<BN_CTX, BN_CTX_free>;
198- using CipherCtxPointer = DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free >;
199+ using BignumGenCallbackPointer = DeleteFnPtr<BN_GENCB, BN_GENCB_free >;
199200using DSAPointer = DeleteFnPtr<DSA, DSA_free>;
200201using DSASigPointer = DeleteFnPtr<DSA_SIG, DSA_SIG_free>;
201202using ECDSASigPointer = DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free>;
@@ -209,10 +210,10 @@ using HMACCtxPointer = DeleteFnPtr<HMAC_CTX, HMAC_CTX_free>;
209210using NetscapeSPKIPointer = DeleteFnPtr<NETSCAPE_SPKI, NETSCAPE_SPKI_free>;
210211using PKCS8Pointer = DeleteFnPtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;
211212using RSAPointer = DeleteFnPtr<RSA, RSA_free>;
212- using SSLCtxPointer = DeleteFnPtr<SSL_CTX, SSL_CTX_free>;
213- using SSLPointer = DeleteFnPtr<SSL, SSL_free>;
214213using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;
215214
215+ class CipherCtxPointer ;
216+
216217struct StackOfXASN1Deleter {
217218 void operator ()(STACK_OF(ASN1_OBJECT) * p) const {
218219 sk_ASN1_OBJECT_pop_free (p, ASN1_OBJECT_free);
@@ -227,6 +228,40 @@ struct Buffer {
227228 size_t len = 0 ;
228229};
229230
231+ class Cipher final {
232+ public:
233+ Cipher () = default ;
234+ Cipher (const EVP_CIPHER* cipher) : cipher_(cipher) {}
235+ Cipher (const Cipher&) = default ;
236+ Cipher& operator =(const Cipher&) = default ;
237+ inline Cipher& operator =(const EVP_CIPHER* cipher) {
238+ cipher_ = cipher;
239+ return *this ;
240+ }
241+ NCRYPTO_DISALLOW_MOVE (Cipher)
242+
243+ inline const EVP_CIPHER* get () const { return cipher_; }
244+ inline operator const EVP_CIPHER*() const { return cipher_; }
245+ inline operator bool () const { return cipher_ != nullptr ; }
246+
247+ int getNid () const ;
248+ int getMode () const ;
249+ int getIvLength () const ;
250+ int getKeyLength () const ;
251+ int getBlockSize () const ;
252+ std::string_view getModeLabel () const ;
253+ std::string_view getName () const ;
254+
255+ bool isSupportedAuthenticatedMode () const ;
256+
257+ static const Cipher FromName (const char * name);
258+ static const Cipher FromNid (int nid);
259+ static const Cipher FromCtx (const CipherCtxPointer& ctx);
260+
261+ private:
262+ const EVP_CIPHER* cipher_ = nullptr ;
263+ };
264+
230265// A managed pointer to a buffer of data. When destroyed the underlying
231266// buffer will be freed.
232267class DataPointer final {
@@ -272,6 +307,7 @@ class BIOPointer final {
272307 static BIOPointer NewSecMem ();
273308 static BIOPointer New (const BIO_METHOD* method);
274309 static BIOPointer New (const void * data, size_t len);
310+ static BIOPointer New (const BIGNUM* bn);
275311 static BIOPointer NewFile (std::string_view filename, std::string_view mode);
276312 static BIOPointer NewFp (FILE* fd, int flags);
277313
@@ -350,8 +386,28 @@ class BignumPointer final {
350386 size_t encodeInto (unsigned char * out) const ;
351387 size_t encodePaddedInto (unsigned char * out, size_t size) const ;
352388
389+ using PrimeCheckCallback = std::function<bool (int , int )>;
390+ int isPrime (int checks,
391+ PrimeCheckCallback cb = defaultPrimeCheckCallback) const ;
392+ struct PrimeConfig {
393+ int bits;
394+ bool safe = false ;
395+ const BignumPointer& add;
396+ const BignumPointer& rem;
397+ };
398+
399+ static BignumPointer NewPrime (
400+ const PrimeConfig& params,
401+ PrimeCheckCallback cb = defaultPrimeCheckCallback);
402+
403+ bool generate (const PrimeConfig& params,
404+ PrimeCheckCallback cb = defaultPrimeCheckCallback) const ;
405+
353406 static BignumPointer New ();
354407 static BignumPointer NewSecure ();
408+ static BignumPointer NewSub (const BignumPointer& a, const BignumPointer& b);
409+ static BignumPointer NewLShift (size_t length);
410+
355411 static DataPointer Encode (const BIGNUM* bn);
356412 static DataPointer EncodePadded (const BIGNUM* bn, size_t size);
357413 static size_t EncodePaddedInto (const BIGNUM* bn,
@@ -366,6 +422,53 @@ class BignumPointer final {
366422
367423 private:
368424 DeleteFnPtr<BIGNUM, BN_clear_free> bn_;
425+
426+ static bool defaultPrimeCheckCallback (int , int ) { return 1 ; }
427+ };
428+
429+ class CipherCtxPointer final {
430+ public:
431+ static CipherCtxPointer New ();
432+
433+ CipherCtxPointer () = default ;
434+ explicit CipherCtxPointer (EVP_CIPHER_CTX* ctx);
435+ CipherCtxPointer (CipherCtxPointer&& other) noexcept ;
436+ CipherCtxPointer& operator =(CipherCtxPointer&& other) noexcept ;
437+ NCRYPTO_DISALLOW_COPY (CipherCtxPointer)
438+ ~CipherCtxPointer ();
439+
440+ inline bool operator ==(std::nullptr_t ) const noexcept {
441+ return ctx_ == nullptr ;
442+ }
443+ inline operator bool () const { return ctx_ != nullptr ; }
444+ inline EVP_CIPHER_CTX* get () const { return ctx_.get (); }
445+ inline operator EVP_CIPHER_CTX*() const { return ctx_.get (); }
446+ void reset (EVP_CIPHER_CTX* ctx = nullptr );
447+ EVP_CIPHER_CTX* release ();
448+
449+ void setFlags (int flags);
450+ bool setKeyLength (size_t length);
451+ bool setIvLength (size_t length);
452+ bool setAeadTag (const Buffer<const char >& tag);
453+ bool setAeadTagLength (size_t length);
454+ bool setPadding (bool padding);
455+ bool init (const Cipher& cipher,
456+ bool encrypt,
457+ const unsigned char * key = nullptr ,
458+ const unsigned char * iv = nullptr );
459+
460+ int getBlockSize () const ;
461+ int getMode () const ;
462+ int getNid () const ;
463+
464+ bool update (const Buffer<const unsigned char >& in,
465+ unsigned char * out,
466+ int * out_len,
467+ bool finalize = false );
468+ bool getAeadTag (size_t len, unsigned char * out);
469+
470+ private:
471+ DeleteFnPtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_free> ctx_;
369472};
370473
371474class EVPKeyPointer final {
@@ -551,7 +654,85 @@ class DHPointer final {
551654 DeleteFnPtr<DH, DH_free> dh_;
552655};
553656
657+ struct StackOfX509Deleter {
658+ void operator ()(STACK_OF(X509) * p) const { sk_X509_pop_free (p, X509_free); }
659+ };
660+ using StackOfX509 = std::unique_ptr<STACK_OF(X509), StackOfX509Deleter>;
661+
554662class X509Pointer ;
663+ class X509View ;
664+
665+ class SSLCtxPointer final {
666+ public:
667+ SSLCtxPointer () = default ;
668+ explicit SSLCtxPointer (SSL_CTX* ctx);
669+ SSLCtxPointer (SSLCtxPointer&& other) noexcept ;
670+ SSLCtxPointer& operator =(SSLCtxPointer&& other) noexcept ;
671+ NCRYPTO_DISALLOW_COPY (SSLCtxPointer)
672+ ~SSLCtxPointer ();
673+
674+ inline bool operator ==(std::nullptr_t ) const noexcept {
675+ return ctx_ == nullptr ;
676+ }
677+ inline operator bool () const { return ctx_ != nullptr ; }
678+ inline SSL_CTX* get () const { return ctx_.get (); }
679+ void reset (SSL_CTX* ctx = nullptr );
680+ void reset (const SSL_METHOD* method);
681+ SSL_CTX* release ();
682+
683+ bool setGroups (const char * groups);
684+ void setStatusCallback (auto callback) {
685+ if (!ctx_) return ;
686+ SSL_CTX_set_tlsext_status_cb (get (), callback);
687+ SSL_CTX_set_tlsext_status_arg (get (), nullptr );
688+ }
689+
690+ static SSLCtxPointer NewServer ();
691+ static SSLCtxPointer NewClient ();
692+ static SSLCtxPointer New (const SSL_METHOD* method = TLS_method());
693+
694+ private:
695+ DeleteFnPtr<SSL_CTX, SSL_CTX_free> ctx_;
696+ };
697+
698+ class SSLPointer final {
699+ public:
700+ SSLPointer () = default ;
701+ explicit SSLPointer (SSL* ssl);
702+ SSLPointer (SSLPointer&& other) noexcept ;
703+ SSLPointer& operator =(SSLPointer&& other) noexcept ;
704+ NCRYPTO_DISALLOW_COPY (SSLPointer)
705+ ~SSLPointer ();
706+
707+ inline bool operator ==(std::nullptr_t ) noexcept { return ssl_ == nullptr ; }
708+ inline operator bool () const { return ssl_ != nullptr ; }
709+ inline SSL* get () const { return ssl_.get (); }
710+ inline operator SSL*() const { return ssl_.get (); }
711+ void reset (SSL* ssl = nullptr );
712+ SSL* release ();
713+
714+ bool setSession (const SSLSessionPointer& session);
715+ bool setSniContext (const SSLCtxPointer& ctx) const ;
716+
717+ const std::string_view getClientHelloAlpn () const ;
718+ const std::string_view getClientHelloServerName () const ;
719+
720+ std::optional<const std::string_view> getServerName () const ;
721+ X509View getCertificate () const ;
722+ EVPKeyPointer getPeerTempKey () const ;
723+ const SSL_CIPHER* getCipher () const ;
724+ bool isServer () const ;
725+
726+ std::optional<uint32_t > verifyPeerCertificate () const ;
727+
728+ void getCiphers (std::function<void (const std::string_view)> cb) const ;
729+
730+ static SSLPointer New (const SSLCtxPointer& ctx);
731+ static std::optional<const std::string_view> GetServerName (const SSL* ssl);
732+
733+ private:
734+ DeleteFnPtr<SSL, SSL_free> ssl_;
735+ };
555736
556737class X509View final {
557738 public:
@@ -565,6 +746,8 @@ class X509View final {
565746 NCRYPTO_DISALLOW_MOVE (X509View)
566747
567748 inline X509* get () const { return const_cast <X509*>(cert_); }
749+ inline operator X509*() const { return const_cast <X509*>(cert_); }
750+ inline operator const X509*() const { return cert_; }
568751
569752 inline bool operator ==(std::nullptr_t ) noexcept { return cert_ == nullptr ; }
570753 inline operator bool () const { return cert_ != nullptr ; }
@@ -589,6 +772,8 @@ class X509View final {
589772 bool checkPrivateKey (const EVPKeyPointer& pkey) const ;
590773 bool checkPublicKey (const EVPKeyPointer& pkey) const ;
591774
775+ std::optional<std::string> getFingerprint (const EVP_MD* method) const ;
776+
592777 X509Pointer clone () const ;
593778
594779 enum class CheckMatch {
@@ -624,12 +809,17 @@ class X509Pointer final {
624809 inline bool operator ==(std::nullptr_t ) noexcept { return cert_ == nullptr ; }
625810 inline operator bool () const { return cert_ != nullptr ; }
626811 inline X509* get () const { return cert_.get (); }
812+ inline operator X509*() const { return cert_.get (); }
813+ inline operator const X509*() const { return cert_.get (); }
627814 void reset (X509* cert = nullptr );
628815 X509* release ();
629816
630817 X509View view () const ;
631818 operator X509View () const { return view (); }
632819
820+ static std::string_view ErrorCode (int32_t err);
821+ static std::optional<std::string_view> ErrorReason (int32_t err);
822+
633823 private:
634824 DeleteFnPtr<X509, X509_free> cert_;
635825};
0 commit comments