Asn1KeyWrapper.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Oiw;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Encodings;
  11. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines;
  12. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  13. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  14. using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
  15. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Operators
  16. {
  17. public class Asn1KeyWrapper
  18. : IKeyWrapper
  19. {
  20. private string algorithm;
  21. private IKeyWrapper wrapper;
  22. public Asn1KeyWrapper(string algorithm, X509Certificate cert)
  23. {
  24. this.algorithm = algorithm;
  25. wrapper = KeyWrapperUtil.WrapperForName(algorithm, cert.GetPublicKey());
  26. }
  27. public Asn1KeyWrapper(DerObjectIdentifier algorithm, X509Certificate cert)
  28. : this(algorithm, cert.GetPublicKey())
  29. {
  30. }
  31. public Asn1KeyWrapper(DerObjectIdentifier algorithm, ICipherParameters key)
  32. : this(algorithm, null, key)
  33. {
  34. }
  35. public Asn1KeyWrapper(DerObjectIdentifier algorithm, Asn1Encodable parameters, X509Certificate cert)
  36. :this(algorithm, parameters, cert.GetPublicKey())
  37. {
  38. }
  39. public Asn1KeyWrapper(DerObjectIdentifier algorithm, Asn1Encodable parameters, ICipherParameters key)
  40. {
  41. this.algorithm = algorithm.Id;
  42. if (algorithm.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
  43. {
  44. RsaesOaepParameters oaepParams = RsaesOaepParameters.GetInstance(parameters);
  45. WrapperProvider provider;
  46. if (oaepParams.MaskGenAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdMgf1))
  47. {
  48. AlgorithmIdentifier digAlg = AlgorithmIdentifier.GetInstance(oaepParams.MaskGenAlgorithm.Parameters);
  49. provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, digAlg.Algorithm);
  50. }
  51. else
  52. {
  53. provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, oaepParams.MaskGenAlgorithm.Algorithm);
  54. }
  55. wrapper = (IKeyWrapper)provider.CreateWrapper(true, key);
  56. }
  57. else if (algorithm.Equals(PkcsObjectIdentifiers.RsaEncryption))
  58. {
  59. wrapper = (IKeyWrapper)new RsaPkcs1Wrapper(true, key);
  60. }
  61. else
  62. {
  63. throw new ArgumentException("unknown algorithm: " + algorithm.Id);
  64. }
  65. }
  66. public object AlgorithmDetails
  67. {
  68. get { return wrapper.AlgorithmDetails; }
  69. }
  70. public IBlockResult Wrap(byte[] keyData)
  71. {
  72. return wrapper.Wrap(keyData);
  73. }
  74. }
  75. public class Asn1KeyUnwrapper
  76. : IKeyUnwrapper
  77. {
  78. private string algorithm;
  79. private IKeyUnwrapper wrapper;
  80. public Asn1KeyUnwrapper(string algorithm, ICipherParameters key)
  81. {
  82. this.algorithm = algorithm;
  83. wrapper = KeyWrapperUtil.UnwrapperForName(algorithm, key);
  84. }
  85. public Asn1KeyUnwrapper(DerObjectIdentifier algorithm, ICipherParameters key)
  86. : this(algorithm, null, key)
  87. {
  88. }
  89. public Asn1KeyUnwrapper(DerObjectIdentifier algorithm, Asn1Encodable parameters, ICipherParameters key)
  90. {
  91. this.algorithm = algorithm.Id;
  92. if (algorithm.Equals(PkcsObjectIdentifiers.IdRsaesOaep))
  93. {
  94. RsaesOaepParameters oaepParams = RsaesOaepParameters.GetInstance(parameters);
  95. WrapperProvider provider;
  96. if (oaepParams.MaskGenAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdMgf1))
  97. {
  98. AlgorithmIdentifier digAlg = AlgorithmIdentifier.GetInstance(oaepParams.MaskGenAlgorithm.Parameters);
  99. provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, digAlg.Algorithm);
  100. }
  101. else
  102. {
  103. provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, oaepParams.MaskGenAlgorithm.Algorithm);
  104. }
  105. wrapper = (IKeyUnwrapper)provider.CreateWrapper(false, key);
  106. }
  107. else if (algorithm.Equals(PkcsObjectIdentifiers.RsaEncryption))
  108. {
  109. RsaesOaepParameters oaepParams = RsaesOaepParameters.GetInstance(parameters);
  110. WrapperProvider provider;
  111. if (oaepParams.MaskGenAlgorithm.Algorithm.Equals(PkcsObjectIdentifiers.IdMgf1))
  112. {
  113. AlgorithmIdentifier digAlg = AlgorithmIdentifier.GetInstance(oaepParams.MaskGenAlgorithm.Parameters);
  114. provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, digAlg.Algorithm);
  115. }
  116. else
  117. {
  118. provider = new RsaOaepWrapperProvider(oaepParams.HashAlgorithm.Algorithm, oaepParams.MaskGenAlgorithm.Algorithm);
  119. }
  120. wrapper = (IKeyUnwrapper)new RsaPkcs1Wrapper(false, key);
  121. }
  122. else
  123. {
  124. throw new ArgumentException("unknown algorithm: " + algorithm.Id);
  125. }
  126. }
  127. public object AlgorithmDetails
  128. {
  129. get { return wrapper.AlgorithmDetails; }
  130. }
  131. public IBlockResult Unwrap(byte[] keyData, int offSet, int length)
  132. {
  133. return wrapper.Unwrap(keyData, offSet, length);
  134. }
  135. }
  136. internal class KeyWrapperUtil
  137. {
  138. //
  139. // Provider
  140. //
  141. private static readonly IDictionary providerMap = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
  142. static KeyWrapperUtil()
  143. {
  144. providerMap.Add("RSA/ECB/PKCS1PADDING", new RsaOaepWrapperProvider(OiwObjectIdentifiers.IdSha1));
  145. providerMap.Add("RSA/NONE/PKCS1PADDING", new RsaOaepWrapperProvider(OiwObjectIdentifiers.IdSha1));
  146. providerMap.Add("RSA/NONE/OAEPWITHSHA1ANDMGF1PADDING", new RsaOaepWrapperProvider(OiwObjectIdentifiers.IdSha1));
  147. providerMap.Add("RSA/NONE/OAEPWITHSHA224ANDMGF1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha224));
  148. providerMap.Add("RSA/NONE/OAEPWITHSHA256ANDMGF1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha256));
  149. providerMap.Add("RSA/NONE/OAEPWITHSHA384ANDMGF1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha384));
  150. providerMap.Add("RSA/NONE/OAEPWITHSHA512ANDMGF1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha512));
  151. providerMap.Add("RSA/NONE/OAEPWITHSHA256ANDMGF1WITHSHA1PADDING", new RsaOaepWrapperProvider(NistObjectIdentifiers.IdSha256, OiwObjectIdentifiers.IdSha1));
  152. }
  153. public static IKeyWrapper WrapperForName(string algorithm, ICipherParameters parameters)
  154. {
  155. WrapperProvider provider = (WrapperProvider)providerMap[Strings.ToUpperCase(algorithm)];
  156. if (provider == null)
  157. throw new ArgumentException("could not resolve " + algorithm + " to a KeyWrapper");
  158. return (IKeyWrapper)provider.CreateWrapper(true, parameters);
  159. }
  160. public static IKeyUnwrapper UnwrapperForName(string algorithm, ICipherParameters parameters)
  161. {
  162. WrapperProvider provider = (WrapperProvider)providerMap[Strings.ToUpperCase(algorithm)];
  163. if (provider == null)
  164. throw new ArgumentException("could not resolve " + algorithm + " to a KeyUnwrapper");
  165. return (IKeyUnwrapper)provider.CreateWrapper(false, parameters);
  166. }
  167. }
  168. internal interface WrapperProvider
  169. {
  170. object CreateWrapper(bool forWrapping, ICipherParameters parameters);
  171. }
  172. internal class RsaPkcs1Wrapper : IKeyWrapper, IKeyUnwrapper
  173. {
  174. private readonly AlgorithmIdentifier algId;
  175. private readonly IAsymmetricBlockCipher engine;
  176. public RsaPkcs1Wrapper(bool forWrapping, ICipherParameters parameters)
  177. {
  178. this.algId = new AlgorithmIdentifier(
  179. PkcsObjectIdentifiers.RsaEncryption,
  180. DerNull.Instance);
  181. this.engine = new Pkcs1Encoding(new RsaBlindedEngine());
  182. this.engine.Init(forWrapping, parameters);
  183. }
  184. public object AlgorithmDetails
  185. {
  186. get { return algId; }
  187. }
  188. public IBlockResult Unwrap(byte[] cipherText, int offset, int length)
  189. {
  190. return new SimpleBlockResult(engine.ProcessBlock(cipherText, offset, length));
  191. }
  192. public IBlockResult Wrap(byte[] keyData)
  193. {
  194. return new SimpleBlockResult(engine.ProcessBlock(keyData, 0, keyData.Length));
  195. }
  196. }
  197. internal class RsaPkcs1WrapperProvider
  198. : WrapperProvider
  199. {
  200. internal RsaPkcs1WrapperProvider()
  201. {
  202. }
  203. object WrapperProvider.CreateWrapper(bool forWrapping, ICipherParameters parameters)
  204. {
  205. return new RsaPkcs1Wrapper(forWrapping, parameters);
  206. }
  207. }
  208. internal class RsaOaepWrapper : IKeyWrapper, IKeyUnwrapper
  209. {
  210. private readonly AlgorithmIdentifier algId;
  211. private readonly IAsymmetricBlockCipher engine;
  212. public RsaOaepWrapper(bool forWrapping, ICipherParameters parameters, DerObjectIdentifier digestOid)
  213. : this(forWrapping, parameters, digestOid, digestOid)
  214. {
  215. }
  216. public RsaOaepWrapper(bool forWrapping, ICipherParameters parameters, DerObjectIdentifier digestOid, DerObjectIdentifier mgfOid)
  217. {
  218. AlgorithmIdentifier digestAlgId = new AlgorithmIdentifier(digestOid, DerNull.Instance);
  219. if (mgfOid.Equals(NistObjectIdentifiers.IdShake128) || mgfOid.Equals(NistObjectIdentifiers.IdShake256))
  220. {
  221. this.algId = new AlgorithmIdentifier(
  222. PkcsObjectIdentifiers.IdRsaesOaep,
  223. new RsaesOaepParameters(
  224. digestAlgId,
  225. new AlgorithmIdentifier(mgfOid),
  226. RsaesOaepParameters.DefaultPSourceAlgorithm));
  227. }
  228. else
  229. {
  230. this.algId = new AlgorithmIdentifier(
  231. PkcsObjectIdentifiers.IdRsaesOaep,
  232. new RsaesOaepParameters(
  233. digestAlgId,
  234. new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, new AlgorithmIdentifier(mgfOid, DerNull.Instance)),
  235. RsaesOaepParameters.DefaultPSourceAlgorithm));
  236. }
  237. this.engine = new OaepEncoding(new RsaBlindedEngine(), DigestUtilities.GetDigest(digestOid), DigestUtilities.GetDigest(mgfOid), null);
  238. this.engine.Init(forWrapping, parameters);
  239. }
  240. public object AlgorithmDetails
  241. {
  242. get { return algId; }
  243. }
  244. public IBlockResult Unwrap(byte[] cipherText, int offset, int length)
  245. {
  246. return new SimpleBlockResult(engine.ProcessBlock(cipherText, offset, length));
  247. }
  248. public IBlockResult Wrap(byte[] keyData)
  249. {
  250. return new SimpleBlockResult(engine.ProcessBlock(keyData, 0, keyData.Length));
  251. }
  252. }
  253. internal class RsaOaepWrapperProvider
  254. : WrapperProvider
  255. {
  256. private readonly DerObjectIdentifier digestOid;
  257. private readonly DerObjectIdentifier mgfOid;
  258. internal RsaOaepWrapperProvider(DerObjectIdentifier digestOid)
  259. {
  260. this.digestOid = digestOid;
  261. this.mgfOid = digestOid;
  262. }
  263. internal RsaOaepWrapperProvider(DerObjectIdentifier digestOid, DerObjectIdentifier mgfOid)
  264. {
  265. this.digestOid = digestOid;
  266. this.mgfOid = mgfOid;
  267. }
  268. object WrapperProvider.CreateWrapper(bool forWrapping, ICipherParameters parameters)
  269. {
  270. return new RsaOaepWrapper(forWrapping, parameters, digestOid, mgfOid);
  271. }
  272. }
  273. }
  274. #pragma warning restore
  275. #endif