jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_keymgmt.c
changeset 43248 5e15de85a1a0
parent 43247 8d242299a219
child 43249 b017b10f62ab
equal deleted inserted replaced
43247:8d242299a219 43248:5e15de85a1a0
     1 /*
       
     2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  */
       
     4 
       
     5 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
       
     6  *
       
     7  * Redistribution and use in  source and binary forms, with or without
       
     8  * modification, are permitted  provided that the following conditions are met:
       
     9  *
       
    10  * 1. Redistributions of  source code must retain the above copyright notice,
       
    11  *    this list of conditions and the following disclaimer.
       
    12  *
       
    13  * 2. Redistributions in  binary form must reproduce the above copyright notice,
       
    14  *    this list of conditions and the following disclaimer in the documentation
       
    15  *    and/or other materials provided with the distribution.
       
    16  *
       
    17  * 3. The end-user documentation included with the redistribution, if any, must
       
    18  *    include the following acknowledgment:
       
    19  *
       
    20  *    "This product includes software developed by IAIK of Graz University of
       
    21  *     Technology."
       
    22  *
       
    23  *    Alternately, this acknowledgment may appear in the software itself, if
       
    24  *    and wherever such third-party acknowledgments normally appear.
       
    25  *
       
    26  * 4. The names "Graz University of Technology" and "IAIK of Graz University of
       
    27  *    Technology" must not be used to endorse or promote products derived from
       
    28  *    this software without prior written permission.
       
    29  *
       
    30  * 5. Products derived from this software may not be called
       
    31  *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
       
    32  *    written permission of Graz University of Technology.
       
    33  *
       
    34  *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
       
    35  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    36  *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    37  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
       
    38  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
       
    39  *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    40  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
       
    41  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
       
    42  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
       
    43  *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    44  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
       
    45  *  POSSIBILITY  OF SUCH DAMAGE.
       
    46  */
       
    47 
       
    48 #include "pkcs11wrapper.h"
       
    49 
       
    50 #include <stdio.h>
       
    51 #include <stdlib.h>
       
    52 #include <string.h>
       
    53 #include <assert.h>
       
    54 
       
    55 #include "sun_security_pkcs11_wrapper_PKCS11.h"
       
    56 
       
    57 #ifdef P11_ENABLE_C_GENERATEKEY
       
    58 /*
       
    59  * Class:     sun_security_pkcs11_wrapper_PKCS11
       
    60  * Method:    C_GenerateKey
       
    61  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
       
    62  * Parametermapping:                    *PKCS11*
       
    63  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
       
    64  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
       
    65  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
       
    66  *                                      CK_ULONG ulCount
       
    67  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
       
    68  */
       
    69 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKey
       
    70     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jobjectArray jTemplate)
       
    71 {
       
    72     CK_SESSION_HANDLE ckSessionHandle;
       
    73     CK_MECHANISM ckMechanism;
       
    74     CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
       
    75     CK_ULONG ckAttributesLength;
       
    76     CK_OBJECT_HANDLE ckKeyHandle = 0;
       
    77     jlong jKeyHandle = 0L;
       
    78     CK_RV rv;
       
    79 
       
    80     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
       
    81     if (ckpFunctions == NULL) { return 0L; }
       
    82 
       
    83     ckSessionHandle = jLongToCKULong(jSessionHandle);
       
    84     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
       
    85     if ((*env)->ExceptionCheck(env)) { return 0L ; }
       
    86 
       
    87     jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
       
    88     if ((*env)->ExceptionCheck(env)) {
       
    89         if (ckMechanism.pParameter != NULL_PTR) {
       
    90             free(ckMechanism.pParameter);
       
    91         }
       
    92         return 0L;
       
    93     }
       
    94 
       
    95     rv = (*ckpFunctions->C_GenerateKey)(ckSessionHandle, &ckMechanism, ckpAttributes, ckAttributesLength, &ckKeyHandle);
       
    96 
       
    97     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
       
    98         jKeyHandle = ckULongToJLong(ckKeyHandle);
       
    99 
       
   100         /* cheack, if we must give a initialization vector back to Java */
       
   101         switch (ckMechanism.mechanism) {
       
   102         case CKM_PBE_MD2_DES_CBC:
       
   103         case CKM_PBE_MD5_DES_CBC:
       
   104         case CKM_PBE_MD5_CAST_CBC:
       
   105         case CKM_PBE_MD5_CAST3_CBC:
       
   106         case CKM_PBE_MD5_CAST128_CBC:
       
   107         /* case CKM_PBE_MD5_CAST5_CBC:  the same as CKM_PBE_MD5_CAST128_CBC */
       
   108         case CKM_PBE_SHA1_CAST128_CBC:
       
   109         /* case CKM_PBE_SHA1_CAST5_CBC: the same as CKM_PBE_SHA1_CAST128_CBC */
       
   110             /* we must copy back the initialization vector to the jMechanism object */
       
   111             copyBackPBEInitializationVector(env, &ckMechanism, jMechanism);
       
   112             break;
       
   113         }
       
   114     }
       
   115 
       
   116     if (ckMechanism.pParameter != NULL_PTR) {
       
   117         free(ckMechanism.pParameter);
       
   118     }
       
   119     freeCKAttributeArray(ckpAttributes, ckAttributesLength);
       
   120 
       
   121     return jKeyHandle ;
       
   122 }
       
   123 #endif
       
   124 
       
   125 #ifdef P11_ENABLE_C_GENERATEKEYPAIR
       
   126 /*
       
   127  * Class:     sun_security_pkcs11_wrapper_PKCS11
       
   128  * Method:    C_GenerateKeyPair
       
   129  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[J
       
   130  * Parametermapping:                          *PKCS11*
       
   131  * @param   jlong jSessionHandle              CK_SESSION_HANDLE hSession
       
   132  * @param   jobject jMechanism                CK_MECHANISM_PTR pMechanism
       
   133  * @param   jobjectArray jPublicKeyTemplate   CK_ATTRIBUTE_PTR pPublicKeyTemplate
       
   134  *                                            CK_ULONG ulPublicKeyAttributeCount
       
   135  * @param   jobjectArray jPrivateKeyTemplate  CK_ATTRIBUTE_PTR pPrivateKeyTemplate
       
   136  *                                            CK_ULONG ulPrivateKeyAttributeCount
       
   137  * @return  jlongArray jKeyHandles            CK_OBJECT_HANDLE_PTR phPublicKey
       
   138  *                                            CK_OBJECT_HANDLE_PTR phPublicKey
       
   139  */
       
   140 JNIEXPORT jlongArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GenerateKeyPair
       
   141     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism,
       
   142      jobjectArray jPublicKeyTemplate, jobjectArray jPrivateKeyTemplate)
       
   143 {
       
   144     CK_SESSION_HANDLE ckSessionHandle;
       
   145     CK_MECHANISM ckMechanism;
       
   146     CK_ATTRIBUTE_PTR ckpPublicKeyAttributes = NULL_PTR;
       
   147     CK_ATTRIBUTE_PTR ckpPrivateKeyAttributes = NULL_PTR;
       
   148     CK_ULONG ckPublicKeyAttributesLength;
       
   149     CK_ULONG ckPrivateKeyAttributesLength;
       
   150     CK_OBJECT_HANDLE_PTR ckpPublicKeyHandle;  /* pointer to Public Key */
       
   151     CK_OBJECT_HANDLE_PTR ckpPrivateKeyHandle; /* pointer to Private Key */
       
   152     CK_OBJECT_HANDLE_PTR ckpKeyHandles;     /* pointer to array with Public and Private Key */
       
   153     jlongArray jKeyHandles = NULL;
       
   154     CK_RV rv;
       
   155     int attempts;
       
   156     const int MAX_ATTEMPTS = 3;
       
   157 
       
   158     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
       
   159     if (ckpFunctions == NULL) { return NULL; }
       
   160 
       
   161     ckSessionHandle = jLongToCKULong(jSessionHandle);
       
   162     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
       
   163     if ((*env)->ExceptionCheck(env)) { return NULL; }
       
   164 
       
   165     ckpKeyHandles = (CK_OBJECT_HANDLE_PTR) malloc(2 * sizeof(CK_OBJECT_HANDLE));
       
   166     if (ckpKeyHandles == NULL) {
       
   167         if (ckMechanism.pParameter != NULL_PTR) {
       
   168             free(ckMechanism.pParameter);
       
   169         }
       
   170         throwOutOfMemoryError(env, 0);
       
   171         return NULL;
       
   172     }
       
   173     ckpPublicKeyHandle = ckpKeyHandles;   /* first element of array is Public Key */
       
   174     ckpPrivateKeyHandle = (ckpKeyHandles + 1);  /* second element of array is Private Key */
       
   175 
       
   176     jAttributeArrayToCKAttributeArray(env, jPublicKeyTemplate, &ckpPublicKeyAttributes, &ckPublicKeyAttributesLength);
       
   177     if ((*env)->ExceptionCheck(env)) {
       
   178         if (ckMechanism.pParameter != NULL_PTR) {
       
   179             free(ckMechanism.pParameter);
       
   180         }
       
   181         free(ckpKeyHandles);
       
   182         return NULL;
       
   183     }
       
   184 
       
   185     jAttributeArrayToCKAttributeArray(env, jPrivateKeyTemplate, &ckpPrivateKeyAttributes, &ckPrivateKeyAttributesLength);
       
   186     if ((*env)->ExceptionCheck(env)) {
       
   187         if (ckMechanism.pParameter != NULL_PTR) {
       
   188             free(ckMechanism.pParameter);
       
   189         }
       
   190         free(ckpKeyHandles);
       
   191         freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
       
   192         return NULL;
       
   193     }
       
   194 
       
   195     /*
       
   196      * Workaround for NSS bug 1012786:
       
   197      *
       
   198      * Key generation may fail with CKR_FUNCTION_FAILED error
       
   199      * if there is insufficient entropy to generate a random key.
       
   200      *
       
   201      * PKCS11 spec says the following about CKR_FUNCTION_FAILED error
       
   202      * (see section 11.1.1):
       
   203      *
       
   204      *      ... In any event, although the function call failed, the situation
       
   205      *      is not necessarily totally hopeless, as it is likely to be
       
   206      *      when CKR_GENERAL_ERROR is returned. Depending on what the root cause of
       
   207      *      the error actually was, it is possible that an attempt
       
   208      *      to make the exact same function call again would succeed.
       
   209      *
       
   210      * Call C_GenerateKeyPair() several times if CKR_FUNCTION_FAILED occurs.
       
   211      */
       
   212     for (attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {
       
   213         rv = (*ckpFunctions->C_GenerateKeyPair)(ckSessionHandle, &ckMechanism,
       
   214                         ckpPublicKeyAttributes, ckPublicKeyAttributesLength,
       
   215                         ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength,
       
   216                         ckpPublicKeyHandle, ckpPrivateKeyHandle);
       
   217         if (rv == CKR_FUNCTION_FAILED) {
       
   218             printDebug("C_1GenerateKeyPair(): C_GenerateKeyPair() failed \
       
   219                     with CKR_FUNCTION_FAILED error, try again\n");
       
   220         } else {
       
   221             break;
       
   222         }
       
   223     }
       
   224 
       
   225     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
       
   226         jKeyHandles = ckULongArrayToJLongArray(env, ckpKeyHandles, 2);
       
   227     }
       
   228 
       
   229     if(ckMechanism.pParameter != NULL_PTR) {
       
   230         free(ckMechanism.pParameter);
       
   231     }
       
   232     free(ckpKeyHandles);
       
   233     freeCKAttributeArray(ckpPublicKeyAttributes, ckPublicKeyAttributesLength);
       
   234     freeCKAttributeArray(ckpPrivateKeyAttributes, ckPrivateKeyAttributesLength);
       
   235 
       
   236     return jKeyHandles ;
       
   237 }
       
   238 #endif
       
   239 
       
   240 #ifdef P11_ENABLE_C_WRAPKEY
       
   241 /*
       
   242  * Class:     sun_security_pkcs11_wrapper_PKCS11
       
   243  * Method:    C_WrapKey
       
   244  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;JJ)[B
       
   245  * Parametermapping:                    *PKCS11*
       
   246  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
       
   247  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
       
   248  * @param   jlong jWrappingKeyHandle    CK_OBJECT_HANDLE hWrappingKey
       
   249  * @param   jlong jKeyHandle            CK_OBJECT_HANDLE hKey
       
   250  * @return  jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
       
   251  *                                      CK_ULONG_PTR pulWrappedKeyLen
       
   252  */
       
   253 JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1WrapKey
       
   254     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jWrappingKeyHandle, jlong jKeyHandle)
       
   255 {
       
   256     CK_SESSION_HANDLE ckSessionHandle;
       
   257     CK_MECHANISM ckMechanism;
       
   258     CK_OBJECT_HANDLE ckWrappingKeyHandle;
       
   259     CK_OBJECT_HANDLE ckKeyHandle;
       
   260     jbyteArray jWrappedKey = NULL;
       
   261     CK_RV rv;
       
   262     CK_BYTE BUF[MAX_STACK_BUFFER_LEN];
       
   263     CK_BYTE_PTR ckpWrappedKey = BUF;
       
   264     CK_ULONG ckWrappedKeyLength = MAX_STACK_BUFFER_LEN;
       
   265 
       
   266     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
       
   267     if (ckpFunctions == NULL) { return NULL; }
       
   268 
       
   269     ckSessionHandle = jLongToCKULong(jSessionHandle);
       
   270     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
       
   271     if ((*env)->ExceptionCheck(env)) { return NULL; }
       
   272 
       
   273     ckWrappingKeyHandle = jLongToCKULong(jWrappingKeyHandle);
       
   274     ckKeyHandle = jLongToCKULong(jKeyHandle);
       
   275 
       
   276     rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
       
   277     if (rv == CKR_BUFFER_TOO_SMALL) {
       
   278         ckpWrappedKey = (CK_BYTE_PTR) malloc(ckWrappedKeyLength);
       
   279         if (ckpWrappedKey == NULL) {
       
   280             if (ckMechanism.pParameter != NULL_PTR) {
       
   281                 free(ckMechanism.pParameter);
       
   282             }
       
   283             throwOutOfMemoryError(env, 0);
       
   284             return NULL;
       
   285         }
       
   286 
       
   287         rv = (*ckpFunctions->C_WrapKey)(ckSessionHandle, &ckMechanism, ckWrappingKeyHandle, ckKeyHandle, ckpWrappedKey, &ckWrappedKeyLength);
       
   288     }
       
   289     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
       
   290         jWrappedKey = ckByteArrayToJByteArray(env, ckpWrappedKey, ckWrappedKeyLength);
       
   291     }
       
   292 
       
   293     if (ckpWrappedKey != BUF) { free(ckpWrappedKey); }
       
   294     if (ckMechanism.pParameter != NULL_PTR) {
       
   295         free(ckMechanism.pParameter);
       
   296     }
       
   297     return jWrappedKey ;
       
   298 }
       
   299 #endif
       
   300 
       
   301 #ifdef P11_ENABLE_C_UNWRAPKEY
       
   302 /*
       
   303  * Class:     sun_security_pkcs11_wrapper_PKCS11
       
   304  * Method:    C_UnwrapKey
       
   305  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[B[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
       
   306  * Parametermapping:                    *PKCS11*
       
   307  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
       
   308  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
       
   309  * @param   jlong jUnwrappingKeyHandle  CK_OBJECT_HANDLE hUnwrappingKey
       
   310  * @param   jbyteArray jWrappedKey      CK_BYTE_PTR pWrappedKey
       
   311  *                                      CK_ULONG_PTR pulWrappedKeyLen
       
   312  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
       
   313  *                                      CK_ULONG ulCount
       
   314  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
       
   315  */
       
   316 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1UnwrapKey
       
   317     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jUnwrappingKeyHandle,
       
   318      jbyteArray jWrappedKey, jobjectArray jTemplate)
       
   319 {
       
   320     CK_SESSION_HANDLE ckSessionHandle;
       
   321     CK_MECHANISM ckMechanism;
       
   322     CK_OBJECT_HANDLE ckUnwrappingKeyHandle;
       
   323     CK_BYTE_PTR ckpWrappedKey = NULL_PTR;
       
   324     CK_ULONG ckWrappedKeyLength;
       
   325     CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
       
   326     CK_ULONG ckAttributesLength;
       
   327     CK_OBJECT_HANDLE ckKeyHandle = 0;
       
   328     jlong jKeyHandle = 0L;
       
   329     CK_RV rv;
       
   330 
       
   331     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
       
   332     if (ckpFunctions == NULL) { return 0L; }
       
   333 
       
   334     ckSessionHandle = jLongToCKULong(jSessionHandle);
       
   335     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
       
   336     if ((*env)->ExceptionCheck(env)) { return 0L; }
       
   337 
       
   338     ckUnwrappingKeyHandle = jLongToCKULong(jUnwrappingKeyHandle);
       
   339     jByteArrayToCKByteArray(env, jWrappedKey, &ckpWrappedKey, &ckWrappedKeyLength);
       
   340     if ((*env)->ExceptionCheck(env)) {
       
   341         if (ckMechanism.pParameter != NULL_PTR) {
       
   342             free(ckMechanism.pParameter);
       
   343         }
       
   344         return 0L;
       
   345     }
       
   346 
       
   347     jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
       
   348     if ((*env)->ExceptionCheck(env)) {
       
   349         if (ckMechanism.pParameter != NULL_PTR) {
       
   350             free(ckMechanism.pParameter);
       
   351         }
       
   352         free(ckpWrappedKey);
       
   353         return 0L;
       
   354     }
       
   355 
       
   356 
       
   357     rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism, ckUnwrappingKeyHandle,
       
   358                  ckpWrappedKey, ckWrappedKeyLength,
       
   359                  ckpAttributes, ckAttributesLength, &ckKeyHandle);
       
   360 
       
   361     if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
       
   362         jKeyHandle = ckLongToJLong(ckKeyHandle);
       
   363 
       
   364 #if 0
       
   365         /* cheack, if we must give a initialization vector back to Java */
       
   366         if (ckMechanism.mechanism == CKM_KEY_WRAP_SET_OAEP) {
       
   367             /* we must copy back the unwrapped key info to the jMechanism object */
       
   368             copyBackSetUnwrappedKey(env, &ckMechanism, jMechanism);
       
   369         }
       
   370 #endif
       
   371     }
       
   372 
       
   373     if (ckMechanism.pParameter != NULL_PTR) {
       
   374         free(ckMechanism.pParameter);
       
   375     }
       
   376     freeCKAttributeArray(ckpAttributes, ckAttributesLength);
       
   377     free(ckpWrappedKey);
       
   378 
       
   379     return jKeyHandle ;
       
   380 }
       
   381 #endif
       
   382 
       
   383 #ifdef P11_ENABLE_C_DERIVEKEY
       
   384 
       
   385 void freeMasterKeyDeriveParams(CK_MECHANISM_PTR ckMechanism) {
       
   386     CK_SSL3_MASTER_KEY_DERIVE_PARAMS *params = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
       
   387     if (params == NULL) {
       
   388         return;
       
   389     }
       
   390 
       
   391     if (params->RandomInfo.pClientRandom != NULL) {
       
   392         free(params->RandomInfo.pClientRandom);
       
   393     }
       
   394     if (params->RandomInfo.pServerRandom != NULL) {
       
   395         free(params->RandomInfo.pServerRandom);
       
   396     }
       
   397     if (params->pVersion != NULL) {
       
   398         free(params->pVersion);
       
   399     }
       
   400 }
       
   401 
       
   402 void freeEcdh1DeriveParams(CK_MECHANISM_PTR ckMechanism) {
       
   403     CK_ECDH1_DERIVE_PARAMS *params = (CK_ECDH1_DERIVE_PARAMS *) ckMechanism->pParameter;
       
   404     if (params == NULL) {
       
   405         return;
       
   406     }
       
   407 
       
   408     if (params->pSharedData != NULL) {
       
   409         free(params->pSharedData);
       
   410     }
       
   411     if (params->pPublicData != NULL) {
       
   412         free(params->pPublicData);
       
   413     }
       
   414 }
       
   415 
       
   416 /*
       
   417  * Copy back the PRF output to Java.
       
   418  */
       
   419 void copyBackTLSPrfParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
       
   420 {
       
   421     jclass jMechanismClass, jTLSPrfParamsClass;
       
   422     CK_TLS_PRF_PARAMS *ckTLSPrfParams;
       
   423     jobject jTLSPrfParams;
       
   424     jfieldID fieldID;
       
   425     CK_MECHANISM_TYPE ckMechanismType;
       
   426     jlong jMechanismType;
       
   427     CK_BYTE_PTR output;
       
   428     jobject jOutput;
       
   429     jint jLength;
       
   430     jbyte* jBytes;
       
   431     int i;
       
   432 
       
   433     /* get mechanism */
       
   434     jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
       
   435     if (jMechanismClass == NULL) { return; }
       
   436     fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
       
   437     if (fieldID == NULL) { return; }
       
   438     jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
       
   439     ckMechanismType = jLongToCKULong(jMechanismType);
       
   440     if (ckMechanismType != ckMechanism->mechanism) {
       
   441         /* we do not have maching types, this should not occur */
       
   442         return;
       
   443     }
       
   444 
       
   445     /* get the native CK_TLS_PRF_PARAMS */
       
   446     ckTLSPrfParams = (CK_TLS_PRF_PARAMS *) ckMechanism->pParameter;
       
   447     if (ckTLSPrfParams != NULL_PTR) {
       
   448         /* get the Java CK_TLS_PRF_PARAMS object (pParameter) */
       
   449         fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
       
   450         if (fieldID == NULL) { return; }
       
   451         jTLSPrfParams = (*env)->GetObjectField(env, jMechanism, fieldID);
       
   452 
       
   453         /* copy back the client IV */
       
   454         jTLSPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS);
       
   455         if (jTLSPrfParamsClass == NULL) { return; }
       
   456         fieldID = (*env)->GetFieldID(env, jTLSPrfParamsClass, "pOutput", "[B");
       
   457         if (fieldID == NULL) { return; }
       
   458         jOutput = (*env)->GetObjectField(env, jTLSPrfParams, fieldID);
       
   459         output = ckTLSPrfParams->pOutput;
       
   460 
       
   461         // Note: we assume that the token returned exactly as many bytes as we
       
   462         // requested. Anything else would not make sense.
       
   463         if (jOutput != NULL) {
       
   464             jLength = (*env)->GetArrayLength(env, jOutput);
       
   465             jBytes = (*env)->GetByteArrayElements(env, jOutput, NULL);
       
   466             if (jBytes == NULL) { return; }
       
   467 
       
   468             /* copy the bytes to the Java buffer */
       
   469             for (i=0; i < jLength; i++) {
       
   470                 jBytes[i] = ckByteToJByte(output[i]);
       
   471             }
       
   472             /* copy back the Java buffer to the object */
       
   473             (*env)->ReleaseByteArrayElements(env, jOutput, jBytes, 0);
       
   474         }
       
   475 
       
   476         // free malloc'd data
       
   477         free(ckTLSPrfParams->pSeed);
       
   478         free(ckTLSPrfParams->pLabel);
       
   479         free(ckTLSPrfParams->pulOutputLen);
       
   480         free(ckTLSPrfParams->pOutput);
       
   481     }
       
   482 }
       
   483 
       
   484 /*
       
   485  * Class:     sun_security_pkcs11_wrapper_PKCS11
       
   486  * Method:    C_DeriveKey
       
   487  * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J
       
   488  * Parametermapping:                    *PKCS11*
       
   489  * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
       
   490  * @param   jobject jMechanism          CK_MECHANISM_PTR pMechanism
       
   491  * @param   jlong jBaseKeyHandle        CK_OBJECT_HANDLE hBaseKey
       
   492  * @param   jobjectArray jTemplate      CK_ATTRIBUTE_PTR pTemplate
       
   493  *                                      CK_ULONG ulCount
       
   494  * @return  jlong jKeyHandle            CK_OBJECT_HANDLE_PTR phKey
       
   495  */
       
   496 JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DeriveKey
       
   497     (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jBaseKeyHandle, jobjectArray jTemplate)
       
   498 {
       
   499     CK_SESSION_HANDLE ckSessionHandle;
       
   500     CK_MECHANISM ckMechanism;
       
   501     CK_OBJECT_HANDLE ckBaseKeyHandle;
       
   502     CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR;
       
   503     CK_ULONG ckAttributesLength;
       
   504     CK_OBJECT_HANDLE ckKeyHandle = 0;
       
   505     jlong jKeyHandle = 0L;
       
   506     CK_RV rv;
       
   507     CK_OBJECT_HANDLE_PTR phKey = &ckKeyHandle;
       
   508 
       
   509     CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
       
   510     if (ckpFunctions == NULL) { return 0L; }
       
   511 
       
   512     ckSessionHandle = jLongToCKULong(jSessionHandle);
       
   513     jMechanismToCKMechanism(env, jMechanism, &ckMechanism);
       
   514     if ((*env)->ExceptionCheck(env)) { return 0L; }
       
   515 
       
   516     ckBaseKeyHandle = jLongToCKULong(jBaseKeyHandle);
       
   517     jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength);
       
   518     if ((*env)->ExceptionCheck(env)) {
       
   519         if (ckMechanism.pParameter != NULL_PTR) {
       
   520             free(ckMechanism.pParameter);
       
   521         }
       
   522         return 0L;
       
   523     }
       
   524 
       
   525     switch (ckMechanism.mechanism) {
       
   526     case CKM_SSL3_KEY_AND_MAC_DERIVE:
       
   527     case CKM_TLS_KEY_AND_MAC_DERIVE:
       
   528     case CKM_TLS_PRF:
       
   529         // these mechanism do not return a key handle via phKey
       
   530         // set to NULL in case pedantic implementations check for it
       
   531         phKey = NULL;
       
   532         break;
       
   533     default:
       
   534         // empty
       
   535         break;
       
   536     }
       
   537 
       
   538     rv = (*ckpFunctions->C_DeriveKey)(ckSessionHandle, &ckMechanism, ckBaseKeyHandle,
       
   539                  ckpAttributes, ckAttributesLength, phKey);
       
   540 
       
   541     jKeyHandle = ckLongToJLong(ckKeyHandle);
       
   542 
       
   543     freeCKAttributeArray(ckpAttributes, ckAttributesLength);
       
   544 
       
   545     switch (ckMechanism.mechanism) {
       
   546     case CKM_SSL3_MASTER_KEY_DERIVE:
       
   547     case CKM_TLS_MASTER_KEY_DERIVE:
       
   548         /* we must copy back the client version */
       
   549         copyBackClientVersion(env, &ckMechanism, jMechanism);
       
   550         freeMasterKeyDeriveParams(&ckMechanism);
       
   551         break;
       
   552     case CKM_SSL3_MASTER_KEY_DERIVE_DH:
       
   553     case CKM_TLS_MASTER_KEY_DERIVE_DH:
       
   554         freeMasterKeyDeriveParams(&ckMechanism);
       
   555         break;
       
   556     case CKM_SSL3_KEY_AND_MAC_DERIVE:
       
   557     case CKM_TLS_KEY_AND_MAC_DERIVE:
       
   558         /* we must copy back the unwrapped key info to the jMechanism object */
       
   559         copyBackSSLKeyMatParams(env, &ckMechanism, jMechanism);
       
   560         break;
       
   561     case CKM_TLS_PRF:
       
   562         copyBackTLSPrfParams(env, &ckMechanism, jMechanism);
       
   563         break;
       
   564     case CKM_ECDH1_DERIVE:
       
   565         freeEcdh1DeriveParams(&ckMechanism);
       
   566         break;
       
   567     default:
       
   568         // empty
       
   569         break;
       
   570     }
       
   571 
       
   572     if (ckMechanism.pParameter != NULL_PTR) {
       
   573         free(ckMechanism.pParameter);
       
   574     }
       
   575     if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; }
       
   576 
       
   577     return jKeyHandle ;
       
   578 }
       
   579 
       
   580 /*
       
   581  * Copy back the client version information from the native
       
   582  * structure to the Java object. This is only used for the
       
   583  * CKM_SSL3_MASTER_KEY_DERIVE mechanism when used for deriving a key.
       
   584  *
       
   585  */
       
   586 void copyBackClientVersion(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
       
   587 {
       
   588   jclass jMechanismClass, jSSL3MasterKeyDeriveParamsClass, jVersionClass;
       
   589   CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ckSSL3MasterKeyDeriveParams;
       
   590   CK_VERSION *ckVersion;
       
   591   jfieldID fieldID;
       
   592   CK_MECHANISM_TYPE ckMechanismType;
       
   593   jlong jMechanismType;
       
   594   jobject jSSL3MasterKeyDeriveParams;
       
   595   jobject jVersion;
       
   596 
       
   597   /* get mechanism */
       
   598   jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM);
       
   599   if (jMechanismClass == NULL) { return; }
       
   600   fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
       
   601   if (fieldID == NULL) { return; }
       
   602   jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
       
   603   ckMechanismType = jLongToCKULong(jMechanismType);
       
   604   if (ckMechanismType != ckMechanism->mechanism) {
       
   605     /* we do not have maching types, this should not occur */
       
   606     return;
       
   607   }
       
   608 
       
   609   /* get the native CK_SSL3_MASTER_KEY_DERIVE_PARAMS */
       
   610   ckSSL3MasterKeyDeriveParams = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) ckMechanism->pParameter;
       
   611   if (ckSSL3MasterKeyDeriveParams != NULL_PTR) {
       
   612     /* get the native CK_VERSION */
       
   613     ckVersion = ckSSL3MasterKeyDeriveParams->pVersion;
       
   614     if (ckVersion != NULL_PTR) {
       
   615       /* get the Java CK_SSL3_MASTER_KEY_DERIVE_PARAMS (pParameter) */
       
   616       fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
       
   617       if (fieldID == NULL) { return; }
       
   618 
       
   619       jSSL3MasterKeyDeriveParams = (*env)->GetObjectField(env, jMechanism, fieldID);
       
   620 
       
   621       /* get the Java CK_VERSION */
       
   622       jSSL3MasterKeyDeriveParamsClass = (*env)->FindClass(env, CLASS_SSL3_MASTER_KEY_DERIVE_PARAMS);
       
   623       if (jSSL3MasterKeyDeriveParamsClass == NULL) { return; }
       
   624       fieldID = (*env)->GetFieldID(env, jSSL3MasterKeyDeriveParamsClass, "pVersion", "L"CLASS_VERSION";");
       
   625       if (fieldID == NULL) { return; }
       
   626       jVersion = (*env)->GetObjectField(env, jSSL3MasterKeyDeriveParams, fieldID);
       
   627 
       
   628       /* now copy back the version from the native structure to the Java structure */
       
   629 
       
   630       /* copy back the major version */
       
   631       jVersionClass = (*env)->FindClass(env, CLASS_VERSION);
       
   632       if (jVersionClass == NULL) { return; }
       
   633       fieldID = (*env)->GetFieldID(env, jVersionClass, "major", "B");
       
   634       if (fieldID == NULL) { return; }
       
   635       (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->major));
       
   636 
       
   637       /* copy back the minor version */
       
   638       fieldID = (*env)->GetFieldID(env, jVersionClass, "minor", "B");
       
   639       if (fieldID == NULL) { return; }
       
   640       (*env)->SetByteField(env, jVersion, fieldID, ckByteToJByte(ckVersion->minor));
       
   641     }
       
   642   }
       
   643 }
       
   644 
       
   645 
       
   646 /*
       
   647  * Copy back the derived keys and initialization vectors from the native
       
   648  * structure to the Java object. This is only used for the
       
   649  * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key.
       
   650  *
       
   651  */
       
   652 void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism)
       
   653 {
       
   654   jclass jMechanismClass, jSSL3KeyMatParamsClass, jSSL3KeyMatOutClass;
       
   655   CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam;
       
   656   CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut;
       
   657   jfieldID fieldID;
       
   658   CK_MECHANISM_TYPE ckMechanismType;
       
   659   jlong jMechanismType;
       
   660   CK_BYTE_PTR iv;
       
   661   jobject jSSL3KeyMatParam;
       
   662   jobject jSSL3KeyMatOut;
       
   663   jobject jIV;
       
   664   jint jLength;
       
   665   jbyte* jBytes;
       
   666   int i;
       
   667 
       
   668   /* get mechanism */
       
   669   jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM);
       
   670   if (jMechanismClass == NULL) { return; }
       
   671   fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J");
       
   672   if (fieldID == NULL) { return; }
       
   673   jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID);
       
   674   ckMechanismType = jLongToCKULong(jMechanismType);
       
   675   if (ckMechanismType != ckMechanism->mechanism) {
       
   676     /* we do not have maching types, this should not occur */
       
   677     return;
       
   678   }
       
   679 
       
   680   /* get the native CK_SSL3_KEY_MAT_PARAMS */
       
   681   ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter;
       
   682   if (ckSSL3KeyMatParam != NULL_PTR) {
       
   683     // free malloc'd data
       
   684     if (ckSSL3KeyMatParam->RandomInfo.pClientRandom != NULL) {
       
   685         free(ckSSL3KeyMatParam->RandomInfo.pClientRandom);
       
   686     }
       
   687     if (ckSSL3KeyMatParam->RandomInfo.pServerRandom != NULL) {
       
   688         free(ckSSL3KeyMatParam->RandomInfo.pServerRandom);
       
   689     }
       
   690 
       
   691     /* get the native CK_SSL3_KEY_MAT_OUT */
       
   692     ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial;
       
   693     if (ckSSL3KeyMatOut != NULL_PTR) {
       
   694       /* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */
       
   695       fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;");
       
   696       if (fieldID == NULL) { return; }
       
   697       jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID);
       
   698 
       
   699       /* get the Java CK_SSL3_KEY_MAT_OUT */
       
   700       jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS);
       
   701       if (jSSL3KeyMatParamsClass == NULL) { return; }
       
   702       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";");
       
   703       if (fieldID == NULL) { return; }
       
   704       jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID);
       
   705 
       
   706       /* now copy back all the key handles and the initialization vectors */
       
   707       /* copy back client MAC secret handle */
       
   708       jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT);
       
   709       if (jSSL3KeyMatOutClass == NULL) { return; }
       
   710       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J");
       
   711       if (fieldID == NULL) { return; }
       
   712       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret));
       
   713 
       
   714       /* copy back server MAC secret handle */
       
   715       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J");
       
   716       if (fieldID == NULL) { return; }
       
   717       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret));
       
   718 
       
   719       /* copy back client secret key handle */
       
   720       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J");
       
   721       if (fieldID == NULL) { return; }
       
   722       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey));
       
   723 
       
   724       /* copy back server secret key handle */
       
   725       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J");
       
   726       if (fieldID == NULL) { return; }
       
   727       (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey));
       
   728 
       
   729       /* copy back the client IV */
       
   730       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B");
       
   731       if (fieldID == NULL) { return; }
       
   732       jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
       
   733       iv = ckSSL3KeyMatOut->pIVClient;
       
   734 
       
   735       if (jIV != NULL) {
       
   736         jLength = (*env)->GetArrayLength(env, jIV);
       
   737         jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
       
   738         if (jBytes == NULL) { return; }
       
   739         /* copy the bytes to the Java buffer */
       
   740         for (i=0; i < jLength; i++) {
       
   741           jBytes[i] = ckByteToJByte(iv[i]);
       
   742         }
       
   743         /* copy back the Java buffer to the object */
       
   744         (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
       
   745       }
       
   746       // free malloc'd data
       
   747       free(ckSSL3KeyMatOut->pIVClient);
       
   748 
       
   749       /* copy back the server IV */
       
   750       fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B");
       
   751       if (fieldID == NULL) { return; }
       
   752       jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID);
       
   753       iv = ckSSL3KeyMatOut->pIVServer;
       
   754 
       
   755       if (jIV != NULL) {
       
   756         jLength = (*env)->GetArrayLength(env, jIV);
       
   757         jBytes = (*env)->GetByteArrayElements(env, jIV, NULL);
       
   758         if (jBytes == NULL) { return; }
       
   759         /* copy the bytes to the Java buffer */
       
   760         for (i=0; i < jLength; i++) {
       
   761           jBytes[i] = ckByteToJByte(iv[i]);
       
   762         }
       
   763         /* copy back the Java buffer to the object */
       
   764         (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0);
       
   765       }
       
   766       // free malloc'd data
       
   767       free(ckSSL3KeyMatOut->pIVServer);
       
   768       free(ckSSL3KeyMatOut);
       
   769     }
       
   770   }
       
   771 }
       
   772 
       
   773 #endif