⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pssl.cxx

📁 基于VXWORKS H323通信技术源代码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -