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 		static if (Derelict_OS_Windows) {
50 			static if (PKCS11_OPENSC_SPY)
51 				enum libNames = "pkcs11-spy.dll";
52 			else
53 				enum libNames = "opensc-pkcs11.dll";
54 		}
55 		else static if( Derelict_OS_Mac ) {
56 			static if (PKCS11_OPENSC_SPY)
57 				enum libNames = "pkcs11-spy.dylib";
58 			else
59 				enum libNames = "opensc-pkcs11.dylib";
60 		}
61 		else static if( Derelict_OS_Posix ) {
62 			static if (PKCS11_OPENSC_SPY)
63 				enum libNames = "pkcs11-spy.so";
64 			else
65 				enum libNames = "opensc-pkcs11.so"; // onepin-opensc-pkcs11.so ?
66 		}
67 		else
68 			static assert( 0, "Need to implement PKCS11 libNames for this operating system." );
69 	}
70 
71 	class PKCS11Loader : SharedLibLoader {
72 
73 		public this() {
74 			super( libNames );
75 		}
76 
77 		protected override void loadSymbols() {
78 			bindFunc( cast(void**)&C_GetFunctionList,   "C_GetFunctionList");
79 
80 		// Try to use C_GetFunctionList; an error implies, the library is not usable
81 			CK_FUNCTION_LIST_PTR  pFunctionList;
82 			enforce(C_GetFunctionList(&pFunctionList) == CKR_OK);
83 
84 			C_Initialize           = pFunctionList.C_Initialize;
85 			C_Finalize             = pFunctionList.C_Finalize;
86 			C_GetInfo              = pFunctionList.C_GetInfo;
87 //		C_GetFunctionList      = pFunctionList.C_GetFunctionList;
88 			C_GetSlotList          = pFunctionList.C_GetSlotList;
89 			C_GetSlotInfo          = pFunctionList.C_GetSlotInfo;
90 			C_GetTokenInfo         = pFunctionList.C_GetTokenInfo;
91 			C_GetMechanismList     = pFunctionList.C_GetMechanismList;
92 			C_GetMechanismInfo     = pFunctionList.C_GetMechanismInfo;
93 			C_InitToken            = pFunctionList.C_InitToken;
94 			C_InitPIN              = pFunctionList.C_InitPIN;
95 			C_SetPIN               = pFunctionList.C_SetPIN;
96 			C_OpenSession          = pFunctionList.C_OpenSession;
97 			C_CloseSession         = pFunctionList.C_CloseSession;
98 			C_CloseAllSessions     = pFunctionList.C_CloseAllSessions;
99 			C_GetSessionInfo       = pFunctionList.C_GetSessionInfo;
100 			C_GetOperationState    = pFunctionList.C_GetOperationState;
101 			C_SetOperationState    = pFunctionList.C_SetOperationState;
102 			C_Login                = pFunctionList.C_Login;
103 			C_Logout               = pFunctionList.C_Logout;
104 			C_CreateObject         = pFunctionList.C_CreateObject;
105 			C_CopyObject           = pFunctionList.C_CopyObject;
106 			C_DestroyObject        = pFunctionList.C_DestroyObject;
107 			C_GetObjectSize        = pFunctionList.C_GetObjectSize;
108 			C_GetAttributeValue    = pFunctionList.C_GetAttributeValue;
109 			C_SetAttributeValue    = pFunctionList.C_SetAttributeValue;
110 			C_FindObjectsInit      = pFunctionList.C_FindObjectsInit;
111 			C_FindObjects          = pFunctionList.C_FindObjects;
112 			C_FindObjectsFinal     = pFunctionList.C_FindObjectsFinal;
113 			C_EncryptInit          = pFunctionList.C_EncryptInit;
114 			C_Encrypt              = pFunctionList.C_Encrypt;
115 			C_EncryptUpdate        = pFunctionList.C_EncryptUpdate;
116 			C_EncryptFinal         = pFunctionList.C_EncryptFinal;
117 			C_DecryptInit          = pFunctionList.C_DecryptInit;
118 			C_Decrypt              = pFunctionList.C_Decrypt;
119 			C_DecryptUpdate        = pFunctionList.C_DecryptUpdate;
120 			C_DecryptFinal         = pFunctionList.C_DecryptFinal;
121 			C_DigestInit           = pFunctionList.C_DigestInit;
122 			C_Digest               = pFunctionList.C_Digest;
123 			C_DigestUpdate         = pFunctionList.C_DigestUpdate;
124 			C_DigestKey            = pFunctionList.C_DigestKey;
125 			C_DigestFinal          = pFunctionList.C_DigestFinal;
126 			C_SignInit             = pFunctionList.C_SignInit;
127 			C_Sign                 = pFunctionList.C_Sign;
128 			C_SignUpdate           = pFunctionList.C_SignUpdate;
129 			C_SignFinal            = pFunctionList.C_SignFinal;
130 			C_SignRecoverInit      = pFunctionList.C_SignRecoverInit;
131 			C_SignRecover          = pFunctionList.C_SignRecover;
132 			C_VerifyInit           = pFunctionList.C_VerifyInit;
133 			C_Verify               = pFunctionList.C_Verify;
134 			C_VerifyUpdate         = pFunctionList.C_VerifyUpdate;
135 			C_VerifyFinal          = pFunctionList.C_VerifyFinal;
136 			C_VerifyRecoverInit    = pFunctionList.C_VerifyRecoverInit;
137 			C_VerifyRecover        = pFunctionList.C_VerifyRecover;
138 			C_DigestEncryptUpdate  = pFunctionList.C_DigestEncryptUpdate;
139 			C_DecryptDigestUpdate  = pFunctionList.C_DecryptDigestUpdate;
140 			C_SignEncryptUpdate    = pFunctionList.C_SignEncryptUpdate;
141 			C_DecryptVerifyUpdate  = pFunctionList.C_DecryptVerifyUpdate;
142 			C_GenerateKey          = pFunctionList.C_GenerateKey;
143 			C_GenerateKeyPair      = pFunctionList.C_GenerateKeyPair;
144 			C_WrapKey              = pFunctionList.C_WrapKey;
145 			C_UnwrapKey            = pFunctionList.C_UnwrapKey;
146 			C_DeriveKey            = pFunctionList.C_DeriveKey;
147 			C_SeedRandom           = pFunctionList.C_SeedRandom;
148 			C_GenerateRandom       = pFunctionList.C_GenerateRandom;
149 			C_GetFunctionStatus    = pFunctionList.C_GetFunctionStatus;
150 			C_CancelFunction       = pFunctionList.C_CancelFunction;
151 			C_WaitForSlotEvent     = pFunctionList.C_WaitForSlotEvent;
152 		}
153 
154 version(PKCS11_DYNAMIC_BINDING_MULTIPLE)
155 		mixin CK_FUNCTION_LIST_FENTRIES;
156 	} // class PKCS11Loader
157 
158 version(PKCS11_DYNAMIC_BINDING_ONE) {
159 
160 	__gshared PKCS11Loader PKCS11;
161 
162 	shared static this() {
163 		PKCS11 = new PKCS11Loader();
164 	}
165 
166 	__gshared {
167 		mixin CK_FUNCTION_LIST_FENTRIES;
168 	}
169 } // version(PKCS11_DYNAMIC_BINDING_ONE)
170 
171 
172 	unittest {
173 		PKCS11.load("opensc-pkcs11.so");
174 	}
175 
176 } // version(PKCS11_DYNAMIC_BINDING)