/*
 *  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 "sslParameters.h"
#include <stdio.h>
#include "jni.h"
#include "hysock.h"
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "jsse_rand.h"

#include "cipherList.h"

int getCipherSpecList(JNIEnv *env, SSL *ssl, const char *protocol, jstring **jciphers, char *openSSLNames[], char *specNames[], int mappedNamesCount) {
    int i, matched, ret, count;
    STACK_OF(SSL_CIPHER) *ciphers;

    ret = SSL_set_cipher_list(ssl, protocol);
    if (ret<=0) {
       ERR_print_errors_fp(stderr);
       // TODO: Throw exception here and return error value
    }

    ciphers = SSL_get_ciphers(ssl);
    count = sk_num(&ciphers->stack);
    *jciphers = malloc(sizeof(jstring)*count);

    matched = 0;
    for (i=0; i<count; i++)
    {
        const char *cipherName = SSL_CIPHER_get_name(sk_value(&ciphers->stack, i));
        int j;
        for (j=0; j<mappedNamesCount; j++) {
            if (!strcmp(cipherName, openSSLNames[j])) {
                (*jciphers)[matched] = (*env)->NewStringUTF(env, specNames[j]);                
                matched++;
                break;
            }
        }
    }

    return matched;
}

JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_initialiseDefaults
  (JNIEnv *env, jclass clazz)
{
    SSL_CTX *context;
    SSL *ssl;
    int i, ret, ssl2matched, ssl3matched, tlsmatched;
    jclass stringClass;
    jobjectArray stringArray;
    jstring *ssl2jciphers, *ssl3jciphers, *tlsjciphers;

    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();

    context = SSL_CTX_new(SSLv23_method());

    ret = SSL_CTX_set_cipher_list(context, "SSLv2:SSLv3:TLSv1");
    if (ret<=0) {
       ERR_print_errors_fp(stderr);
       // TODO: throw exception here and return
    }

    ssl = SSL_new(context);
    
    // TODO: check for exception return
    ssl2matched = getCipherSpecList(env, ssl, "SSLv2:@STRENGTH", &ssl2jciphers, getSSLv2OpenSSLNames(), getSSLv2SpecNames(), SSLv2_CIPHER_COUNT);
    ssl3matched = getCipherSpecList(env, ssl, "SSLv3:@STRENGTH", &ssl3jciphers, getSSLv3OpenSSLNames(), getSSLv3SpecNames(), SSLv3_CIPHER_COUNT);
    tlsmatched = getCipherSpecList(env, ssl, "TLSv1:@STRENGTH", &tlsjciphers, getTLSv1OpenSSLNames(), getTLSv1SpecNames(), TLSv1_CIPHER_COUNT);

    stringClass = (*env)->FindClass(env, "java/lang/String");
    stringArray = (*env)->NewObjectArray(env, ssl2matched + ssl3matched + tlsmatched, stringClass, NULL);
    for (i=0; i<tlsmatched; i++)
    {
        (*env)->SetObjectArrayElement(env, stringArray, i, tlsjciphers[i]);
        (*env)->DeleteLocalRef(env, tlsjciphers[i]);
    }
    for (i=0; i<ssl3matched; i++)
    {
        (*env)->SetObjectArrayElement(env, stringArray, i + tlsmatched, ssl3jciphers[i]);
        (*env)->DeleteLocalRef(env, ssl3jciphers[i]);
    }
    for (i=0; i<ssl2matched; i++)
    {
        (*env)->SetObjectArrayElement(env, stringArray, i + ssl3matched + tlsmatched, ssl2jciphers[i]);
        (*env)->DeleteLocalRef(env, ssl2jciphers[i]);
    }
    
    free(ssl2jciphers);
    free(ssl3jciphers);
    free(tlsjciphers);
    SSL_free(ssl);
    SSL_CTX_free(context);

    // Initialise our global RNG functions to call into RNGHandler
    initialiseRandMethod(env);

    // Return the array of default cipher suites
    return stringArray;
}

// Callback for temporary RSA key generation
RSA *tmp_rsa_callback(SSL *s, int is_export, int keylength)
{
    return RSA_generate_key(keylength, RSA_F4, NULL, NULL);
}

// Callback for DH params generation
// TODO: Would pregenerated params do? e.g. get_rfc2409_prime_768() etc.
DH *tmp_dh_callback(SSL *s, int is_export, int keylength)
{
    DH *dh;

    // For key lengths under 1024 generate the DH params directly
    // For 1024 (or greater) use DSA generation for performance
    if (keylength < 1024) {
        dh = DH_generate_parameters(keylength, 5, NULL, NULL);
    } else {
        DSA *dsa = DSA_generate_parameters(1024, NULL, 0, NULL, NULL, NULL, NULL);
        dh = DSA_dup_DH(dsa);
        DSA_free(dsa);
    }  

    // TODO: Throw an exception if dh is NULL?
    return dh;
}

JNIEXPORT jlong JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_initialiseContext
  (JNIEnv *env, jclass clazz, jobjectArray jtrustCerts, jbyteArray jkeyCert, jbyteArray jprivateKey)
{
    SSL_CTX *context;
    jint size;
    jint i;
    X509_STORE *certStore;
    X509 *x509cert;
    const unsigned char *temp;
    int ret;

    context = SSL_CTX_new(SSLv23_method());

    ret = SSL_CTX_set_cipher_list(context, "SSLv2:SSLv3:TLSv1");
    if (ret<=0) {
       ERR_print_errors_fp(stderr);
    }

    // Set client auth off by default
    SSL_CTX_set_verify(context, SSL_VERIFY_NONE, NULL);

    // Set callback for DH key exchange.
    SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
    SSL_CTX_set_tmp_dh_callback(context, &tmp_dh_callback);
    SSL_CTX_set_tmp_rsa_callback(context, &tmp_rsa_callback);

    // First initilise the trust certificates in our newly created context
    size = (*env)->GetArrayLength(env, jtrustCerts);
    if (size) {
        // Get the current trust certificate store and add any certs passed in
        certStore = SSL_CTX_get_cert_store(context);
        for (i=0; i<size; i++) {
            jbyteArray cert = (jbyteArray) (*env)->GetObjectArrayElement(env, jtrustCerts, i);
            jint byteSize = (*env)->GetArrayLength(env, cert);
            
            // malloc a buffer for the ASN1 encoded certificate
            jbyte *certBuffer = (jbyte*) malloc(byteSize * sizeof(jbyte*)); 
            (*env)->GetByteArrayRegion(env, cert, 0, byteSize, certBuffer);

            // Copy certBuffer as the d2i_X509 will increment it
            temp = (const unsigned char*)certBuffer;

            // Create an X509 from the ASN1 encoded certificate
            x509cert = d2i_X509(NULL, &temp, (int)byteSize);

            // Add the certificate to the existing ones in the SSL_CTX
            ret = X509_STORE_add_cert(certStore, x509cert);
            if (ret<=0) {
               ERR_print_errors_fp(stderr);
            }
            free(certBuffer);
        }
    }

    if (jkeyCert != NULL) {
        jint byteSize = (*env)->GetArrayLength(env, jkeyCert);
            
        // malloc a buffer for the ASN1 encoded certificate
        jbyte *certBuffer = (jbyte*) malloc(byteSize * sizeof(jbyte*)); 
        (*env)->GetByteArrayRegion(env, jkeyCert, 0, byteSize, certBuffer);

        // Set the key cert passed in as the default for this context
        ret = SSL_CTX_use_certificate_ASN1(context, byteSize, (unsigned char *)certBuffer);
        if (ret<=0) {
           ERR_print_errors_fp(stderr);
        }
        free(certBuffer);
    }

    if (jprivateKey != NULL) {
        jint byteSize = (*env)->GetArrayLength(env, jprivateKey);
            
        // malloc a buffer for the ASN1 encoded certificate
        jbyte *certBuffer = (jbyte*) malloc(byteSize * sizeof(jbyte*)); 
        (*env)->GetByteArrayRegion(env, jprivateKey, 0, byteSize, certBuffer);

        // Set the private key passed in as the default for this context
        ret = SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, context, (unsigned char *)certBuffer, byteSize);
        if (ret<=0) {
           ERR_print_errors_fp(stderr);
        }

        SSL_CTX_check_private_key(context);
        if (ret<=0) {
           ERR_print_errors_fp(stderr);
        }
        free(certBuffer);
    }
    
    return addr2jlong(context);
}

JNIEXPORT void JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_setEnabledProtocolsImpl
  (JNIEnv *env, jclass clazz, jlong context, jlong jssl, jint flags) 
{
    SSL_CTX *ctx = jlong2addr(SSL_CTX, context);
    SSL *ssl = jlong2addr(SSL, jssl);
    long options = 0;
    long mask = SSL_OP_NO_TLSv1 | SSL_OP_NO_SSLv3 | SSL_OP_NO_SSLv2;

    if (flags & PROTOCOL_TLSv1) {
        options |= SSL_OP_NO_TLSv1;
    }
    if (flags & PROTOCOL_SSLv3) {
        options |= SSL_OP_NO_SSLv3;
    }
    if (flags & PROTOCOL_SSLv2) {
        options |= SSL_OP_NO_SSLv2;
    }

    // Clearing the options enables the protocol, setting disables
    SSL_CTX_clear_options(ctx, options);
    SSL_CTX_set_options(ctx, options ^ mask);

    // If we have been passed an SSL pointer, set the options on that SSL too
    if (ssl) {
        SSL_clear_options(ssl, options);
        SSL_set_options(ssl, options ^ mask);
    }
}

JNIEXPORT void JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_setClientAuthImpl
  (JNIEnv *env, jclass clazz, jlong context, jlong jssl, jshort flag)
{
    SSL_CTX *ctx = jlong2addr(SSL_CTX, context);
    SSL *ssl = jlong2addr(SSL, jssl);
    int mode = 0;

    switch (flag) {
    case NO_CLIENT_AUTH:
        mode = SSL_VERIFY_NONE;
        break;
    case REQUEST_CLIENT_AUTH:
        mode = SSL_VERIFY_PEER;
        break;
    case REQUIRE_CLIENT_AUTH:
        mode = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
        break;
    default:
        // Should never happen
        return;
    }

    // Set the client authentication mode with a NULL callback
    SSL_CTX_set_verify(ctx, mode, NULL);

    // If we have been passed an SSL pointer, set the options on that SSL too
    if (ssl) {
        SSL_set_verify(ssl, mode, NULL);
    }
}

char* findOpenSSLName(const char *cipher) {
    int i, numNames;
    char **openSSLNames, **specNames;
    if (strstr(cipher, "TLS_")) {
        // This is a TLS cipher name
        numNames = TLSv1_CIPHER_COUNT;
        specNames = getTLSv1SpecNames();
        openSSLNames = getTLSv1OpenSSLNames();
        
    } else if (strstr(cipher, "SSL_CK")) {
        // This is an SSLv2 cipher name
        numNames = SSLv2_CIPHER_COUNT;
        specNames = getSSLv2SpecNames();
        openSSLNames = getSSLv2OpenSSLNames();
    } else {
        // This is an SSLv3 cipher name
        numNames = SSLv3_CIPHER_COUNT;
        specNames = getSSLv3SpecNames();
        openSSLNames = getSSLv3OpenSSLNames();
    }

    for (i=0; i<numNames; i++) {
        if (!strcmp(cipher, specNames[i])) {
            return openSSLNames[i];
        }
    }

    return NULL;  
}

JNIEXPORT void JNICALL Java_org_apache_harmony_xnet_provider_jsse_SSLParameters_setEnabledCipherSuitesImpl
  (JNIEnv *env, jclass clazz, jlong context, jlong jssl, jobjectArray jenabledCiphers)
{
    jsize i;
    int size = 0;
    jsize count = (*env)->GetArrayLength(env, jenabledCiphers);
    char *cipherList;
    
    // Calculate the length of the cipher string for OpenSSL.
    // This is strlen(cipher) + 1 for the ':' separator or the final '/0'
    for (i=0; i<count; i++) {
        size += (*env)->GetStringUTFLength(env, (jstring)(*env)->GetObjectArrayElement(env, jenabledCiphers, i)) + 1;
    }

    // malloc the memory we need
    // TODO: go through the port library for this
    cipherList = malloc(size);
    memset(cipherList, 0, size);

    // Now strcat all our cipher names separated by colons, as required by OpenSSL
    for (i=0; i<count; i++) {
        jstring jcipher = (jstring)(*env)->GetObjectArrayElement(env, jenabledCiphers, i);
        const char *cipher = (*env)->GetStringUTFChars(env, jcipher, NULL);

        char *openSSLName = findOpenSSLName(cipher);
        if (openSSLName) {
            strcat(cipherList, openSSLName);
            if (i != count-1) {
                strcat(cipherList, ":");
            }
        }

        (*env)->ReleaseStringUTFChars(env, jcipher, cipher);
    }

    // Set the new cipher list in the context and SSL, if specified
    SSL_CTX_set_cipher_list(jlong2addr(SSL_CTX, context), cipherList);
    if (jssl) {
        SSL_set_cipher_list(jlong2addr(SSL, jssl), cipherList);
    }
}
