Migrating Keys From Software to a SafeNet Luna PCIe HSM
SafeNet Luna PCIe 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 Luna PCIe HSM.
Sample Program
The sample program below encrypts a known RSA private key, then unwraps the key pair onto the SafeNet Luna PCIe 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) 2017, Gemalto, 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;
}