📄 pssl.cxx
字号:
}BOOL PSSLContext::UseDiffieHellman(const PSSLDiffieHellman & dh){ return SSL_CTX_set_tmp_dh(context, (dh_st *)dh) > 0;}BOOL PSSLContext::SetCipherList(const PString & ciphers){ if (ciphers.IsEmpty()) return FALSE; return SSL_CTX_set_cipher_list(context, (char *)(const char *)ciphers);}///////////////////////////////////////////////////////////////////////////// SSLChannel//PSSLChannel::PSSLChannel(PSSLContext * ctx, BOOL autoDel){ if (ctx != NULL) { context = ctx; autoDeleteContext = autoDel; } else { context = new PSSLContext; autoDeleteContext = TRUE; } ssl = SSL_new(*context); if (ssl == NULL) PSSLAssert("Error creating channel: ");}PSSLChannel::PSSLChannel(PSSLContext & ctx){ context = &ctx; autoDeleteContext = FALSE; ssl = SSL_new(*context);}PSSLChannel::~PSSLChannel(){ // free the SSL connection if (ssl != NULL) SSL_free(ssl); if (autoDeleteContext) delete context;}BOOL PSSLChannel::Read(void * buf, PINDEX len){ flush(); channelPointerMutex.StartRead(); lastReadCount = 0; BOOL returnValue = FALSE; if (readChannel == NULL) SetErrorValues(NotOpen, EBADF, LastReadError); else if (readTimeout == 0 && SSL_pending(ssl) == 0) SetErrorValues(Timeout, ETIMEDOUT, LastReadError); else { readChannel->SetReadTimeout(readTimeout); int readResult = SSL_read(ssl, (char *)buf, len); lastReadCount = readResult; returnValue = readResult > 0; if (readResult < 0 && GetErrorCode(LastReadError) == NoError) ConvertOSError(-1, LastReadError); } channelPointerMutex.EndRead(); return returnValue;}BOOL PSSLChannel::Write(const void * buf, PINDEX len){ flush(); channelPointerMutex.StartRead(); lastWriteCount = 0; BOOL returnValue; if (writeChannel == NULL) { SetErrorValues(NotOpen, EBADF, LastWriteError); returnValue = FALSE; } else { writeChannel->SetWriteTimeout(writeTimeout); int writeResult = SSL_write(ssl, (const char *)buf, len); lastWriteCount = writeResult; returnValue = lastWriteCount >= len; if (writeResult < 0 && GetErrorCode(LastWriteError) == NoError) ConvertOSError(-1, LastWriteError); } channelPointerMutex.EndRead(); return returnValue;}BOOL PSSLChannel::Close(){ BOOL ok = SSL_shutdown(ssl); return PIndirectChannel::Close() && ok;}BOOL PSSLChannel::ConvertOSError(int error, ErrorGroup group){ Errors lastError = NoError; DWORD osError = 0; if (SSL_get_error(ssl, error) != SSL_ERROR_NONE && (osError = ERR_peek_error()) != 0) { osError |= 0x80000000; lastError = Miscellaneous; } return SetErrorValues(lastError, osError, group);}PString PSSLChannel::GetErrorText(ErrorGroup group) const{ if ((lastErrorNumber[group]&0x80000000) == 0) return PIndirectChannel::GetErrorText(group); char buf[200]; return ERR_error_string(lastErrorNumber[group]&0x7fffffff, buf);}BOOL PSSLChannel::Accept(){ if (IsOpen()) return ConvertOSError(SSL_accept(ssl)); return FALSE;}BOOL PSSLChannel::Accept(PChannel & channel){ if (Open(channel)) return ConvertOSError(SSL_accept(ssl)); return FALSE;}BOOL PSSLChannel::Accept(PChannel * channel, BOOL autoDelete){ if (Open(channel, autoDelete)) return ConvertOSError(SSL_accept(ssl)); return FALSE;}BOOL PSSLChannel::Connect(){ if (IsOpen()) return ConvertOSError(SSL_connect(ssl)); return FALSE;}BOOL PSSLChannel::Connect(PChannel & channel){ if (Open(channel)) return ConvertOSError(SSL_connect(ssl)); return FALSE;}BOOL PSSLChannel::Connect(PChannel * channel, BOOL autoDelete){ if (Open(channel, autoDelete)) return ConvertOSError(SSL_connect(ssl)); return FALSE;}BOOL PSSLChannel::UseCertificate(const PSSLCertificate & certificate){ return SSL_use_certificate(ssl, certificate);}void PSSLChannel::SetVerifyMode(VerifyMode mode){ int verify; switch (mode) { default : case VerifyNone: verify = SSL_VERIFY_NONE; break; case VerifyPeer: verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; break; case VerifyPeerMandatory: verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; } SSL_set_verify(ssl, verify, VerifyCallBack);}BOOL PSSLChannel::RawSSLRead(void * buf, PINDEX & len){ if (!PIndirectChannel::Read(buf, len)) return FALSE; len = GetLastReadCount(); return TRUE;}////////////////////////////////////////////////////////////////////////////// Low level interface to SSLEay routines//#define PSSLCHANNEL(bio) ((PSSLChannel *)(bio->ptr))extern "C" {#if (OPENSSL_VERSION_NUMBER < 0x00906000)typedef int (*ifptr)();typedef long (*lfptr)();#endifstatic int Psock_new(BIO * bio){ bio->init = 0; bio->num = 0; bio->ptr = NULL; // this is really (PSSLChannel *) bio->flags = 0; return(1);}static int Psock_free(BIO * bio){ if (bio == NULL) return 0; if (bio->shutdown) { if (bio->init) { PSSLCHANNEL(bio)->Shutdown(PSocket::ShutdownReadAndWrite); PSSLCHANNEL(bio)->Close(); } bio->init = 0; bio->flags = 0; } return 1;}static long Psock_ctrl(BIO * bio, int cmd, long num, void * /*ptr*/){ switch (cmd) { case BIO_CTRL_SET_CLOSE: bio->shutdown = (int)num; return 1; case BIO_CTRL_GET_CLOSE: return bio->shutdown; case BIO_CTRL_FLUSH: return 1; } // Other BIO commands, return 0 return 0;}static int Psock_read(BIO * bio, char * out, int outl){ if (out == NULL) return 0; BIO_clear_retry_flags(bio); // Skip over the polymorphic read, want to do real one PINDEX len = outl; if (PSSLCHANNEL(bio)->RawSSLRead(out, len)) return len; switch (PSSLCHANNEL(bio)->GetErrorCode(PChannel::LastReadError)) { case PChannel::Interrupted : case PChannel::Timeout : BIO_set_retry_read(bio); return -1; default : break; } return 0;}static int Psock_write(BIO * bio, const char * in, int inl){ if (in == NULL) return 0; BIO_clear_retry_flags(bio); // Skip over the polymorphic write, want to do real one if (PSSLCHANNEL(bio)->PIndirectChannel::Write(in, inl)) return PSSLCHANNEL(bio)->GetLastWriteCount(); switch (PSSLCHANNEL(bio)->GetErrorCode(PChannel::LastWriteError)) { case PChannel::Interrupted : case PChannel::Timeout : BIO_set_retry_write(bio); return -1; default : break; } return 0;}static int Psock_puts(BIO * bio, const char * str){ int n,ret; n = strlen(str); ret = Psock_write(bio,str,n); return ret;}};static BIO_METHOD methods_Psock ={ BIO_TYPE_SOCKET, "PTLib-PSSLChannel",#if (OPENSSL_VERSION_NUMBER < 0x00906000) (ifptr)Psock_write, (ifptr)Psock_read, (ifptr)Psock_puts, NULL, (lfptr)Psock_ctrl, (ifptr)Psock_new, (ifptr)Psock_free#else Psock_write, Psock_read, Psock_puts, NULL, Psock_ctrl, Psock_new, Psock_free#endif};BOOL PSSLChannel::OnOpen(){ BIO * bio = BIO_new(&methods_Psock); if (bio == NULL) { SSLerr(SSL_F_SSL_SET_FD,ERR_R_BUF_LIB); return FALSE; } // "Open" then bio bio->ptr = this; bio->init = 1; SSL_set_bio(ssl, bio, bio); return TRUE;}////////////////////////////////////////////////////////////////////////////// misc unused code//#if 0extern "C" {static verify_depth = 0;static verify_error = VERIFY_OK;// should be X509 * but we can just have them as char *. int verify_callback(int ok, X509 * xs, X509 * xi, int depth, int error){ char *s; s = (char *)X509_NAME_oneline(X509_get_subject_name(xs)); if (s == NULL) {// ERR_print_errors(bio_err); return(0); } PError << "depth= " << depth << " " << (char *)s << endl; free(s); if (error == VERIFY_ERR_UNABLE_TO_GET_ISSUER) { s=(char *)X509_NAME_oneline(X509_get_issuer_name(xs)); if (s == NULL) { PError << "verify error" << endl; //ERR_print_errors(bio_err); return(0); } PError << "issuer = " << s << endl; free(s); } if (!ok) { PError << "verify error:num=" << error << " " << X509_cert_verify_error_string(error) << endl; if (verify_depth <= depth) { ok=1; verify_error=VERIFY_OK; } else { ok=0; verify_error=error; } } PError << "verify return:" << ok << endl; return(ok);}};#endif#endif // P_SSL// End of file ////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -