Home >

SDK Reference Guide > Design Considerations > Migrating Keys From Software to a SafeNet HSM

Migrating Keys From Software to a SafeNet HSM

SafeNet HSMs expect key material to be in PKCS#8 format.  PKCS#8 format follows BER (Basic encoding rules)/DER (distinguished encoding rules) encoding.  An example of this format can be found in the document "Some examples of PKCS standards" produced by RSA, and available on their web site (http://www.rsasecurity.com/rsalabs/pkcs/index.html at the bottom of the page, under “Related Documents”).

Here is an example of a formatted key:

 0x30, 
 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 
 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 
 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 
 0x00, 0xb8, 0xb5, 0x0f, 0x49, 0x46, 0xb5, 0x5d, 0x58, 0x04, 0x8e, 0x52, 
 0x59, 0x39, 0xdf, 0xd6, 0x29, 0x45, 0x6b, 0x6c, 0x96, 0xbb, 0xab, 0xa5, 
 0x6f, 0x72, 0x1b, 0x16, 0x96, 0x74, 0xd5, 0xf9, 0xb4, 0x41, 0xa3, 0x7c, 
 0xe1, 0x94, 0x73, 0x4b, 0xa7, 0x23, 0xff, 0x61, 0xeb, 0xce, 0x5a, 0xe7, 
 0x7f, 0xe3, 0x74, 0xe8, 0x52, 0x5b, 0xd6, 0x5d, 0x5c, 0xdc, 0x98, 0x49, 
 0xfe, 0x51, 0xc2, 0x7e, 0x8f, 0x3b, 0x37, 0x5c, 0xb3, 0x11, 0xed, 0x85, 
 0x91, 0x15, 0x92, 0x24, 0xd8, 0xf1, 0x7b, 0x3d, 0x2f, 0x8b, 0xcd, 0x1b, 
 0x30, 0x14, 0xa3, 0x6b, 0x1b, 0x4d, 0x27, 0xff, 0x6a, 0x58, 0x84, 0x9e, 
 0x79, 0x94, 0xca, 0x78, 0x64, 0x01, 0x33, 0xc3, 0x58, 0xfc, 0xd3, 0x83, 
 0xeb, 0x2f, 0xab, 0x6f, 0x85, 0x5a, 0x38, 0x41, 0x3d, 0x73, 0x20, 0x1b, 
 0x82, 0xbc, 0x7e, 0x76, 0xde, 0x5c, 0xfe, 0x42, 0xd6, 0x7b, 0x86, 0x4f, 
 0x79, 0x78, 0x29, 0x82, 0x87, 0xa6, 0x24, 0x43, 0x39, 0x74, 0xfe, 0xf2, 
 0x0c, 0x08, 0xbe, 0xfa, 0x1e, 0x0a, 0x48, 0x6f, 0x14, 0x86, 0xc5, 0xcd, 
 0x9a, 0x98, 0x09, 0x2d, 0xf3, 0xf3, 0x5a, 0x7a, 0xa4, 0xe6, 0x8a, 0x2e, 
 0x49, 0x8a,  0xde, 
 0x73, 0xe9, 0x37, 0xa0, 0x5b, 0xef, 0xd0, 0xe0, 0x13, 0xac, 0x88, 0x5f, 
 0x59, 0x47, 0x96, 0x7f, 0x78, 0x18, 0x0e, 0x44, 0x6a, 0x5d,  0xec, 
 0x6e, 0xed, 0x4f, 0xf6, 0x6a, 0x7a, 0x58, 0x6b, 0xfe, 0x6c, 0x5a, 0xb9, 
 0xd2, 0x22, 0x3a, 0x1f, 0xdf, 0xc3, 0x09, 0x3f, 0x6b, 0x2e, 0xf1, 0x6d, 
 0xc3, 0xfb, 0x4e, 0xd4, 0xf2, 0xa3, 0x94, 0x13, 0xb0, 0xbf, 0x1e, 0x06, 
 0x2e, 0x29, 0x55, 0x00, 0xaa, 0x98, 0xd9, 0xe8, 0x77, 0x84, 0x8b, 0x3f, 
 0x5f, 0x5e, 0xf7, 0xf8, 0xa7, 0xe6, 0x02, 0xd2, 0x18, 0xb0, 0x52, 0xd0, 
 0x37, 0x2e, 0x53, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 
 0x0c, 0xdf, 0xd1, 0xe8, 0xf1, 0x9c, 0xc2, 0x9c, 0xd7, 0xf4, 0x73, 0x98, 
 0xf4, 0x87, 0xbd, 0x8d, 0xb2, 0xe1, 0x01, 0xf8, 0x9f, 0xac, 0x1f, 0x23, 
 0xdd, 0x78, 0x35, 0xe2, 0xd6, 0xd1, 0xf3, 0x4d, 0xb5, 0x25, 0x88, 0x16, 
 0xd1, 0x1a, 0x18, 0x33, 0xd6, 0x36, 0x7e, 0xc4, 0xc8, 0xe5, 0x5d, 0x2d, 
 0x74, 0xd5, 0x39, 0x3c, 0x44, 0x5a, 0x74, 0xb7, 0x7c, 0x48, 0xc1, 0x1f, 
 0x90, 0xe3, 0x55, 0x9e, 0xf6, 0x29, 0xad, 0xb4, 0x6d, 0x93, 0x78, 0xb3, 
 0xdc, 0x25, 0x0b, 0x9c, 0x73, 0x78, 0x7b, 0x93, 0x4c, 0xd3, 0x47, 0x09, 
 0xda, 0xe6, 0x69, 0x18, 0xc6, 0x0f, 0xfb, 0xa5, 0x95, 0xf5, 0xe8, 0x75, 
 0xe1, 0x01, 0x1b, 0xd3, 0x1c, 0xa2, 0x57, 0x03, 0x64, 0xdb, 0xf9, 0x5d, 
 0xf3, 0x3c, 0xa7, 0xd1, 0x4b, 0xb0, 0x90, 0x1b, 0x90, 0x62, 0xb4, 0x88, 
 0x30, 0x4b, 0x40, 0x4d, 0xcf, 0x7d, 0x89, 0x7a, 0xfb, 0x29, 0xc9, 0x64, 
 0x34, 0x0a, 0x52, 0xf6, 0x70, 0x7c, 0x76, 0x5a, 0x2e, 0x8f, 0x50, 0xd4, 
 0x92, 0x15, 0x97, 0xed, 0x4c, 0x2e, 0xf2, 0x3a, 0xd0, 0x58, 0x7e, 0xdb, 
 0xf1, 0xf4, 0xdd, 0x07, 0x76, 0x04, 0xf0, 0x55, 0x8b, 0x72, 0x2b, 0xa7, 
 0xa8, 0x78, 0x78, 0x67, 0xe6, 0xd8, 0xa5, 0xde, 0xe7, 0xc9, 0x1f, 0x5a, 
 0xa0, 0x89, 0xc7, 0x24, 0xa2, 0x71, 0xb6, 0x7b, 0x3b, 0xe6, 0x92, 0x69, 
 0x22, 0xaa, 0xe2, 0x47, 0x4b, 0x80, 0x3f, 0x6a, 0xab, 0xce, 0x4e, 0xcd, 
 0xe8, 0x94, 0x6c, 0xf7, 0x84, 0x73, 0x85, 0xfd, 0x85, 0x1d, 0xae, 0x81, 
 0xf7, 0xec, 0x12, 0x31, 0x7d, 0xc1, 0x99, 0xc0, 0x3c, 0x51, 0xb0, 0xdc, 
 0xb0, 0xba, 0x9c, 0x84, 0xb8, 0x70, 0xc2, 0x09, 0x7f, 0x96, 0x3d, 0xa1, 
 0xe2, 0x64, 0x27, 0x7a, 0x22, 0xb8, 0x75, 0xb9, 0xd1, 0x5f, 0xa5, 0x23, 
 0xf9, 0x62, 0xe0, 0x41, 0x02, 0x81, 0x81, 0x00, 0xf4, 0xf3, 0x08, 0xcf, 
 0x83, 0xb0, 0xab, 0xf2, 0x0f, 0x1a, 0x08, 0xaf, 0xc2, 0x42, 0x29, 0xa7, 
 0x9c, 0x5e, 0x52, 0x19, 0x69, 0x8d, 0x5b, 0x52, 0x29, 0x9c, 0x06, 0x6a, 
 0x5a, 0x32, 0x8f, 0x08, 0x45, 0x6c, 0x43, 0xb5, 0xac, 0xc3, 0xbb, 0x90, 
 0x7b, 0xec, 0xbb, 0x5d, 0x71, 0x25, 0x82, 0xf8, 0x40, 0xbf, 0x38, 0x00, 
 0x20, 0xf3, 0x8a, 0x38, 0x43, 0xde, 0x04, 0x41, 0x19, 0x5f, 0xeb, 0xb0, 
 0x50, 0x59, 0x10, 0xe1, 0x54, 0x62, 0x5c, 0x93, 0xd9, 0xdc, 0x63, 0x24, 
 0xd0, 0x17, 0x00, 0xc0, 0x44, 0x3e, 0xfc, 0xd1, 0xda, 0x4b, 0x24, 0xf7, 
 0xcb, 0x16, 0x35, 0xe6, 0x9f, 0x67, 0x96, 0x5f, 0xb0, 0x94, 0xde, 0xfa, 
 0xa1, 0xfd, 0x8c, 0x8a, 0xd1, 0x5c, 0x02, 0x8d, 0xe0, 0xa0, 0xa0,  0x02, 
 0x1d, 0x56, 0xaf, 0x13, 0x3a, 0x65, 0x5e, 0x8e, 0xde, 0xd1, 0xa8, 0x28, 
 0x8b, 0x71, 0xc9, 0x65, 0x02, 0x81, 0x81, 0x00, 0xc1, 0x0a,  0x47, 
 0x39, 0x91, 0x06, 0x1e, 0xb9, 0x43, 0x7c, 0x9e, 0x97, 0xc5, 0x09, 0x08, 
 0xbc, 0x22, 0x47, 0xe2, 0x96, 0x8e, 0x1c, 0x74, 0x80, 0x50, 0x6c, 0x9f, 
 0xef, 0x2f, 0xe5, 0x06, 0x3e, 0x73, 0x66, 0x76, 0x02, 0xbd, 0x9a, 0x1c, 
 0xfc, 0xf9, 0x6a, 0xb8, 0xf9, 0x36, 0x15, 0xb5, 0x20, 0x0b, 0x6b, 0x54, 
 0x83, 0x9c, 0x86, 0xba, 0x13, 0xb7, 0x99, 0x54, 0xa0, 0x93, 0x0d, 0xd6, 
 0x1e, 0xc1, 0x12, 0x72, 0x0d, 0xea, 0xb0, 0x14, 0x30, 0x70, 0x73, 0xef, 
 0x6b, 0x4c, 0xae, 0xb6, 0xff, 0xd4, 0xbb, 0x89, 0xa1, 0xec, 0xca, 0xa6, 
 0xe9, 0x95, 0x56, 0xac, 0xe2, 0x9b, 0x97, 0x2f, 0x2c, 0xdf, 0xa3, 0x6e, 
 0x59, 0xff, 0xcd, 0x3c, 0x6f, 0x57, 0xcc, 0x6e, 0x44, 0xc4, 0x27, 0xbf, 
 0xc3, 0xdd, 0x19, 0x9e, 0x81, 0x16, 0xe2, 0x8f, 0x65, 0x34, 0xa7, 0x0f, 
 0x22, 0xba, 0xbf, 0x79, 0x57, 0x02, 0x81, 0x80, 0x2e, 0x21, 0x0e, 0xc9, 
 0xb5, 0xad, 0x31, 0xd4, 0x76, 0x0f, 0x9b, 0x0f, 0x2e, 0x70, 0x33, 0x54, 
 0x03, 0x58, 0xa7, 0xf1, 0x6d, 0x35, 0x57, 0xbb, 0x53, 0x66, 0xb4, 0xb6, 
 0x96, 0xa1, 0xea, 0xd9, 0xcd, 0xe9, 0x23, 0x9f, 0x35, 0x17, 0xef, 0x5c, 
 0xb8, 0x59, 0xce, 0xb7, 0x3c, 0x35, 0xaa, 0x42, 0x82, 0x3f, 0x00, 0x96, 
 0xd5, 0x9d, 0xc7, 0xab, 0xec, 0xec, 0x04, 0xb5, 0x15, 0xc8, 0x40, 0xa4, 
 0x85, 0x9d, 0x20, 0x56, 0xaf, 0x03, 0x8f, 0x17, 0xb0, 0xf1, 0x96, 0x22, 
 0x3a, 0xa5, 0xfa, 0x58, 0x3b, 0x01, 0xf9, 0xae, 0xb3, 0x83, 0x6f, 0x44, 
 0xd3, 0x14, 0x2d, 0xb6, 0x6e, 0xd2, 0x9d, 0x39, 0x0c, 0x12, 0x1d, 0x23, 
 0xea, 0x19, 0xcb, 0xbb, 0xe0, 0xcd, 0x89, 0x15, 0x9a, 0xf5, 0xe4, 0xec, 
 0x41, 0x06, 0x30, 0x16, 0x58, 0xea, 0xfa, 0x31, 0xc1, 0xb8, 0x8e, 0x08, 
 0x84, 0xaa, 0x3b, 0x19, 0x02, 0x81, 0x80, 0x70, 0x4c, 0xf8, 0x6e, 0x86, 
 0xed, 0xd6, 0x85, 0xd4, 0xba, 0xf4, 0xd0, 0x3a, 0x32, 0x2d, 0x40, 0xb5, 
 0x78, 0xb8, 0x5a, 0xf9, 0xc5, 0x98, 0x08, 0xe5, 0xc0, 0xab, 0xb2, 0x4c, 
 0x5c, 0xa2, 0x2b, 0x46, 0x9b, 0x3e, 0xe0, 0x0d, 0x49, 0x50, 0xbf, 0xe2, 
 0xa1, 0xb1, 0x86, 0x59, 0x6e, 0x7b, 0x76, 0x6e, 0xee, 0x3b, 0xb6, 0x6d, 
 0x22, 0xfb, 0xb1, 0x68, 0xc7, 0xec, 0xb1, 0x95, 0x9b, 0x21, 0x0b, 0xb7, 
 0x2a, 0x71, 0xeb, 0xa2, 0xb2, 0x58, 0xac, 0x6d, 0x5f, 0x24, 0xd3, 0x79, 
 0x42, 0xd2, 0xf7, 0x35, 0xdc, 0xfc, 0x0e, 0x95, 0x60, 0xb7, 0x85, 0x7f, 
 0xf9, 0x72, 0x8e, 0x4a, 0x11, 0xc3, 0xc2, 0x09, 0x40, 0x5c, 0x7c, 0x43, 
 0x12, 0x34, 0xac, 0x59, 0x99, 0x76, 0x34,  0xcf, 
 0x20, 0x88, 0xb0, 0xfb, 0x39, 0x62, 0x3a, 0x9b, 0x03, 0xa6, 0x84, 0x2c, 
 0x03, 0x5c, 0x0c, 0xca, 0x33, 0x85, 0xf5, 0x02, 0x81, 0x80,  0x56, 
 0x99, 0xe9, 0x17, 0xdc, 0x33, 0xe1, 0x33, 0x8d, 0x5c, 0xba, 0x17, 0x32, 
 0xb7, 0x8c, 0xbd, 0x4b, 0x7f, 0x42, 0x3a, 0x79, 0x90, 0xe3,  0x70, 
 0xe3, 0x27, 0xce, 0x22, 0x59, 0x02, 0xc0, 0xb1, 0x0e, 0x57, 0xf5, 0xdf, 
 0x07, 0xbf, 0xf8, 0x4e, 0x10, 0xef, 0x2a, 0x62, 0x30, 0x03,  0xd4, 
 0x80, 0xcf, 0x20, 0x84, 0x25, 0x66, 0x3f, 0xc7, 0x4f, 0x56, 0x8c, 0x1e, 
 0xe1, 0x18, 0x91, 0xc1, 0xfd, 0x71, 0x5f, 0x65, 0x9b, 0xe4,  0x4f, 
 0xe0, 0x1a, 0x3a, 0xf8, 0xc1, 0x69, 0xdb, 0xd3, 0xbb, 0x8d, 0x91, 0xd1, 
 0x11, 0x4f, 0x7e, 0x91, 0x1b, 0xb4, 0x27, 0xa5, 0xab, 0x7c,  0x7b, 
 0x76, 0xd4, 0x78, 0xfe, 0x63, 0x44, 0x63, 0x7e, 0xe3, 0xa6, 0x60, 0x4f, 
 0xb9, 0x55, 0x28, 0xba, 0xba, 0x83, 0x1a, 0x2d, 0x43, 0xd5,  0xf7, 
 0x2e, 0xe0, 0xfc, 0xa8, 0x14, 0x9b, 0x91, 0x2a, 0x36, 0xbf, 0xc7, 0x14
 

The example above contains the exponent, the modulus, and private key material.

Other Formats of Key Material

The format of key material depends on the application, and is therefore unpredictable.  Key material commonly exists in any of the following formats; ASN1, PEM, P12, PFX, etc.  Key material in those formats, or in another format, can likely be re-formatted to be acceptable for moving onto the SafeNet HSM.  

Sample Program

The sample program below encrypts a known RSA private key, then unwraps the key pair onto the SafeNet HSM Partition.

/****************************************************************************\

*

* File: UnwrapKey.cpp*

* Encrypts a PrivateKeyInfo structure with a generated DES key and then

* unwraps the RSA key onto a token.

*

* This file is provided as an example only.

*

*

* Copyright (C) 2011, SafeNet, Inc.

*

* All rights reserved. This file contains information that is

* proprietary to SafeNet, Inc. and may not be

* distributed or copied without written consent from

* SafeNet, Inc.

*

\**************************************************************/

#ifdef UNIX

#define _POSIX_SOURCE 1

#endif

#ifdef USING_STATIC_CHRYSTOKI

# define STATIC  ckdemo_cpp

#endif

#include <assert.h>

#include <iostream.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <sys/stat.h>

#include <time.h>

#ifdef _WINDOWS

#include <conio.h>

#include <io.h>

