コード例 #1
0
ファイル: ssl.cpp プロジェクト: zalemwoo/mordor-base
size_t
SSLStream::read(void *buffer, size_t length)
{
    const int toRead = (int)std::min<size_t>(0x0fffffff, length);
    while (true) {
        unsigned long error = SSL_ERROR_NONE;
        const int result = sslCallWithLock(std::bind(SSL_read, m_ssl.get(), buffer, toRead), &error);
        if (result > 0) {
            return result;
        }
        MORDOR_LOG_DEBUG(g_log) << this << " SSL_read(" << m_ssl.get() << ", "
            << toRead << "): " << result << " (" << error << ")";
        switch (error) {
            case SSL_ERROR_NONE:
                return result;
            case SSL_ERROR_ZERO_RETURN:
                // Received close_notify message
                MORDOR_ASSERT(result == 0);
                return 0;
            case SSL_ERROR_WANT_READ:
                wantRead();
                continue;
            case SSL_ERROR_WANT_WRITE:
            case SSL_ERROR_WANT_CONNECT:
            case SSL_ERROR_WANT_ACCEPT:
            case SSL_ERROR_WANT_X509_LOOKUP:
                MORDOR_NOTREACHED();
            case SSL_ERROR_SYSCALL:
                if (hasOpenSSLError()) {
                    std::string message = getOpenSSLErrorMessage();
                    MORDOR_LOG_ERROR(g_log) << this << " SSL_read("
                        << m_ssl.get() << ", " << toRead << "): " << result
                        << " (" << error << ", " << message << ")";
                    MORDOR_THROW_EXCEPTION(OpenSSLException(message))
                       // << boost::errinfo_api_function("SSL_read");
                    ;
                }
                MORDOR_LOG_WARNING(g_log) << this << " SSL_read("
                    << m_ssl.get() << ", " << toRead << "): " << result
                    << " (" << error << ")";
                if (result == 0) {
                    return 0;
                }
                MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("SSL_read");
            case SSL_ERROR_SSL:
                {
                    MORDOR_ASSERT(hasOpenSSLError());
                    std::string message = getOpenSSLErrorMessage();
                    MORDOR_LOG_ERROR(g_log) << this << " SSL_read("
                        << m_ssl.get() << ", " << toRead << "): " << result
                        << " (" << error << ", " << message << ")";
                    MORDOR_THROW_EXCEPTION(OpenSSLException(message))
                      //  << boost::errinfo_api_function("SSL_read");
                    ;
                }
            default:
                MORDOR_NOTREACHED();
        }
    }
}
コード例 #2
0
ファイル: crl.hpp プロジェクト: akoshelnik/openvpn3
      void parse_pem(const std::string& crl_txt)
      {
	BIO *bio = BIO_new_mem_buf(const_cast<char *>(crl_txt.c_str()), crl_txt.length());
	if (!bio)
	  throw OpenSSLException();

	X509_CRL *crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
	BIO_free(bio);
	if (!crl)
	  throw OpenSSLException("CRL::parse_pem");

	erase();
	crl_ = crl;
      }
コード例 #3
0
ファイル: x509.hpp プロジェクト: akoshelnik/openvpn3
      void parse_pem(const std::string& cert_txt, const std::string& title)
      {
	BIO *bio = BIO_new_mem_buf(const_cast<char *>(cert_txt.c_str()), cert_txt.length());
	if (!bio)
	  throw OpenSSLException();

	::X509 *cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
	BIO_free(bio);
	if (!cert)
	  throw OpenSSLException(std::string("X509::parse_pem: error in ") + title + std::string(":"));

	erase();
	x509_ = cert;
      }
