📄 pssl.cxx
字号:
/*
* pssl.cxx
*
* SSL implementation for PTLib using the SSLeay package
*
* Portable Windows Library
*
* Copyright (c) 1993-2002 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.
*
* Contributor(s): ______________________________________.
*
* Portions bsed upon the file crypto/buffer/bss_sock.c
* Original copyright notice appears below
*
* $Id: pssl.cxx,v 1.1 2006/06/29 04:18:03 joegenbaclor Exp $
* $Log: pssl.cxx,v $
* Revision 1.1 2006/06/29 04:18:03 joegenbaclor
* *** empty log message ***
*
* Revision 1.42 2006/05/26 22:05:42 hfriederich
* Fixing compilation under Mac OS X
*
* Revision 1.41 2005/11/30 12:47:41 csoutheren
* Removed tabs, reformatted some code, and changed tags for Doxygen
*
* Revision 1.40 2005/10/17 01:25:05 csoutheren
* Added check for ssl with const argumetns
*
* Revision 1.39 2004/04/09 06:52:17 rjongbloed
* Removed #pargma linker command for /delayload of DLL as documentations sais that
* you cannot do this.
*
* Revision 1.38 2004/02/23 23:52:20 csoutheren
* Added pragmas to avoid every Windows application needing to include libs explicitly
*
* Revision 1.37 2004/02/22 01:57:37 ykiryanov
* Put a fix for a compiler choke on BeOS when calling macro d2i_DHparams_bio in PSSLDiffieHellman::Load. Fast on Monday.
*
* Revision 1.36 2003/04/16 08:00:19 robertj
* Windoes psuedo autoconf support
*
* Revision 1.35 2002/11/06 22:47:25 robertj
* Fixed header comment (copyright etc)
*
* Revision 1.34 2002/06/07 02:55:23 robertj
* Fixed GNU warning
*
* Revision 1.33 2002/04/02 16:59:35 robertj
* Fixed GNU warning
*
* Revision 1.32 2002/04/02 16:17:28 robertj
* Fixed bug where returned TRUE when read count 0 or write count not len
* which is not according to Read()/Write() semantics. Could cause high CPU
* loops when sockets shutdown.
*
* Revision 1.31 2002/03/28 07:26:25 robertj
* Added Diffie-Hellman parameters wrapper class.
*
* Revision 1.30 2001/12/13 09:15:41 robertj
* Added function to get private key as ray DER binary data or as base64 string.
*
* Revision 1.29 2001/12/06 04:06:03 robertj
* Removed "Win32 SSL xxx" build configurations in favour of system
* environment variables to select optional libraries.
*
* Revision 1.28 2001/12/04 02:59:18 robertj
* Fixed problem on platforms where a pointer is not the same size as an int.
*
* Revision 1.27 2001/10/31 01:31:26 robertj
* Added enhancements for saving/loading/creating certificates and keys.
*
* Revision 1.26 2001/09/28 08:50:48 robertj
* Fixed bug where last count not set to zero if have error on read/write.
*
* Revision 1.25 2001/09/10 02:51:23 robertj
* Major change to fix problem with error codes being corrupted in a
* PChannel when have simultaneous reads and writes in threads.
*
* Revision 1.24 2001/06/01 00:53:59 robertj
* Added certificate constructor that takes a PBYTEArray
*
* Revision 1.23 2001/05/31 07:04:11 craigs
* Changed random seed function
*
* Revision 1.22 2001/05/29 03:33:54 craigs
* Added options to be compatible with OpenSSL 0.9.6
*
* Revision 1.21 2001/05/16 06:31:37 robertj
* Fixed GNU C++ compatibility
*
* Revision 1.20 2001/05/16 06:02:37 craigs
* Changed to allow detection of non-SSL connection to SecureHTTPServiceProcess
*
* Revision 1.19 2001/05/09 07:00:22 robertj
* Removed clearing of lock callbacks in context destructor, should not!
*
* Revision 1.18 2001/02/16 07:13:41 robertj
* Fixed bug in PSSLChannel error detection, thinks a zero byte write is error.
*
* Revision 1.17 2000/11/27 06:46:16 robertj
* Added asserts with SSL error message text.
*
* Revision 1.16 2000/11/14 08:33:16 robertj
* Added certificate and private key classes.
*
* Revision 1.15 2000/11/03 10:00:43 robertj
* Fixed initialisation of SSL, needed random number seed for some modes.
*
* Revision 1.14 2000/09/01 03:32:46 robertj
* Fixed assert on setting directories for CAs.
*
* Revision 1.13 2000/09/01 02:06:00 craigs
* Changed to OpenSSL_add_ssl_algorthms to fix link problem on some machines
*
* Revision 1.12 2000/08/25 13:56:46 robertj
* Fixed some GNU warnings
*
* Revision 1.11 2000/08/25 08:11:02 robertj
* Fixed OpenSSL support so can operate as a server channel.
*
* Revision 1.10 2000/08/04 12:52:18 robertj
* SSL changes, added error functions, removed need to have openssl include directory in app.
*
* 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 <ptclib/mime.h>
#if P_SSL
#define USE_SOCKETS
extern "C" {
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
};
#ifdef _MSC_VER
#pragma comment(lib, P_SSL_LIB1)
#pragma comment(lib, P_SSL_LIB2)
#endif
///////////////////////////////////////////////////////////////////////////////
PARRAY(PSSLMutexArrayBase, PMutex);
class PSSLMutexArray : public PSSLMutexArrayBase
{
PCLASSINFO(PSSLMutexArray, PSSLMutexArrayBase);
public:
PSSLMutexArray();
};
class PSSL_BIO
{
public:
PSSL_BIO(BIO_METHOD *method = BIO_s_file_internal())
{ bio = BIO_new(method); }
~PSSL_BIO()
{ BIO_free(bio); }
operator BIO*() const
{ return bio; }
bool OpenRead(const PFilePath & filename)
{ return BIO_read_filename(bio, (char *)(const char *)filename) > 0; }
bool OpenWrite(const PFilePath & filename)
{ return BIO_write_filename(bio, (char *)(const char *)filename) > 0; }
bool OpenAppend(const PFilePath & filename)
{ return BIO_append_filename(bio, (char *)(const char *)filename) > 0; }
protected:
BIO * bio;
};
#define new PNEW
///////////////////////////////////////////////////////////////////////////////
PSSLMutexArray::PSSLMutexArray()
{
// Initialise all of the mutexes for multithreaded operation.
SetSize(CRYPTO_num_locks());
for (PINDEX i = 0; i < GetSize(); i++)
SetAt(i, new PMutex);
}
///////////////////////////////////////////////////////////////////////////////
PSSLPrivateKey::PSSLPrivateKey()
{
key = NULL;
}
PSSLPrivateKey::PSSLPrivateKey(unsigned modulus,
void (*callback)(int,int,void *),
void *cb_arg)
{
key = NULL;
Create(modulus, callback, cb_arg);
}
PSSLPrivateKey::PSSLPrivateKey(const PFilePath & keyFile, PSSLFileTypes fileType)
{
key = NULL;
Load(keyFile, fileType);
}
PSSLPrivateKey::PSSLPrivateKey(const BYTE * keyData, PINDEX keySize)
{
#if P_SSL_USE_CONST
key = d2i_AutoPrivateKey(NULL, &keyData, keySize);
#else
key = d2i_AutoPrivateKey(NULL, (BYTE **)&keyData, keySize);
#endif
}
PSSLPrivateKey::PSSLPrivateKey(const PBYTEArray & keyData)
{
const BYTE * keyPtr = keyData;
#if P_SSL_USE_CONST
key = d2i_AutoPrivateKey(NULL, &keyPtr, keyData.GetSize());
#else
key = d2i_AutoPrivateKey(NULL, (BYTE **)&keyPtr, keyData.GetSize());
#endif
}
PSSLPrivateKey::PSSLPrivateKey(const PSSLPrivateKey & privKey)
{
key = privKey.key;
}
PSSLPrivateKey & PSSLPrivateKey::operator=(const PSSLPrivateKey & privKey)
{
if (key != NULL)
EVP_PKEY_free(key);
key = privKey.key;
return *this;
}
PSSLPrivateKey::~PSSLPrivateKey()
{
if (key != NULL)
EVP_PKEY_free(key);
}
BOOL PSSLPrivateKey::Create(unsigned modulus,
void (*callback)(int,int,void *),
void *cb_arg)
{
if (key != NULL) {
EVP_PKEY_free(key);
key = NULL;
}
if (modulus < 384) {
return FALSE;
}
key = EVP_PKEY_new();
if (key == NULL)
return FALSE;
if (EVP_PKEY_assign_RSA(key, RSA_generate_key(modulus, 0x10001, callback, cb_arg)))
return TRUE;
EVP_PKEY_free(key);
key = NULL;
return FALSE;
}
PBYTEArray PSSLPrivateKey::GetData() const
{
PBYTEArray data;
if (key != NULL) {
BYTE * keyPtr = data.GetPointer(i2d_PrivateKey(key, NULL));
i2d_PrivateKey(key, &keyPtr);
}
return data;
}
PString PSSLPrivateKey::AsString() const
{
return PBase64::Encode(GetData());
}
BOOL PSSLPrivateKey::Load(const PFilePath & keyFile, PSSLFileTypes fileType)
{
if (key != NULL) {
EVP_PKEY_free(key);
key = NULL;
}
PSSL_BIO in;
if (!in.OpenRead(keyFile)) {
SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB);
return FALSE;
}
if (fileType == PSSLFileTypeDEFAULT)
fileType = keyFile.GetType() == ".pem" ? PSSLFileTypePEM : PSSLFileTypeASN1;
switch (fileType) {
case PSSLFileTypeASN1 :
key = d2i_PrivateKey_bio(in, NULL);
if (key != NULL)
return TRUE;
SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_ASN1_LIB);
break;
case PSSLFileTypePEM :
key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
if (key != NULL)
return TRUE;
SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_PEM_LIB);
break;
default :
SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
}
return FALSE;
}
BOOL PSSLPrivateKey::Save(const PFilePath & keyFile, BOOL append, PSSLFileTypes fileType)
{
if (key == NULL)
return FALSE;
PSSL_BIO out;
if (!(append ? out.OpenAppend(keyFile) : out.OpenWrite(keyFile))) {
SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,ERR_R_SYS_LIB);
return FALSE;
}
if (fileType == PSSLFileTypeDEFAULT)
fileType = keyFile.GetType() == ".pem" ? PSSLFileTypePEM : PSSLFileTypeASN1;
switch (fileType) {
case PSSLFileTypeASN1 :
if (i2d_PrivateKey_bio(out, key))
return TRUE;
SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_ASN1_LIB);
break;
case PSSLFileTypePEM :
if (PEM_write_bio_PrivateKey(out, key, NULL, NULL, 0, 0, NULL))
return TRUE;
SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_PEM_LIB);
break;
default :
SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE,SSL_R_BAD_SSL_FILETYPE);
}
return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -