--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javaextensions/satsa/crypto/src/stsrsacipher.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,270 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation of STSRSACipher
+ *
+*/
+
+
+
+#include "stsrsacipher.h"
+#include "stsconstants.h"
+#include <asymmetric.h>
+
+#include <x509cert.h>
+#include <hash.h>
+#include <asymmetrickeys.h>
+#include <asymmetric.h>
+#include <asnpkcs.h>
+#include <asn1dec.h>
+#include "logger.h"
+
+namespace java
+{
+namespace satsa
+{
+
+
+STSRSACipher::STSRSACipher()
+{
+ mRSA = NULL;
+ mpkey = NULL;
+}
+
+STSRSACipher* STSRSACipher::Create(int* errCode)
+{
+ STSRSACipher* self = new STSRSACipher;
+ if (self == NULL)
+ {
+ *errCode = KSTSErrNoMemory;
+ return NULL;
+ }
+ else
+ {
+ *errCode = 0;
+ return self;
+ }
+
+}
+
+
+STSRSACipher::~STSRSACipher()
+{
+
+}
+
+jint STSRSACipher::DoInit(JNIEnv* aJni, const TCipherMode aMode,
+ const jstring /*aKeyAlgorithm*/, const jstring /*aKeyFormat*/,
+ const jbyteArray aKeyEncoded, const jbyteArray aParams)
+{
+ LOG(ESATSA, EInfo, "STSRSACipher::DoInit+");
+ if (aParams)
+ {
+ ELOG(ESATSA, "STSRSACipher::DoInit:RSA algorithm cannot have parameters");
+ // RSA algorithm cannot have parameters
+ return KSTSErrArgument;
+ }
+
+ // Read the encoded key from the jbytearray
+ int key_length = aJni->GetArrayLength(aKeyEncoded);
+ const unsigned char *key = new unsigned char[key_length];
+ aJni->GetByteArrayRegion(aKeyEncoded, 0, key_length, (signed char*) key);
+
+ if (aMode == EEncryptMode)
+ {
+ LOG(ESATSA, EInfo, "STSRSACipher::DoInit:encryption mode");
+ // encryption mode: read the public key from subject public key info
+
+ // decode the encoded key data into a RSA data structure.
+ mRSA = d2i_RSA_PUBKEY(&mRSA, &key, (long) key_length);
+ if (mRSA == NULL)
+ {
+ ELOG(ESATSA, "STSRSACipher::DoInit:Failed to get proper data");
+ return KSTSErrInvalidKey;
+ }
+
+ }
+ else
+ {
+ LOG(ESATSA, EInfo, "STSRSACipher::DoInit:decryption mode");
+ // decryption mode: decode the private key in PKCS8 format encoded in
+ // ASN1 DER format
+ // load the algorithm lookup tables
+ OpenSSL_add_all_algorithms();
+
+ // create the BIO pointer
+ BIO *bp;
+ bp = BIO_new_mem_buf((void *) key, key_length);
+
+ // Decode the PKCS8 key from the der encoded key data
+ mpkey = EVP_PKEY_new();
+ if (NULL == mpkey)
+ {
+ ELOG(ESATSA, "STSRSACipher::DoInit:Key is null");
+ return KSTSErrNoMemory;
+ }
+ mpkey = d2i_PKCS8PrivateKey_bio(bp, &mpkey, NULL, NULL);
+ if (mpkey == NULL)
+ {
+ ELOG(ESATSA, "STSRSACipher::DoInit:key is improper");
+ return KSTSErrInvalidKey;
+ }
+
+ // Create the RSA data structure to be used for decryption
+ mRSA = EVP_PKEY_get1_RSA(mpkey);
+ if (mRSA == NULL)
+ {
+ ELOG(ESATSA, "STSRSACipher::DoInit:failed to create rsa data");
+ return KSTSErrInvalidKey;
+ }
+
+ }
+ // Init success and mode can be changed
+ mMode = aMode;
+ LOG(ESATSA, EInfo, "STSRSACipher::DoInit--");
+ return 0;
+
+}
+
+jint STSRSACipher::DoFinal(JNIEnv* aJni, jbyteArray aInput, jint aInputOffset,
+ jint aInputLength, jbyteArray aOutput, jint aOutputOffset)
+{
+ LOG(ESATSA, EInfo, "STSRSACipher::DoFinal+");
+ int output_length = 0;
+ if (mRSA == NULL)
+ {
+ // Init was not called successfully.
+ ELOG(ESATSA, "STSRSACipher::DoFinal:Init was not called successfully.");
+ return (KSTSErrIllegalState);
+ }
+
+ //read the input data to be encrypted/decrypted
+ unsigned char* inputBuf = new unsigned char[aInputLength];
+ aJni->GetByteArrayRegion(aInput, aInputOffset, aInputLength,
+ (signed char *) inputBuf);
+
+ int max_output_length = RSA_size(mRSA);
+ unsigned char* outputBuf = new unsigned char[max_output_length];
+
+ if (mMode == EEncryptMode)
+ {
+ if (aInputLength > (max_output_length - 11))
+ {
+ ELOG(ESATSA, "STSRSACipher::DoFinal:Wrong Input length");
+ return (KSTSErrIllegalState);
+ }
+
+ // encrypt the data
+ output_length = RSA_public_encrypt(aInputLength, inputBuf, outputBuf,
+ mRSA, RSA_PKCS1_PADDING);
+
+ if (output_length > aJni->GetArrayLength(aOutput))
+ {
+ ELOG(ESATSA, "STSRSACipher::DoFinal:short output buffer");
+ return (KSTSErrShortBuffer);
+ }
+
+ aJni->SetByteArrayRegion(aOutput, aOutputOffset, output_length,
+ (signed char *) outputBuf);
+
+ }
+ else // Decrypt mode
+ {
+ // decrypt the data
+ output_length = RSA_private_decrypt(aInputLength, inputBuf, outputBuf,
+ mRSA, RSA_PKCS1_PADDING);
+
+ if (output_length > aJni->GetArrayLength(aOutput))
+ {
+ ELOG(ESATSA, "STSRSACipher::DoFinal:wrong output length");
+ return (KSTSErrShortBuffer);
+ }
+
+ // encryption/decryption successfully completed
+ aJni->SetByteArrayRegion(aOutput, aOutputOffset, output_length,
+ (signed char *) outputBuf);
+
+ }
+ LOG(ESATSA, EInfo, "STSRSACipher::DoFinal:--");
+ return output_length;
+
+}
+
+jint STSRSACipher::Update(JNIEnv* aJni, jbyteArray aInput, jint aInputOffset,
+ jint aInputLength, jbyteArray aOutput, jint aOutputOffset)
+{
+ LOG(ESATSA, EInfo, "STSRSACipher::Update+");
+ int output_length = 0;
+ if (mRSA == NULL)
+ {
+ ELOG(ESATSA, "STSRSACipher::Update:Init was not called successfully.");
+ // Init was not called successfully.
+ return (KSTSErrIllegalState);
+ }
+
+ // read the input data to be encrypted/decrypted
+ unsigned char* inputBuf = new unsigned char[aInputLength];
+ aJni->GetByteArrayRegion(aInput, aInputOffset, aInputLength,
+ (signed char *) inputBuf);
+
+ int max_output_length = RSA_size(mRSA);
+ unsigned char* outputBuf = new unsigned char[max_output_length];
+
+ if (mMode == EEncryptMode)
+ {
+ if (aInputLength > (max_output_length - 11))
+ {
+ ELOG(ESATSA, "STSRSACipher::Update:wrong input length.");
+ return (KSTSErrIllegalStateInput);
+ }
+
+ // encrypt the data
+ output_length = RSA_public_encrypt(aInputLength, inputBuf, outputBuf,
+ mRSA, RSA_PKCS1_PADDING);
+
+ if (output_length > aJni->GetArrayLength(aOutput))
+ {
+ ELOG(ESATSA, "STSRSACipher::Update:wrong output length");
+ return (KSTSErrShortBuffer);
+ }
+
+ aJni->SetByteArrayRegion(aOutput, aOutputOffset, output_length,
+ (signed char *) outputBuf);
+
+ }
+ else // Decrypt mode
+ {
+ // decrypt the data
+ output_length = RSA_private_decrypt(aInputLength, inputBuf, outputBuf,
+ mRSA, RSA_PKCS1_PADDING);
+
+ if (output_length > aJni->GetArrayLength(aOutput))
+ {
+ return (KSTSErrShortBuffer);
+ }
+
+ // encryption/decryption successfully completed
+ aJni->SetByteArrayRegion(aOutput, aOutputOffset, output_length,
+ (signed char *) outputBuf);
+
+ }
+
+ LOG(ESATSA, EInfo, "STSRSACipher::Update--");
+ return output_length;
+
+}
+
+} // namespace satsa
+} // namespace java
+
+