/*
 * Copyright 2002-2006 The Apache Software Foundation.
 *
 * Licensed 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
 * imitations under the License.
 */

#include <openssl/rand.h>
#include <openssl/rand.h>
#include <jni.h>
#include "org_apache_security_juice_provider_SecureRandomOpenSSL.h"

#include "openSSLNative.h"

/*
 * Class:     org_apache_security_juice_provider_SecureRandomOpenSSL
 * Method:    getBytes
 * Signature: ([BI)I
 */
JNIEXPORT jint JNICALL Java_org_apache_security_juice_provider_SecureRandomOpenSSL_getBytes
(JNIEnv *env, jobject jobj, jbyteArray out, jint length) {

    jclass clazz;

    jbyte *holderBytes = (*env)->GetByteArrayElements(env, out, 0);
    if (holderBytes == NULL) {
        return 0;
    }
    if(!RAND_bytes(holderBytes, length)) {
        (*env)->ReleaseByteArrayElements(env, out, holderBytes, 0);
        clazz = (*env)->FindClass(env, RUNTIME_EX);
        (*env)->ThrowNew(env, clazz, getErrorStringOpenSSL("JuiCE OpenSSL: error in random number generator"));
        return 0;
    }
    (*env)->ReleaseByteArrayElements(env, out, holderBytes, 0);
    return 1;
}

/*
 * Class:     org_apache_security_juice_provider_SecureRandomOpenSSL
 * Method:    setSeed
 * Signature: ([BI)V
 */
JNIEXPORT void JNICALL Java_org_apache_security_juice_provider_SecureRandomOpenSSL_setSeed
(JNIEnv *env, jobject jobj, jbyteArray seed, jint length) {
  
    jbyte *holderBytes = (*env)->GetByteArrayElements(env, seed, 0);
    if (holderBytes == NULL) {
        return;
    }   
    RAND_seed(holderBytes, length);
    (*env)->ReleaseByteArrayElements(env, seed, holderBytes, 0);
}
