📄 pssl.cxx
字号:
/* * pssl.cxx * * SSL implementation for PTLib using the SSLeay package * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * Portions bsed upon the file crypto/buffer/bss_sock.c * Original copyright notice appears below * * $Id: pssl.cxx,v 1.9 2000/01/10 02:24:09 craigs Exp $ * $Log: pssl.cxx,v $ * Revision 1.9 2000/01/10 02:24:09 craigs * Updated for new OpenSSL * * Revision 1.8 1998/12/04 13:04:18 craigs * Changed for SSLeay 0.9 * * Revision 1.7 1998/09/23 06:22:35 robertj * Added open source copyright license. * * Revision 1.6 1998/01/26 02:50:17 robertj * GNU Support * * Revision 1.5 1997/05/04 02:50:54 craigs * Added support for client and server sertificates * * Revision 1.1 1996/11/15 07:38:34 craigs * Initial revision * *//* crypto/buffer/bss_sock.c *//* Copyright (C) 1995-1996 Eric Young (eay@mincom.oz.au) * All rights reserved. * * This file is part of an SSL implementation written * by Eric Young (eay@mincom.oz.au). * The implementation was written so as to conform with Netscapes SSL * specification. This library and applications are * FREE FOR COMMERCIAL AND NON-COMMERCIAL USE * as long as the following conditions are aheared to. * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. If this code is used in a product, * Eric Young should be given attribution as the author of the parts used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Eric Young (eay@mincom.oz.au) * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */#ifdef __GNUC__#pragma implementation "pssl.h"#endif#include <ptlib.h>#include <ptclib/pssl.h>#include <openssl/buffer.h>#include <openssl/crypto.h>PMutex PSSLChannel::initFlag;SSL_CTX * PSSLChannel::context = NULL;extern "C" {typedef int (verifyCallBackType)();};///////////////////////////////////////////////////////////////////////////////static PMutex semaphores[CRYPTO_NUM_LOCKS];extern "C" {void locking_callback(int mode, int type, const char * /* file */, int /* line */){ if (mode & CRYPTO_LOCK) semaphores[type].Wait(); else semaphores[type].Signal();}};static void thread_setup(){ CRYPTO_set_locking_callback((void (*)(int,int,const char *,int))locking_callback);}void PSSLChannel::Cleanup(){ CRYPTO_set_locking_callback(NULL); SSL_CTX_free(context);}///////////////////////////////////////////////////////////////////////////////extern "C" {static int verifyCallBack(int ok, X509_STORE_CTX * ctx){ X509 * err_cert = X509_STORE_CTX_get_current_cert(ctx); //int err = X509_STORE_CTX_get_error(ctx); int depth = X509_STORE_CTX_get_error_depth(ctx); // get the subject name, just for verification char buf[256]; X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); PError << "Verify callback depth " << depth << " : cert name = " << buf << endl; return ok;}};///////////////////////////////////////////////////////////////////////////// SSLChannel//PSSLChannel::PSSLChannel(){ initFlag.Wait(); if (context == NULL) { SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); //SSLeay_add_all_algorithms(); // create the new SSL context SSL_METHOD *meth = SSLv2_client_method(); context = SSL_CTX_new(meth); PAssert(context != NULL, "Cannot create master SSL context"); // set other stuff SSL_CTX_set_options (context, 0); //SSL_CTX_set_quiet_shutdown (context, 1); //SSL_CTX_sess_set_cache_size(context, 128); // set default ciphers //PConfig config(PConfig::Environment); //PString str = config.GetString("SSL_CIPHER"); //if (!str.IsEmpty()) // SSL_CTX_set_cipher_list(context, (char *)(const char *)str); // set default verify mode //SSL_CTX_set_verify(context, SSL_VERIFY_NONE, (verifyCallBackType *)verifyCallBack); PAssert( //SSL_CTX_load_verify_locations(context,NULL,NULL/*CAfile,CApath*/) && SSL_CTX_set_default_verify_paths(context), "Cannot set CAfile and path"); //PAssert (X509_set_default_verify_paths(context->cert), // "SSL: Cannot load certificates via X509_set_default_verify_paths"); // set up multithread stuff //thread_setup(); // and make sure everything gets torn-down correctly atexit(Cleanup); } initFlag.Signal(); // create an SSL context ssl = SSL_new(context);}PSSLChannel::~PSSLChannel(){ // free the SSL context SSL_free(ssl);}/////////////////////////////////////////////////int PSSLChannel::SetClientCertificate(const PString & privateCert){ return SetClientCertificate((const char *)privateCert, (const char *)privateCert);}int PSSLChannel::SetClientCertificate(const PString & privateCert, const PString & privateKey){ return SetClientCertificate((const char *)privateCert, (const char *)privateKey);}int PSSLChannel::SetClientCertificate(const char * certFile, const char * keyFile){ // set up certificate and key if (certFile != NULL) { if (!SSL_use_certificate_file(ssl, (char *)certFile, X509_FILETYPE_PEM)) return PSSLChannel::UnknownCertificate; if (keyFile == NULL) keyFile = certFile; if (!SSL_use_RSAPrivateKey_file(ssl, (char *)keyFile, X509_FILETYPE_PEM)) return PSSLChannel::UnknownPrivateKey; if (!SSL_check_private_key(ssl)) return PSSLChannel::PrivateKeyMismatch; } return PSSLChannel::CertificateOK;}/////////////////////////////////////////////////BOOL PSSLChannel::SetCAPath(const PDirectory & caPath){ return SetCAPathAndFile((const char *)caPath, NULL);}BOOL PSSLChannel::SetCAFile(const PFilePath & caFile){ return SetCAPathAndFile(NULL, (const char *)caFile);}BOOL PSSLChannel::SetCAPathAndFile(const PDirectory & caPath, const PFilePath & caFile){ return SetCAPathAndFile((const char *)caPath, (const char *)caFile);}BOOL PSSLChannel::SetCAPathAndFile(const char * CApath, const char * CAfile){ PString path = CApath; if (path.Right(1)[0] == PDIR_SEPARATOR) path = path.Left(path.GetLength()-1); return SSL_CTX_load_verify_locations(context, (char *)CAfile, (char *)(const char *)path ) && SSL_CTX_set_default_verify_paths(context);}/////////////////////////////////////////////////void PSSLChannel::SetVerifyMode(int mode){ int verify; switch (mode) { 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, (verifyCallBackType *)verifyCallBack);}/////////////////////////////////////////////////BOOL PSSLChannel::Accept(PChannel & channel){ if (!Open(channel)) return FALSE; // set the "fd" to use with this SSL context Set_SSL_Fd(); // connect the SSL layer return SSL_accept(ssl) > 0;}BOOL PSSLChannel::Connect(PChannel & channel){ if (!Open(channel)) return FALSE; // set the "fd" to use with this SSL context Set_SSL_Fd(); // connect the SSL layer return SSL_connect(ssl) > 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -