/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <activemq/util/Config.h>

#include "SSLSocket.h"
#include "SSLSocketInputStream.h"
#include "SSLSocketOutputStream.h"
#include "SSLError.h"
#include "SocketError.h"

#ifdef AMQ_HAVE_OPENSSL

using namespace activemq::network;
using namespace activemq::io;

///////////////////////////////////////////////////////////////////////////////
SSLSocket::SSLSocket() throw (SocketException)
:
TcpSocket(),
ctx( SSL_CTX_new( SSLv3_client_method() )),
ssl( 0 ),
verify_peer( false )
{
    if( !ctx )
    throw SocketException( __FILE__, __LINE__,
            "Failed to allocate SSL context");
}

///////////////////////////////////////////////////////////////////////////////
SSLSocket::SSLSocket( SocketHandle socketHandle ) throw (SocketException)
:
TcpSocket(),
ctx( SSL_CTX_new( SSLv3_client_method() )),
ssl( 0 ),
verify_peer( false )
{
    if( !ctx )
    throw SocketException( __FILE__, __LINE__,
            "Failed to allocate SSL context - %s",
            SSLError::getErrorString().c_str());

    initializeSSL( socketHandle );

    try {
        this->socketHandle = socketHandle;
        this->inputStream = new SSLSocketInputStream( socketHandle, ssl );
        this->outputStream = new SSLSocketOutputStream( socketHandle, ssl );
    }
    AMQ_CATCH_RETHROW( SocketException )
    AMQ_CATCHALL_THROW( SocketException )
}

