1 
2 using System;
3 using System.Collections.Generic;
4 using System.Reflection;
5 
6 using Net.Sf.Pkcs11.Objects;
7 using Net.Sf.Pkcs11.Wrapper;
8 
9 namespace Net.Sf.Pkcs11
10 {
11     /// <summary>
12     /// Represents an open Session with a Token.
13     /// </summary>
14     public class Session : IDisposable
15     {
16         #region Members
17         Token token;
18 
19         uint hSession;
20         #endregion
21 
22         #region Properties
23 
24         /// <summary>
25         /// Session's Token
26         /// </summary>
27         public Token Token
28         {
29             get { return token; }
30         }
31 
32         /// <summary>
33         /// Session's Cryptoki Module
34         /// </summary>
35         public Module Module
36         {
37             get { return token.Module; }
38         }
39 
40         /// <summary>
41         /// Session Handle / id
42         /// </summary>
43         public uint HSession
44         {
45             get { return hSession; }
46         }
47 
48         #endregion
49 
50         #region Methods
51 
52         #region Instance
53 
54         /// <summary>
55         /// Constructor
56         /// </summary>
57         /// <param name="token">Session's Token</param>
58         /// <param name="hSession">Session Handle / Id</param>
Session(Token token, uint hSession)59         public Session(Token token, uint hSession)
60         {
61             this.token = token;
62             this.hSession = hSession;
63         }
64 
65         #endregion
66 
67         #region Authentication
68 
Login(UserType userType, string pwd)69         public void Login(UserType userType, string pwd)
70         {
71             this.Module.P11Module.Login(this.HSession, (CKU)userType, pwd);
72         }
73 
Logout()74         public void Logout()
75         {
76             this.Module.P11Module.Logout(hSession);
77         }
78 
79         #endregion
80 
81         #region Initialization
82 
SetPIN(string oldPIN, string newPIN)83         public void SetPIN(string oldPIN, string newPIN)
84         {
85             Module.P11Module.SetPIN(hSession, oldPIN, newPIN);
86         }
87 
InitPIN(string pin)88         public void InitPIN(string pin)
89         {
90             Module.P11Module.InitPIN(hSession, pin);
91         }
92 
93         #endregion
94 
95         #region Encipher
96 
97         #region Digest
98 
DigestInit(Mechanism mechanism)99         public void DigestInit(Mechanism mechanism)
100         {
101             this.Module.P11Module.DigestInit(hSession, mechanism.CK_MECHANISM);
102         }
103 
DigestUpdate(byte[] data)104         public void DigestUpdate(byte[] data)
105         {
106             this.Module.P11Module.DigestUpdate(hSession, data);
107         }
108 
Digest(byte[] data)109         public byte[] Digest(byte[] data)
110         {
111             return this.Module.P11Module.Digest(hSession, data);
112         }
113 
DigestFinal()114         public byte[] DigestFinal()
115         {
116             return this.Module.P11Module.DigestFinal(hSession);
117         }
118         #endregion
119 
120         #region Encrypt
121 
EncryptInit(Mechanism mechanism, PublicKey key)122         public void EncryptInit(Mechanism mechanism, PublicKey key)
123         {
124             this.Module.P11Module.EncryptInit(hSession, mechanism.CK_MECHANISM, key.HObj);
125         }
126 
EncryptInit(Mechanism mechanism, SecretKey key)127         public void EncryptInit(Mechanism mechanism, SecretKey key)
128         {
129             this.Module.P11Module.EncryptInit(hSession, mechanism.CK_MECHANISM, key.HObj);
130         }
131 
Encrypt(byte[] data)132         public byte[] Encrypt(byte[] data)
133         {
134             return this.Module.P11Module.Encrypt(hSession, data);
135         }
136 
EncryptUpdate(byte[] data)137         public byte[] EncryptUpdate(byte[] data)
138         {
139             return this.Module.P11Module.EncryptUpdate(hSession, data);
140         }
141 
EncryptFinal()142         public byte[] EncryptFinal()
143         {
144             return this.Module.P11Module.EncryptFinal(hSession);
145         }
146         #endregion
147 
148         #region Decrypt
149 
DecryptInit(Mechanism mechanism, PrivateKey key)150         public void DecryptInit(Mechanism mechanism, PrivateKey key)
151         {
152             this.Module.P11Module.DecryptInit(hSession, mechanism.CK_MECHANISM, key.HObj);
153         }
154 
DecryptInit(Mechanism mechanism, SecretKey key)155         public void DecryptInit(Mechanism mechanism, SecretKey key)
156         {
157             this.Module.P11Module.DecryptInit(hSession, mechanism.CK_MECHANISM, key.HObj);
158         }
159 
Decrypt(byte[] data)160         public byte[] Decrypt(byte[] data)
161         {
162             return this.Module.P11Module.Decrypt(hSession, data);
163         }
164 
DecryptUpdate(byte[] data)165         public byte[] DecryptUpdate(byte[] data)
166         {
167             return this.Module.P11Module.DecryptUpdate(hSession, data);
168         }
169 
DecryptFinal()170         public byte[] DecryptFinal()
171         {
172             return this.Module.P11Module.DecryptFinal(hSession);
173         }
174         #endregion
175 
176         #region Signature
177 
SignInit(Mechanism signingMechanism, PrivateKey key)178         public void SignInit(Mechanism signingMechanism, PrivateKey key)
179         {
180             this.Module.P11Module.SignInit(hSession, signingMechanism.CK_MECHANISM, key.HObj);
181         }
182 
SignUpdate(byte[] data)183         public void SignUpdate(byte[] data)
184         {
185             this.Module.P11Module.SignUpdate(hSession, data);
186         }
187 
SignFinal()188         public byte[] SignFinal()
189         {
190             return this.Module.P11Module.SignFinal(hSession);
191         }
192 
Sign(byte[] data)193         public byte[] Sign(byte[] data)
194         {
195             return this.Module.P11Module.Sign(hSession, data);
196         }
197         #endregion
198 
199         #region Verification
200 
VerifyInit(Mechanism signingMechanism, PublicKey key)201         public void VerifyInit(Mechanism signingMechanism, PublicKey key)
202         {
203             this.Module.P11Module.VerifyInit(hSession, signingMechanism.CK_MECHANISM, key.HObj);
204         }
205 
VerifyInit(Mechanism signingMechanism, Certificate certificate)206         public void VerifyInit(Mechanism signingMechanism, Certificate certificate)
207         {
208             this.Module.P11Module.VerifyInit(hSession, signingMechanism.CK_MECHANISM, certificate.HObj);
209         }
210 
VerifyUpdate(byte[] data)211         public void VerifyUpdate(byte[] data)
212         {
213             this.Module.P11Module.VerifyUpdate(hSession, data);
214         }
215 
VerifyFinal(byte[] signature)216         public bool VerifyFinal(byte[] signature)
217         {
218             try
219             {
220                 this.Module.P11Module.VerifyFinal(hSession, signature);
221                 return true;
222             }
223             catch (TokenException tex)
224             {
225                 if (tex.ErrorCode == CKR.SIGNATURE_INVALID) return false;
226                 throw tex;
227             }
228         }
229 
Verify(byte[] data, byte[] signature)230         public bool Verify(byte[] data, byte[] signature)
231         {
232 
233             try
234             {
235                 this.Module.P11Module.Verify(hSession, data, signature);
236                 return true;
237             }
238             catch (TokenException tex)
239             {
240                 if (tex.ErrorCode == CKR.SIGNATURE_INVALID) return false;
241                 throw tex;
242             }
243         }
244         #endregion
245 
246         #region Key Generation
247 
GenerateKey(Mechanism mech, P11Object template)248         public SecretKey GenerateKey(Mechanism mech, P11Object template)
249         {
250             uint hKey = this.Module.P11Module.GenerateKey(hSession, mech.CK_MECHANISM, getAssignedAttributes(template));
251             return (SecretKey)SecretKey.GetInstance(this, hKey);
252         }
253 
GenerateKeyPair(Mechanism mech, P11Object pubTemplate, P11Object privTemplate)254         public KeyPair GenerateKeyPair(Mechanism mech, P11Object pubTemplate, P11Object privTemplate)
255         {
256 
257             KeyPairHandler hkp = this.Module.P11Module.GenerateKeyPair(
258                 hSession,
259                 mech.CK_MECHANISM,
260                 getAssignedAttributes(pubTemplate),
261                 getAssignedAttributes(privTemplate)
262             );
263 
264             return new KeyPair(
265                 (PublicKey)PublicKey.GetInstance(this, hkp.hPublicKey),
266                 (PrivateKey)PrivateKey.GetInstance(this, hkp.hPrivateKey)
267             );
268         }
269 
270 
271         #endregion
272 
273         #endregion
274 
275         #region Objects
276 
277         #region Search
278 
FindObjectsInit(params P11Attribute[] attrs)279         public void FindObjectsInit(params P11Attribute[] attrs)
280         {
281             CK_ATTRIBUTE[] ckAttrs = P11Util.ConvertToCK_ATTRIBUTEs(attrs);
282             this.Module.P11Module.FindObjectsInit(this.hSession, ckAttrs);
283         }
284 
FindObjects(uint maxCount)285         public P11Object[] FindObjects(uint maxCount)
286         {
287             uint[] hObjs = this.Module.P11Module.FindObjects(HSession, maxCount);
288             P11Object[] objs = new P11Object[hObjs.Length];
289             for (int i = 0; i < hObjs.Length; ++i)
290             {
291                 objs[i] = P11Object.GetInstance(this, hObjs[i]);
292             }
293             return objs;
294         }
295 
FindObjectsFinal()296         public void FindObjectsFinal()
297         {
298             this.Module.P11Module.FindObjectsFinal(hSession);
299         }
300 
301         #endregion
302 
303         #region Management
304 
CreateObject(P11Object template)305         public P11Object CreateObject(P11Object template)
306         {
307 
308             uint hObj = this.Module.P11Module.CreateObject(hSession, getAssignedAttributes(template));
309             return P11Object.GetInstance(this, hObj);
310         }
311 
DestroyObject(P11Object obj)312         public void DestroyObject(P11Object obj)
313         {
314             this.Module.P11Module.DestroyObject(hSession, obj.HObj);
315         }
316 
317         #endregion
318 
319         #endregion
320 
321         #region General
322 
Dispose()323         public void Dispose()
324         {
325             CloseSession();
326         }
327 
CloseSession()328         private void CloseSession()
329         {
330             this.Module.P11Module.CloseSession(hSession);
331         }
332 
getAssignedAttributes(P11Object obj)333         private static CK_ATTRIBUTE[] getAssignedAttributes(P11Object obj)
334         {
335             PropertyInfo[] props = obj.GetType().GetProperties();
336             List<CK_ATTRIBUTE> attrs = new List<CK_ATTRIBUTE>();
337             for (int i = 0; i < props.Length; i++)
338             {
339                 P11Attribute val = props[i].GetValue(obj, null) as P11Attribute;
340                 if (val != null && val.IsAssigned)
341                     attrs.Add(val.CK_ATTRIBUTE);
342             }
343             return attrs.ToArray();
344         }
345 
346         #endregion
347 
348         #endregion
349     }
350 }
351