📄 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.8 1998/12/04 13:04:18 craigs Exp $
* $Log: pssl.cxx,v $
* 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>
#ifdef P_SSL
#include <pssl.h>
#include "buffer.h"
#include "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, 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,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 + -