javaextensions/satsa/crypto/src/stsrsacipher.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of STSRSACipher
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "stsrsacipher.h"
       
    21 #include "stsconstants.h"
       
    22 #include  <asymmetric.h>
       
    23 
       
    24 #include <x509cert.h>
       
    25 #include <hash.h>
       
    26 #include <asymmetrickeys.h>
       
    27 #include <asymmetric.h>
       
    28 #include <asnpkcs.h>
       
    29 #include <asn1dec.h>
       
    30 #include "logger.h"
       
    31 
       
    32 namespace java
       
    33 {
       
    34 namespace satsa
       
    35 {
       
    36 
       
    37 
       
    38 STSRSACipher::STSRSACipher()
       
    39 {
       
    40     mRSA = NULL;
       
    41     mpkey = NULL;
       
    42 }
       
    43 
       
    44 STSRSACipher* STSRSACipher::Create(int* errCode)
       
    45 {
       
    46     STSRSACipher* self = new STSRSACipher;
       
    47     if (self == NULL)
       
    48     {
       
    49         *errCode = KSTSErrNoMemory;
       
    50         return NULL;
       
    51     }
       
    52     else
       
    53     {
       
    54         *errCode = 0;
       
    55         return self;
       
    56     }
       
    57 
       
    58 }
       
    59 
       
    60 
       
    61 STSRSACipher::~STSRSACipher()
       
    62 {
       
    63 
       
    64 }
       
    65 
       
    66 jint STSRSACipher::DoInit(JNIEnv* aJni, const TCipherMode aMode,
       
    67                           const jstring /*aKeyAlgorithm*/, const jstring /*aKeyFormat*/,
       
    68                           const jbyteArray aKeyEncoded, const jbyteArray aParams)
       
    69 {
       
    70     LOG(ESATSA, EInfo, "STSRSACipher::DoInit+");
       
    71     if (aParams)
       
    72     {
       
    73         ELOG(ESATSA, "STSRSACipher::DoInit:RSA algorithm cannot have parameters");
       
    74         // RSA algorithm cannot have parameters
       
    75         return KSTSErrArgument;
       
    76     }
       
    77 
       
    78     // Read the encoded key from the jbytearray
       
    79     int key_length = aJni->GetArrayLength(aKeyEncoded);
       
    80     const unsigned char *key = new unsigned char[key_length];
       
    81     aJni->GetByteArrayRegion(aKeyEncoded, 0, key_length, (signed char*) key);
       
    82 
       
    83     if (aMode == EEncryptMode)
       
    84     {
       
    85         LOG(ESATSA, EInfo, "STSRSACipher::DoInit:encryption mode");
       
    86         // encryption mode: read the public key from subject public key info
       
    87 
       
    88         // decode the encoded key data into a RSA data structure.
       
    89         mRSA = d2i_RSA_PUBKEY(&mRSA, &key, (long) key_length);
       
    90         if (mRSA == NULL)
       
    91         {
       
    92             ELOG(ESATSA, "STSRSACipher::DoInit:Failed to get proper data");
       
    93             return KSTSErrInvalidKey;
       
    94         }
       
    95 
       
    96     }
       
    97     else
       
    98     {
       
    99         LOG(ESATSA, EInfo, "STSRSACipher::DoInit:decryption mode");
       
   100         // decryption mode: decode the private key in PKCS8 format encoded in
       
   101         // ASN1 DER format
       
   102         // load the algorithm lookup tables
       
   103         OpenSSL_add_all_algorithms();
       
   104 
       
   105         // create the BIO pointer
       
   106         BIO *bp;
       
   107         bp = BIO_new_mem_buf((void *) key, key_length);
       
   108 
       
   109         // Decode the PKCS8 key from the der encoded key data
       
   110         mpkey = EVP_PKEY_new();
       
   111         if (NULL == mpkey)
       
   112         {
       
   113             ELOG(ESATSA, "STSRSACipher::DoInit:Key is null");
       
   114             return KSTSErrNoMemory;
       
   115         }
       
   116         mpkey = d2i_PKCS8PrivateKey_bio(bp, &mpkey, NULL, NULL);
       
   117         if (mpkey == NULL)
       
   118         {
       
   119             ELOG(ESATSA, "STSRSACipher::DoInit:key is improper");
       
   120             return KSTSErrInvalidKey;
       
   121         }
       
   122 
       
   123         // Create the RSA data structure to be used for decryption
       
   124         mRSA = EVP_PKEY_get1_RSA(mpkey);
       
   125         if (mRSA == NULL)
       
   126         {
       
   127             ELOG(ESATSA, "STSRSACipher::DoInit:failed to create rsa data");
       
   128             return KSTSErrInvalidKey;
       
   129         }
       
   130 
       
   131     }
       
   132     // Init success and mode can be changed
       
   133     mMode = aMode;
       
   134     LOG(ESATSA, EInfo, "STSRSACipher::DoInit--");
       
   135     return 0;
       
   136 
       
   137 }
       
   138 
       
   139 jint STSRSACipher::DoFinal(JNIEnv* aJni, jbyteArray aInput, jint aInputOffset,
       
   140                            jint aInputLength, jbyteArray aOutput, jint aOutputOffset)
       
   141 {
       
   142     LOG(ESATSA, EInfo, "STSRSACipher::DoFinal+");
       
   143     int output_length = 0;
       
   144     if (mRSA == NULL)
       
   145     {
       
   146         // Init was not called successfully.
       
   147         ELOG(ESATSA, "STSRSACipher::DoFinal:Init was not called successfully.");
       
   148         return (KSTSErrIllegalState);
       
   149     }
       
   150 
       
   151     //read the input data to be encrypted/decrypted
       
   152     unsigned char* inputBuf = new unsigned char[aInputLength];
       
   153     aJni->GetByteArrayRegion(aInput, aInputOffset, aInputLength,
       
   154                              (signed char *) inputBuf);
       
   155 
       
   156     int max_output_length = RSA_size(mRSA);
       
   157     unsigned char* outputBuf = new unsigned char[max_output_length];
       
   158 
       
   159     if (mMode == EEncryptMode)
       
   160     {
       
   161         if (aInputLength > (max_output_length - 11))
       
   162         {
       
   163             ELOG(ESATSA, "STSRSACipher::DoFinal:Wrong Input length");
       
   164             return (KSTSErrIllegalState);
       
   165         }
       
   166 
       
   167         // encrypt the data
       
   168         output_length = RSA_public_encrypt(aInputLength, inputBuf, outputBuf,
       
   169                                            mRSA, RSA_PKCS1_PADDING);
       
   170 
       
   171         if (output_length > aJni->GetArrayLength(aOutput))
       
   172         {
       
   173             ELOG(ESATSA, "STSRSACipher::DoFinal:short output buffer");
       
   174             return (KSTSErrShortBuffer);
       
   175         }
       
   176 
       
   177         aJni->SetByteArrayRegion(aOutput, aOutputOffset, output_length,
       
   178                                  (signed char *) outputBuf);
       
   179 
       
   180     }
       
   181     else // Decrypt mode
       
   182     {
       
   183         // decrypt the data
       
   184         output_length = RSA_private_decrypt(aInputLength, inputBuf, outputBuf,
       
   185                                             mRSA, RSA_PKCS1_PADDING);
       
   186 
       
   187         if (output_length > aJni->GetArrayLength(aOutput))
       
   188         {
       
   189             ELOG(ESATSA, "STSRSACipher::DoFinal:wrong output length");
       
   190             return (KSTSErrShortBuffer);
       
   191         }
       
   192 
       
   193         // encryption/decryption successfully completed
       
   194         aJni->SetByteArrayRegion(aOutput, aOutputOffset, output_length,
       
   195                                  (signed char *) outputBuf);
       
   196 
       
   197     }
       
   198     LOG(ESATSA, EInfo, "STSRSACipher::DoFinal:--");
       
   199     return output_length;
       
   200 
       
   201 }
       
   202 
       
   203 jint STSRSACipher::Update(JNIEnv* aJni, jbyteArray aInput, jint aInputOffset,
       
   204                           jint aInputLength, jbyteArray aOutput, jint aOutputOffset)
       
   205 {
       
   206     LOG(ESATSA, EInfo, "STSRSACipher::Update+");
       
   207     int output_length = 0;
       
   208     if (mRSA == NULL)
       
   209     {
       
   210         ELOG(ESATSA, "STSRSACipher::Update:Init was not called successfully.");
       
   211         // Init was not called successfully.
       
   212         return (KSTSErrIllegalState);
       
   213     }
       
   214 
       
   215     // read the input data to be encrypted/decrypted
       
   216     unsigned char* inputBuf = new unsigned char[aInputLength];
       
   217     aJni->GetByteArrayRegion(aInput, aInputOffset, aInputLength,
       
   218                              (signed char *) inputBuf);
       
   219 
       
   220     int max_output_length = RSA_size(mRSA);
       
   221     unsigned char* outputBuf = new unsigned char[max_output_length];
       
   222 
       
   223     if (mMode == EEncryptMode)
       
   224     {
       
   225         if (aInputLength > (max_output_length - 11))
       
   226         {
       
   227             ELOG(ESATSA, "STSRSACipher::Update:wrong input length.");
       
   228             return (KSTSErrIllegalStateInput);
       
   229         }
       
   230 
       
   231         // encrypt the data
       
   232         output_length = RSA_public_encrypt(aInputLength, inputBuf, outputBuf,
       
   233                                            mRSA, RSA_PKCS1_PADDING);
       
   234 
       
   235         if (output_length > aJni->GetArrayLength(aOutput))
       
   236         {
       
   237             ELOG(ESATSA, "STSRSACipher::Update:wrong output length");
       
   238             return (KSTSErrShortBuffer);
       
   239         }
       
   240 
       
   241         aJni->SetByteArrayRegion(aOutput, aOutputOffset, output_length,
       
   242                                  (signed char *) outputBuf);
       
   243 
       
   244     }
       
   245     else // Decrypt mode
       
   246     {
       
   247         // decrypt the data
       
   248         output_length = RSA_private_decrypt(aInputLength, inputBuf, outputBuf,
       
   249                                             mRSA, RSA_PKCS1_PADDING);
       
   250 
       
   251         if (output_length > aJni->GetArrayLength(aOutput))
       
   252         {
       
   253             return (KSTSErrShortBuffer);
       
   254         }
       
   255 
       
   256         // encryption/decryption successfully completed
       
   257         aJni->SetByteArrayRegion(aOutput, aOutputOffset, output_length,
       
   258                                  (signed char *) outputBuf);
       
   259 
       
   260     }
       
   261 
       
   262     LOG(ESATSA, EInfo, "STSRSACipher::Update--");
       
   263     return output_length;
       
   264 
       
   265 }
       
   266 
       
   267 } // namespace satsa
       
   268 } // namespace java
       
   269 
       
   270