Added a new Attribute to store TPM key handle
[aaf/sshsm.git] / SoftHSMv2 / src / lib / HwInfra / HwInfra.cpp
1 /* Copyright 2018 Intel Corporation, Inc
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *       http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <sys/types.h>
19 #include <dirent.h>
20 #include <string.h>
21 #include <dlfcn.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include "HwInfra.h"
26 #include "hwpluginif.h"
27 #include "OSAttributes.h"
28 #include "cryptoki.h"
29
30 char hw_plugins_parent_dir[MAX_PARENT_PATH_NAME+1] = "";
31 char *default_hw_plugin_parent_dir = "/tmp/hwparent/";
32 void *g_dl_handle;
33 SSHSM_HW_FUNCTIONS_t g_pluginfuncs;
34
35 /**
36   Function name : prepareHWPlugin
37   Description:  This function is expected to be called by C_Initialize
38   of softHSM.  This function does following
39   -- Reads the parent directory entries
40   -- If the subdirectory entry starts with 'S', then it calls loadHWPlugin
41   -- if the loadHWPlugin returns failure, then it finds the next subdirectory
42      that start with 'S' and calls loadHWPlugin.
43 **/
44
45 int prepareHWPlugin()
46 {
47   DIR *dirhandle;
48   struct dirent *entry;
49   int len;
50   char *env;
51   int ret_val = 0;
52
53   LOG("%s() called \n", __func__);
54   /** check if there is any envrionment variable defined to represent
55    ** hw plugin parent directory.
56    **/
57   env = getenv("SSHSM_HW_PLUGINS_PARENT_DIR");
58   if (env != NULL)
59   {
60      len = strlen(env);
61      if (len > MAX_PARENT_PATH_NAME)
62      {
63         LOG("SSHSM_HW_PLUGINS_PARENT_DIR environment is too long %d \n", len);
64         return(SSHSM_HW_PLUGIN_ERROR_BASE + ENVIRONMENT_TOO_LONG);
65      }
66      strcpy(hw_plugins_parent_dir, env);
67   }
68   else
69   {
70      strcpy(hw_plugins_parent_dir, default_hw_plugin_parent_dir);
71   }
72
73   /**Read parent directory entries **/
74   ret_val = -1;
75   dirhandle = opendir (hw_plugins_parent_dir);
76   if (dirhandle != NULL)
77     {
78       int count = 0;
79       while (NULL != (entry = readdir (dirhandle)) )
80       {
81          count++;
82          /**Check if it is directory **/
83          if (entry->d_type == DT_DIR)
84          {
85              /** See if it starts with 'S' **/
86              if ((entry->d_name[0] == 'S') ||
87                  (entry->d_name[0] == 's') )
88              {
89                 /** Load plugin.so file if it exists in the subdirectory
90                     load it and check whether the HW is present by calling
91                     init function  **/
92                 ret_val = loadHWPlugin( hw_plugins_parent_dir,
93                                 entry->d_name);
94                 if(ret_val == 0)
95                 {
96                   break;
97                 }
98              }
99          }
100       }
101     }
102   else
103   {
104     LOG ("Couldn't open the directory \n");
105     return ret_val;
106   }
107
108   closedir(dirhandle);
109   return ret_val;
110 }
111
112 /**
113   Function name : loadHWPlugin
114   Description:  It first checks whether there is plugin.so file, activate
115   directory and at least one key directory. if any of them not present, then
116   it returns error.  If all three are present, then it calls
117   of softHSM.  It calls HwPlugin_Initiate_Activate_and_load_key() function.
118 **/
119
120 int loadHWPlugin(char *parent_dir, char *pluginsubdir)
121 {
122    char fullpath[256+1];
123    DIR *dirhandle;
124    struct dirent *entry;
125    char so_present, activate_dir_present, key_dir_present;
126    hwpluginentries_t *entries;
127    int ret_val = -1;
128
129    if (strlen(parent_dir) + strlen(pluginsubdir) > 256 )
130    {
131      LOG("hwpluing path is too long  \n");
132      return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
133    }
134
135    strcpy(fullpath, parent_dir);
136    strcat(fullpath, pluginsubdir);
137
138    dirhandle = opendir(fullpath);
139
140    entries = (hwpluginentries_t*)malloc(sizeof(hwpluginentries_t));
141    if (entries == NULL )
142    {
143      LOG("Could not allocate entries  \n");
144      closedir(dirhandle);
145      return(SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
146    }
147    memset(entries, 0, sizeof(hwpluginentries_t));
148
149    if (dirhandle != NULL)
150    {
151       so_present = 0;
152       activate_dir_present = 0;
153       key_dir_present = 0;
154       while (NULL != (entry = readdir (dirhandle)) )
155       {
156          /** Ensure that the directory has plugin.so file, activate directory,
157           ** at least one key directory
158           **/
159
160           if ((entry->d_type == DT_REG) &&
161               (strcmp(entry->d_name, "plugin.so") == 0))
162           {
163              so_present = 1;
164              if (strlen(fullpath) + strlen("/")+ strlen(entry->d_name) > 256)
165              {
166                 LOG("plugin so path is too long  \n");
167                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
168                 break;
169              }
170              strcpy(entries->so_full_path, fullpath);
171              strcat(entries->so_full_path, "/");
172              strcat(entries->so_full_path, entry->d_name);
173           }
174
175           if ((entry->d_type == DT_DIR) &&
176               (strcmp(entry->d_name, "activate") == 0 ))
177           {
178              activate_dir_present = 1;
179              if (strlen(fullpath) + 2*strlen("/")+ strlen(entry->d_name) > 256)
180              {
181                 LOG("activate path is too long  \n");
182                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
183                 break;
184              }
185              strcpy(entries->activate_dir_full_path, fullpath);
186              strcat(entries->activate_dir_full_path, "/");
187              strcat(entries->activate_dir_full_path, entry->d_name);
188              strcat(entries->activate_dir_full_path, "/");
189           }
190
191           if ((entry->d_type == DT_DIR) &&
192               (strncmp(entry->d_name, "key", 3) == 0 ))
193           {
194              key_dir_present = 1;
195              if (strlen(fullpath) + 2*strlen("/")+ strlen(entry->d_name) > 256)
196              {
197                 LOG("activate path is too long  \n");
198                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
199                 break;
200              }
201              strcpy(entries->key_dir_full_path[entries->num_key_dirs],
202                              fullpath);
203              strcat(entries->key_dir_full_path[entries->num_key_dirs], "/");
204              strcat(entries->key_dir_full_path[entries->num_key_dirs],
205                               entry->d_name);
206              strcat(entries->key_dir_full_path[entries->num_key_dirs], "/");
207              entries->num_key_dirs++;
208           }
209
210           if (so_present && activate_dir_present && key_dir_present)
211           {
212               printf("so dir path: %s \n", entries->so_full_path);
213               printf("activate dir path: %s \n", entries->activate_dir_full_path);
214               ret_val = HwPlugin_Initiate_Activate_and_load_keys(entries);
215               break;
216           }
217       }
218
219       if (!so_present || !activate_dir_present || !key_dir_present)
220       {
221           LOG("Minimum set of entries not present hwplugin dir plugindir %s so_present %d activate present %d key present %d \n", fullpath,  so_present, activate_dir_present, key_dir_present);
222           return(SSHSM_HW_PLUGIN_ERROR_BASE + INCOMPLETE_PLUGIN_DIR);
223       }
224    }
225    else
226    {
227      LOG("Could not open hwplugin directory %s \n", fullpath);
228      return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_OPEN_ERROR);
229    }
230    free(entries);
231    closedir(dirhandle);
232    return(ret_val);
233 }
234
235
236 /**
237 ** Function name: HWPlugin_Initiate_Activate_and_load_keys
238 ** Description:  This function loads plugin, gets the function pointers,
239 ** activates the plugin and then finally loads the keys
240 **/
241 int HwPlugin_Initiate_Activate_and_load_keys(hwpluginentries_t *entries)
242 {
243      int ret_val;
244
245      ret_val = load_hw_plugin_and_get_function_pointers(entries->so_full_path,
246                    &g_pluginfuncs);
247      if(ret_val != 0)
248         return(ret_val);
249
250      ret_val = init_hw_plugin(&g_pluginfuncs);
251      if(ret_val != 0 )
252         return(ret_val);
253
254      ret_val = activate_hw_plugin(entries, &g_pluginfuncs);
255      if (ret_val != 0 )
256        return(ret_val);
257
258      ret_val = load_keys_in_hw_plugin(entries, &g_pluginfuncs);
259      if (ret_val != 0 )
260        return(ret_val);
261
262      return(0);
263 }
264
265
266 /**
267   Function name : load_hw_plugin_and_get_function_pointers
268 **/
269
270 int load_hw_plugin_and_get_function_pointers(char *so_path,
271               SSHSM_HW_FUNCTIONS_t *funcs)
272 {
273    int (*functogetpluginfuncs)(SSHSM_HW_FUNCTIONS_t *fs);
274    int ret_val;
275
276    g_dl_handle = dlopen(so_path, RTLD_NOW);
277    if(g_dl_handle == NULL )
278    {
279        LOG("dlopen on %s failed: %s \n", so_path, dlerror());
280        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_DL_OPEN_ERROR);
281    }
282
283    functogetpluginfuncs = NULL;
284    functogetpluginfuncs = (int (*)(SSHSM_HW_FUNCTIONS_t *)) dlsym(g_dl_handle,
285              "sshsm_hw_plugin_get_plugin_functions");
286
287    if (functogetpluginfuncs == NULL)
288    {
289        LOG("dlsym of sshsm_hw_plugin_get_plugin_functions : %s \n", dlerror() );
290        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_DL_SYM_ERROR);
291    }
292
293    ret_val = functogetpluginfuncs(funcs);
294
295     return ret_val;
296 }
297
298 int init_hw_plugin(SSHSM_HW_FUNCTIONS_t *funcs)
299 {
300     int ret_val;
301
302     ret_val = (funcs->xxx_init)();
303
304     if(ret_val != 0 )
305     {
306        LOG("HWPlugin init failed \n" );
307        return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
308
309     }
310     return(ret_val);
311 }
312
313
314 int activate_hw_plugin(hwpluginentries_t *entries, SSHSM_HW_FUNCTIONS_t *funcs)
315 {
316    int ret_val;
317
318    if( (entries == NULL) || (funcs == NULL) )
319    {
320      ret_val = -1;
321      LOG("activate_hw_plugin: Input values are NULL \n");
322      return ret_val;
323    }
324    /** Read all files starting with 'A' and pass the information to
325     ** plugin
326     **/
327
328    SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t comp_buffers;
329
330    memset(&comp_buffers, 0, sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t));
331
332    ret_val = get_all_file_contents(entries->activate_dir_full_path, 'A',
333                        &comp_buffers);
334
335    if (ret_val == 0 )
336    {
337      ret_val = (funcs->xxx_activate)(&comp_buffers);
338      //free_buffers(&comp_buffers);
339    }
340
341    return(ret_val);
342 }
343
344 int load_keys_in_hw_plugin(hwpluginentries_t *entries,
345                    SSHSM_HW_FUNCTIONS_t *funcs)
346 {
347
348     int ret_val;
349     void *key_handle;
350     int ii;
351     //unsigned long hwkeyhandle=987654321;
352     //key_handle = (void *) &hwkeyhandle;
353
354     SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t comp_buffers;
355     SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t import_public_key;
356
357     /**
358      Travese through all key directories and load the key in plugin
359     **/
360
361     ret_val = -1;
362     for(ii = 0; ii < entries->num_key_dirs; ii++)
363     {
364        memset(&comp_buffers, 0,
365           sizeof(SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t));
366
367        ret_val = get_all_file_contents(entries->key_dir_full_path[ii], 'K',
368                         &comp_buffers);
369
370        if(ret_val == 0)
371        {
372            ret_val = (funcs->xxx_load_key)(&comp_buffers, &key_handle,
373                                                        &import_public_key);
374            //free_buffers(&comp_buffers);
375            if(ret_val == 0)
376            {
377                /** Get PKCS11 information **/
378                /** Call SoftHSM functions to create private key object */
379                if (ret_val == 0) {
380                    ret_val = program_pkcs11_info(entries->key_dir_full_path[ii],
381                                              &key_handle,  &import_public_key);
382                    if (import_public_key.modulus != NULL)
383                       free(import_public_key.modulus);
384                    if (import_public_key.exponent != NULL)
385                       free(import_public_key.exponent);
386                }
387            }
388        }
389
390     }
391
392     return(ret_val);
393 }
394
395 int get_all_file_contents(char *dirpath, char starting_char,
396                   SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers )
397 {
398    DIR *dirhandle;
399    struct dirent *entry;
400
401    buffer_info_t *buffer;
402    char *token;
403
404    struct stat st;
405    int fd;
406
407    int ret_val = 0;
408
409
410    char fullpath[256+1];
411
412    dirhandle = opendir(dirpath);
413    if (dirhandle != NULL)
414    {
415       while (NULL != (entry = readdir (dirhandle)))
416       {
417          if ((entry->d_type == DT_REG) &&
418               (entry->d_name[0] == starting_char))
419          {
420              buffer = (buffer_info_t*) malloc(sizeof(buffer_info_t));
421              if (buffer == NULL )
422              {
423                LOG("Could not allocate entries  \n");
424                ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
425                break;
426              }
427              token = strchr(entry->d_name, '.');
428              strcpy(buffer->id, token+1);
429
430              /** get full path of the file **/
431              if ((strlen(dirpath) + strlen(entry->d_name)) > 256)
432              {
433                 LOG("file  path is too long  \n");
434                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
435                 free(buffer);
436                 break;
437              }
438              strcpy(fullpath,dirpath);
439              strcat(fullpath, entry->d_name);
440              stat(fullpath, &st);
441              buffer->buffer = (unsigned char*) malloc(st.st_size);
442              if(buffer->buffer == NULL)
443              {
444                LOG("Could not allocate entries  \n");
445                ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
446                free(buffer);
447                break;
448              }
449              buffer->length_of_buffer = st.st_size;
450              fd = open(fullpath, O_RDONLY);
451              if (fd == -1 )
452              {
453                LOG("Could not open file %s  \n", fullpath);
454                ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + ALLOCATION_ERROR);
455                free(buffer->buffer);
456                free(buffer);
457                break;
458              }
459
460              if(read(fd, buffer->buffer, st.st_size) < 0)
461              {
462                 LOG("Reading from file %s failed \n", fullpath);
463                 continue;
464              }
465
466              close(fd);
467
468              /** Now write this buffer in c_buffers **/
469              c_buffers->buffer_info[c_buffers->num_buffers] = buffer;
470              c_buffers->num_buffers++;
471
472          }
473       }
474    }
475    else
476    {
477      LOG("Could not open hwplugin directory %s \n", dirpath);
478      return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_OPEN_ERROR);
479    }
480
481    closedir(dirhandle);
482    //if (ret_val != 0 )
483      //free_buffers(c_buffers);
484
485    return(ret_val);
486 }
487
488 void free_buffers ( SSHSM_HW_PLUGIN_ACTIVATE_LOAD_IN_INFO_t *c_buffers )
489 {
490    int ii;
491
492    for(ii = 0; ii < c_buffers->num_buffers; ii++)
493    {
494       free(c_buffers->buffer_info[ii]->buffer);
495       free(c_buffers->buffer_info[ii]);
496    }
497 }
498
499 int program_pkcs11_info (char *dirpath, void *key_handle,
500                          SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *import_public_key)
501 {
502    DIR *dirhandle;
503    struct dirent *entry;
504
505    char fullpath[256+1];
506    int ret_val = 0;
507
508    FILE *fp;
509    char buffer[80+1];
510
511    unsigned int  slot_id = 0;
512    unsigned char upin[64+1];
513    int upin_len = 0;
514    unsigned char keyid[64+1];
515    int key_id_len = 0;
516    unsigned char key_label[64+1] = "";
517    char *valuep;
518    char *endvalue;
519
520
521    dirhandle = opendir(dirpath);
522    if (dirhandle != NULL)
523    {
524       while (NULL != (entry = readdir (dirhandle)))
525       {
526            if (strcmp(entry->d_name, "pkcs11.cfg") == 0 )
527            {
528               /** get full path of the file **/
529                if ((strlen(dirpath) + strlen(entry->d_name)) > 256)
530              {
531                 LOG("file  path is too long  \n");
532                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
533                 break;
534              }
535              strcpy(fullpath,dirpath);
536              strcat(fullpath, entry->d_name);
537
538              fp = fopen(fullpath, "r");
539              if(fp == NULL )
540              {
541                 ret_val = (SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_PATH_TOO_LONG);
542                 break;
543              }
544              while (fgets(buffer, 80, fp) != NULL)
545              {
546                  valuep = strchr(buffer, ':');
547                  if(valuep == NULL)
548                     continue;
549                  valuep[0] = '\0';
550
551                  /** Looks like \n is part of buffer that is read via fgets
552                   ** Replacce tha with 0 **/
553                  endvalue = strchr(valuep+1, '\n');
554                  if(endvalue != NULL)
555                     endvalue[0] =  '\0';
556                  if (strcmp(buffer, "slot") == 0)
557                  {
558                     slot_id = strtoul(valuep+1, NULL, 10);
559                     continue;
560                  }
561                  if(strcmp(buffer, "key_id") == 0 )
562                  {
563                     strcpy((char*)keyid, valuep+1);
564                     key_id_len = strlen((char*)keyid);
565                     continue;
566                  }
567                  if(strcmp(buffer, "key_label") == 0 )
568                  {
569                     strcpy((char*)key_label, valuep+1);
570                     continue;
571                  }
572                  if(strcmp(buffer, "upin") == 0 )
573                  {
574                     strcpy((char*) upin, valuep+1);
575                     upin_len = strlen((char *) upin);
576                     continue;
577                  }
578              }
579              fclose(fp);
580
581              /** Program key in SoftHSM **/
582              ret_val = PrepareKeyInSoftHSM(slot_id, upin, upin_len, keyid,
583                            key_id_len, key_label, key_handle, import_public_key);
584
585               break;
586            }
587
588       }
589    }
590
591    return ret_val;
592 }
593
594
595 void long_to_byte_string(const unsigned long longValue, unsigned char *out, size_t *outlen)
596 {
597         unsigned long setValue = longValue;
598         unsigned char byteStrIn[8];
599         size_t i;
600
601         for (i = 0; i < 8; i++)
602         {
603             byteStrIn[7-i] = (unsigned char) (setValue & 0xFF);
604             setValue >>= 8;
605         }
606         for (i = 0; i < 8; i++)
607         {
608             if (byteStrIn[i])
609                break;
610         }
611         memcpy(out, &byteStrIn[i], 8-i);
612         *outlen = 8-i;
613 }
614
615
616
617 /*** PrepareKeyInSoftHSM
618 ** Description:  It creates the object in softhsm with given key id and
619 ** key label and also stores the keyhandle that was returned by hardware plugin
620 ** Inputs:
621 **   -  Slot ID
622 **   -  Key ID
623 **   -  Key Label
624 **   -  upin
625 **   -  pluginkeyHandle
626 ** Output:
627 **    - None
628 ** Renturs
629 **     - SUCCESS or FAILURE
630 *****/
631 int PrepareKeyInSoftHSM(unsigned int slot_id,
632                unsigned char *upin, int upin_len,
633                unsigned char *key_id, int key_id_len,
634                unsigned char *key_label, void *key_handle,
635                SSHSM_HW_PLUGIN_IMPORT_PUBLIC_KEY_INFO_t *import_public_key)
636 {
637     CK_SESSION_HANDLE hSession;
638     CK_RV ret_val;
639     int ii;
640     CK_OBJECT_HANDLE hKey;
641     unsigned char key_handle_str[32] = {0};
642
643     printf ("slot %ul upin %s key_id %s key_label %s \n", slot_id, upin, key_id,
644              key_label);
645     if(!key_handle)
646     {
647         printf("Input Key handle is NULL ! \n");
648         return (SSHSM_HW_PLUGIN_ERROR_BASE + INVALID_KEY_ERROR);
649     }
650     if (import_public_key->modulus == NULL ||
651                     import_public_key->exponent == NULL)
652     {
653          return (SSHSM_HW_PLUGIN_ERROR_BASE + INVALID_KEY_ERROR);
654     }
655
656     /** For creating the key object, first the session needs to be opened
657         C_OpenSession is used to open the session
658      **/
659     ret_val = C_OpenSession(slot_id, CKF_SERIAL_SESSION | CKF_RW_SESSION,
660                             NULL_PTR, NULL_PTR, &hSession);
661
662     if (ret_val != CKR_OK)
663     {
664         printf("OpenSession failed for slot %x \n", slot_id);
665         return(ret_val);
666     }
667
668     /** Next step is login
669      ** C_Login is used to login to the session
670      **/
671     ret_val = C_Login(hSession, CKU_USER,  upin, upin_len);
672     if (ret_val != CKR_OK)
673     {
674         printf("Login failed: 0x%lx | for slot %x upin below \n", ret_val, slot_id);
675         for (ii = 0; ii < upin_len; ii++ )
676            printf("%2x  %c \n",  upin[ii], upin[ii]);
677         return(ret_val);
678     }
679
680     CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
681     CK_KEY_TYPE keyType = CKK_RSA;
682     CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE ;
683
684     unsigned long int key_id_int = atol( (const char*) key_id );
685     unsigned char byte_str[8];
686     size_t outlen;
687     long_to_byte_string(key_id_int, byte_str, &outlen);
688
689     CK_ATTRIBUTE keyTemplate[] = {
690         { CKA_CLASS,            &privClass,         sizeof(privClass) },
691         { CKA_KEY_TYPE,         &keyType,           sizeof(keyType) },
692         { CKA_LABEL,            key_label,          strlen((char *) key_label) },
693         { CKA_ID,               byte_str,           outlen },
694         { CKA_SIGN,             &ckTrue,            sizeof(ckTrue) },
695         { CKA_DECRYPT,          &ckTrue,            sizeof(ckTrue) },
696         { CKA_UNWRAP,           &ckFalse,           sizeof(ckFalse) },
697         { CKA_TOKEN,            &ckTrue,            sizeof(ckTrue) },
698         { CKA_PRIVATE,          &ckTrue,            sizeof(ckTrue) },
699         { CKA_EXTRACTABLE,      &ckFalse,           sizeof(ckFalse) },
700         { CKA_SENSITIVE,        &ckFalse,           sizeof(ckFalse) },
701         { CKA_PUBLIC_EXPONENT,  import_public_key->exponent, import_public_key->exponent_size},
702         //{ CKA_MODULUS,          pN,                 sizeof(pN) },
703         { CKA_MODULUS,          import_public_key->modulus, import_public_key->modulus_size },
704         { CKA_PRIVATE_EXPONENT, 0,                 0 },
705         { CKA_PRIME_2,          0,                  0},
706         { CKA_EXPONENT_1,       0,                  0},
707         { CKA_EXPONENT_2,       0,                  0},
708         { CKA_COEFFICIENT,      0,                  0},
709         { CKA_OS_PRIVATE_HANDLE,       (CK_VOID_PTR ) *((CK_ULONG*)key_handle),      sizeof(CK_ULONG) }
710     };
711
712
713     CK_OBJECT_HANDLE hObject;
714     CK_ULONG ulObjectCount;
715     CK_RV rv;
716
717     rv = C_FindObjectsInit(hSession, keyTemplate, 0);
718     if(rv != CKR_OK) {
719         LOG ("C_FindObjectsInit rv %ld\n", rv);
720     }
721     rv = C_FindObjects(hSession, &hObject, 16, &ulObjectCount);
722     printf("PrepareKeyInSoftHSM: ulObjectCount %ld\n", ulObjectCount);
723     if(rv != CKR_OK || ulObjectCount == 0) {
724         ret_val =  C_CreateObject(hSession, keyTemplate,
725                  sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE),&hKey);
726         if (ret_val != CKR_OK)
727         {
728             printf("CreateObject failed: 0x%lx | for slot %x | keylabel %s | keyid below \n",
729                 ret_val, slot_id, key_label);
730             for (ii = 0; ii < key_id_len; ii++ )
731                printf("%2x  %c \n",  key_id[ii], key_id[ii]);
732         //return(ret_val);
733         }
734     }
735     else {
736         printf("PrepareKeyInSoftHSM: Object already exists\n");
737     }
738
739     rv = C_FindObjectsFinal(hSession);
740     if(rv != CKR_OK) {
741         LOG ("C_FindObjectsFinal rv %ld\n", rv);
742     }
743
744     ret_val = C_Logout(hSession);
745     if (ret_val != CKR_OK)
746     {
747         printf("Logout failed 0x%lx | for slot %x \n", ret_val, slot_id);
748         return(ret_val);
749     }
750
751     ret_val = C_CloseSession(hSession);
752     if (ret_val != CKR_OK)
753     {
754         printf("C_CloseSession failed for slot %x \n", slot_id);
755         return(ret_val);
756     }
757
758     return ret_val;
759 }
760
761 int HwInfraSignInit(void *keyHandle,  unsigned long mechanism,
762                  void* param, int paramLen, void **hwCryptoOpaque)
763 {
764     if (g_pluginfuncs.xxx_rsa_sign_init == NULL)
765         return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
766
767     return (g_pluginfuncs.xxx_rsa_sign_init(keyHandle, mechanism, param,
768                                                  paramLen, hwCryptoOpaque)) ;
769
770 }
771
772 int HwInfraSign(void *keyHandle,  unsigned long mechanism,
773                  unsigned char *msg, int msg_len, void *hwCryptoOpaque,
774                  unsigned char *outsig,  int *outsiglen)
775 {
776     if (g_pluginfuncs.xxx_rsa_sign == NULL)
777         return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
778
779     return ( g_pluginfuncs.xxx_rsa_sign(keyHandle, mechanism, msg, msg_len,
780                 hwCryptoOpaque, outsig, outsiglen) );
781 }
782
783 int HwInfraSignUpdate(void *keyHandle, unsigned long mechanism,
784                       unsigned char *param, int paramLen, void *hwCryptoOpaque)
785 {
786     if (g_pluginfuncs.xxx_rsa_sign_update == NULL)
787         return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
788
789     int x =  ( g_pluginfuncs.xxx_rsa_sign_update(keyHandle, mechanism, param,
790                                                paramLen, hwCryptoOpaque) );
791     return 0;
792 }
793
794 int HwInfraSignFinal(void *keyHandle, unsigned long mechanism,
795                   void *hwCryptoOpaque,
796                  unsigned char *outsig,  int *outsiglen)
797 {
798     if (g_pluginfuncs.xxx_rsa_sign_final == NULL)
799         return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
800
801     return ( g_pluginfuncs.xxx_rsa_sign_final(keyHandle, mechanism,
802                                      hwCryptoOpaque, outsig, outsiglen) );
803 }
804
805 int HwInfraSignCleanup(void *keyHandle, unsigned long mechanism,
806                        void *hwCryptoOpaque)
807 {
808     if (g_pluginfuncs.xxx_rsa_sign_cleanup == NULL)
809         return(SSHSM_HW_PLUGIN_ERROR_BASE + PLUGIN_INIT_ERROR);
810
811     return ( g_pluginfuncs.xxx_rsa_sign_cleanup(keyHandle, mechanism,
812                                                 hwCryptoOpaque) );
813 }
814