DCL 3.7.4
Loading...
Searching...
No Matches
SSLSocket.cpp
Go to the documentation of this file.
1/*
2 * REFERENCES
3 *
4 * OPENSSL
5 * http://www.rtfm.com/sslbook/
6 * http://www.openssl.org/
7 *
8 * SCHANNEL
9 * Windows SDKs
10 * MSDN/Win32 and COM/Security/Authentication/
11 * Using Authentication/Using SSPI/
12 * Creating a Secure Connection Using Schannel
13 *
14 * Windows SDKs 2003
15 * Samples/
16 */
17
18#include <dcl/Config.h>
19
20#ifdef __WINNT__
21 #include <winsock2.h>
22#else
23 #include <sys/socket.h>
24#endif
25
26#if __DCL_OPENSSL
27 #include <openssl/ssl.h>
28 #include <openssl/err.h>
29 #include <dcl/Thread.h>
30#elif __DCL_SCHANNEL
31 #define SEC_FAILED(ss) (ss < 0)
32#endif
33
34#include <dcl/Object.h>
35#include <dcl/Charset.h>
36#include <dcl/Numeric.h>
37#include <dcl/SSLSocket.h>
38
39__DCL_BEGIN_NAMESPACE
40
41#if __DCL_HAVE_THIS_FILE__
42#undef __THIS_FILE__
43static const char_t __THIS_FILE__[] = __T("dcl/SSLSocket.cpp");
44#endif
45
47
48SSLException::SSLException(Exception* _cause)
49 : Exception(_cause)
50{
51}
52
53#if __DCL_OPENSSL
54SSLException::SSLException()
56{
57 unsigned long e = ERR_get_error();
58 char buf[256];
59 ERR_error_string_n(e, buf, sizeof(buf));
60
61 LocaleDecoder decoder;
62 __message = decoder.decode(buf);
63}
64
65#elif __DCL_SCHANNEL
66static HMODULE __hSecure32_dll__ = NULL;
67
68static String __GetStatusMessage(SECURITY_STATUS _ss)
69{
70 if (__hSecure32_dll__ == NULL)
71 __hSecure32_dll__ = LoadLibraryW(__T("secure32.dll"));
72
73 StringBuilder sb;
74 wchar_t* msg = NULL;
75 DWORD dwLength = FormatMessageW(
76 FORMAT_MESSAGE_ALLOCATE_BUFFER |
77 FORMAT_MESSAGE_FROM_SYSTEM |
78 FORMAT_MESSAGE_IGNORE_INSERTS,
79 __hSecure32_dll__,
80 _ss,
81 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
82 (LPWSTR) &msg,
83 0,
84 NULL
85 );
86
87 if (dwLength > 0) {
88 for ( ; dwLength; dwLength--)
89 if (!(msg[dwLength - 1] == L'\r' || msg[dwLength - 1] == L'\n'))
90 break;
91
92 sb.assign(msg, dwLength);
93 LocalFree(msg);
94
95 sb += L" (ERROR=";
96 sb += UInteger::toString(_ss, 10);
97 sb += L")";
98 }
99 else
100 sb = L"::FormatMessage Fail!";
101
102 return sb;
103}
104
105SSLException::SSLException(SECURITY_STATUS _ss)
106{
107 __message = __GetStatusMessage(_ss);
108}
109#endif
110
111String SSLException::toString() const
112{
113 return __message;
114}
115
117
118size_t SSLSocket::available() const
120{
121#if __DCL_OPENSSL
122 __DCL_ASSERT_HANDLE(__ctx != NULL);
123 __DCL_ASSERT_HANDLE(__ssl != NULL);
124 __DCL_TRACE2(__T("%d, %d\n"), (int) Socket::available(), SSL_pending(__ssl));
125 return (size_t) SSL_pending(__ssl);
126#else
127 return Socket::available();
128#endif
129}
130
131#if 0
132size_t SSLSocket::read(void* _buf, size_t _n)
134
135size_t SSLSocket::write(const void* _buf, size_t _n)
137
138void SSLSocket::bind(
139 const Addr& _my_addr,
140 int _type, int _protocol, bool _reuse
142
143void SSLSocket::accept(SSLSocket& _r)
145
146void SSLSocket::connect(const Addr& _serv_addr)
148#endif
149
150#if __DCL_OPENSSL
151static thread_once_t __opensslOnceControl = THREAD_ONCE_INIT;
152
153static void __opensslLibraryInit()
154{
155 SSL_library_init();
156 SSL_load_error_strings();
157}
158#endif
159
160#if 0
161int SSLSocket::pem_passwd_cb(char* _buf, int _size, int _rwflag, void* _userdata)
162{
163 SSLSocket* obj = (SSLSocket*) _userdata;
164 return obj->onPermPasswordCallback(_buf, _size, _rwflag);
165}
166
167int SSLSocket::onPermPasswordCallback(char* _buf, int _size, int _rwflag)
168{
169 int n = (int) __defaultPassword.length() > (_size - 1) ?
170 (_size - 1) : (int) __defaultPassword.length();
171 strncpy(_buf, __defaultPassword.data(), n);
172 _buf[n] = '\0';
173 return n;
174}
175
176bool SSLSocket::__opensslContextInit(const char* _keyfile)
177{
178 Thread::once(__opensslOnceControl, __opensslLibraryInit);
179
180 SSL_CTX* ctx = SSL_CTX_new(SSLv23_method());
181 if (!(SSL_CTX_use_certificate_chain_file(ctx, "client.pem"))) {
182 __DCL_TRACE0(__T("Can't read certificate file\n"));
183 goto __failed;
184 }
185 SSL_CTX_set_default_passwd_cb(ctx, SSLSocket::pem_passwd_cb);
186 SSL_CTX_set_default_passwd_cb_userdata(ctx, this);
187
188 if (!(SSL_CTX_use_PrivateKey_file(ctx, "client.pem", SSL_FILETYPE_PEM))) {
189 __DCL_TRACE0(__T("Can't read key file\n"));
190 goto __failed;
191 }
192
193#define CA_LIST "root.pem"
194
195 if( !(SSL_CTX_load_verify_locations(ctx, CA_LIST, 0))) {
196 __DCL_TRACE0(__T("Can't read CA list\n"));
197 goto __failed;
198 }
199
200#if (OPENSSL_VERSION_NUMBER < 0x00905100L)
201 SSL_CTX_set_verify_depth(ctx,1);
202#endif
203
204 __ctx = ctx;
205 return true;
206
207__failed:
208 if (ctx)
209 SSL_CTX_free(ctx);
210 return false;
211}
212
213#endif
214
217{
218#if __DCL_OPENSSL
219 Thread::once(__opensslOnceControl, __opensslLibraryInit);
220 __ctx = NULL;
221 __ssl = NULL;
222 SSL_CTX* ctx = SSL_CTX_new(SSLv23_method());
223 if (ctx == NULL)
224 throw new SSLException();
225 __ctx = ctx;
226
227#elif __DCL_SCHANNEL
228 SecInvalidateHandle(&__cred);
229 SecInvalidateHandle(&__ctxt);
230
231 CredHandle cred;
232 SCHANNEL_CRED credData;
233 TimeStamp tsExpiry;
234
235 ZeroMemory(&credData, sizeof(credData));
236 credData.dwVersion = SCHANNEL_CRED_VERSION;
237 // Specify the TLS V1.0 (client-side) security protocol.
238 // credData.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
239
240 credData.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
241 credData.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION;
242
243 SECURITY_STATUS ss = AcquireCredentialsHandleW(
244 NULL, // __in SEC_CHAR* pszPrincipal, default principal
245 (LPWSTR) UNISP_NAME_W, // __in SEC_CHAR* pszPackage, for Schannel
246 SECPKG_CRED_OUTBOUND, // __in ULONG fCredentialUse,
247 NULL, // __in PLUID pvLogonID, use the current LOGON id
248 &credData, // __in PVOID pAuthData, protocol-specific data
249 NULL, // __in SEC_GET_KEY_FN pGetKeyFn, default
250 NULL, // __in PVOID pvGetKeyArgument, default
251 &cred, // __out PCredHandle phCredential,
252 &tsExpiry // __out PTimeStamp ptsExpiry
253 );
254 if (ss != SEC_E_OK)
255 throw new SSLException(ss);
256
257 __cred = cred;
258#endif
259}
260
266
267SSLSocket::SSLSocket(const String& _addr, uint16_t _port)
269{
270 construct();
271 Socket::open(_addr, _port);
272}
273
275{
276#if __DCL_OPENSSL
277 if (__ssl)
278#elif __DCL_SCHANNEL
279 if (SecIsValidHandle(&__ctxt))
280#endif
281 {
282 try {
283 close();
284 }
285 catch (Exception* cause) {
286 __DCL_TRACE1(__T("Error! SSLSocket::~SSLSocket %ls\n"), cause->toString().data());
287 cause->destroy();
288 }
289 }
290
291#if __DCL_OPENSSL
292 if (__ctx) {
293 SSL_CTX_free(__ctx);
294 #ifdef __DCL_DEBUG
295 __ctx = NULL;
296 #endif
297 }
298
299#elif __DCL_SCHANNEL
300 if (SecIsValidHandle(&__cred)) {
301 SECURITY_STATUS __UNUSED__ ss = FreeCredentialsHandle(&__cred);
302 #ifdef __DCL_DEBUG
303 if (ss != SEC_E_OK)
304 __DCL_TRACE1(__T("Warning!! [%ls]\n"), __GetStatusMessage(ss).data());
305 SecInvalidateHandle(&__cred);
306 #endif
307 }
308
309#endif
310}
311
314{
315#if __DCL_OPENSSL
316 __DCL_ASSERT_HANDLE(__ssl != NULL);
317 SSL_free(__ssl);
318 __ssl = NULL;
319
320#elif __DCL_SCHANNEL
321 __DCL_ASSERT_HANDLE(SecIsValidHandle(&__ctxt));
322 SECURITY_STATUS __UNUSED__ ss = DeleteSecurityContext(&__ctxt);
323 #ifdef __DCL_DEBUG
324 if (ss != SEC_E_OK)
325 __DCL_TRACE1(__T("Warning!! [%ls]\n"), __GetStatusMessage(ss).data());
326 #endif
327 SecInvalidateHandle(&__ctxt);
328
329#endif
330
332}
333
334#if 0
335void SSLSocket::bind(const struct sockaddr* _my_addr, socklen_t _addrlen)
337
338void SSLSocket::listen(unsigned _backlog)
340
341void SSLSocket::accept(SSLSocket& r, struct sockaddr* _addr, socklen_t* _addrlen)
343
344#endif
345
346void SSLSocket::connect(const sockaddr* _serv_addr, socklen_t _addrlen)
348{
349 Socket::connect(_serv_addr, _addrlen);
350
351 __DCL_TRACE0(__T("SSLSocket::connect()\n"));
352
353#if __DCL_OPENSSL
354 __DCL_ASSERT_HANDLE(__ctx != NULL);
355 __DCL_ASSERT_HANDLE(__ssl == NULL);
356 __ssl = SSL_new(__ctx);
357 BIO* bio = BIO_new_socket(__handle, BIO_NOCLOSE);
358
359 SSL_set_bio(__ssl, bio, bio);
360
361 if (SSL_connect(__ssl) < 0)
362 throw new IOException(toString(), new SSLException());
363
364#elif __DCL_SCHANNEL
365 DWORD fContextReq = ISC_REQ_SEQUENCE_DETECT
366 | ISC_REQ_REPLAY_DETECT
367 | ISC_REQ_CONFIDENTIALITY
368 | ISC_RET_EXTENDED_ERROR
369 | ISC_REQ_ALLOCATE_MEMORY
370 | ISC_REQ_STREAM;
371
372 SecBufferDesc outBufferDesc;
373 SecBuffer outBuffers[1];
374
375 outBuffers[0].BufferType = SECBUFFER_TOKEN;
376 outBuffers[0].cbBuffer = 0;
377 outBuffers[0].pvBuffer = NULL;
378 outBufferDesc.ulVersion = SECBUFFER_VERSION;
379 outBufferDesc.cBuffers = 1;
380 outBufferDesc.pBuffers = outBuffers;
381
382 CtxtHandle ctxt;
383 ULONG ctxtAttr;
384 TimeStamp tsExpiry;
385
386 SECURITY_STATUS ss = InitializeSecurityContextW(
387 &__cred, // __in PCredHandle phCredential,
388 NULL, // __in_out PCtxtHandle phContext,
389 NULL, // __in SEC_CHAR* pszTargetName,
390 fContextReq, // __in ULONG fContextReq,
391 0, // ULONG Reserved1,
392 0, // __in ULONG TargetDataRep,
393 NULL, // __in_out PSecBufferDesc pInput,
394 0, // ULONG Reserved2,
395 &ctxt, // __in_out PCtxtHandle phNewContext,
396 &outBufferDesc, // __out PSecBufferDesc pOutput,
397 &ctxtAttr, // __out PULONG pfContextAttr,
398 &tsExpiry // __out PTimeStamp ptsExpiry
399 );
400
401 if (FAILED(ss))
402 throw new IOException(toString(), new SSLException(ss));
403
404 __DCL_TRACE1(__T("%ls\n"), __GetStatusMessage(ss).data());
405
406 if (outBuffers[0].cbBuffer != 0 && outBuffers[0].pvBuffer != NULL) {
407 __DCL_TRACE3(__T("%d, %d, [%ls]\n"),
408 outBuffers[0].BufferType,
409 outBuffers[0].cbBuffer,
410 String::tryString((const char*) outBuffers[0].pvBuffer,
411 outBuffers[0].cbBuffer, 8).data()
412 );
413 int n = ::send((UINT_PTR) __handle,
414 (const char*) outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0);
415 if (n == SOCKET_ERROR || n == 0) {
416 FreeContextBuffer(outBuffers[0].pvBuffer);
417 DeleteSecurityContext(&ctxt);
418 throw new IOException(toString(), WSAGetLastError());
419 }
420
421 __DCL_TRACE1(__T("[%d] bytes of Handshake data sent\n"), n);
422 FreeContextBuffer(outBuffers[0].pvBuffer);
423 outBuffers[0].pvBuffer = NULL;
424 }
425
426 // Handshake
427 SecBufferDesc inBufferDesc;
428 SecBuffer inBuffers[2];
429
430 __UNUSED__ DWORD WSAError = 0;
431#define READ_BUFFER_SIZE 0x10000
432 char* readBuffer = (char*) malloc(READ_BUFFER_SIZE);
433 bool fDoRead = true;
434 unsigned int nRead = 0;
435
436 while (ss == SEC_I_CONTINUE_NEEDED
437 || ss == SEC_E_INCOMPLETE_MESSAGE
438 || ss == SEC_I_INCOMPLETE_CREDENTIALS
439 ) {
440 if (0 == nRead || ss == SEC_E_INCOMPLETE_MESSAGE) {
441 if (fDoRead) {
442 int n = ::recv(
443 (UINT_PTR) __handle,
444 readBuffer + nRead,
445 READ_BUFFER_SIZE - nRead,
446 0
447 );
448 if (n == SOCKET_ERROR) {
449 WSAError = WSAGetLastError();
450 ss = SEC_E_INTERNAL_ERROR;
451 break;
452 }
453 else if (n == 0) {
454 WSAError = WSAECONNRESET;
455 ss = SEC_E_INTERNAL_ERROR;
456 break;
457 }
458 __DCL_TRACE2(__T("Handshake read [%d] [%ls]\n"), n,
459 String::tryString((const char*) readBuffer + nRead, n, 8).data());
460
461 nRead += n;
462 }
463 else
464 fDoRead = true;
465 }
466
467 inBuffers[0].BufferType = SECBUFFER_TOKEN;
468 inBuffers[0].cbBuffer = nRead;
469 inBuffers[0].pvBuffer = readBuffer;
470
471 inBuffers[1].BufferType = SECBUFFER_EMPTY;
472 inBuffers[1].cbBuffer = 0;
473 inBuffers[1].pvBuffer = NULL;
474
475 inBufferDesc.ulVersion = SECBUFFER_VERSION;
476 inBufferDesc.cBuffers = 2;
477 inBufferDesc.pBuffers = inBuffers;
478
479 outBuffers[0].BufferType = SECBUFFER_TOKEN;
480 outBuffers[0].cbBuffer = 0;
481 outBuffers[0].pvBuffer = NULL;
482
483 outBufferDesc.ulVersion = SECBUFFER_VERSION;
484 outBufferDesc.cBuffers = 1;
485 outBufferDesc.pBuffers = outBuffers;
486
487 ss = InitializeSecurityContextW(
488 &__cred,
489 &ctxt,
490 NULL,
491 fContextReq,
492 0,
493 SECURITY_NATIVE_DREP,
494 &inBufferDesc,
495 0,
496 NULL,
497 &outBufferDesc,
498 &ctxtAttr,
499 &tsExpiry
500 );
501
502 if (ss == SEC_E_OK
503 || ss == SEC_I_CONTINUE_NEEDED
504 || (FAILED(ss) && (ctxtAttr & ISC_RET_EXTENDED_ERROR))
505 ) {
506 if (outBuffers[0].cbBuffer != 0 && outBuffers[0].pvBuffer != NULL) {
507 int n = ::send(
508 (UINT_PTR) __handle,
509 (const char*) outBuffers[0].pvBuffer,
510 outBuffers[0].cbBuffer,
511 0
512 );
513 if (n == SOCKET_ERROR || n == 0) {
514 WSAError = WSAGetLastError();
515 FreeContextBuffer(outBuffers[0].pvBuffer);
516 DeleteSecurityContext(&ctxt);
517 ss = SEC_E_INTERNAL_ERROR;
518 break;
519 }
520
521 __DCL_TRACE1(__T("[%d] bytes of Handshake data sent\n"), n);
522 FreeContextBuffer(outBuffers[0].pvBuffer);
523 outBuffers[0].pvBuffer = NULL;
524 }
525 }
526
527 if (ss == SEC_E_INCOMPLETE_MESSAGE) {
528 __DCL_TRACE0(__T("====================== SEC_E_INCOMPLETE_MESSAGE =====================\n"));
529 continue;
530 }
531
532 __DCL_TRACE1(__T("Before OK[%u]\n"), ss);
533 if (ss == SEC_E_OK) {
534 __DCL_TRACE0(__T("Handshake was successful\n"));
535 if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
536 __DCL_TRACE1(__T("Extad data [%d] bytes\n"), inBuffers[1].cbBuffer);
537 }
538 break;
539 }
540
541 __DCL_TRACE2(__T("[%u][%ls]\n"), ss, __GetStatusMessage(ss).data());
542 if(ss == SEC_I_INCOMPLETE_CREDENTIALS) {
543 __DCL_TRACE0(__T("SEC_I_INCOMPLETE_CREDENTIALS\n"));
544
545 // FIXME!! 2026-02-05 작업을 하다 중단된 것 같다!!!
546 // Get New client Credentials
547 break;
548
549 fDoRead = false;
550 ss = SEC_I_CONTINUE_NEEDED;
551 continue;
552 }
553
554 if (inBuffers[1].BufferType == SECBUFFER_EXTRA) {
555 __DCL_TRACE1(__T("Extad data [%d] bytes\n"), inBuffers[1].cbBuffer);
556 memcpy(readBuffer,
557 readBuffer + (nRead - inBuffers[1].cbBuffer),
558 inBuffers[1].cbBuffer
559 );
560 nRead = inBuffers[1].cbBuffer;
561 }
562 else
563 nRead = 0;
564 }
565
566 free(readBuffer);
567 if (FAILED(ss)) {
568 DeleteSecurityContext(&ctxt);
569 }
570 else
571 __ctxt = ctxt;
572
573#endif
574}
575
576size_t SSLSocket::send(const void* _buf, size_t _n, int _flags)
578{
579#if __DCL_OPENSSL
580 __DCL_ASSERT_HANDLE(__ctx != NULL);
581 __DCL_ASSERT_HANDLE(__ssl != NULL);
582
583 __DCL_TRACE2(__T("SSLSocket::send(%p, %zd)\n"), _buf, _n);
584
585 int n = (int) _n;
586 int r = SSL_write(__ssl, _buf, (int) _n);
587
588 __DCL_TRACE1(__T("SSLSocket::SSL_write(%d)\n"),r);
589
590 if (r > 0)
591 return (size_t) r;
592
593 switch(SSL_get_error(__ssl, r)) {
594 case SSL_ERROR_NONE:
595 if(n != r)
596 __DCL_TRACE0(__T("Incomplete write!\n"));
597 break;
598 default:
599 throw new IOException(toString(), new SSLException());
600 }
601#endif
602
603 return 0;
604}
605
606size_t SSLSocket::recv(void* _buf, size_t _n, int _flags)
608{
609#if __DCL_OPENSSL
610 __DCL_ASSERT_HANDLE(__ctx != NULL);
611 __DCL_ASSERT_HANDLE(__ssl != NULL);
612
613 __DCL_TRACE2(__T("SSLSocket::recv(%p, %zd)\n"), _buf, _n);
614
615 __DCL_TRACE2(__T("before avail[%zd], pending[%d]\n"),
616 Socket::available(), SSL_pending(__ssl));
617 int n = (int) _n;
618 int r = SSL_read(__ssl, _buf, n);
619 __DCL_TRACE1(__T("SSLSocket::SSL_read(%d)\n"), r);
620 __DCL_TRACE2(__T("after avail[%zd], pending[%d]\n"),
621 Socket::available(), SSL_pending(__ssl));
622 if (r > 0)
623 return (size_t) r;
624
625 switch (SSL_get_error(__ssl, r)) {
626 case SSL_ERROR_ZERO_RETURN:
627 __DCL_TRACE0(__T("SSL error zero return\n"));
628 // ssl close notify, and send close notify
629 SSL_shutdown(__ssl);
630 break;
631 case SSL_ERROR_SYSCALL:
632 __DCL_TRACE0(__T("SSL Error: Premature close\n"));
633 break;
634 default:
635 throw new IOException(toString(), new SSLException());
636 }
637#endif
638 // DWORD dw = SCHANNEL_SHUTDOWN;
639
640 return 0;
641}
642
644{
645#if __DCL_OPENSSL
646 __DCL_ASSERT_HANDLE(__ctx != NULL);
647 __DCL_ASSERT_HANDLE(__ssl != NULL);
648
649 return SSL_get_verify_result(__ssl) !=X509_V_OK;
650#endif
651 return false;
652}
653
655{
656 String s;
657
658#if __DCL_OPENSSL
659 __DCL_ASSERT_HANDLE(__ctx != NULL);
660 __DCL_ASSERT_HANDLE(__ssl != NULL);
661
662 char peer_CN[512];
663 X509* peer = SSL_get_peer_certificate(__ssl);
664 if (peer) {
665 int r = X509_NAME_get_text_by_NID(
666 X509_get_subject_name(peer),
667 NID_commonName,
668 peer_CN,
669 sizeof(peer_CN)
670 );
671
672 if (r > 0) {
673 LocaleDecoder decoder;
674 s = decoder.decode(peer_CN);
675 }
676 }
677
678#endif
679 return s;
680}
681
682__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
#define __UNUSED__
Definition Config.h:341
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS2(e1, e2)
Definition Config.h:153
#define __DCL_THROWS1(e)
Definition Config.h:152
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_TRACE0(psz)
Definition Object.h:398
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_TRACE3(fmt, arg1, arg2, arg3)
Definition Object.h:401
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define __DCL_ASSERT_HANDLE(expr)
Definition Object.h:408
#define __DCL_TRACE2(fmt, arg1, arg2)
Definition Object.h:400
#define THREAD_ONCE_INIT
Definition Thread.h:35
pthread_once_t thread_once_t
Definition Thread.h:36
virtual String toString() const
Definition Exception.cpp:40
virtual void destroy()
Definition Exception.cpp:74
HandleType __handle
Definition File.h:255
virtual void close() __DCL_THROWS1(IOException *)
Definition File.cpp:369
virtual size_t read(void *_buf, size_t _n) __DCL_THROWS1(IOException *)
Definition File.cpp:482
virtual String toString() const
virtual size_t write(const void *_buf, size_t _n) __DCL_THROWS1(IOException *)
Definition File.cpp:541
virtual size_t available() const __DCL_THROWS1(IOException *)
Definition File.cpp:407
String __message
Definition SSLSocket.h:39
virtual size_t send(const void *_buf, size_t _n, int _flags=0) __DCL_THROWS1(IOException *)
virtual size_t recv(void *_buf, size_t _n, int _flags=0) __DCL_THROWS1(IOException *)
SSLSocket() __DCL_THROWS1(SSLException *)
virtual void close() __DCL_THROWS1(IOException *)
bool isPeerCertificateVerified() const
SSLException *virtual ~SSLSocket()
virtual void connect(const sockaddr *_serv_addr, socklen_t _addrlen) __DCL_THROWS1(IOException *)
void construct() __DCL_THROWS1(SSLException *)
String getPeerCertificateCommonName() const
String toString(unsigned _base=10) const
Definition Numeric.inl:57