1 /*
2  * COPYRIGHT (c) International Business Machines Corp. 2005-2017
3  *
4  * This program is provided under the terms of the Common Public License,
5  * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
6  * software constitutes recipient's acceptance of CPL-1.0 terms which can be
7  * found in the file LICENSE file or at
8  * https://opensource.org/licenses/cpl1.0.php
9  */
10 
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "pkcs11types.h"
15 #include "defs.h"
16 #include "host_defs.h"
17 #include "h_extern.h"
18 #include "tok_spec_struct.h"
19 #include "trace.h"
20 
mech_array_to_list(struct mech_list_item * head,MECH_LIST_ELEMENT mech_list_arr[],int list_len)21 void mech_array_to_list(struct mech_list_item *head,
22                         MECH_LIST_ELEMENT mech_list_arr[], int list_len)
23 {
24     int i;
25     struct mech_list_item *current;
26     current = head;
27     for (i = 0; i < list_len; i++) {
28         current->next = malloc(sizeof(struct mech_list_item));
29         current = current->next;
30         memcpy(&current->element, &mech_list_arr[i], sizeof(MECH_LIST_ELEMENT));
31     }
32 }
33 
find_mech_list_item_for_type(CK_MECHANISM_TYPE type,struct mech_list_item * head)34 struct mech_list_item *find_mech_list_item_for_type(CK_MECHANISM_TYPE type,
35                                                     struct mech_list_item *head)
36 {
37     struct mech_list_item *res;
38     res = head->next;
39     while (res) {
40         if (res->element.mech_type == type) {
41             goto out;
42         }
43         res = res->next;
44     }
45 
46 out:
47     return res;
48 }
49 
free_mech_list(struct mech_list_item * head)50 void free_mech_list(struct mech_list_item *head)
51 {
52     struct mech_list_item *walker;
53     walker = head->next;
54     while (walker) {
55         struct mech_list_item *next;
56         next = walker->next;
57         free(walker);
58         walker = next;
59     }
60 }
61 
62 /**
63  * If a type exists in the source that is not in the target, copy it
64  * over. If a type exists in both the source and the target, overwrite
65  * the target.
66  */
merge_mech_lists(struct mech_list_item * head_of_target,struct mech_list_item * head_of_source)67 void merge_mech_lists(struct mech_list_item *head_of_target,
68                       struct mech_list_item *head_of_source)
69 {
70     UNUSED(head_of_target);
71     UNUSED(head_of_source);
72 }
73 
ock_generic_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)74 CK_RV ock_generic_get_mechanism_list(CK_MECHANISM_TYPE_PTR pMechanismList,
75                                      CK_ULONG_PTR pulCount)
76 {
77     int rc = CKR_OK;
78     unsigned int i;
79     if (pMechanismList == NULL) {
80         (*pulCount) = mech_list_len;
81         goto out;
82     }
83     if ((*pulCount) < mech_list_len) {
84         (*pulCount) = mech_list_len;
85         TRACE_ERROR("%s\n", ock_err(ERR_BUFFER_TOO_SMALL));
86         rc = CKR_BUFFER_TOO_SMALL;
87         goto out;
88     }
89     for (i = 0; i < mech_list_len; i++)
90         pMechanismList[i] = mech_list[i].mech_type;
91     (*pulCount) = mech_list_len;
92 
93 out:
94     return rc;
95 }
96 
ock_generic_get_mechanism_info(CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)97 CK_RV ock_generic_get_mechanism_info(CK_MECHANISM_TYPE type,
98                                      CK_MECHANISM_INFO_PTR pInfo)
99 {
100     int rc = CKR_OK;
101     unsigned int i;
102     for (i = 0; i < mech_list_len; i++) {
103         if (mech_list[i].mech_type == type) {
104             memcpy(pInfo, &mech_list[i].mech_info, sizeof(CK_MECHANISM_INFO));
105             goto out;
106         }
107     }
108     TRACE_ERROR("%s\n", ock_err(ERR_MECHANISM_INVALID));
109     rc = CKR_MECHANISM_INVALID;
110 
111 out:
112     return rc;
113 }
114 
115 /*
116  * For Netscape we want to not support the SSL3 mechs since the native
117  * ones perform much better.  Force those slots to be RSA... it's ugly
118  * but it works.
119  */
netscape_hack(CK_MECHANISM_TYPE_PTR mech_arr_ptr,CK_ULONG count)120 static void netscape_hack(CK_MECHANISM_TYPE_PTR mech_arr_ptr, CK_ULONG count)
121 {
122     char *envrn;
123     CK_ULONG i;
124     if ((envrn = getenv("NS_SERVER_HOME")) != NULL) {
125         for (i = 0; i < count; i++) {
126             switch (mech_arr_ptr[i]) {
127             case CKM_SSL3_PRE_MASTER_KEY_GEN:
128             case CKM_SSL3_MASTER_KEY_DERIVE:
129             case CKM_SSL3_KEY_AND_MAC_DERIVE:
130             case CKM_SSL3_MD5_MAC:
131             case CKM_SSL3_SHA1_MAC:
132                 mech_arr_ptr[i] = CKM_RSA_PKCS;
133                 break;
134             }
135         }
136     }
137 }
138 
mechanism_list_transformations(CK_MECHANISM_TYPE_PTR mech_arr_ptr,CK_ULONG_PTR count_ptr)139 void mechanism_list_transformations(CK_MECHANISM_TYPE_PTR mech_arr_ptr,
140                                     CK_ULONG_PTR count_ptr)
141 {
142     netscape_hack(mech_arr_ptr, (*count_ptr));
143 }
144