1178825Sdfr/* 2233294Sstas * Copyright (c) 2006 - 2008 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 5178825Sdfr * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 9178825Sdfr * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 20178825Sdfr * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34178825Sdfr#include "hx_locl.h" 35178825Sdfr#include "pkcs11.h" 36178825Sdfr#include <err.h> 37178825Sdfr 38178825Sdfrstatic CK_FUNCTION_LIST_PTR func; 39178825Sdfr 40178825Sdfr 41178825Sdfrstatic CK_RV 42233294Sstasfind_object(CK_SESSION_HANDLE session, 43178825Sdfr char *id, 44233294Sstas CK_OBJECT_CLASS key_class, 45178825Sdfr CK_OBJECT_HANDLE_PTR object) 46178825Sdfr{ 47178825Sdfr CK_ULONG object_count; 48178825Sdfr CK_RV ret; 49178825Sdfr CK_ATTRIBUTE search_data[] = { 50178825Sdfr {CKA_ID, id, 0 }, 51178825Sdfr {CKA_CLASS, &key_class, sizeof(key_class)} 52178825Sdfr }; 53178825Sdfr CK_ULONG num_search_data = sizeof(search_data)/sizeof(search_data[0]); 54178825Sdfr 55178825Sdfr search_data[0].ulValueLen = strlen(id); 56178825Sdfr 57178825Sdfr ret = (*func->C_FindObjectsInit)(session, search_data, num_search_data); 58178825Sdfr if (ret != CKR_OK) 59178825Sdfr return ret; 60178825Sdfr 61178825Sdfr ret = (*func->C_FindObjects)(session, object, 1, &object_count); 62178825Sdfr if (ret != CKR_OK) 63178825Sdfr return ret; 64178825Sdfr if (object_count == 0) { 65178825Sdfr printf("found no object\n"); 66178825Sdfr return 1; 67178825Sdfr } 68178825Sdfr 69178825Sdfr ret = (*func->C_FindObjectsFinal)(session); 70178825Sdfr if (ret != CKR_OK) 71178825Sdfr return ret; 72178825Sdfr 73178825Sdfr return CKR_OK; 74178825Sdfr} 75178825Sdfr 76178825Sdfrstatic char *sighash = "hej"; 77178825Sdfrstatic char signature[1024]; 78178825Sdfr 79178825Sdfr 80178825Sdfrint 81178825Sdfrmain(int argc, char **argv) 82178825Sdfr{ 83178825Sdfr CK_SLOT_ID_PTR slot_ids; 84178825Sdfr CK_SLOT_ID slot; 85178825Sdfr CK_ULONG num_slots; 86178825Sdfr CK_RV ret; 87178825Sdfr CK_SLOT_INFO slot_info; 88178825Sdfr CK_TOKEN_INFO token_info; 89178825Sdfr CK_SESSION_HANDLE session; 90178825Sdfr CK_OBJECT_HANDLE public, private; 91178825Sdfr 92178825Sdfr ret = C_GetFunctionList(&func); 93178825Sdfr if (ret != CKR_OK) 94178825Sdfr errx(1, "C_GetFunctionList failed: %d", (int)ret); 95178825Sdfr 96178825Sdfr (*func->C_Initialize)(NULL_PTR); 97178825Sdfr 98178825Sdfr ret = (*func->C_GetSlotList)(FALSE, NULL, &num_slots); 99178825Sdfr if (ret != CKR_OK) 100178825Sdfr errx(1, "C_GetSlotList1 failed: %d", (int)ret); 101178825Sdfr 102178825Sdfr if (num_slots == 0) 103178825Sdfr errx(1, "no slots"); 104178825Sdfr 105178825Sdfr if ((slot_ids = calloc(1, num_slots * sizeof(*slot_ids))) == NULL) 106178825Sdfr err(1, "alloc slots failed"); 107178825Sdfr 108178825Sdfr ret = (*func->C_GetSlotList)(FALSE, slot_ids, &num_slots); 109178825Sdfr if (ret != CKR_OK) 110178825Sdfr errx(1, "C_GetSlotList2 failed: %d", (int)ret); 111178825Sdfr 112178825Sdfr slot = slot_ids[0]; 113178825Sdfr free(slot_ids); 114178825Sdfr 115178825Sdfr ret = (*func->C_GetSlotInfo)(slot, &slot_info); 116178825Sdfr if (ret) 117178825Sdfr errx(1, "C_GetSlotInfo failed: %d", (int)ret); 118178825Sdfr 119178825Sdfr if ((slot_info.flags & CKF_TOKEN_PRESENT) == 0) 120178825Sdfr errx(1, "no token present"); 121178825Sdfr 122233294Sstas ret = (*func->C_OpenSession)(slot, CKF_SERIAL_SESSION, 123178825Sdfr NULL, NULL, &session); 124178825Sdfr if (ret != CKR_OK) 125178825Sdfr errx(1, "C_OpenSession failed: %d", (int)ret); 126233294Sstas 127178825Sdfr ret = (*func->C_GetTokenInfo)(slot, &token_info); 128178825Sdfr if (ret) 129178825Sdfr errx(1, "C_GetTokenInfo1 failed: %d", (int)ret); 130178825Sdfr 131178825Sdfr if (token_info.flags & CKF_LOGIN_REQUIRED) { 132178825Sdfr ret = (*func->C_Login)(session, CKU_USER, 133178825Sdfr (unsigned char*)"foobar", 6); 134178825Sdfr if (ret != CKR_OK) 135178825Sdfr errx(1, "C_Login failed: %d", (int)ret); 136178825Sdfr } 137178825Sdfr 138178825Sdfr ret = (*func->C_GetTokenInfo)(slot, &token_info); 139178825Sdfr if (ret) 140178825Sdfr errx(1, "C_GetTokenInfo2 failed: %d", (int)ret); 141178825Sdfr 142178825Sdfr if (token_info.flags & CKF_LOGIN_REQUIRED) 143178825Sdfr errx(1, "login required, even after C_Login"); 144178825Sdfr 145178825Sdfr ret = find_object(session, "cert", CKO_PUBLIC_KEY, &public); 146178825Sdfr if (ret != CKR_OK) 147178825Sdfr errx(1, "find cert failed: %d", (int)ret); 148178825Sdfr ret = find_object(session, "cert", CKO_PRIVATE_KEY, &private); 149178825Sdfr if (ret != CKR_OK) 150178825Sdfr errx(1, "find private key failed: %d", (int)ret); 151178825Sdfr 152178825Sdfr { 153178825Sdfr CK_ULONG ck_sigsize; 154178825Sdfr CK_MECHANISM mechanism; 155178825Sdfr 156178825Sdfr memset(&mechanism, 0, sizeof(mechanism)); 157178825Sdfr mechanism.mechanism = CKM_RSA_PKCS; 158178825Sdfr 159178825Sdfr ret = (*func->C_SignInit)(session, &mechanism, private); 160178825Sdfr if (ret != CKR_OK) 161178825Sdfr return 1; 162233294Sstas 163178825Sdfr ck_sigsize = sizeof(signature); 164178825Sdfr ret = (*func->C_Sign)(session, (CK_BYTE *)sighash, strlen(sighash), 165178825Sdfr (CK_BYTE *)signature, &ck_sigsize); 166178825Sdfr if (ret != CKR_OK) { 167178825Sdfr printf("C_Sign failed with: %d\n", (int)ret); 168178825Sdfr return 1; 169178825Sdfr } 170178825Sdfr 171178825Sdfr ret = (*func->C_VerifyInit)(session, &mechanism, public); 172178825Sdfr if (ret != CKR_OK) 173178825Sdfr return 1; 174178825Sdfr 175233294Sstas ret = (*func->C_Verify)(session, (CK_BYTE *)signature, ck_sigsize, 176178825Sdfr (CK_BYTE *)sighash, strlen(sighash)); 177178825Sdfr if (ret != CKR_OK) { 178178825Sdfr printf("message: %d\n", (int)ret); 179178825Sdfr return 1; 180178825Sdfr } 181178825Sdfr } 182178825Sdfr 183178825Sdfr#if 0 184178825Sdfr { 185178825Sdfr CK_ULONG ck_sigsize, outsize; 186178825Sdfr CK_MECHANISM mechanism; 187178825Sdfr char outdata[1024]; 188178825Sdfr 189178825Sdfr memset(&mechanism, 0, sizeof(mechanism)); 190178825Sdfr mechanism.mechanism = CKM_RSA_PKCS; 191178825Sdfr 192178825Sdfr ret = (*func->C_EncryptInit)(session, &mechanism, public); 193178825Sdfr if (ret != CKR_OK) 194178825Sdfr return 1; 195233294Sstas 196178825Sdfr ck_sigsize = sizeof(signature); 197178825Sdfr ret = (*func->C_Encrypt)(session, (CK_BYTE *)sighash, strlen(sighash), 198178825Sdfr (CK_BYTE *)signature, &ck_sigsize); 199178825Sdfr if (ret != CKR_OK) { 200178825Sdfr printf("message: %d\n", (int)ret); 201178825Sdfr return 1; 202178825Sdfr } 203178825Sdfr 204178825Sdfr ret = (*func->C_DecryptInit)(session, &mechanism, private); 205178825Sdfr if (ret != CKR_OK) 206178825Sdfr return 1; 207178825Sdfr 208178825Sdfr outsize = sizeof(outdata); 209233294Sstas ret = (*func->C_Decrypt)(session, (CK_BYTE *)signature, ck_sigsize, 210178825Sdfr (CK_BYTE *)outdata, &outsize); 211178825Sdfr if (ret != CKR_OK) { 212178825Sdfr printf("message: %d\n", (int)ret); 213178825Sdfr return 1; 214178825Sdfr } 215178825Sdfr 216233294Sstas if (ct_memcmp(sighash, outdata, strlen(sighash)) != 0) 217178825Sdfr return 1; 218178825Sdfr } 219178825Sdfr#endif 220178825Sdfr 221178825Sdfr ret = (*func->C_CloseSession)(session); 222178825Sdfr if (ret != CKR_OK) 223178825Sdfr return 1; 224178825Sdfr 225178825Sdfr (*func->C_Finalize)(NULL_PTR); 226178825Sdfr 227178825Sdfr return 0; 228178825Sdfr} 229