1 /* pkcs11.h 2 * Copyright (c) OASIS Open 2016. All Rights Reserved./ 3 * Copyright (C) 2017 for the binding: Carsten Blüggel <carblue@geekmail.de> 4 * /Distributed under the terms of the OASIS IPR Policy, 5 * [http://www.oasis-open.org/policies-guidelines/ipr], AS-IS, WITHOUT ANY 6 * IMPLIED OR EXPRESS WARRANTY; there is no warranty of MERCHANTABILITY, FITNESS FOR A 7 * PARTICULAR PURPOSE or NONINFRINGEMENT of the rights of others. 8 */ 9 10 /* Latest version of the specification: 11 * http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html 12 */ 13 /* 14 Written in the D programming language. 15 See also https://github.com/jpf91/systemd/wiki/Deimos-git-branch-structure 16 For git maintenance (ensure at least one congruent line with originating C header): 17 #define _PKCS11_H_ 1 18 19 Different from the C source which unrolls all #include of pkcs11t.h and pkcs11f.h in pkcs11.h, 20 the extern function decls ("extern" form of all the entry points) and 21 function pointer decls (typedef form of all the entry points) from pkcs11f.h are in pkcs11f.d, 22 the struct CK_FUNCTION_LIST is in pkcs11t.d as well as all content from pkcs11t.h. 23 */ 24 25 module pkcs11; 26 27 28 public import pkcs11.pkcs11t; 29 public import pkcs11.pkcs11f; 30 31 // PKCS11_DYNAMIC_BINDING_ONE / PKCS11_DYNAMIC_BINDING_MULTIPLE are mutual exclusive ! 32 version( PKCS11_DYNAMIC_BINDING_ONE) 33 version=PKCS11_DYNAMIC_BINDING; 34 else version(PKCS11_DYNAMIC_BINDING_MULTIPLE) 35 version=PKCS11_DYNAMIC_BINDING; 36 37 // only version(PKCS11_DYNAMIC_BINDING) needs compiling 38 version(PKCS11_DYNAMIC_BINDING) { 39 40 version(PKCS11_OPENSC_SPY) enum PKCS11_OPENSC_SPY = true; 41 else enum PKCS11_OPENSC_SPY = false; 42 43 private { 44 import std.exception : enforce; 45 import derelict.util.exception, 46 derelict.util.loader, 47 derelict.util.system; 48 49 version(P11KIT) { // use highest priority pkcs#11 module as configured by p11-kit 50 static if (Derelict_OS_Windows) 51 enum libNames = "libp11-kit.dll"; 52 else static if( Derelict_OS_Mac ) 53 enum libNames = "libp11-kit.dylib"; 54 else static if( Derelict_OS_Posix ) 55 enum libNames = "libp11-kit.so"; 56 else 57 static assert( 0, "Need to implement PKCS11 libNames for this operating system." ); 58 } 59 else { 60 static if (Derelict_OS_Windows) { 61 static if (PKCS11_OPENSC_SPY) 62 enum libNames = "pkcs11-spy.dll"; 63 else 64 enum libNames = "opensc-pkcs11.dll"; 65 } 66 else static if( Derelict_OS_Mac ) { 67 static if (PKCS11_OPENSC_SPY) 68 enum libNames = "pkcs11-spy.dylib"; 69 else 70 enum libNames = "opensc-pkcs11.dylib"; 71 } 72 else static if( Derelict_OS_Posix ) { 73 static if (PKCS11_OPENSC_SPY) 74 enum libNames = "pkcs11-spy.so"; 75 else 76 enum libNames = "opensc-pkcs11.so"; // onepin-opensc-pkcs11.so ? 77 } 78 else 79 static assert( 0, "Need to implement PKCS11 libNames for this operating system." ); 80 } 81 } // private 82 83 class PKCS11Loader : SharedLibLoader { 84 85 public this() { 86 super( libNames ); 87 } 88 89 protected override void loadSymbols() { 90 bindFunc( cast(void**)&C_GetFunctionList, "C_GetFunctionList"); 91 92 // Try to use C_GetFunctionList; an error implies, the library is not usable 93 CK_FUNCTION_LIST_PTR pFunctionList; 94 enforce(C_GetFunctionList(&pFunctionList) == CKR_OK); 95 version(PKCS11_DYNAMIC_BINDING_ONE) 96 m_function_list_ptr = pFunctionList; 97 98 C_Initialize = pFunctionList.C_Initialize; 99 C_Finalize = pFunctionList.C_Finalize; 100 C_GetInfo = pFunctionList.C_GetInfo; 101 // C_GetFunctionList = pFunctionList.C_GetFunctionList; 102 C_GetSlotList = pFunctionList.C_GetSlotList; 103 C_GetSlotInfo = pFunctionList.C_GetSlotInfo; 104 C_GetTokenInfo = pFunctionList.C_GetTokenInfo; 105 C_GetMechanismList = pFunctionList.C_GetMechanismList; 106 C_GetMechanismInfo = pFunctionList.C_GetMechanismInfo; 107 C_InitToken = pFunctionList.C_InitToken; 108 C_InitPIN = pFunctionList.C_InitPIN; 109 C_SetPIN = pFunctionList.C_SetPIN; 110 C_OpenSession = pFunctionList.C_OpenSession; 111 C_CloseSession = pFunctionList.C_CloseSession; 112 C_CloseAllSessions = pFunctionList.C_CloseAllSessions; 113 C_GetSessionInfo = pFunctionList.C_GetSessionInfo; 114 C_GetOperationState = pFunctionList.C_GetOperationState; 115 C_SetOperationState = pFunctionList.C_SetOperationState; 116 C_Login = pFunctionList.C_Login; 117 C_Logout = pFunctionList.C_Logout; 118 C_CreateObject = pFunctionList.C_CreateObject; 119 C_CopyObject = pFunctionList.C_CopyObject; 120 C_DestroyObject = pFunctionList.C_DestroyObject; 121 C_GetObjectSize = pFunctionList.C_GetObjectSize; 122 C_GetAttributeValue = pFunctionList.C_GetAttributeValue; 123 C_SetAttributeValue = pFunctionList.C_SetAttributeValue; 124 C_FindObjectsInit = pFunctionList.C_FindObjectsInit; 125 C_FindObjects = pFunctionList.C_FindObjects; 126 C_FindObjectsFinal = pFunctionList.C_FindObjectsFinal; 127 C_EncryptInit = pFunctionList.C_EncryptInit; 128 C_Encrypt = pFunctionList.C_Encrypt; 129 C_EncryptUpdate = pFunctionList.C_EncryptUpdate; 130 C_EncryptFinal = pFunctionList.C_EncryptFinal; 131 C_DecryptInit = pFunctionList.C_DecryptInit; 132 C_Decrypt = pFunctionList.C_Decrypt; 133 C_DecryptUpdate = pFunctionList.C_DecryptUpdate; 134 C_DecryptFinal = pFunctionList.C_DecryptFinal; 135 C_DigestInit = pFunctionList.C_DigestInit; 136 C_Digest = pFunctionList.C_Digest; 137 C_DigestUpdate = pFunctionList.C_DigestUpdate; 138 C_DigestKey = pFunctionList.C_DigestKey; 139 C_DigestFinal = pFunctionList.C_DigestFinal; 140 C_SignInit = pFunctionList.C_SignInit; 141 C_Sign = pFunctionList.C_Sign; 142 C_SignUpdate = pFunctionList.C_SignUpdate; 143 C_SignFinal = pFunctionList.C_SignFinal; 144 C_SignRecoverInit = pFunctionList.C_SignRecoverInit; 145 C_SignRecover = pFunctionList.C_SignRecover; 146 C_VerifyInit = pFunctionList.C_VerifyInit; 147 C_Verify = pFunctionList.C_Verify; 148 C_VerifyUpdate = pFunctionList.C_VerifyUpdate; 149 C_VerifyFinal = pFunctionList.C_VerifyFinal; 150 C_VerifyRecoverInit = pFunctionList.C_VerifyRecoverInit; 151 C_VerifyRecover = pFunctionList.C_VerifyRecover; 152 C_DigestEncryptUpdate = pFunctionList.C_DigestEncryptUpdate; 153 C_DecryptDigestUpdate = pFunctionList.C_DecryptDigestUpdate; 154 C_SignEncryptUpdate = pFunctionList.C_SignEncryptUpdate; 155 C_DecryptVerifyUpdate = pFunctionList.C_DecryptVerifyUpdate; 156 C_GenerateKey = pFunctionList.C_GenerateKey; 157 C_GenerateKeyPair = pFunctionList.C_GenerateKeyPair; 158 C_WrapKey = pFunctionList.C_WrapKey; 159 C_UnwrapKey = pFunctionList.C_UnwrapKey; 160 C_DeriveKey = pFunctionList.C_DeriveKey; 161 C_SeedRandom = pFunctionList.C_SeedRandom; 162 C_GenerateRandom = pFunctionList.C_GenerateRandom; 163 C_GetFunctionStatus = pFunctionList.C_GetFunctionStatus; 164 C_CancelFunction = pFunctionList.C_CancelFunction; 165 C_WaitForSlotEvent = pFunctionList.C_WaitForSlotEvent; 166 } 167 168 version(PKCS11_DYNAMIC_BINDING_ONE) { 169 __gshared CK_FUNCTION_LIST_PTR m_function_list_ptr; 170 171 // for (rare) cases, when it's required to pass the access to Cryptoki-functions 172 @property __gshared CK_FUNCTION_LIST_PTR function_list_ptr() { 173 return m_function_list_ptr; 174 } 175 } 176 version(PKCS11_DYNAMIC_BINDING_MULTIPLE) 177 mixin CK_FUNCTION_LIST_FENTRIES; 178 } // class PKCS11Loader 179 180 version(PKCS11_DYNAMIC_BINDING_ONE) { 181 __gshared PKCS11Loader PKCS11; 182 183 shared static this() { 184 PKCS11 = new PKCS11Loader(); 185 } 186 187 __gshared { 188 mixin CK_FUNCTION_LIST_FENTRIES; 189 } 190 } // version(PKCS11_DYNAMIC_BINDING_ONE) 191 192 193 unittest { 194 PKCS11.load("opensc-pkcs11.so"); 195 version(PKCS11_DYNAMIC_BINDING_ONE) { 196 // the following usage of function_list_ptr is not necessary in regular use cases; here only for testing purpose of @property function 197 auto p = PKCS11.function_list_ptr; 198 p.C_Initialize(null); 199 p.C_Finalize(null); 200 } 201 } 202 203 } // version(PKCS11_DYNAMIC_BINDING)