/Framework/Tools/Emulator/Signature.cs

https://bitbucket.org/CW2/netduinofirmware · C# · 523 lines · 432 code · 85 blank · 6 comment · 86 complexity · 4e418e47e16b3e1f88ea1caf2a19df7f MD5 · raw file

  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4. using System;
  5. using System.Diagnostics;
  6. using System.Security.Cryptography;
  7. using System.Runtime.InteropServices;
  8. using System.Security.Cryptography.X509Certificates;
  9. namespace Microsoft.SPOT.Emulator.PKCS11
  10. {
  11. internal class SignatureDriver : HalDriver<ISignatureDriver>, ISignatureDriver
  12. {
  13. private bool m_signHash;
  14. private bool Init(int session, AlgorithmType alg, AlgorithmType hash, int hKey, bool isVerify)
  15. {
  16. //bool bRet = false;
  17. try
  18. {
  19. SessionData ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
  20. KeyData kd = null;
  21. CryptokiObject obj = ctx.ObjectCtx.GetObject(hKey);
  22. if (obj == null) return false;
  23. if (obj.Type == CryptokiObjectType.Key)
  24. {
  25. kd = obj.Data as KeyData;
  26. }
  27. else if (obj.Type == CryptokiObjectType.Cert)
  28. {
  29. X509Certificate2 cert = obj.Data as X509Certificate2;
  30. kd = new KeyData(null, cert);
  31. }
  32. else
  33. {
  34. return false;
  35. }
  36. byte[] keyData = kd.KeyBytes;
  37. // remove
  38. if (((uint)((uint)hash & (uint)CryptokiObjectMgrDriver.CryptokiAttribType.SIGN_NO_NODIGEST_FLAG)) != 0)
  39. {
  40. m_signHash = true;
  41. hash = (AlgorithmType)((uint)hash & ~(uint)CryptokiObjectMgrDriver.CryptokiAttribType.SIGN_NO_NODIGEST_FLAG);
  42. }
  43. else
  44. {
  45. m_signHash = false;
  46. }
  47. switch (alg)
  48. {
  49. case AlgorithmType.RSA_PKCS:
  50. {
  51. RSACryptoServiceProvider csp;
  52. SignatureData sigData = isVerify ? ctx.VerifyCtx : ctx.SignCtx;
  53. if (keyData != null)
  54. {
  55. csp = new RSACryptoServiceProvider();
  56. csp.ImportCspBlob(keyData);
  57. }
  58. else
  59. {
  60. X509Certificate2 cert = kd.KeyCsp as X509Certificate2;
  61. if (isVerify)
  62. {
  63. csp = cert.PublicKey.Key as RSACryptoServiceProvider;
  64. }
  65. else
  66. {
  67. csp = cert.PrivateKey as RSACryptoServiceProvider;
  68. }
  69. }
  70. if (isVerify) sigData.SignObject = new RSAPKCS1SignatureDeformatter(csp);
  71. else sigData.SignObject = new RSAPKCS1SignatureFormatter(csp);
  72. switch (hash)
  73. {
  74. case AlgorithmType.SHA_1:
  75. sigData.SignHashAlg = new SHA1CryptoServiceProvider();
  76. if (isVerify) ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA1");
  77. else ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA1");
  78. break;
  79. case AlgorithmType.SHA256:
  80. sigData.SignHashAlg = new SHA256CryptoServiceProvider();
  81. if (isVerify) ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA256");
  82. else ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA256");
  83. break;
  84. case AlgorithmType.SHA512:
  85. sigData.SignHashAlg = new SHA512CryptoServiceProvider();
  86. if (isVerify) ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA512");
  87. else ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA512");
  88. break;
  89. case AlgorithmType.MD5:
  90. sigData.SignHashAlg = new MD5CryptoServiceProvider();
  91. if (isVerify) ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("MD5");
  92. else ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("MD5");
  93. break;
  94. // no hash, means that we are signing a hash value
  95. case (AlgorithmType)(uint.MaxValue):
  96. break;
  97. default:
  98. return false;
  99. }
  100. }
  101. break;
  102. case AlgorithmType.ECDSA:
  103. {
  104. ECDsaCng csp = kd.KeyCsp as ECDsaCng;
  105. if (csp == null) return false;
  106. SignatureData sigData = isVerify ? ctx.VerifyCtx : ctx.SignCtx;
  107. sigData.SignObject = csp;
  108. switch(hash)
  109. {
  110. case AlgorithmType.SHA_1:
  111. csp.HashAlgorithm = CngAlgorithm.Sha1;
  112. sigData.SignHashAlg = new SHA1CryptoServiceProvider();
  113. break;
  114. case AlgorithmType.SHA256:
  115. csp.HashAlgorithm = CngAlgorithm.Sha256;
  116. sigData.SignHashAlg = new SHA256CryptoServiceProvider();
  117. break;
  118. case AlgorithmType.SHA384:
  119. csp.HashAlgorithm = CngAlgorithm.Sha384;
  120. sigData.SignHashAlg = new SHA384CryptoServiceProvider();
  121. break;
  122. case AlgorithmType.SHA512:
  123. csp.HashAlgorithm = CngAlgorithm.Sha512;
  124. sigData.SignHashAlg = new SHA512CryptoServiceProvider();
  125. break;
  126. case AlgorithmType.MD5:
  127. csp.HashAlgorithm = CngAlgorithm.MD5;
  128. sigData.SignHashAlg = new MD5CryptoServiceProvider();
  129. break;
  130. default:
  131. return false;
  132. }
  133. }
  134. break;
  135. case AlgorithmType.DSA:
  136. {
  137. DSACryptoServiceProvider csp = new DSACryptoServiceProvider();
  138. csp.ImportCspBlob(keyData);
  139. SignatureData sigData = isVerify ? ctx.VerifyCtx : ctx.SignCtx;
  140. if (isVerify) sigData.SignObject = new DSASignatureDeformatter(csp);
  141. else sigData.SignObject = new DSASignatureFormatter(csp);
  142. switch(hash)
  143. {
  144. case AlgorithmType.SHA_1:
  145. sigData.SignHashAlg = new SHA1CryptoServiceProvider();
  146. if (isVerify) ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA1");
  147. else ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA1");
  148. break;
  149. case AlgorithmType.SHA256:
  150. sigData.SignHashAlg = new SHA256CryptoServiceProvider();
  151. if (isVerify) ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA256");
  152. else ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA256");
  153. break;
  154. case AlgorithmType.SHA512:
  155. sigData.SignHashAlg = new SHA512CryptoServiceProvider();
  156. if (isVerify) ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("SHA512");
  157. else ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("SHA512");
  158. break;
  159. case AlgorithmType.MD5:
  160. sigData.SignHashAlg = new MD5CryptoServiceProvider();
  161. if (isVerify) ((AsymmetricSignatureDeformatter)sigData.SignObject).SetHashAlgorithm("MD5");
  162. else ((AsymmetricSignatureFormatter)sigData.SignObject).SetHashAlgorithm("MD5");
  163. break;
  164. default:
  165. return false;
  166. }
  167. }
  168. break;
  169. default:
  170. return false;
  171. }
  172. }
  173. catch (Exception e)
  174. {
  175. Debug.Print("Exception: " + e.Message);
  176. return false;
  177. }
  178. return true;
  179. }
  180. #region ISignatureDriver Members
  181. bool ISignatureDriver.SignInit(int session, int alg, int hashAlg, int hKey)
  182. {
  183. return Init(session, (AlgorithmType)alg, (AlgorithmType)hashAlg, hKey, false);
  184. }
  185. bool ISignatureDriver.Sign(int session, IntPtr Data, int DataLen, IntPtr Signature, ref int SignatureLen)
  186. {
  187. SessionData ctx = null;
  188. try
  189. {
  190. ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
  191. unsafe
  192. {
  193. byte[] data = new byte[DataLen];
  194. byte[] sig = null;
  195. Marshal.Copy(Data, data, 0, DataLen);
  196. HashAlgorithm hash = ctx.SignCtx.SignHashAlg;
  197. if (hash == null || m_signHash)
  198. {
  199. object signer = ctx.SignCtx.SignObject;
  200. if (signer is AsymmetricSignatureFormatter)
  201. {
  202. sig = ((AsymmetricSignatureFormatter)signer).CreateSignature(data);
  203. }
  204. else if (signer is ECDsaCng)
  205. {
  206. sig = ((ECDsaCng)signer).SignHash(data);
  207. }
  208. }
  209. else
  210. {
  211. hash.ComputeHash(data);
  212. object signer = ctx.SignCtx.SignObject;
  213. if (signer is AsymmetricSignatureFormatter)
  214. {
  215. sig = ((AsymmetricSignatureFormatter)signer).CreateSignature(hash);
  216. }
  217. else if (signer is ECDsaCng)
  218. {
  219. sig = ((ECDsaCng)signer).SignHash(hash.Hash);
  220. }
  221. }
  222. if (Signature == IntPtr.Zero)
  223. {
  224. SignatureLen = sig.Length;
  225. return true;
  226. }
  227. if (sig == null || sig.Length > SignatureLen) throw new ArgumentException();
  228. Marshal.Copy(sig, 0, Signature, sig.Length);
  229. SignatureLen = sig.Length;
  230. return true;
  231. }
  232. }
  233. catch (Exception e)
  234. {
  235. Debug.Print("Exception: " + e.ToString());
  236. return false;
  237. }
  238. finally
  239. {
  240. if (Signature != IntPtr.Zero && ctx != null)
  241. {
  242. ctx.SignCtx.Clear();
  243. }
  244. }
  245. }
  246. bool ISignatureDriver.SignFinal(int session, IntPtr Signature, ref int SignatureLen)
  247. {
  248. SessionData ctx = null;
  249. try
  250. {
  251. ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
  252. unsafe
  253. {
  254. byte[] sig = null;
  255. object signer = ctx.SignCtx.SignObject;
  256. HashAlgorithm hash = ctx.SignCtx.SignHashAlg;
  257. if (signer is AsymmetricSignatureFormatter)
  258. {
  259. sig = ((AsymmetricSignatureFormatter)signer).CreateSignature(hash);
  260. }
  261. else if (signer is ECDsaCng)
  262. {
  263. sig = ((ECDsaCng)signer).SignHash(hash.Hash);
  264. }
  265. if (sig.Length > SignatureLen) throw new ArgumentException();
  266. Marshal.Copy(sig, 0, Signature, sig.Length);
  267. SignatureLen = sig.Length;
  268. }
  269. }
  270. catch (Exception e)
  271. {
  272. Debug.Print("Exception: " + e.ToString());
  273. return false;
  274. }
  275. finally
  276. {
  277. if (ctx != null)
  278. {
  279. ctx.SignCtx.Clear();
  280. }
  281. }
  282. return true;
  283. }
  284. bool ISignatureDriver.SignUpdate(int session, IntPtr Data, int DataLen)
  285. {
  286. SessionData ctx = null;
  287. try
  288. {
  289. ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
  290. unsafe
  291. {
  292. byte[] data = new byte[DataLen];
  293. Marshal.Copy(Data, data, 0, DataLen);
  294. HashAlgorithm hash = ctx.SignCtx.SignHashAlg;
  295. if (hash == null)
  296. {
  297. return false;
  298. }
  299. else
  300. {
  301. hash.ComputeHash(data);
  302. }
  303. }
  304. }
  305. catch (Exception e)
  306. {
  307. Debug.Print("Exception: " + e.ToString());
  308. if (ctx != null)
  309. {
  310. ctx.SignCtx.Clear();
  311. }
  312. return false;
  313. }
  314. return true;
  315. }
  316. bool ISignatureDriver.VerifyInit(int session, int alg, int hashAlg, int hKey)
  317. {
  318. return Init(session, (AlgorithmType)alg, (AlgorithmType)hashAlg, hKey, true);
  319. }
  320. bool ISignatureDriver.Verify(int session, IntPtr Data, int DataLen, IntPtr Signature, int SignatureLen)
  321. {
  322. SessionData ctx = null;
  323. try
  324. {
  325. ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
  326. unsafe
  327. {
  328. byte[] data = new byte[DataLen];
  329. byte[] sig = new byte[SignatureLen];
  330. Marshal.Copy(Data, data, 0, DataLen);
  331. Marshal.Copy(Signature, sig, 0, SignatureLen);
  332. object verifier = ctx.VerifyCtx.SignObject;
  333. HashAlgorithm hash = ctx.VerifyCtx.SignHashAlg;
  334. if (hash == null || m_signHash)
  335. {
  336. if (verifier is AsymmetricSignatureDeformatter)
  337. {
  338. return ((AsymmetricSignatureDeformatter)verifier).VerifySignature(data, sig);
  339. }
  340. else if(verifier is ECDsaCng)
  341. {
  342. return ((ECDsaCng)verifier).VerifyHash(data, sig);
  343. }
  344. }
  345. else
  346. {
  347. hash.ComputeHash(data);
  348. if (verifier is AsymmetricSignatureDeformatter)
  349. {
  350. return ((AsymmetricSignatureDeformatter)verifier).VerifySignature(hash, sig);
  351. }
  352. else if (verifier is ECDsaCng)
  353. {
  354. return ((ECDsaCng)verifier).VerifyHash(hash.Hash, sig);
  355. }
  356. }
  357. }
  358. }
  359. catch (Exception e)
  360. {
  361. Debug.Print("Exception: " + e.ToString());
  362. return false;
  363. }
  364. finally
  365. {
  366. if (ctx != null)
  367. {
  368. ctx.VerifyCtx.Clear();
  369. }
  370. }
  371. return false;
  372. }
  373. bool ISignatureDriver.VerifyFinal(int session, IntPtr Signature, int SignatureLen)
  374. {
  375. SessionData ctx = null;
  376. try
  377. {
  378. ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
  379. unsafe
  380. {
  381. byte[] sig = new byte[SignatureLen];
  382. Marshal.Copy(Signature, sig, 0, SignatureLen);
  383. object verifier = ctx.VerifyCtx.SignObject;
  384. HashAlgorithm hash = ctx.VerifyCtx.SignHashAlg;
  385. if(hash == null) return false;
  386. if (verifier is AsymmetricSignatureDeformatter)
  387. {
  388. return ((AsymmetricSignatureDeformatter)verifier).VerifySignature(hash, sig);
  389. }
  390. else if (verifier is ECDsaCng)
  391. {
  392. return ((ECDsaCng)verifier).VerifyHash(hash.Hash, sig);
  393. }
  394. }
  395. }
  396. catch (Exception e)
  397. {
  398. Debug.Print("Exception: " + e.ToString());
  399. return false;
  400. }
  401. finally
  402. {
  403. if (ctx != null)
  404. {
  405. ctx.VerifyCtx.Clear();
  406. }
  407. }
  408. return false;
  409. }
  410. bool ISignatureDriver.VerifyUpdate(int session, IntPtr Data, int DataLen)
  411. {
  412. SessionData ctx = null;
  413. try
  414. {
  415. ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
  416. unsafe
  417. {
  418. byte[] data = new byte[DataLen];
  419. Marshal.Copy(Data, data, 0, DataLen);
  420. HashAlgorithm hash = ctx.VerifyCtx.SignHashAlg;
  421. if (hash == null) return false;
  422. hash.ComputeHash(data);
  423. }
  424. }
  425. catch (Exception e)
  426. {
  427. Debug.Print("Exception3: " + e.ToString());
  428. if (ctx != null)
  429. {
  430. ctx.VerifyCtx.Clear();
  431. }
  432. return false;
  433. }
  434. return true;
  435. }
  436. #endregion
  437. }
  438. }