DotNetUtilities.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. #if !(NETCF_1_0 || SILVERLIGHT || PORTABLE || NETFX_CORE)
  4. using System;
  5. using System.Security.Cryptography;
  6. using SystemX509 = System.Security.Cryptography.X509Certificates;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  11. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  12. using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
  13. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Security
  14. {
  15. /// <summary>
  16. /// A class containing methods to interface the BouncyCastle world to the .NET Crypto world.
  17. /// </summary>
  18. public sealed class DotNetUtilities
  19. {
  20. private DotNetUtilities()
  21. {
  22. }
  23. /// <summary>
  24. /// Create an System.Security.Cryptography.X509Certificate from an X509Certificate Structure.
  25. /// </summary>
  26. /// <param name="x509Struct"></param>
  27. /// <returns>A System.Security.Cryptography.X509Certificate.</returns>
  28. public static SystemX509.X509Certificate ToX509Certificate(
  29. X509CertificateStructure x509Struct)
  30. {
  31. return new SystemX509.X509Certificate(x509Struct.GetDerEncoded());
  32. }
  33. public static SystemX509.X509Certificate ToX509Certificate(
  34. X509Certificate x509Cert)
  35. {
  36. return new SystemX509.X509Certificate(x509Cert.GetEncoded());
  37. }
  38. public static X509Certificate FromX509Certificate(
  39. SystemX509.X509Certificate x509Cert)
  40. {
  41. return new X509CertificateParser().ReadCertificate(x509Cert.GetRawCertData());
  42. }
  43. public static AsymmetricCipherKeyPair GetDsaKeyPair(DSA dsa)
  44. {
  45. return GetDsaKeyPair(dsa.ExportParameters(true));
  46. }
  47. public static AsymmetricCipherKeyPair GetDsaKeyPair(DSAParameters dp)
  48. {
  49. DsaValidationParameters validationParameters = (dp.Seed != null)
  50. ? new DsaValidationParameters(dp.Seed, dp.Counter)
  51. : null;
  52. DsaParameters parameters = new DsaParameters(
  53. new BigInteger(1, dp.P),
  54. new BigInteger(1, dp.Q),
  55. new BigInteger(1, dp.G),
  56. validationParameters);
  57. DsaPublicKeyParameters pubKey = new DsaPublicKeyParameters(
  58. new BigInteger(1, dp.Y),
  59. parameters);
  60. DsaPrivateKeyParameters privKey = new DsaPrivateKeyParameters(
  61. new BigInteger(1, dp.X),
  62. parameters);
  63. return new AsymmetricCipherKeyPair(pubKey, privKey);
  64. }
  65. public static DsaPublicKeyParameters GetDsaPublicKey(DSA dsa)
  66. {
  67. return GetDsaPublicKey(dsa.ExportParameters(false));
  68. }
  69. public static DsaPublicKeyParameters GetDsaPublicKey(DSAParameters dp)
  70. {
  71. DsaValidationParameters validationParameters = (dp.Seed != null)
  72. ? new DsaValidationParameters(dp.Seed, dp.Counter)
  73. : null;
  74. DsaParameters parameters = new DsaParameters(
  75. new BigInteger(1, dp.P),
  76. new BigInteger(1, dp.Q),
  77. new BigInteger(1, dp.G),
  78. validationParameters);
  79. return new DsaPublicKeyParameters(
  80. new BigInteger(1, dp.Y),
  81. parameters);
  82. }
  83. public static AsymmetricCipherKeyPair GetRsaKeyPair(RSA rsa)
  84. {
  85. return GetRsaKeyPair(rsa.ExportParameters(true));
  86. }
  87. public static AsymmetricCipherKeyPair GetRsaKeyPair(RSAParameters rp)
  88. {
  89. BigInteger modulus = new BigInteger(1, rp.Modulus);
  90. BigInteger pubExp = new BigInteger(1, rp.Exponent);
  91. RsaKeyParameters pubKey = new RsaKeyParameters(
  92. false,
  93. modulus,
  94. pubExp);
  95. RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
  96. modulus,
  97. pubExp,
  98. new BigInteger(1, rp.D),
  99. new BigInteger(1, rp.P),
  100. new BigInteger(1, rp.Q),
  101. new BigInteger(1, rp.DP),
  102. new BigInteger(1, rp.DQ),
  103. new BigInteger(1, rp.InverseQ));
  104. return new AsymmetricCipherKeyPair(pubKey, privKey);
  105. }
  106. public static RsaKeyParameters GetRsaPublicKey(RSA rsa)
  107. {
  108. return GetRsaPublicKey(rsa.ExportParameters(false));
  109. }
  110. public static RsaKeyParameters GetRsaPublicKey(
  111. RSAParameters rp)
  112. {
  113. return new RsaKeyParameters(
  114. false,
  115. new BigInteger(1, rp.Modulus),
  116. new BigInteger(1, rp.Exponent));
  117. }
  118. public static AsymmetricCipherKeyPair GetKeyPair(AsymmetricAlgorithm privateKey)
  119. {
  120. if (privateKey is DSA)
  121. {
  122. return GetDsaKeyPair((DSA)privateKey);
  123. }
  124. if (privateKey is RSA)
  125. {
  126. return GetRsaKeyPair((RSA)privateKey);
  127. }
  128. throw new ArgumentException("Unsupported algorithm specified", "privateKey");
  129. }
  130. public static RSA ToRSA(RsaKeyParameters rsaKey)
  131. {
  132. // TODO This appears to not work for private keys (when no CRT info)
  133. return CreateRSAProvider(ToRSAParameters(rsaKey));
  134. }
  135. public static RSA ToRSA(RsaKeyParameters rsaKey, CspParameters csp)
  136. {
  137. // TODO This appears to not work for private keys (when no CRT info)
  138. return CreateRSAProvider(ToRSAParameters(rsaKey), csp);
  139. }
  140. public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey)
  141. {
  142. return CreateRSAProvider(ToRSAParameters(privKey));
  143. }
  144. public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey, CspParameters csp)
  145. {
  146. return CreateRSAProvider(ToRSAParameters(privKey), csp);
  147. }
  148. public static RSA ToRSA(RsaPrivateKeyStructure privKey)
  149. {
  150. return CreateRSAProvider(ToRSAParameters(privKey));
  151. }
  152. public static RSA ToRSA(RsaPrivateKeyStructure privKey, CspParameters csp)
  153. {
  154. return CreateRSAProvider(ToRSAParameters(privKey), csp);
  155. }
  156. public static RSAParameters ToRSAParameters(RsaKeyParameters rsaKey)
  157. {
  158. RSAParameters rp = new RSAParameters();
  159. rp.Modulus = rsaKey.Modulus.ToByteArrayUnsigned();
  160. if (rsaKey.IsPrivate)
  161. rp.D = ConvertRSAParametersField(rsaKey.Exponent, rp.Modulus.Length);
  162. else
  163. rp.Exponent = rsaKey.Exponent.ToByteArrayUnsigned();
  164. return rp;
  165. }
  166. public static RSAParameters ToRSAParameters(RsaPrivateCrtKeyParameters privKey)
  167. {
  168. RSAParameters rp = new RSAParameters();
  169. rp.Modulus = privKey.Modulus.ToByteArrayUnsigned();
  170. rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
  171. rp.P = privKey.P.ToByteArrayUnsigned();
  172. rp.Q = privKey.Q.ToByteArrayUnsigned();
  173. rp.D = ConvertRSAParametersField(privKey.Exponent, rp.Modulus.Length);
  174. rp.DP = ConvertRSAParametersField(privKey.DP, rp.P.Length);
  175. rp.DQ = ConvertRSAParametersField(privKey.DQ, rp.Q.Length);
  176. rp.InverseQ = ConvertRSAParametersField(privKey.QInv, rp.Q.Length);
  177. return rp;
  178. }
  179. public static RSAParameters ToRSAParameters(RsaPrivateKeyStructure privKey)
  180. {
  181. RSAParameters rp = new RSAParameters();
  182. rp.Modulus = privKey.Modulus.ToByteArrayUnsigned();
  183. rp.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
  184. rp.P = privKey.Prime1.ToByteArrayUnsigned();
  185. rp.Q = privKey.Prime2.ToByteArrayUnsigned();
  186. rp.D = ConvertRSAParametersField(privKey.PrivateExponent, rp.Modulus.Length);
  187. rp.DP = ConvertRSAParametersField(privKey.Exponent1, rp.P.Length);
  188. rp.DQ = ConvertRSAParametersField(privKey.Exponent2, rp.Q.Length);
  189. rp.InverseQ = ConvertRSAParametersField(privKey.Coefficient, rp.Q.Length);
  190. return rp;
  191. }
  192. // TODO Move functionality to more general class
  193. private static byte[] ConvertRSAParametersField(BigInteger n, int size)
  194. {
  195. byte[] bs = n.ToByteArrayUnsigned();
  196. if (bs.Length == size)
  197. return bs;
  198. if (bs.Length > size)
  199. throw new ArgumentException("Specified size too small", "size");
  200. byte[] padded = new byte[size];
  201. Array.Copy(bs, 0, padded, size - bs.Length, bs.Length);
  202. return padded;
  203. }
  204. private static RSA CreateRSAProvider(RSAParameters rp)
  205. {
  206. CspParameters csp = new CspParameters();
  207. csp.KeyContainerName = string.Format("BouncyCastle-{0}", Guid.NewGuid());
  208. RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp);
  209. rsaCsp.ImportParameters(rp);
  210. return rsaCsp;
  211. }
  212. private static RSA CreateRSAProvider(RSAParameters rp, CspParameters csp)
  213. {
  214. RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider(csp);
  215. rsaCsp.ImportParameters(rp);
  216. return rsaCsp;
  217. }
  218. }
  219. }
  220. #endif
  221. #pragma warning restore
  222. #endif