1 /* $NetBSD: test_soft_pkcs11.c,v 1.1.1.2 2014/04/24 12:45:42 pettai Exp $ */ 2 3 /* 4 * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "hx_locl.h" 37 #include "pkcs11.h" 38 #include <err.h> 39 40 static CK_FUNCTION_LIST_PTR func; 41 42 43 static CK_RV 44 find_object(CK_SESSION_HANDLE session, 45 char *id, 46 CK_OBJECT_CLASS key_class, 47 CK_OBJECT_HANDLE_PTR object) 48 { 49 CK_ULONG object_count; 50 CK_RV ret; 51 CK_ATTRIBUTE search_data[] = { 52 {CKA_ID, id, 0 }, 53 {CKA_CLASS, &key_class, sizeof(key_class)} 54 }; 55 CK_ULONG num_search_data = sizeof(search_data)/sizeof(search_data[0]); 56 57 search_data[0].ulValueLen = strlen(id); 58 59 ret = (*func->C_FindObjectsInit)(session, search_data, num_search_data); 60 if (ret != CKR_OK) 61 return ret; 62 63 ret = (*func->C_FindObjects)(session, object, 1, &object_count); 64 if (ret != CKR_OK) 65 return ret; 66 if (object_count == 0) { 67 printf("found no object\n"); 68 return 1; 69 } 70 71 ret = (*func->C_FindObjectsFinal)(session); 72 if (ret != CKR_OK) 73 return ret; 74 75 return CKR_OK; 76 } 77 78 static char *sighash = "hej"; 79 static char signature[1024]; 80 81 82 int 83 main(int argc, char **argv) 84 { 85 CK_SLOT_ID_PTR slot_ids; 86 CK_SLOT_ID slot; 87 CK_ULONG num_slots; 88 CK_RV ret; 89 CK_SLOT_INFO slot_info; 90 CK_TOKEN_INFO token_info; 91 CK_SESSION_HANDLE session; 92 CK_OBJECT_HANDLE public, private; 93 94 ret = C_GetFunctionList(&func); 95 if (ret != CKR_OK) 96 errx(1, "C_GetFunctionList failed: %d", (int)ret); 97 98 (*func->C_Initialize)(NULL_PTR); 99 100 ret = (*func->C_GetSlotList)(FALSE, NULL, &num_slots); 101 if (ret != CKR_OK) 102 errx(1, "C_GetSlotList1 failed: %d", (int)ret); 103 104 if (num_slots == 0) 105 errx(1, "no slots"); 106 107 if ((slot_ids = calloc(1, num_slots * sizeof(*slot_ids))) == NULL) 108 err(1, "alloc slots failed"); 109 110 ret = (*func->C_GetSlotList)(FALSE, slot_ids, &num_slots); 111 if (ret != CKR_OK) 112 errx(1, "C_GetSlotList2 failed: %d", (int)ret); 113 114 slot = slot_ids[0]; 115 free(slot_ids); 116 117 ret = (*func->C_GetSlotInfo)(slot, &slot_info); 118 if (ret) 119 errx(1, "C_GetSlotInfo failed: %d", (int)ret); 120 121 if ((slot_info.flags & CKF_TOKEN_PRESENT) == 0) 122 errx(1, "no token present"); 123 124 ret = (*func->C_OpenSession)(slot, CKF_SERIAL_SESSION, 125 NULL, NULL, &session); 126 if (ret != CKR_OK) 127 errx(1, "C_OpenSession failed: %d", (int)ret); 128 129 ret = (*func->C_GetTokenInfo)(slot, &token_info); 130 if (ret) 131 errx(1, "C_GetTokenInfo1 failed: %d", (int)ret); 132 133 if (token_info.flags & CKF_LOGIN_REQUIRED) { 134 ret = (*func->C_Login)(session, CKU_USER, 135 (unsigned char*)"foobar", 6); 136 if (ret != CKR_OK) 137 errx(1, "C_Login failed: %d", (int)ret); 138 } 139 140 ret = (*func->C_GetTokenInfo)(slot, &token_info); 141 if (ret) 142 errx(1, "C_GetTokenInfo2 failed: %d", (int)ret); 143 144 if (token_info.flags & CKF_LOGIN_REQUIRED) 145 errx(1, "login required, even after C_Login"); 146 147 ret = find_object(session, "cert", CKO_PUBLIC_KEY, &public); 148 if (ret != CKR_OK) 149 errx(1, "find cert failed: %d", (int)ret); 150 ret = find_object(session, "cert", CKO_PRIVATE_KEY, &private); 151 if (ret != CKR_OK) 152 errx(1, "find private key failed: %d", (int)ret); 153 154 { 155 CK_ULONG ck_sigsize; 156 CK_MECHANISM mechanism; 157 158 memset(&mechanism, 0, sizeof(mechanism)); 159 mechanism.mechanism = CKM_RSA_PKCS; 160 161 ret = (*func->C_SignInit)(session, &mechanism, private); 162 if (ret != CKR_OK) 163 return 1; 164 165 ck_sigsize = sizeof(signature); 166 ret = (*func->C_Sign)(session, (CK_BYTE *)sighash, strlen(sighash), 167 (CK_BYTE *)signature, &ck_sigsize); 168 if (ret != CKR_OK) { 169 printf("C_Sign failed with: %d\n", (int)ret); 170 return 1; 171 } 172 173 ret = (*func->C_VerifyInit)(session, &mechanism, public); 174 if (ret != CKR_OK) 175 return 1; 176 177 ret = (*func->C_Verify)(session, (CK_BYTE *)signature, ck_sigsize, 178 (CK_BYTE *)sighash, strlen(sighash)); 179 if (ret != CKR_OK) { 180 printf("message: %d\n", (int)ret); 181 return 1; 182 } 183 } 184 185 #if 0 186 { 187 CK_ULONG ck_sigsize, outsize; 188 CK_MECHANISM mechanism; 189 char outdata[1024]; 190 191 memset(&mechanism, 0, sizeof(mechanism)); 192 mechanism.mechanism = CKM_RSA_PKCS; 193 194 ret = (*func->C_EncryptInit)(session, &mechanism, public); 195 if (ret != CKR_OK) 196 return 1; 197 198 ck_sigsize = sizeof(signature); 199 ret = (*func->C_Encrypt)(session, (CK_BYTE *)sighash, strlen(sighash), 200 (CK_BYTE *)signature, &ck_sigsize); 201 if (ret != CKR_OK) { 202 printf("message: %d\n", (int)ret); 203 return 1; 204 } 205 206 ret = (*func->C_DecryptInit)(session, &mechanism, private); 207 if (ret != CKR_OK) 208 return 1; 209 210 outsize = sizeof(outdata); 211 ret = (*func->C_Decrypt)(session, (CK_BYTE *)signature, ck_sigsize, 212 (CK_BYTE *)outdata, &outsize); 213 if (ret != CKR_OK) { 214 printf("message: %d\n", (int)ret); 215 return 1; 216 } 217 218 if (ct_memcmp(sighash, outdata, strlen(sighash)) != 0) 219 return 1; 220 } 221 #endif 222 223 ret = (*func->C_CloseSession)(session); 224 if (ret != CKR_OK) 225 return 1; 226 227 (*func->C_Finalize)(NULL_PTR); 228 229 return 0; 230 } 231