EncryptedValueBuilder.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Crmf;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  8. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  9. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  10. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  11. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Pkcs;
  12. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  13. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.IO;
  14. using Best.HTTP.SecureProtocol.Org.BouncyCastle.X509;
  15. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crmf
  16. {
  17. public class EncryptedValueBuilder
  18. {
  19. private readonly IKeyWrapper wrapper;
  20. private readonly ICipherBuilderWithKey encryptor;
  21. private readonly IEncryptedValuePadder padder;
  22. ///
  23. /// Create a builder that makes EncryptedValue structures.
  24. ///
  25. /// <param name="wrapper">wrapper a wrapper for key used to encrypt the actual data contained in the EncryptedValue.</param>
  26. /// <param name="encryptor">encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue. </param>
  27. ///
  28. public EncryptedValueBuilder(IKeyWrapper wrapper, ICipherBuilderWithKey encryptor)
  29. : this(wrapper, encryptor, null)
  30. {
  31. }
  32. ///
  33. /// Create a builder that makes EncryptedValue structures with fixed length blocks padded using the passed in padder.
  34. ///
  35. /// <param name="wrapper">a wrapper for key used to encrypt the actual data contained in the EncryptedValue.</param>
  36. /// <param name="encryptor">encryptor an output encryptor to encrypt the actual data contained in the EncryptedValue.</param>
  37. /// <param name="padder">padder a padder to ensure that the EncryptedValue created will always be a constant length.</param>
  38. ///
  39. public EncryptedValueBuilder(IKeyWrapper wrapper, ICipherBuilderWithKey encryptor, IEncryptedValuePadder padder)
  40. {
  41. this.wrapper = wrapper;
  42. this.encryptor = encryptor;
  43. this.padder = padder;
  44. }
  45. ///
  46. /// Build an EncryptedValue structure containing the passed in pass phrase.
  47. ///
  48. /// <param name="revocationPassphrase">a revocation pass phrase.</param>
  49. ///<returns>an EncryptedValue containing the encrypted pass phrase.</returns>
  50. ///
  51. public EncryptedValue Build(char[] revocationPassphrase)
  52. {
  53. return EncryptData(PadData(Strings.ToUtf8ByteArray(revocationPassphrase)));
  54. }
  55. ///<summary>
  56. /// Build an EncryptedValue structure containing the certificate contained in
  57. /// the passed in holder.
  58. ///</summary>
  59. /// <param name="holder">a holder containing a certificate.</param>
  60. /// <returns>an EncryptedValue containing the encrypted certificate.</returns>
  61. /// <exception cref="CrmfException">on a failure to encrypt the data, or wrap the symmetric key for this value.</exception>
  62. ///
  63. public EncryptedValue Build(X509Certificate holder)
  64. {
  65. try
  66. {
  67. return EncryptData(PadData(holder.GetEncoded()));
  68. }
  69. catch (IOException e)
  70. {
  71. throw new CrmfException("cannot encode certificate: " + e.Message, e);
  72. }
  73. }
  74. ///<summary>
  75. /// Build an EncryptedValue structure containing the private key contained in
  76. /// the passed info structure.
  77. ///</summary>
  78. /// <param name="privateKeyInfo">a PKCS#8 private key info structure.</param>
  79. /// <returns>an EncryptedValue containing an EncryptedPrivateKeyInfo structure.</returns>
  80. /// <exception cref="CrmfException">on a failure to encrypt the data, or wrap the symmetric key for this value.</exception>
  81. ///
  82. public EncryptedValue Build(PrivateKeyInfo privateKeyInfo)
  83. {
  84. Pkcs8EncryptedPrivateKeyInfoBuilder encInfoBldr = new Pkcs8EncryptedPrivateKeyInfoBuilder(privateKeyInfo);
  85. AlgorithmIdentifier intendedAlg = privateKeyInfo.PrivateKeyAlgorithm;
  86. AlgorithmIdentifier symmAlg = (AlgorithmIdentifier)encryptor.AlgorithmDetails;
  87. DerBitString encSymmKey;
  88. try
  89. {
  90. Pkcs8EncryptedPrivateKeyInfo encInfo = encInfoBldr.Build(encryptor);
  91. encSymmKey = new DerBitString(wrapper.Wrap(((KeyParameter)encryptor.Key).GetKey()).Collect());
  92. AlgorithmIdentifier keyAlg = (AlgorithmIdentifier)wrapper.AlgorithmDetails;
  93. Asn1OctetString valueHint = null;
  94. return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, new DerBitString(encInfo.GetEncryptedData()));
  95. }
  96. catch (Exception e)
  97. {
  98. throw new CrmfException("cannot wrap key: " + e.Message, e);
  99. }
  100. }
  101. private EncryptedValue EncryptData(byte[] data)
  102. {
  103. MemoryOutputStream bOut = new MemoryOutputStream();
  104. var cipher = encryptor.BuildCipher(bOut);
  105. try
  106. {
  107. using (var eOut = cipher.Stream)
  108. {
  109. eOut.Write(data, 0, data.Length);
  110. }
  111. }
  112. catch (IOException e)
  113. {
  114. throw new CrmfException("cannot process data: " + e.Message, e);
  115. }
  116. AlgorithmIdentifier intendedAlg = null;
  117. AlgorithmIdentifier symmAlg = (AlgorithmIdentifier)encryptor.AlgorithmDetails;
  118. DerBitString encSymmKey;
  119. try
  120. {
  121. encSymmKey = new DerBitString(wrapper.Wrap(((KeyParameter)encryptor.Key).GetKey()).Collect());
  122. }
  123. catch (Exception e)
  124. {
  125. throw new CrmfException("cannot wrap key: " + e.Message, e);
  126. }
  127. AlgorithmIdentifier keyAlg = (AlgorithmIdentifier)wrapper.AlgorithmDetails;
  128. Asn1OctetString valueHint = null;
  129. DerBitString encValue = new DerBitString(bOut.ToArray());
  130. return new EncryptedValue(intendedAlg, symmAlg, encSymmKey, keyAlg, valueHint, encValue);
  131. }
  132. private byte[] PadData(byte[] data)
  133. {
  134. if (padder != null)
  135. {
  136. return padder.GetPaddedData(data);
  137. }
  138. return data;
  139. }
  140. }
  141. }
  142. #pragma warning restore
  143. #endif