13
13
#include < openssl/ssl.h>
14
14
#include < openssl/x509.h>
15
15
#include < cstddef>
16
+ #include < functional>
16
17
#include < list>
17
18
#include < memory>
18
19
#include < optional>
@@ -195,7 +196,7 @@ template <typename T, void (*function)(T*)>
195
196
using DeleteFnPtr = typename FunctionDeleter<T, function>::Pointer;
196
197
197
198
using 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 >;
199
200
using DSAPointer = DeleteFnPtr<DSA, DSA_free>;
200
201
using DSASigPointer = DeleteFnPtr<DSA_SIG, DSA_SIG_free>;
201
202
using ECDSASigPointer = DeleteFnPtr<ECDSA_SIG, ECDSA_SIG_free>;
@@ -209,10 +210,10 @@ using HMACCtxPointer = DeleteFnPtr<HMAC_CTX, HMAC_CTX_free>;
209
210
using NetscapeSPKIPointer = DeleteFnPtr<NETSCAPE_SPKI, NETSCAPE_SPKI_free>;
210
211
using PKCS8Pointer = DeleteFnPtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>;
211
212
using RSAPointer = DeleteFnPtr<RSA, RSA_free>;
212
- using SSLCtxPointer = DeleteFnPtr<SSL_CTX, SSL_CTX_free>;
213
- using SSLPointer = DeleteFnPtr<SSL, SSL_free>;
214
213
using SSLSessionPointer = DeleteFnPtr<SSL_SESSION, SSL_SESSION_free>;
215
214
215
+ class CipherCtxPointer ;
216
+
216
217
struct StackOfXASN1Deleter {
217
218
void operator ()(STACK_OF(ASN1_OBJECT) * p) const {
218
219
sk_ASN1_OBJECT_pop_free (p, ASN1_OBJECT_free);
@@ -227,6 +228,40 @@ struct Buffer {
227
228
size_t len = 0 ;
228
229
};
229
230
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
+
230
265
// A managed pointer to a buffer of data. When destroyed the underlying
231
266
// buffer will be freed.
232
267
class DataPointer final {
@@ -272,6 +307,7 @@ class BIOPointer final {
272
307
static BIOPointer NewSecMem ();
273
308
static BIOPointer New (const BIO_METHOD* method);
274
309
static BIOPointer New (const void * data, size_t len);
310
+ static BIOPointer New (const BIGNUM* bn);
275
311
static BIOPointer NewFile (std::string_view filename, std::string_view mode);
276
312
static BIOPointer NewFp (FILE* fd, int flags);
277
313
@@ -350,8 +386,28 @@ class BignumPointer final {
350
386
size_t encodeInto (unsigned char * out) const ;
351
387
size_t encodePaddedInto (unsigned char * out, size_t size) const ;
352
388
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
+
353
406
static BignumPointer New ();
354
407
static BignumPointer NewSecure ();
408
+ static BignumPointer NewSub (const BignumPointer& a, const BignumPointer& b);
409
+ static BignumPointer NewLShift (size_t length);
410
+
355
411
static DataPointer Encode (const BIGNUM* bn);
356
412
static DataPointer EncodePadded (const BIGNUM* bn, size_t size);
357
413
static size_t EncodePaddedInto (const BIGNUM* bn,
@@ -366,6 +422,53 @@ class BignumPointer final {
366
422
367
423
private:
368
424
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_;
369
472
};
370
473
371
474
class EVPKeyPointer final {
@@ -551,7 +654,85 @@ class DHPointer final {
551
654
DeleteFnPtr<DH, DH_free> dh_;
552
655
};
553
656
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
+
554
662
class 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
+ };
555
736
556
737
class X509View final {
557
738
public:
@@ -565,6 +746,8 @@ class X509View final {
565
746
NCRYPTO_DISALLOW_MOVE (X509View)
566
747
567
748
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_; }
568
751
569
752
inline bool operator ==(std::nullptr_t ) noexcept { return cert_ == nullptr ; }
570
753
inline operator bool () const { return cert_ != nullptr ; }
@@ -589,6 +772,8 @@ class X509View final {
589
772
bool checkPrivateKey (const EVPKeyPointer& pkey) const ;
590
773
bool checkPublicKey (const EVPKeyPointer& pkey) const ;
591
774
775
+ std::optional<std::string> getFingerprint (const EVP_MD* method) const ;
776
+
592
777
X509Pointer clone () const ;
593
778
594
779
enum class CheckMatch {
@@ -624,12 +809,17 @@ class X509Pointer final {
624
809
inline bool operator ==(std::nullptr_t ) noexcept { return cert_ == nullptr ; }
625
810
inline operator bool () const { return cert_ != nullptr ; }
626
811
inline X509* get () const { return cert_.get (); }
812
+ inline operator X509*() const { return cert_.get (); }
813
+ inline operator const X509*() const { return cert_.get (); }
627
814
void reset (X509* cert = nullptr );
628
815
X509* release ();
629
816
630
817
X509View view () const ;
631
818
operator X509View () const { return view (); }
632
819
820
+ static std::string_view ErrorCode (int32_t err);
821
+ static std::optional<std::string_view> ErrorReason (int32_t err);
822
+
633
823
private:
634
824
DeleteFnPtr<X509, X509_free> cert_;
635
825
};
0 commit comments