///////////////////////////////////////////////////////////////////////////////
SSLSocket::~SSLSocket()
{
    // Pretend shutdown, we do not want the destructor to block.
    TcpSocket::close();

    if( ssl != 0 ) {
        if( SSL_get_shutdown( ssl ) == 0 )
        SSL_set_shutdown( ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN );
        SSL_shutdown( ssl );
    }

    if( ssl ) SSL_free( ssl );
    if( ctx ) SSL_CTX_free( ctx );
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::connect(const char* host, int port) throw ( SocketException )
{
    if( ssl ) {
        throw SocketException( __FILE__, __LINE__,
                "SSLSocket::connect - Socket already connected."
                " host: %s, port: %d", host, port );
    }

    TcpSocket::connect (host, port);
    if( isConnected() ) {
        while( true ) {

            int result = SSL_connect(ssl);

            switch (SSL_get_error (ssl, result))
            {
                case SSL_ERROR_NONE:
                    // Apart from verification we are done.
                    verifyPeerCertificate( host );
                    return;

                case SSL_ERROR_SSL:
                case SSL_ERROR_ZERO_RETURN:
                    TcpSocket::close();
                    throw SocketException( __FILE__, __LINE__,
                            SSLError::getErrorString().c_str());

                case SSL_ERROR_WANT_READ:
                case SSL_ERROR_WANT_WRITE:
                    // Repeat the operation.
                    break;

                case SSL_ERROR_SYSCALL:
                    TcpSocket::close();
                    throw SocketException( __FILE__, __LINE__,
                            SocketError::getErrorString().c_str() );
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::verifyPeerCertificate( const char* host )
throw( SocketException )
{
    // Verify the certificate name.
    if( verify_peer ) {
        X509 *peer_cert = SSL_get_peer_certificate( ssl );

        if( !peer_cert ) {
            TcpSocket::close();
            throw SocketException( __FILE__, __LINE__,
                    "No peer certificate for verify");
        }

        X509_NAME *subject = X509_get_subject_name( peer_cert );

        std::string need_name (verify_name);
        if( need_name.empty() ) {
            need_name = host;
        }

        bool match = false;
        std::string peer_name;

        int i = -1;
        do {
            i = X509_NAME_get_index_by_NID( subject, NID_commonName, i );
            if( i >= 0 ) {
                X509_NAME_ENTRY *name = X509_NAME_get_entry( subject, i );

                unsigned char *cn;
                if( ASN1_STRING_to_UTF8( &cn, name->value ) >= 0 ) {
                    peer_name = reinterpret_cast<char*> (cn);
                    std::free( cn );

                    if( peer_name == need_name ) {
                        match = true;
                    }
                }
            }
        }while( i >= 0 && !match );

        if( !match ) {
            TcpSocket::close();

            if( peer_name.length() ) {
                throw SocketException( __FILE__, __LINE__,
                        "Peer certificate mismatch for %s"
                        " - peer name %s",
                        verify_name.c_str(),
                        peer_name.c_str() );
            } else {
                throw SocketException( __FILE__, __LINE__,
                        "Unable to find certificate CN");
            }
        }
    }
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::initialize() throw( SocketException )
{
    // Destroy the input stream.
    if( inputStream != NULL ) {
        delete inputStream;
        inputStream = NULL;
    }

    // Destroy the output stream.
    if( outputStream != NULL ) {
        delete outputStream;
        outputStream = NULL;
    }

    if( ssl ) {
        SSL_free( ssl );
        ssl = 0;
    }
    initializeSSL( socketHandle );

    // Create an input/output stream for this socket.
    inputStream = new SSLSocketInputStream( socketHandle, ssl );
    outputStream = new SSLSocketOutputStream( socketHandle, ssl );
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::initializeSSL( SocketHandle handle )
throw (SocketException)
{
    ssl = SSL_new( ctx );
    if( !ssl ) {
        throw SocketException( __FILE__, __LINE__,
                "Failed to allocate SSL - %s",
                SSLError::getErrorString().c_str());
    }

    BIO* bio = BIO_new( BIO_s_socket() );
    if( !bio ) {
        throw SocketException( __FILE__, __LINE__,
                "Failed to create BIO for SSL");
    }

    BIO_set_fd( bio, handle, BIO_NOCLOSE );
    SSL_set_bio( ssl, bio, bio );
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::close() throw( cms::CMSException )
{
    // Close the input stream.
    if( inputStream != NULL ) {
        inputStream->close();
    }

    // Close the output stream.
    if( outputStream != NULL ) {
        outputStream->close();
    }

    if( ssl ) {
        // The ssl can not yet be free'd, it is still use in the streams.
        SSL_shutdown(ssl);
    }
    TcpSocket::close ();
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::setCAFilePath( std::string const& file,
        std::string const& path )
throw( SocketException )
{
    if( file.length() || path.length() ) {

        const char *c_file = file.length() ? file.c_str() : 0;
        const char *c_path = path.length() ? path.c_str() : 0;

        if( !SSL_CTX_load_verify_locations( ctx, c_file, c_path )) {
            throw SocketException( __FILE__, __LINE__,
                    "Failed to load verify locations - %s",
                    SSLError::getErrorString().c_str());
        }
    }

    // Should we do this automatically? 
    if( !SSL_CTX_set_default_verify_paths( ctx )) {
        throw SocketException( __FILE__, __LINE__,
                "Failed to load default verify locations - %s",
                SSLError::getErrorString().c_str());
    }
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::setCertFile( std::string const& cert_file,
        std::string const& key_file )
throw( SocketException )
{
    if( cert_file.length() ) {
        if( !SSL_CTX_use_certificate_file( ctx, cert_file.c_str (),
                        SSL_FILETYPE_PEM )) {
            throw SocketException( __FILE__, __LINE__,
                    "Failed to load certificate %s - %s",
                    cert_file.c_str(),
                    SSLError::getErrorString().c_str());
        }

        const char *c_key_file
        = key_file.length() ? key_file.c_str() : cert_file.c_str();

        if( !SSL_CTX_use_PrivateKey_file( ctx, c_key_file,
                        SSL_FILETYPE_PEM )) {
            throw SocketException( __FILE__, __LINE__,
                    "Failed to load private key %s - %s",
                    c_key_file,
                    SSLError::getErrorString().c_str());
        }
    }
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::setPassword( std::string const& password )
throw( SocketException )
{
    if( password.length() ) {
        this->password = password;
        void* data = static_cast<void*> (&this->password);

        SSL_CTX_set_default_passwd_cb( ctx, password_cb );
        SSL_CTX_set_default_passwd_cb_userdata( ctx, data );
    }
}

///////////////////////////////////////////////////////////////////////////////
int SSLSocket::password_cb( char* buffer, int size, int, void* data)
{
    std::string *password = static_cast<std::string*>( data );
    std::strncpy( buffer, password->c_str(), size );
    return password->length();
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::setVerifyPeer( bool value, std::string const& name )
throw( SocketException )
{
    verify_peer = value;
    if( verify_peer ) {
        verify_name = name;
        SSL_CTX_set_verify( ctx, SSL_VERIFY_PEER, 0);
    }
}

///////////////////////////////////////////////////////////////////////////////
void SSLSocket::setCiphers( std::string const& ciphers )
throw( SocketException )
{
    if( ciphers.length() ) {
        if( SSL_CTX_set_cipher_list( ctx, ciphers.c_str() ) == 0) {
            throw SocketException( __FILE__, __LINE__,
                    "Failed to set ciphers %s - %s",
                    ciphers.c_str(),
                    SSLError::getErrorString().c_str());
        }
    }
}

#endif /* AMQ_HAVE_OPENSSL */
