1 #include <Core/Core.h>
2 
3 #include <openssl/ssl.h>
4 #include <openssl/conf.h>
5 #include <openssl/err.h>
6 #include <openssl/engine.h>
7 
8 namespace Upp {
9 
10 INITIALIZE(SSL);
11 INITIALIZE(SSLSocket);
12 INITIALIZE(P7S);
13 
14 void SslInitThread();
15 
16 class SslBuffer
17 {
18 public:
buf_mem(m)19 	SslBuffer(BUF_MEM *m = NULL) : buf_mem(m) {}
~SslBuffer()20 	~SslBuffer()                              { Clear(); }
21 
IsEmpty()22 	bool     IsEmpty() const                  { return !buf_mem; }
23 
Set(BUF_MEM * b)24 	bool     Set(BUF_MEM *b)                  { Clear(); return !!(buf_mem = b); }
Create()25 	bool     Create()                         { return Set(BUF_MEM_new()); }
Clear()26 	void     Clear()                          { if(buf_mem) { BUF_MEM_free(buf_mem); buf_mem = NULL; } }
Detach()27 	BUF_MEM *Detach()                         { BUF_MEM *b = buf_mem; buf_mem = NULL; return b; }
28 
29 	bool     Grow(int length);
30 
31 	String   Get() const;
32 	bool     Set(const String& d);
33 
34 	operator BUF_MEM * () const { return buf_mem; }
35 
36 private:
37 	BUF_MEM *buf_mem;
38 };
39 
40 class SslStream
41 {
42 public:
bio(b)43 	SslStream(BIO *b = NULL) : bio(b)        {}
~SslStream()44 	~SslStream()                             { Clear(); }
45 
IsEmpty()46 	bool     IsEmpty() const                 { return !bio; }
47 
Set(BIO * b)48 	bool     Set(BIO *b)                     { Clear(); return !!(bio = b); }
49 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
Create(const BIO_METHOD * meth)50 	bool     Create(const BIO_METHOD *meth)  { return Set(BIO_new(meth)); }
51 #else
Create(BIO_METHOD * meth)52 	bool     Create(BIO_METHOD *meth)        { return Set(BIO_new(meth)); }
53 #endif
Clear()54 	void     Clear()                         { if(bio) { BIO_free(bio); bio = NULL; } }
55 
56 	bool     OpenBuffer(const char *data, int length);
57 	bool     CreateBuffer();
58 	String   GetResult() const;
59 
60 	operator BIO * () const                  { return bio; }
61 
62 private:
63 	BIO     *bio;
64 };
65 
66 class SslKey
67 {
68 public:
key(k)69 	SslKey(EVP_PKEY *k = NULL) : key(k) {}
~SslKey()70 	~SslKey()                           { Clear(); }
71 
IsEmpty()72 	bool      IsEmpty() const            { return !key; }
73 
Set(EVP_PKEY * k)74 	bool      Set(EVP_PKEY *k)           { Clear(); return !!(key = k); }
Clear()75 	void      Clear()                    { if(key) { EVP_PKEY_free(key); key = NULL; } }
Detach()76 	EVP_PKEY *Detach()                   { EVP_PKEY *k = key; key = NULL; return k; }
77 
78 	operator  EVP_PKEY * () const        { return key; }
79 
80 	bool      Load(const String& data);
81 
82 private:
83 	EVP_PKEY *key;
84 };
85 
86 class SslCertificate
87 {
88 public:
cert(c)89 	SslCertificate(X509 *c = NULL) : cert(c) {}
~SslCertificate()90 	~SslCertificate()                        { Clear(); }
91 
IsEmpty()92 	bool     IsEmpty() const                 { return !cert; }
93 
Set(X509 * c)94 	bool     Set(X509 *c)                    { Clear(); return !!(cert = c); }
Create()95 	bool     Create()                        { return Set(X509_new()); }
Clear()96 	void     Clear()                         { if(cert) { X509_free(cert); cert = NULL; } }
Detach()97 	X509    *Detach()                        { X509 *c = cert; cert = NULL; return c; }
98 
99 	bool     Load(const String& data, bool asn1 = false);
100 	String   Save(bool asn1 = false) const;
101 
102 	String   GetSubjectName() const;
103 	String   GetIssuerName() const;
104 	Date     GetNotBefore() const;
105 	Date     GetNotAfter() const;
106 	int      GetVersion() const;
107 	String   GetSerialNumber() const;
108 
109 	operator X509 * () const                 { return cert; }
110 
111 private:
112 	X509    *cert;
113 };
114 
115 class SslContext
116 {
117 public:
118 	SslContext(SSL_CTX *c = NULL);
~SslContext()119 	~SslContext()                              { Clear(); }
120 
IsEmpty()121 	bool     IsEmpty() const                   { return !ssl_ctx; }
122 
Set(SSL_CTX * c)123 	bool     Set(SSL_CTX *c)                   { Clear(); return !!(ssl_ctx = c); }
Create(SSL_METHOD * meth)124 	bool     Create(SSL_METHOD *meth)          { return Set(SSL_CTX_new(meth)); }
Clear()125 	void     Clear()                           { if(ssl_ctx) { SSL_CTX_free(ssl_ctx); ssl_ctx = NULL; } }
Detach()126 	SSL_CTX *Detach()                          { SSL_CTX *c = ssl_ctx; ssl_ctx = NULL; return c; }
127 
128 	operator SSL_CTX * () const                { return ssl_ctx; }
129 
130 	bool     CipherList(const char *list);
131 	bool     UseCertificate(String certificate, String private_key, bool cert_asn1 = false);
132 	void     VerifyPeer(bool verify = true, int depth = 2);
133 
134 private:
135 	SSL_CTX *ssl_ctx;
136 };
137 
138 String SslGetLastError(int& code);
139 String SslGetLastError();
140 String SslToString(X509_NAME *name);
141 Date   Asn1ToDate(ASN1_STRING *time);
142 String Asn1ToString(ASN1_STRING *s);
143 
144 }
145