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