#include <windows.h>

#endif

#ifdef UNIX

#include <unistd.h>

#endif

#include "source/cryptoki.h"

#include "source/Ckbridge.h"

#define DIM(a)                   (sizeof(a)/sizeof(a[0]))

CK_BBOOL no = FALSE;

CK_BBOOL yes = TRUE;

const int MAX =100;

// Function Prototypes

CK_RV  Pinlogin(CK_SESSION_HANDLE hSession);

int getPinString(CK_CHAR_PTR pw);

// Main

int main( void )

{

   int               error = 0;

   CK_RV             retCode = CKR_OK;

   CK_SESSION_HANDLE hSessionHandle;

   CK_CHAR_PTR       userPIN = (CK_CHAR_PTR)"default";

   CK_USHORT         lenuserPIN  = 7;

   CK_CHAR_PTR       soPIN = (CK_CHAR_PTR)"default";

   CK_USHORT         lensoPIN = 7;

   CK_USHORT         usNumberOfSlots;

   CK_SLOT_ID_PTR    pSlotList;

   CK_OBJECT_HANDLE hKey;

   CK_MECHANISM mech;

   CK_VERSION version;

   struct

   {

      CK_INFO info;

      char reserved[100]; // This is in case the library that we are

                          // talking to requires a larger info structure

                          // then the one defined.

   } protectedInfo;

//Disclaimer

   cout << "\n\n\n\n";

cout << "THE SOFTWARE IS PROVIDED BY SAFENET INCORPORATED (SAFENET) ON AN 'AS IS' BASIS, \n";

cout << "WITHOUT ANY OTHER WARRANTIES OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED \n";

cout << "TO, WARRANTIES OF MERCHANTABLE QUALITY, SATISFACTORY QUALITY, MERCHANTABILITY OR FITNESS FOR\n";

cout << "A PARTICULAR PURPOSE, OR THOSE ARISING BY LAW, STATUTE, USAGE OF TRADE, COURSE OF DEALING OR\n";

cout << "OTHERWISE.  SAFENET DOES NOT WARRANT THAT THE SOFTWARE WILL MEET YOUR REQUIREMENTS OR \n";

cout << "THAT OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR THAT THE SOFTWARE WILL BE ERROR-FREE.\n";

cout << "YOU ASSUME THE ENTIRE RISK AS TO THE RESULTS AND PERFORMANCE OF THE SOFTWARE.  NEITHER \n";

cout << "SAFENET NOR OUR LICENSORS, DEALERS OR SUPPLIERS SHALL HAVE ANY LIABILITY TO YOU OR ANY\n";

cout << "OTHER PERSON OR ENTITY FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, PUNITIVE, \n";

cout << "EXEMPLARY OR AY OTHER DAMAGES WHATSOEVER, INCLUDING, BUT NOT LIMITED TO, LOSS OF REVENUE OR \n";

cout << "PROFIT, LOST OR DAMAGED DATA, LOSS OF USE OR OTHER COMMERCIAL OR ECONOMIC LOSS, EVEN IF \n";

cout << "SAFENET HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR THEY ARE FORESEEABLE. \n";

cout << "SAFENET IS ALSO NOT RESPONSIBLE FOR CLAIMS BY A THIRD PARTY.  THE MAXIMUM AGGREGATE \n";

cout << "LIABILITY OF SAFENET TO YOU AND THAT OF SAFENET’S LICENSORS, DEALERS AND SUPPLIERS \n";

cout << "SHALL NOT EXCEED FORTY DOLLARS ($40.00CDN).  THE LIMITATIONS IN THIS SECTION SHALL APPLY \n";

cout << "WHETHER OR NOT THE ALLEGED BREACH OR DEFAULT IS A BREACH OF A FUNDAMENTAL CONDITION OR TERM \n";

cout << "OR A FUNDAMENTAL BREACH.  SOME STATES/COUNTRIES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF\n";

cout << "LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE LIMITATION MAY NOT APPLY TO \n";

cout << "YOU.\n";

cout << "THE LIMITED WARRANTY, EXCLUSIVE REMEDIES AND LIMITED LIABILITY SET OUT HEREIN ARE FUNDAMENTAL \n";

cout << "ELEMENTS OF THE BASIS OF THE BARGAIN BETWEEN YOU AND SAFENET.  \n";

cout << "NO SUPPORT.  YOU ACKNOWLEDGE AND AGREE THAT THERE ARE NO SUPPORT SERVICES PROVIDED BY SAFENET\n";

cout << "INCORPORATED FOR THIS SOFTWARE\n" << endl;

   // Display Generic Warning

   cout << "\nInsert a token for the test...";

   cout << "\n\nWARNING!!! This test initializes the first ";

   cout << " token detected in the card reader.";

   cout << "\nDo not use a token that you don't want erased.";

   cout << "\nYou can use CTRL-C to abort now...Otherwise...";

   cout << "\n\n... press <Enter> key to continue ...\n";

   cout.flush();

   getchar(); // Wait for keyboard hit

#ifndef STATIC   

   // Connect to Chrystoki

if(!CrystokiConnect())

{

cout << "\n" "Unable to connect to Chrystoki.  Error = " << LibError() << "\n";

error = -1;

      goto exit_routine_1;

}

#endif

   // Verify this is the version of the library required

   retCode = C_GetInfo(&protectedInfo.info);

   if( retCode != CKR_OK )

   {

      cout << endl << "Unable to call C_GetInfo() before C_Initialize()\n";

error = -2;

      goto exit_routine_2;

   }

   else

   {

      CK_BYTE majorVersion = protectedInfo.info.version.major;

      CK_BYTE expectedVersion;

#ifndef PKCS11_2_0

      expectedVersion = 1;

#else

      expectedVersion = 2;

#endif

      if( expectedVersion != majorVersion )

      {

         cout << endl << "This version of the program was built for Cryptoki version "

              << (int)expectedVersion << ".\n"

              << "The loaded Cryptoki library reports its version to be "

              << (int)majorVersion << ".\n"

              << "Program will terminate.\n";

         // Wait to exit until user read message and acknowledges

         cout << endl << "Press <Enter> key to end.";

         getchar(); // Wait for keyboard hit

   error = -3;

         goto exit_routine_2;

      }

   }

   // Initialize the Library

retCode = C_Initialize(NULL);

if(retCode != CKR_OK)

{

cout << "\n" "Error 0x" << hex << retCode << " initializing cryptoki.\n";

error = -4;

      goto exit_routine_3;

}

// Get the number of tokens possibly available

retCode = C_GetSlotList(TRUE, NULL, &usNumberOfSlots);

if(retCode != CKR_OK)

{

cout << "\n" "Error 0x" << hex << retCode << " getting slot list.\n";

error = -5;

      goto exit_routine_3;

}

// Are any tokens present?

if(usNumberOfSlots == 0)

{

cout << "\n" "No tokens found\n";

error = -6;

      goto exit_routine_3;

   }

   // Get a list of slots

pSlotList = new CK_SLOT_ID[usNumberOfSlots];

retCode = C_GetSlotList(TRUE, pSlotList, &usNumberOfSlots);

if(retCode != CKR_OK)

{

cout << "\n" "Error 0x" << hex << retCode << " getting slot list.\n";

error = -7;

      goto exit_routine_4;

}

   // Open a session

retCode = C_OpenSession(pSlotList[0], CKF_RW_SESSION | CKF_SERIAL_SESSION,

      NULL, NULL, &hSessionHandle);

if(retCode != CKR_OK)

{

cout << "\n" "Error 0x" << hex << retCode << " opening session.\n";

error = -9;

      goto exit_routine_4;

}

Pinlogin(hSessionHandle);

if(retCode != CKR_OK)

{

cout << "\n" "Error 0x" << hex << retCode << " Calling PinLogin fn";

exit(hSessionHandle);

}

  // Encrypt an RSA Key and then unwrap it onto the token

   {

      // The following is an RSA Key that is formatted as a PrivateKeyInfo structure

   //BER encoded format

      const CK_BYTE pRsaKey[] = {

 0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,

0x01, 0x05, 0x00, 0x04,

 0x82, 0x04, 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb8, 0xb5, 0x0f, 0x49,

0x46, 0xb5, 0x5d, 0x58,

 0x04, 0x8e, 0x52, 0x59, 0x39, 0xdf, 0xd6, 0x29, 0x45, 0x6b, 0x6c, 0x96, 0xbb, 0xab, 0xa5, 0x6f, 0x72, 0x1b, 0x16,

0x96, 0x74, 0xd5, 0xf9,

 0xb4, 0x41, 0xa3, 0x7c, 0xe1, 0x94, 0x73, 0x4b, 0xa7, 0x23, 0xff, 0x61, 0xeb, 0xce, 0x5a, 0xe7, 0x7f, 0xe3, 0x74,

0xe8, 0x52, 0x5b, 0xd6,

 0x5d, 0x5c, 0xdc, 0x98, 0x49, 0xfe, 0x51, 0xc2, 0x7e, 0x8f, 0x3b, 0x37, 0x5c, 0xb3, 0x11, 0xed, 0x85, 0x91, 0x15,

0x92, 0x24, 0xd8, 0xf1,

 0x7b, 0x3d, 0x2f, 0x8b, 0xcd, 0x1b, 0x30, 0x14, 0xa3, 0x6b, 0x1b, 0x4d, 0x27, 0xff, 0x6a, 0x58, 0x84, 0x9e, 0x79,

0x94, 0xca, 0x78, 0x64,

 0x01, 0x33, 0xc3, 0x58, 0xfc, 0xd3, 0x83, 0xeb, 0x2f, 0xab, 0x6f, 0x85, 0x5a, 0x38, 0x41, 0x3d, 0x73, 0x20, 0x1b,

0x82, 0xbc, 0x7e, 0x76,

 0xde, 0x5c, 0xfe, 0x42, 0xd6, 0x7b, 0x86, 0x4f, 0x79, 0x78, 0x29, 0x82, 0x87, 0xa6, 0x24, 0x43, 0x39, 0x74, 0xfe,

0xf2, 0x0c, 0x08, 0xbe,

 0xfa, 0x1e, 0x0a, 0x48, 0x6f, 0x14, 0x86, 0xc5, 0xcd, 0x9a, 0x98, 0x09, 0x2d, 0xf3, 0xf3, 0x5a, 0x7a, 0xa4, 0xe6,

0x8a, 0x2e, 0x49, 0x8a, 0xde, 0x73, 0xe9, 0x37, 0xa0, 0x5b, 0xef,

 0xd0, 0xe0, 0x13, 0xac, 0x88, 0x5f, 0x59, 0x47, 0x96, 0x7f, 0x78, 0x18, 0x0e, 0x44, 0x6a, 0x5d, 0xec, 0x6e, 0xed,

0x4f, 0xf6, 0x6a, 0x7a,

 0x58, 0x6b, 0xfe, 0x6c, 0x5a, 0xb9, 0xd2, 0x22, 0x3a, 0x1f, 0xdf, 0xc3, 0x09, 0x3f, 0x6b, 0x2e, 0xf1, 0x6d, 0xc3,

0xfb, 0x4e, 0xd4, 0xf2,

 0xa3, 0x94, 0x13, 0xb0, 0xbf, 0x1e, 0x06, 0x2e, 0x29, 0x55, 0x00, 0xaa, 0x98, 0xd9, 0xe8, 0x77, 0x84, 0x8b, 0x3f,

0x5f, 0x5e, 0xf7, 0xf8,

 0xa7, 0xe6, 0x02, 0xd2, 0x18, 0xb0, 0x52, 0xd0, 0x37, 0x2e, 0x53, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01,

0x00, 0x0c, 0xdf, 0xd1,

 0xe8, 0xf1, 0x9c, 0xc2, 0x9c, 0xd7, 0xf4, 0x73, 0x98, 0xf4, 0x87, 0xbd, 0x8d, 0xb2, 0xe1, 0x01, 0xf8, 0x9f, 0xac,

0x1f, 0x23, 0xdd, 0x78,

 0x35, 0xe2, 0xd6, 0xd1, 0xf3, 0x4d, 0xb5, 0x25, 0x88, 0x16, 0xd1, 0x1a, 0x18, 0x33, 0xd6, 0x36, 0x7e, 0xc4, 0xc8,

0xe5, 0x5d, 0x2d, 0x74,

 0xd5, 0x39, 0x3c, 0x44, 0x5a, 0x74, 0xb7, 0x7c, 0x48, 0xc1, 0x1f, 0x90, 0xe3, 0x55, 0x9e, 0xf6, 0x29, 0xad, 0xb4,

0x6d, 0x93, 0x78, 0xb3,

 0xdc, 0x25, 0x0b, 0x9c, 0x73, 0x78, 0x7b, 0x93, 0x4c, 0xd3, 0x47, 0x09, 0xda, 0xe6, 0x69, 0x18, 0xc6, 0x0f, 0xfb,

0xa5, 0x95, 0xf5, 0xe8,

 0x75, 0xe1, 0x01, 0x1b, 0xd3, 0x1c, 0xa2, 0x57, 0x03, 0x64, 0xdb, 0xf9, 0x5d, 0xf3, 0x3c, 0xa7, 0xd1, 0x4b, 0xb0,

0x90, 0x1b, 0x90, 0x62,

 0xb4, 0x88, 0x30, 0x4b, 0x40, 0x4d, 0xcf, 0x7d, 0x89, 0x7a, 0xfb, 0x29, 0xc9, 0x64, 0x34, 0x0a, 0x52, 0xf6, 0x70,

0x7c, 0x76, 0x5a, 0x2e,

 0x8f, 0x50, 0xd4, 0x92, 0x15, 0x97, 0xed, 0x4c, 0x2e, 0xf2, 0x3a, 0xd0, 0x58, 0x7e, 0xdb, 0xf1, 0xf4, 0xdd, 0x07,

0x76, 0x04, 0xf0, 0x55,

 0x8b, 0x72, 0x2b, 0xa7, 0xa8, 0x78, 0x78, 0x67, 0xe6, 0xd8, 0xa5, 0xde, 0xe7, 0xc9, 0x1f, 0x5a, 0xa0, 0x89, 0xc7,

0x24, 0xa2, 0x71, 0xb6,

 0x7b, 0x3b, 0xe6, 0x92, 0x69, 0x22, 0xaa, 0xe2, 0x47, 0x4b, 0x80, 0x3f, 0x6a, 0xab, 0xce, 0x4e, 0xcd, 0xe8, 0x94,

0x6c, 0xf7, 0x84, 0x73,

 0x85, 0xfd, 0x85, 0x1d, 0xae, 0x81, 0xf7, 0xec, 0x12, 0x31, 0x7d, 0xc1, 0x99, 0xc0, 0x3c, 0x51, 0xb0, 0xdc, 0xb0,

0xba, 0x9c, 0x84, 0xb8,

 0x70, 0xc2, 0x09, 0x7f, 0x96, 0x3d, 0xa1, 0xe2, 0x64, 0x27, 0x7a, 0x22, 0xb8, 0x75, 0xb9, 0xd1, 0x5f, 0xa5, 0x23,

0xf9, 0x62, 0xe0, 0x41,

 0x02, 0x81, 0x81, 0x00, 0xf4, 0xf3, 0x08, 0xcf, 0x83, 0xb0, 0xab, 0xf2, 0x0f, 0x1a, 0x08, 0xaf, 0xc2, 0x42, 0x29,

0xa7, 0x9c, 0x5e, 0x52,

 0x19, 0x69, 0x8d, 0x5b, 0x52, 0x29, 0x9c, 0x06, 0x6a, 0x5a, 0x32, 0x8f, 0x08, 0x45, 0x6c, 0x43, 0xb5, 0xac, 0xc3,

0xbb, 0x90, 0x7b, 0xec,

 0xbb, 0x5d, 0x71, 0x25, 0x82, 0xf8, 0x40, 0xbf, 0x38, 0x00, 0x20, 0xf3, 0x8a, 0x38, 0x43, 0xde, 0x04, 0x41, 0x19,

0x5f, 0xeb, 0xb0, 0x50,

 0x59, 0x10, 0xe1, 0x54, 0x62, 0x5c, 0x93, 0xd9, 0xdc, 0x63, 0x24, 0xd0, 0x17, 0x00, 0xc0, 0x44, 0x3e, 0xfc, 0xd1,

0xda, 0x4b, 0x24, 0xf7,

 0xcb, 0x16, 0x35, 0xe6, 0x9f, 0x67, 0x96, 0x5f, 0xb0, 0x94, 0xde, 0xfa, 0xa1, 0xfd, 0x8c, 0x8a, 0xd1, 0x5c, 0x02,

0x8d, 0xe0, 0xa0, 0xa0,

 0x02, 0x1d, 0x56, 0xaf, 0x13, 0x3a, 0x65, 0x5e, 0x8e, 0xde, 0xd1, 0xa8, 0x28, 0x8b, 0x71, 0xc9, 0x65, 0x02, 0x81,

0x81, 0x00, 0xc1, 0x0a,

 0x47, 0x39, 0x91, 0x06, 0x1e, 0xb9, 0x43, 0x7c, 0x9e, 0x97, 0xc5, 0x09, 0x08, 0xbc, 0x22, 0x47, 0xe2, 0x96, 0x8e,

0x1c, 0x74, 0x80, 0x50,

 0x6c, 0x9f, 0xef, 0x2f, 0xe5, 0x06, 0x3e, 0x73, 0x66, 0x76, 0x02, 0xbd, 0x9a, 0x1c, 0xfc, 0xf9, 0x6a, 0xb8, 0xf9,

0x36, 0x15, 0xb5, 0x20,

 0x0b, 0x6b, 0x54, 0x83, 0x9c, 0x86, 0xba, 0x13, 0xb7, 0x99, 0x54, 0xa0, 0x93, 0x0d, 0xd6, 0x1e, 0xc1, 0x12, 0x72,

0x0d, 0xea, 0xb0, 0x14,

 0x30, 0x70, 0x73, 0xef, 0x6b, 0x4c, 0xae, 0xb6, 0xff, 0xd4, 0xbb, 0x89, 0xa1, 0xec, 0xca, 0xa6, 0xe9, 0x95, 0x56,

0xac, 0xe2, 0x9b, 0x97,

 0x2f, 0x2c, 0xdf, 0xa3, 0x6e, 0x59, 0xff, 0xcd, 0x3c, 0x6f, 0x57, 0xcc, 0x6e, 0x44, 0xc4, 0x27, 0xbf, 0xc3, 0xdd,

0x19, 0x9e, 0x81, 0x16,

 0xe2, 0x8f, 0x65, 0x34, 0xa7, 0x0f, 0x22, 0xba, 0xbf, 0x79, 0x57, 0x02, 0x81, 0x80, 0x2e, 0x21, 0x0e, 0xc9, 0xb5,

0xad, 0x31, 0xd4, 0x76,

 0x0f, 0x9b, 0x0f, 0x2e, 0x70, 0x33, 0x54, 0x03, 0x58, 0xa7, 0xf1, 0x6d, 0x35, 0x57, 0xbb, 0x53, 0x66, 0xb4, 0xb6,

0x96, 0xa1, 0xea, 0xd9,

 0xcd, 0xe9, 0x23, 0x9f, 0x35, 0x17, 0xef, 0x5c, 0xb8, 0x59, 0xce, 0xb7, 0x3c, 0x35, 0xaa, 0x42, 0x82, 0x3f, 0x00,

0x96, 0xd5, 0x9d, 0xc7,

 0xab, 0xec, 0xec, 0x04, 0xb5, 0x15, 0xc8, 0x40, 0xa4, 0x85, 0x9d, 0x20, 0x56, 0xaf, 0x03, 0x8f, 0x17, 0xb0, 0xf1,

0x96, 0x22, 0x3a, 0xa5,

 0xfa, 0x58, 0x3b, 0x01, 0xf9, 0xae, 0xb3, 0x83, 0x6f, 0x44, 0xd3, 0x14, 0x2d, 0xb6, 0x6e, 0xd2, 0x9d, 0x39, 0x0c,

0x12, 0x1d, 0x23, 0xea,

 0x19, 0xcb, 0xbb, 0xe0, 0xcd, 0x89, 0x15, 0x9a, 0xf5, 0xe4, 0xec, 0x41, 0x06, 0x30, 0x16, 0x58, 0xea, 0xfa, 0x31,

0xc1, 0xb8, 0x8e, 0x08,

 0x84, 0xaa, 0x3b, 0x19, 0x02, 0x81, 0x80, 0x70, 0x4c, 0xf8, 0x6e, 0x86, 0xed, 0xd6, 0x85, 0xd4, 0xba, 0xf4, 0xd0,

0x3a, 0x32, 0x2d, 0x40,

 0xb5, 0x78, 0xb8, 0x5a, 0xf9, 0xc5, 0x98, 0x08, 0xe5, 0xc0, 0xab, 0xb2, 0x4c, 0x5c, 0xa2, 0x2b, 0x46, 0x9b, 0x3e,

0xe0, 0x0d, 0x49, 0x50,

 0xbf, 0xe2, 0xa1, 0xb1, 0x86, 0x59, 0x6e, 0x7b, 0x76, 0x6e, 0xee, 0x3b, 0xb6, 0x6d, 0x22, 0xfb, 0xb1, 0x68, 0xc7,

0xec, 0xb1, 0x95, 0x9b,

 0x21, 0x0b, 0xb7, 0x2a, 0x71, 0xeb, 0xa2, 0xb2, 0x58, 0xac, 0x6d, 0x5f, 0x24, 0xd3, 0x79, 0x42, 0xd2, 0xf7, 0x35,

0xdc, 0xfc, 0x0e, 0x95,

 0x60, 0xb7, 0x85, 0x7f, 0xf9, 0x72, 0x8e, 0x4a, 0x11, 0xc3, 0xc2, 0x09, 0x40, 0x5c, 0x7c, 0x43, 0x12, 0x34, 0xac,

0x59, 0x99, 0x76, 0x34,

 0xcf, 0x20, 0x88, 0xb0, 0xfb, 0x39, 0x62, 0x3a, 0x9b, 0x03, 0xa6, 0x84, 0x2c, 0x03, 0x5c, 0x0c, 0xca, 0x33, 0x85,

0xf5, 0x02, 0x81, 0x80,

 0x56, 0x99, 0xe9, 0x17, 0xdc, 0x33, 0xe1, 0x33, 0x8d, 0x5c, 0xba, 0x17, 0x32, 0xb7, 0x8c, 0xbd, 0x4b, 0x7f, 0x42,

0x3a, 0x79, 0x90, 0xe3,

 0x70, 0xe3, 0x27, 0xce, 0x22, 0x59, 0x02, 0xc0, 0xb1, 0x0e, 0x57, 0xf5, 0xdf, 0x07, 0xbf, 0xf8, 0x4e, 0x10, 0xef,

0x2a, 0x62, 0x30, 0x03,

 0xd4, 0x80, 0xcf, 0x20, 0x84, 0x25, 0x66, 0x3f, 0xc7, 0x4f, 0x56, 0x8c, 0x1e, 0xe1, 0x18, 0x91, 0xc1, 0xfd, 0x71,

0x5f, 0x65, 0x9b, 0xe4,

 0x4f, 0xe0, 0x1a, 0x3a, 0xf8, 0xc1, 0x69, 0xdb, 0xd3, 0xbb, 0x8d, 0x91, 0xd1, 0x11, 0x4f, 0x7e, 0x91, 0x1b, 0xb4,

0x27, 0xa5, 0xab, 0x7c,

 0x7b, 0x76, 0xd4, 0x78, 0xfe, 0x63, 0x44, 0x63, 0x7e, 0xe3, 0xa6, 0x60, 0x4f, 0xb9, 0x55, 0x28, 0xba, 0xba, 0x83,

0x1a, 0x2d, 0x43, 0xd5,

 0xf7, 0x2e, 0xe0, 0xfc, 0xa8, 0x14, 0x9b, 0x91, 0x2a, 0x36, 0xbf, 0xc7, 0x14

  };

CK_BYTE

  knownRSA1Modulus[] = {

0xb8, 0xb5, 0x0f, 0x49, 0x46, 0xb5, 0x5d, 0x58, 0x04, 0x8e, 0x52, 0x59, 0x39, 0xdf, 0xd6,

0x29,

0x45, 0x6b, 0x6c, 0x96, 0xbb, 0xab, 0xa5, 0x6f, 0x72, 0x1b, 0x16, 0x96, 0x74, 0xd5, 0xf9,

0xb4,

0x41, 0xa3, 0x7c, 0xe1, 0x94, 0x73, 0x4b, 0xa7, 0x23, 0xff, 0x61, 0xeb, 0xce, 0x5a, 0xe7,

0x7f,

0xe3, 0x74, 0xe8, 0x52, 0x5b, 0xd6, 0x5d, 0x5c, 0xdc, 0x98, 0x49, 0xfe, 0x51, 0xc2, 0x7e,

0x8f,

0x3b, 0x37, 0x5c, 0xb3, 0x11, 0xed, 0x85, 0x91, 0x15, 0x92, 0x24, 0xd8, 0xf1, 0x7b, 0x3d,

0x2f,

0x8b, 0xcd, 0x1b, 0x30, 0x14, 0xa3, 0x6b, 0x1b, 0x4d, 0x27, 0xff, 0x6a, 0x58, 0x84, 0x9e,

0x79,

0x94, 0xca, 0x78, 0x64, 0x01, 0x33, 0xc3, 0x58, 0xfc, 0xd3, 0x83, 0xeb, 0x2f, 0xab, 0x6f,

0x85,

0x5a, 0x38, 0x41, 0x3d, 0x73, 0x20, 0x1b, 0x82, 0xbc, 0x7e, 0x76, 0xde, 0x5c, 0xfe, 0x42,

0xd6,

0x7b, 0x86, 0x4f, 0x79, 0x78, 0x29, 0x82, 0x87, 0xa6, 0x24, 0x43, 0x39, 0x74, 0xfe, 0xf2,

0x0c,

0x08, 0xbe, 0xfa, 0x1e, 0x0a, 0x48, 0x6f, 0x14, 0x86, 0xc5, 0xcd, 0x9a, 0x98, 0x09, 0x2d,

0xf3,

0xf3, 0x5a, 0x7a, 0xa4, 0xe6, 0x8a, 0x2e, 0x49, 0x8a, 0xde, 0x73, 0xe9, 0x37, 0xa0, 0x5b,

0xef,

0xd0, 0xe0, 0x13, 0xac, 0x88, 0x5f, 0x59, 0x47, 0x96, 0x7f, 0x78, 0x18, 0x0e, 0x44, 0x6a,

0x5d,

0xec, 0x6e, 0xed, 0x4f, 0xf6, 0x6a, 0x7a, 0x58, 0x6b, 0xfe, 0x6c, 0x5a, 0xb9, 0xd2, 0x22,

0x3a,

0x1f, 0xdf, 0xc3, 0x09, 0x3f, 0x6b, 0x2e, 0xf1, 0x6d, 0xc3, 0xfb, 0x4e, 0xd4, 0xf2, 0xa3,

0x94,

0x13, 0xb0, 0xbf, 0x1e, 0x06, 0x2e, 0x29, 0x55, 0x00, 0xaa, 0x98, 0xd9, 0xe8, 0x77, 0x84,

0x8b,

0x3f, 0x5f, 0x5e, 0xf7, 0xf8, 0xa7, 0xe6, 0x02, 0xd2, 0x18, 0xb0, 0x52, 0xd0, 0x37, 0x2e,

0x53,

      },

      knownRSA1PubExponent[] = { 0x01, 0x00, 0x01 };

      char *pPlainData = 0;

      unsigned long ulPlainDataLength;

      char *pEncryptedData = 0;

      unsigned long ulEncryptedDataLength = 0;

      CK_MECHANISM mech;

      CK_USHORT   usStatus=0,

                  usKeyLength;

      CK_OBJECT_HANDLE hKey;

      CK_OBJECT_CLASS    SymKeyClass  = CKO_SECRET_KEY;

      CK_BBOOL           bTrue = 1,

                         bFalse = 0,

                         bToken = bTrue,

                         bSensitive = bTrue,

                         bPrivate = bTrue,

                         bEncrypt = bTrue,

                         bDecrypt = bTrue,

                         bSign = bFalse, // "..."

                         bVerify = bFalse, //Will not allow sign/verify operation.

                         bWrap = bTrue,

                         bUnwrap = bTrue,

#ifdef EXTRACTABLE

                         bExtract = bTrue,

#endif //EXTRACTABLE

                         bDerive = bTrue;

      CK_KEY_TYPE        keyType;

      CK_USHORT          usValueBits;

      char               pbPublicKeyLabel[128];

      CK_ATTRIBUTE_PTR pPublicTemplate;

      CK_USHORT usPublicTemplateSize = 0;

      char iv[8] = { '1', '2', '3', '4', '5', '6', '7', '8' };

      CK_ATTRIBUTE SymKeyTemplate[] = {

         {CKA_CLASS, 0, sizeof(SymKeyClass)},

         {CKA_KEY_TYPE, 0, sizeof(keyType)},

         {CKA_TOKEN, 0, sizeof(bToken)},

         {CKA_SENSITIVE, 0, sizeof(bSensitive)},

         {CKA_PRIVATE, 0, sizeof(bPrivate)},

         {CKA_ENCRYPT, 0, sizeof(bEncrypt)},

         {CKA_DECRYPT, 0, sizeof(bDecrypt)},

         {CKA_SIGN, 0, sizeof(bSign)},

         {CKA_VERIFY, 0, sizeof(bVerify)},

         {CKA_WRAP, 0, sizeof(bWrap)},

         {CKA_UNWRAP, 0, sizeof(bUnwrap)},

         {CKA_DERIVE, 0, sizeof(bDerive)},

         {CKA_VALUE_LEN,0,  sizeof(usKeyLength) },

         {CKA_LABEL, 0, 0}  // Always keep last!!!

#ifdef EXTRACTABLE      //Conditional stuff must be at the end!!!!!

         {CKA_EXTRACTABLE, 0, sizeof(bExtract)},

#endif //EXTRACTABLE

      };

      CK_OBJECT_HANDLE hUnWrappedKey, hPublicRSAKey;

      char             *pbWrappedKey;

      unsigned long    ulWrappedKeySize;

      CK_OBJECT_CLASS  privateKey = CKO_PRIVATE_KEY,

publicKey = CKO_PUBLIC_KEY;

      CK_KEY_TYPE      rsaType   = CKK_RSA;

      CK_BYTE          pLabel[]  = "RSA private Key",

pbPublicRSAKeyLabel[] = "RSA Public Key";

      CK_ATTRIBUTE *pTemplate;

      CK_ULONG     usTemplateSize,

ulPublicRSAKeyTemplateSize;

      CK_ATTRIBUTE pPublicRSAKeyTemplate[] = {

         {CKA_CLASS,    0, sizeof(publicKey) },

         {CKA_KEY_TYPE, 0,    sizeof(rsaType)    },

         {CKA_TOKEN,    0,     sizeof(bToken)     },

         {CKA_PRIVATE,  0,   sizeof(bPrivate)   },

         {CKA_ENCRYPT,  0,   sizeof(bEncrypt)   },

         {CKA_VERIFY,   0,      sizeof(bSign)      },

         {CKA_WRAP,     0,      sizeof(bWrap)      },

 {CKA_MODULUS, 0, sizeof(knownRSA1Modulus) },

 {CKA_PUBLIC_EXPONENT, 0, sizeof(knownRSA1PubExponent) },

         {CKA_LABEL,    0,      sizeof(pbPublicRSAKeyLabel)     }

      };

      CK_ATTRIBUTE pPrivateKeyTemplate[] = {

         {CKA_CLASS,    &privateKey, sizeof(privateKey) },

         {CKA_KEY_TYPE, &rsaType,    sizeof(rsaType)    },

         {CKA_TOKEN,    &bToken,     sizeof(bToken)     },

         {CKA_SENSITIVE,&bSensitive, sizeof(bSensitive) },

         {CKA_PRIVATE,  &bPrivate,   sizeof(bPrivate)   },

         {CKA_DECRYPT,  &bEncrypt,   sizeof(bEncrypt)   },

         {CKA_SIGN,     &bSign,      sizeof(bSign)      },

 //{CKA_SIGN_RECOVER, &bTrue, sizeof(bTrue)     },

         {CKA_UNWRAP,   &bWrap,      sizeof(bWrap)      },

{CKA_EXTRACTABLE, &bFalse, sizeof(bFalse)      },

{CKA_LABEL,       pLabel,  sizeof(pLabel)     }

      };

      // Generate a DES3 Key

      SymKeyTemplate[0].pValue = &SymKeyClass;

      SymKeyTemplate[1].pValue = &keyType;

      SymKeyTemplate[2].pValue = &bToken;

      SymKeyTemplate[3].pValue = &bSensitive;

      SymKeyTemplate[4].pValue = &bPrivate;

      SymKeyTemplate[5].pValue = &bEncrypt;    

      SymKeyTemplate[6].pValue = &bDecrypt;

      SymKeyTemplate[7].pValue = &bSign;

      SymKeyTemplate[8].pValue = &bVerify;

      SymKeyTemplate[9].pValue = &bWrap;

      SymKeyTemplate[10].pValue = &bUnwrap;

      SymKeyTemplate[11].pValue = &bDerive;

      SymKeyTemplate[12].pValue =  &usKeyLength;

      SymKeyTemplate[13].pValue = pbPublicKeyLabel;

#ifdef EXTRACTABLE        

      SymKeyTemplate[14].pValue = &bExtract;

#endif //EXTRACTABLE

      mech.mechanism = CKM_DES3_KEY_GEN;

      mech.pParameter = 0;

      mech.usParameterLen = 0;

      keyType = CKK_DES3;

      usKeyLength = 24;

      strcpy( pbPublicKeyLabel, "Generated DES3 Key" );

      pPublicTemplate = SymKeyTemplate;

      usPublicTemplateSize = DIM(SymKeyTemplate);

      // Adjust size of label (ALWAYS LAST ENTRY IN ARRAY)

      pPublicTemplate[usPublicTemplateSize-1].usValueLen = strlen(

pbPublicKeyLabel );

      retCode = C_GenerateKey(   hSessionHandle,

                                 (CK_MECHANISM_PTR)&mech,

                                 pPublicTemplate,

                                 usPublicTemplateSize,

                                 &hKey);

      if(retCode == CKR_OK)

      {

         cout << pbPublicKeyLabel << ": " << hKey << endl;

      }

      else

      {

   cout << "\n" "Error 0x" << hex << retCode;

         cout << " generating the DES3 Key.\n";

   error = -11;

         goto exit_routine_6;

      }

      // Encrypt the RSA Key

      mech.mechanism = CKM_DES3_CBC;

      mech.pParameter = iv;

      mech.usParameterLen = sizeof(iv);

      pPlainData = (char *)(pRsaKey);

      ulPlainDataLength = sizeof(pRsaKey);

      // Allocate memory for output buffer

      if( retCode == CKR_OK )

      {

         pEncryptedData = new char [ulPlainDataLength + 2048]; // Leave

// extra room for

// RSA Operations

         if( !pEncryptedData )

         {

            retCode = CKR_DEVICE_ERROR;

         }

      }

      // Start encrypting

      if( retCode == CKR_OK )

      {

         retCode = C_EncryptInit(hSessionHandle, &mech, hKey);

      }

      // Continue encrypting

      if( retCode == CKR_OK )

      {

         CK_USHORT usInDataLen,

                   usOutDataLen = (CK_USHORT) (ulPlainDataLength + 2048);

         CK_ULONG  ulBytesRemaining = ulPlainDataLength;

         char *    pPlainTextPointer = pPlainData;

         char *    pEncryptedDataPointer = pEncryptedData;

         while (ulBytesRemaining > 0)

         {

            if (ulBytesRemaining > 0xfff0) // We are longer than a USHORT can handle

            {

               usInDataLen = 0xfff0;

               ulBytesRemaining -= usInDataLen;

            }

            else

            {

               usInDataLen = (CK_USHORT) ulBytesRemaining;

               ulBytesRemaining -= usInDataLen;

            }

            retCode = C_EncryptUpdate( hSessionHandle,

                                       (CK_BYTE_PTR)pPlainTextPointer,

                                       usInDataLen,

                                       (CK_BYTE_PTR)pEncryptedDataPointer,

                                       &usOutDataLen );

            pPlainTextPointer += usInDataLen;

            pEncryptedDataPointer += usOutDataLen;

            ulEncryptedDataLength += usOutDataLen;

         }

      }         

   

      // Finish encrypting

      if( retCode == CKR_OK )

      {

         CK_USHORT usOutDataLen;

         CK_BYTE_PTR pOutData = (CK_BYTE_PTR)pEncryptedData;

         pOutData += ulEncryptedDataLength;

         retCode = C_EncryptFinal(hSessionHandle, pOutData, &usOutDataLen);

         ulEncryptedDataLength += usOutDataLen;

      }

      else

      {

   cout << "\n" "Error 0x" << hex << retCode;

         cout << " somewhere in the encrypting.\n";

         if( pEncryptedData )

         {

            delete pEncryptedData;

         }

   error = -12;

         goto exit_routine_6;

      }

      mech.mechanism      = CKM_DES3_CBC;

      mech.pParameter     = (void*) "12345678"; // 8 byte IV

      mech.usParameterLen = 8;

      pTemplate = pPrivateKeyTemplate;

      usTemplateSize = DIM(pPrivateKeyTemplate);

     pbWrappedKey = pEncryptedData;

      ulWrappedKeySize = ulEncryptedDataLength;

      if( retCode == CKR_OK )

      {

         retCode = C_UnwrapKey( hSessionHandle,

                                 &mech,

                                 hKey,

                                 (CK_BYTE_PTR)pbWrappedKey,

                                 (CK_USHORT)ulWrappedKeySize,

                                 pTemplate,

                                 usTemplateSize,

                                 &hUnWrappedKey);

      }

      // Report unwrapped key handle

      if( retCode == CKR_OK )

      {

         cout << "\n Private key Unwrapped key is:" << hUnWrappedKey <<"\n\n";

      }

      else

      {

   cout << "\n" "Error 0x" << hex << retCode;

         cout << " unwrapping.\n";

         if( pEncryptedData )

         {

            delete pEncryptedData;

         }

   error = -13;

         goto exit_routine_6;

      }

      // Release temporary memory

      if( pEncryptedData )

      {

         delete pEncryptedData;

      }

   // Create the Public Key that goes with the Private Key

   if( retCode == CKR_OK )

   {

  // Unwrap it onto the token

  pPublicRSAKeyTemplate[0].pValue = &publicKey;

  pPublicRSAKeyTemplate[1].pValue = &rsaType;

  pPublicRSAKeyTemplate[2].pValue = &bToken;

  pPublicRSAKeyTemplate[3].pValue = &bPrivate;

  pPublicRSAKeyTemplate[4].pValue = &bEncrypt;    

  pPublicRSAKeyTemplate[5].pValue = &bSign;

  pPublicRSAKeyTemplate[6].pValue = &bWrap;

  pPublicRSAKeyTemplate[7].pValue = knownRSA1Modulus;

  pPublicRSAKeyTemplate[8].pValue = knownRSA1PubExponent;

  pPublicRSAKeyTemplate[9].pValue = pbPublicRSAKeyLabel;

  pTemplate = pPublicRSAKeyTemplate;

  usTemplateSize = DIM(pPublicRSAKeyTemplate);

  retCode = C_CreateObject(  hSessionHandle,

pTemplate,

 usTemplateSize,

 &hPublicRSAKey);

  if(retCode == CKR_OK)

  {

 cout << pbPublicRSAKeyLabel << ": " << hPublicRSAKey << endl;

  }

  else

  {

 cout << "\n" "Error 0x" << hex << retCode;

 cout << " creating the RSA Public Key.\n";

 error = -14;

 goto exit_routine_6;

  }

   }

if( retCode == CKR_OK )

   {

CK_CHAR label[] = "RSA Key";

CK_ATTRIBUTE RSAFindPriTemplate[] =

{

CKA_LABEL, label, sizeof(label)

};

CK_ULONG numHandles;

CK_OBJECT_HANDLE handles[1000];

retCode = C_FindObjectsInit( hSessionHandle, RSAFindPriTemplate, 1 );

if(retCode != CKR_OK)

{

cout << "C_FindObjectsInit not returning OK (" << hex << retCode << ")\n\n";

goto exit_routine_6;

}

retCode =C_FindObjects( hSessionHandle , handles, 90,

&numHandles );

if(retCode != CKR_OK)

{

cout << "C_FindObjects not returning OK (" << hex <<

retCode << ")\n\n";

goto exit_routine_6;

}

cout << "Everything's GOOD\n\n";

for(int i=0; i < numHandles; i++)

{

cout << handles[i] << "\n";

}

}

}

//CJM-> END OF TEST CODE

   // Beginning of exit routines

exit_routine_6:

   // Logout

   retCode = C_Logout(hSessionHandle);

   if(retCode != CKR_OK)

{

cout << "\n" "Error 0x" << hex << retCode << " logging out.";

}

exit_routine_5:

// Close the session

   retCode = C_CloseSession(hSessionHandle);

if(retCode != CKR_OK)

{

cout << "\n" "Error 0x" << hex << retCode << " closing session.";

}

exit_routine_4:

   delete pSlotList;

exit_routine_3:

#ifdef PKCS11_2_0

   C_Finalize(0);

#else

   C_Terminate();

#endif

exit_routine_2:

#ifndef STATIC

   // No longer need Chrystoki

   CrystokiDisconnect();

#endif

exit_routine_1:

   cout << "\nDone. (" << dec << error << ")\n";

   cout.flush();

   return error;

}