コード例 #4
0
ファイル: ssl.cpp プロジェクト: zalemwoo/mordor-base
SSLStream::SSLStream(Stream::ptr parent, bool client, bool own, SSL_CTX *ctx)
: MutatingFilterStream(parent, own)
{
    MORDOR_ASSERT(parent);
    clearSSLError();
    if (ctx)
        m_ctx.reset(ctx, &nop<SSL_CTX *>);
    else
        m_ctx.reset(SSL_CTX_new(client ? SSLv23_client_method() :
            SSLv23_server_method()), &SSL_CTX_free);
    if (!m_ctx) {
        MORDOR_ASSERT(hasOpenSSLError());
        MORDOR_THROW_EXCEPTION(OpenSSLException(getOpenSSLErrorMessage()))
           // << boost::errinfo_api_function("SSL_CTX_new");
        ;
    }
    // Auto-generate self-signed server cert
    if (!ctx && !client) {
        std::shared_ptr<X509> cert;
        std::shared_ptr<EVP_PKEY> pkey;
        mkcert(cert, pkey, 1024, rand(), 365);
        SSL_CTX_use_certificate(m_ctx.get(), cert.get());
        SSL_CTX_use_PrivateKey(m_ctx.get(), pkey.get());
    }
    m_ssl.reset(SSL_new(m_ctx.get()), &SSL_free);
    if (!m_ssl) {
        MORDOR_ASSERT(hasOpenSSLError());
        MORDOR_THROW_EXCEPTION(OpenSSLException(getOpenSSLErrorMessage()))
          //  << boost::errinfo_api_function("SSL_CTX_new");
        ;
    }
    m_readBio = BIO_new(BIO_s_mem());
    m_writeBio = BIO_new(BIO_s_mem());
    if (!m_readBio || !m_writeBio) {
        if (m_readBio) BIO_free(m_readBio);
        if (m_writeBio) BIO_free(m_writeBio);
        MORDOR_ASSERT(hasOpenSSLError());
        MORDOR_THROW_EXCEPTION(OpenSSLException(getOpenSSLErrorMessage()))
          //  << boost::errinfo_api_function("BIO_new");
        ;
    }
    BIO_set_mem_eof_return(m_readBio, -1);

    SSL_set_bio(m_ssl.get(), m_readBio, m_writeBio);
}
コード例 #5
0
ファイル: RSAKeyImpl.cpp プロジェクト: obiltschnig/poco
RSAKeyImpl::RSAKeyImpl(const X509Certificate& cert):
	KeyPairImpl("rsa", KT_RSA_IMPL),
	_pRSA(0)
{
	const X509* pCert = cert.certificate();
	EVP_PKEY* pKey = X509_get_pubkey(const_cast<X509*>(pCert));
	if (pKey)
	{
		_pRSA = EVP_PKEY_get1_RSA(pKey);
		EVP_PKEY_free(pKey);
	}
	else
		throw OpenSSLException("RSAKeyImpl(const X509Certificate&)");
}
コード例 #6
0
ファイル: ssl.cpp プロジェクト: zalemwoo/mordor-base
void
SSLStream::serverNameIndication(const std::string &hostname)
{
    // Older versions of OpenSSL don't support this (I'm looking at you,
    // Leopard); just ignore it then
#ifdef SSL_set_tlsext_host_name
    std::lock_guard<std::mutex> lock(m_mutex);
    if (!SSL_set_tlsext_host_name(m_ssl.get(), hostname.c_str())) {
        if (!hasOpenSSLError()) return;
        std::string message = getOpenSSLErrorMessage();
        MORDOR_LOG_ERROR(g_log) << this << " SSL_set_tlsext_host_name("
            << m_ssl.get() << ", " << hostname.c_str() << "): " << message;
        MORDOR_THROW_EXCEPTION(OpenSSLException(message))
          //  << boost::errinfo_api_function("SSL_set_tlsext_host_name");
        ;
    }
#endif
}
コード例 #7
0
ファイル: crl.hpp プロジェクト: akoshelnik/openvpn3
      std::string render_pem() const
      {
	if (crl_)
	  {
	    BIO *bio = BIO_new(BIO_s_mem());
	    const int ret = PEM_write_bio_X509_CRL(bio, crl_);
	    if (ret == 0)
	      {
		BIO_free(bio);
		throw OpenSSLException("CRL::render_pem");
	      }

	    {
	      char *temp;
	      const int buf_len = BIO_get_mem_data(bio, &temp);
	      std::string ret = std::string(temp, buf_len);
	      BIO_free(bio);
	      return ret;
	    }
	  }
	else
	  return "";
      }
