diff -r f5050f1da672 -r 04becd199f91 javaextensions/satsa/crypto/src/stsrsasignature.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/satsa/crypto/src/stsrsasignature.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,285 @@ +/* +* 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 STSRSASIgnature + * +*/ + + + +#include +#include +#include +#include +#include "stsconstants.h" +#include "stsrsasignature.h" + +#include "javajniutils.h" +#include "logger.h" + +namespace java +{ +namespace satsa +{ + +STSRSASignature::STSRSASignature() +{ + mRSAKey = NULL; + mHashID = NULL; + mRSA = NULL; + mpkey = NULL; +} + + + +int STSRSASignature::Construct(const std::wstring aPadding) +{ + LOG(ESATSA, EInfo, "STSRSASignature::Construct+"); + + if (aPadding == STSDigestSHA1) + { + md = EVP_sha1(); + } + else if (aPadding == STSDigestMD2) + { + md = EVP_md2(); + } + else if (aPadding == STSDigestMD5) + { + md = EVP_md5(); + } + else + { + return KSTSErrArgument; + } + + if (md == NULL) + { + // Algorithm was not found + return KSTSErrDigest; + } + else + { + + mdctx = new EVP_MD_CTX; + if (mdctx != NULL) + { + EVP_MD_CTX_init(mdctx); + return 0; + } + else + { + return KSTSErrDigest; + } + } + +} + + + +STSRSASignature* STSRSASignature::Create(const std::wstring aPadding, + int* errCode) +{ + LOG(ESATSA, EInfo, "STSRSASignature::Create+"); + STSRSASignature* self = new STSRSASignature; + if (self == NULL) + { + // object was not created successfully + *errCode = KSTSErrNoMemory; + return NULL; + } + else + { + // Object created, call the second level constructor + *errCode = self->Construct(aPadding); + if (*errCode == 0) + { + return self; + } + else + { + delete self; + return NULL; + } + } +} + + +STSRSASignature::~STSRSASignature() +{ + if (mHashID != NULL) + delete mHashID; + + if (mRSAKey != NULL) + delete mRSAKey; + + if (mpkey != NULL) + EVP_PKEY_free(mpkey); + + if (mRSA != NULL) + mRSA = NULL; + +} + +int STSRSASignature::InitVerify(JNIEnv* aJni, jstring aKeyAlgorithm, + jstring aKeyFormat, jbyteArray aKeyEncoded) +{ + LOG(ESATSA, EInfo, "STSRSASignature::InitVerify+"); + int retVal = 0; + + // Check key validity + + // Key must be created for used algorithm + std::wstring key_algorithm; + try + { + key_algorithm = java::util::JniUtils::jstringToWstring(aJni, + aKeyAlgorithm); + } + catch (...) + { + ELOG(ESATSA, "InitVerify: caught exception. Return error code"); + return (KSTSErrInvalidKey); + } + ELOG(ESATSA, "STSRSASignature::InitVerify: Check Algorithm"); + if (key_algorithm != STSAlgorithmRSA) + { + return (KSTSErrInvalidKey); + } + // Format: Only X509 keys are supported + std::wstring key_format; + try + { + key_format = java::util::JniUtils::jstringToWstring(aJni, aKeyFormat); + } + catch (...) + { + ELOG(ESATSA, "InitVerify: caught exception. Return error code"); + return (KSTSErrInvalidKey); + } + + LOG(ESATSA, EInfo, "STSRSASignature::InitVerify: Check key format"); + if (key_format != STSKeyFormatX509) + { + return (KSTSErrInvalidKey); + } + + // Read the encoded key from the jbytearray + LOG(ESATSA, EInfo, "STSRSASignature::InitVerify:read the encoded key"); + int key_length = aJni->GetArrayLength(aKeyEncoded); + const unsigned char *key = new unsigned char[key_length]; + aJni->GetByteArrayRegion(aKeyEncoded, 0, key_length, (signed char*) key); + + // decode the encoded key data into a RSA data structure. + LOG(ESATSA, EInfo,"decode the encoded key data into a RSA data"); + mRSA = d2i_RSA_PUBKEY(&mRSA, &key, (long) key_length); + if (mRSA == NULL) + { + return KSTSErrInvalidKey; + } + + LOG(ESATSA, EInfo, "STSRSASignature::InitVerify: get mpkey"); + mpkey = EVP_PKEY_new(); + EVP_PKEY_set1_RSA(mpkey, mRSA); + + LOG(ESATSA, EInfo, "STSRSASignature::InitVerify: verify init call"); + retVal = EVP_VerifyInit_ex(mdctx, md, NULL); + + LOG(ESATSA, EInfo, "STSRSASignature::InitVerify---"); + return retVal; + +} + +int STSRSASignature::Verify(JNIEnv* aJni, jbyteArray aSignature) +{ + LOG(ESATSA, EInfo, "STSRSASignature::Verify++"); + int result; + + if (mpkey == NULL) + { + ELOG(ESATSA, "STSRSASignature::Verify: mpkey is null"); + // Not initialized + return (KSTSErrSignature); + } + else if (!mIsUpdated) + { + LOG(ESATSA, EInfo, "STSRSASignature::Verify: Not updated"); + return false; + } + else if (mdctx == NULL) + { + // If data is not updated TCK requires that exception is not thrown and + // false is returned. + ELOG(ESATSA, "STSRSASignature::Verify: mdctx is null"); + return false; + } + + // Read the signature data from the jbytearray + int siglen = aJni->GetArrayLength(aSignature); + const unsigned char *sigbuf = new unsigned char[siglen]; + aJni->GetByteArrayRegion(aSignature, 0, siglen, (signed char*) sigbuf); + + result = EVP_VerifyFinal(mdctx, sigbuf, siglen, mpkey); + mIsUpdated = false; + + // reset the digest + LOG(ESATSA, EInfo, "STSRSASignature::Verify: reset the digest"); + const EVP_MD* md = NULL; + md = EVP_MD_CTX_md(mdctx); + EVP_MD_CTX_init(mdctx); + EVP_DigestInit_ex(mdctx, md, NULL); + + LOG(ESATSA, EInfo, "Verify: check result and return proper value"); + if (0 == result) + { + return false; + } + else if (1 == result) + { + return true; + } + else + { + return KSTSErrSignature; + } +} + +int STSRSASignature::Update(JNIEnv* aJni, jbyteArray aData, jint aOffset, + jint aLength) +{ + LOG(ESATSA, EInfo, "STSRSASignature::Update++"); + if (mpkey == NULL) + { + ELOG(ESATSA, "STSRSASignature::Update: mpkey is null"); + // Not initialized + return KSTSErrSignature; + } + + // Read the signature data from the jbytearray + const unsigned char *data = new unsigned char[aLength]; + aJni->GetByteArrayRegion(aData, aOffset, aLength, (signed char*) data); + + int result = EVP_VerifyUpdate(mdctx, (const void *) data, + (unsigned int) aLength); + + if (!mIsUpdated) + { + mIsUpdated = true; + } + LOG(ESATSA, EInfo, "STSRSASignature::Update: return result"); + return result; +} + +} // namespace satsa +} // namespace java +