CK_RV  Pinlogin(CK_SESSION_HANDLE hSession)

{

 

CK_RV retCode;

unsigned char buffer[MAX];

int count =0;

cout << "Please enter the USER password : " << endl;

//calling get PinString to mask input, variable "count"

//holds length of "buffer"(password)

//needed for Login call

count = getPinString(buffer);

//Login as user on  token in slot

retCode = C_Login(hSession, CKU_USER, buffer, count);

if(retCode != CKR_OK)

{

cout << "\n" "Error 0x" << hex << retCode;

      cout << " logging in as user.";

  exit(hSession);

  return -3;

}

cout << "logging into the token....";

cout << "\nlogged into token " << endl;

return retCode;

}

///////////////////////////////////////////////////////////////////////

// getPinString()

// ==============

//

// This function retrieves a pin string from the user.  It modifies the

// console mode before starting so that the characters the user types are

// not echoed, and a '*' character is displayed for each typed character

// instead.

//

// Backspace is supported, but we don't get any fancier than that.

////////////////////////////////////////////////////////////////////////

int getPinString(CK_CHAR_PTR pw)

{

    int len=0;

    char c=0;

    // Unfortunately, the method of turning off character echo is

// different for Windows and Unix platforms.  So we have to

// conditionally compile the appropriate section.  Even the basic

// password retrieval is slightly different, since

    // Windows and Unix use different character codes for the return key.

#ifdef WIN32

    DWORD mode;

    // This console mode stuff only applies to windows.  We'll have to

// do something else when it comes to unix.

    if (GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode)) {

        if (SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode & (!ENABLE_ECHO_INPUT))) {

            while (c  != '\r') {

                // wait for a character to be hit

                while (!_kbhit()) {

                    Sleep(100);

                }

                // get it

                c = _getch();

                // check for carriage return

                if (c != '\r') {

                    // check for backspace

                    if (c!='\b') {

                        // neither CR nor BS -- add it to the password string

                        printf("*");

                        *pw++ = c;

                        len++;

                    } else {

// handle backspace -- delete the last character &

// erase it from the screen

                        if (len > 0) {

                            pw--;

                            len--;

                            printf("\b \b");

}

}

}

}

            // Add the zero-termination

            *pw = '\0';

            SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode);

            printf("\n");

}

    }

#endif

    return len;

}