コード例 #8
0
ファイル: RSAKeyImpl.cpp プロジェクト: obiltschnig/poco
RSAKeyImpl::RSAKeyImpl(const EVPPKey& key):
	KeyPairImpl("rsa", KT_RSA_IMPL),
	_pRSA(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>((const EVP_PKEY*)key)))
{
	if (!_pRSA) throw OpenSSLException();
}
コード例 #9
0
ファイル: ssl.cpp プロジェクト: zalemwoo/mordor-base
void
SSLStream::connect()
{
    while (true) {
        unsigned long error = SSL_ERROR_NONE;
        const int result = sslCallWithLock(std::bind(SSL_connect, m_ssl.get()), &error);
        MORDOR_LOG_DEBUG(g_log) << this << " SSL_connect(" << m_ssl.get()
            << "): " << result << " (" << error << ")";
        if (result > 0) {
            flush(false);
            return;
        }
        switch (error) {
            case SSL_ERROR_NONE:
                flush(false);
                return;
            case SSL_ERROR_ZERO_RETURN:
                // Received close_notify message
                return;
            case SSL_ERROR_WANT_READ:
                flush();
                wantRead();
                continue;
            case SSL_ERROR_WANT_WRITE:
            case SSL_ERROR_WANT_CONNECT:
            case SSL_ERROR_WANT_ACCEPT:
            case SSL_ERROR_WANT_X509_LOOKUP:
                MORDOR_NOTREACHED();
            case SSL_ERROR_SYSCALL:
                if (hasOpenSSLError()) {
                    std::string message = getOpenSSLErrorMessage();
                    MORDOR_LOG_ERROR(g_log) << this << " SSL_connect("
                        << m_ssl.get() << "): " << result << " (" << error
                        << ", " << message << ")";
                    MORDOR_THROW_EXCEPTION(OpenSSLException(message))
                       // << boost::errinfo_api_function("SSL_connect");
                    ;
                }
                MORDOR_LOG_ERROR(g_log) << this << " SSL_connect("
                    << m_ssl.get() << "): " << result << " (" << error
                    << ")";
                if (result == 0) {
                    MORDOR_THROW_EXCEPTION(UnexpectedEofException());
                }
                MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("SSL_connect");
            case SSL_ERROR_SSL:
                {
                    MORDOR_ASSERT(hasOpenSSLError());
                    std::string message = getOpenSSLErrorMessage();
                    MORDOR_LOG_ERROR(g_log) << this << " SSL_connect("
                        << m_ssl.get() << "): " << result << " (" << error
                        << ", " << message << ")";
                    MORDOR_THROW_EXCEPTION(OpenSSLException(message))
                      //  << boost::errinfo_api_function("SSL_connect");
                    ;
                }
            default:
                MORDOR_NOTREACHED();
        }
    }
}
コード例 #10
0
ファイル: ssl.cpp プロジェクト: zalemwoo/mordor-base
void
SSLStream::close(CloseType type)
{
    MORDOR_ASSERT(type == BOTH);
    if (!(sslCallWithLock(std::bind(SSL_get_shutdown, m_ssl.get()), NULL) & SSL_SENT_SHUTDOWN)) {
        unsigned long error = SSL_ERROR_NONE;
        const int result = sslCallWithLock(std::bind(SSL_shutdown, m_ssl.get()), &error);
        if (result <= 0) {
            MORDOR_LOG_DEBUG(g_log) << this << " SSL_shutdown(" << m_ssl.get()
                << "): " << result << " (" << error << ")";
            switch (error) {
                case SSL_ERROR_NONE:
                case SSL_ERROR_ZERO_RETURN:
                    break;
                case SSL_ERROR_WANT_READ:
                case SSL_ERROR_WANT_WRITE:
                case SSL_ERROR_WANT_CONNECT:
                case SSL_ERROR_WANT_ACCEPT:
                case SSL_ERROR_WANT_X509_LOOKUP:
                    MORDOR_NOTREACHED();
                case SSL_ERROR_SYSCALL:
                    if (hasOpenSSLError()) {
                        std::string message = getOpenSSLErrorMessage();
                        MORDOR_LOG_ERROR(g_log) << this << " SSL_shutdown("
                            << m_ssl.get() << "): " << result << " (" << error
                            << ", " << message << ")";
                        MORDOR_THROW_EXCEPTION(OpenSSLException(message))
                           // << boost::errinfo_api_function("SSL_shutdown");
                        ;
                    }
                    MORDOR_LOG_ERROR(g_log) << this << " SSL_shutdown("
                        << m_ssl.get() << "): " << result << " (" << error
                        << ")";
                    if (result == 0)
                        break;
                    MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("SSL_shutdown");
                case SSL_ERROR_SSL:
                    {
                        MORDOR_ASSERT(hasOpenSSLError());
                        std::string message = getOpenSSLErrorMessage();
                        MORDOR_LOG_ERROR(g_log) << this << " SSL_shutdown("
                            << m_ssl.get() << "): " << result << " (" << error
                            << ", " << message << ")";
                        MORDOR_THROW_EXCEPTION(OpenSSLException(message))
                          //  << boost::errinfo_api_function("SSL_shutdown");
                        ;
                    }
                default:
                    MORDOR_NOTREACHED();
            }
        }
        flush(false);
    }

    while (!(sslCallWithLock(std::bind(SSL_get_shutdown, m_ssl.get()), NULL) & SSL_RECEIVED_SHUTDOWN)) {
        unsigned long error = SSL_ERROR_NONE;
        const int result = sslCallWithLock(std::bind(SSL_shutdown, m_ssl.get()), &error);
        MORDOR_LOG_DEBUG(g_log) << this << " SSL_shutdown(" << m_ssl.get()
            << "): " << result << " (" << error << ")";
        if (result > 0) {
            break;
        }
        switch (error) {
            case SSL_ERROR_NONE:
            case SSL_ERROR_ZERO_RETURN:
                break;
            case SSL_ERROR_WANT_READ:
                flush();
                wantRead();
                continue;
            case SSL_ERROR_WANT_WRITE:
            case SSL_ERROR_WANT_CONNECT:
            case SSL_ERROR_WANT_ACCEPT:
            case SSL_ERROR_WANT_X509_LOOKUP:
                MORDOR_NOTREACHED();
            case SSL_ERROR_SYSCALL:
                if (hasOpenSSLError()) {
                    std::string message = getOpenSSLErrorMessage();
                    MORDOR_LOG_ERROR(g_log) << this << " SSL_shutdown("
                        << m_ssl.get() << "): " << result << " (" << error
                        << ", " << message << ")";
                    MORDOR_THROW_EXCEPTION(OpenSSLException(message))
                       // << boost::errinfo_api_function("SSL_shutdown");
                    ;
                }
                MORDOR_LOG_WARNING(g_log) << this << " SSL_shutdown(" << m_ssl.get()
                    << "): " << result << " (" << error << ")";
                if (result == 0) {
                    break;
                }
                MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("SSL_shutdown");
            case SSL_ERROR_SSL:
                {
                    MORDOR_ASSERT(hasOpenSSLError());
                    std::string message = getOpenSSLErrorMessage();
                    MORDOR_LOG_ERROR(g_log) << this << " SSL_shutdown("
                        << m_ssl.get() << "): " << result << " (" << error
                        << ", " << message << ")";
                    MORDOR_THROW_EXCEPTION(OpenSSLException(message))
                      //  << boost::errinfo_api_function("SSL_shutdown");
                    ;
                }
            default:
                MORDOR_NOTREACHED();
        }
        break;
    }
    parent()->close();
}