ProtectedPkiMessageBuilder.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections.Generic;
  5. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cmp;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms;
  8. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  9. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  10. using Best.HTTP.SecureProtocol.Org.BouncyCastle.X509;
  11. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Cmp
  12. {
  13. public sealed class ProtectedPkiMessageBuilder
  14. {
  15. private readonly PkiHeaderBuilder m_hdrBuilder;
  16. private PkiBody body;
  17. private readonly List<InfoTypeAndValue> generalInfos = new List<InfoTypeAndValue>();
  18. private readonly List<X509Certificate> extraCerts = new List<X509Certificate>();
  19. public ProtectedPkiMessageBuilder(GeneralName sender, GeneralName recipient)
  20. : this(PkiHeader.CMP_2000, sender, recipient)
  21. {
  22. }
  23. public ProtectedPkiMessageBuilder(int pvno, GeneralName sender, GeneralName recipient)
  24. {
  25. m_hdrBuilder = new PkiHeaderBuilder(pvno, sender, recipient);
  26. }
  27. public ProtectedPkiMessageBuilder SetTransactionId(byte[] tid)
  28. {
  29. m_hdrBuilder.SetTransactionID(tid);
  30. return this;
  31. }
  32. public ProtectedPkiMessageBuilder SetFreeText(PkiFreeText freeText)
  33. {
  34. m_hdrBuilder.SetFreeText(freeText);
  35. return this;
  36. }
  37. public ProtectedPkiMessageBuilder AddGeneralInfo(InfoTypeAndValue genInfo)
  38. {
  39. generalInfos.Add(genInfo);
  40. return this;
  41. }
  42. public ProtectedPkiMessageBuilder SetMessageTime(DateTime time)
  43. {
  44. m_hdrBuilder.SetMessageTime(new Asn1GeneralizedTime(time));
  45. return this;
  46. }
  47. public ProtectedPkiMessageBuilder SetMessageTime(Asn1GeneralizedTime generalizedTime)
  48. {
  49. m_hdrBuilder.SetMessageTime(generalizedTime);
  50. return this;
  51. }
  52. public ProtectedPkiMessageBuilder SetRecipKID(byte[] id)
  53. {
  54. m_hdrBuilder.SetRecipKID(id);
  55. return this;
  56. }
  57. public ProtectedPkiMessageBuilder SetRecipNonce(byte[] nonce)
  58. {
  59. m_hdrBuilder.SetRecipNonce(nonce);
  60. return this;
  61. }
  62. public ProtectedPkiMessageBuilder SetSenderKID(byte[] id)
  63. {
  64. m_hdrBuilder.SetSenderKID(id);
  65. return this;
  66. }
  67. public ProtectedPkiMessageBuilder SetSenderNonce(byte[] nonce)
  68. {
  69. m_hdrBuilder.SetSenderNonce(nonce);
  70. return this;
  71. }
  72. public ProtectedPkiMessageBuilder SetBody(PkiBody body)
  73. {
  74. this.body = body;
  75. return this;
  76. }
  77. public ProtectedPkiMessageBuilder AddCmpCertificate(X509Certificate certificate)
  78. {
  79. extraCerts.Add(certificate);
  80. return this;
  81. }
  82. public ProtectedPkiMessage Build(ISignatureFactory signatureFactory)
  83. {
  84. if (null == body)
  85. throw new InvalidOperationException("body must be set before building");
  86. IStreamCalculator<IBlockResult> calculator = signatureFactory.CreateCalculator();
  87. if (!(signatureFactory.AlgorithmDetails is AlgorithmIdentifier algorithmDetails))
  88. throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier");
  89. FinalizeHeader(algorithmDetails);
  90. PkiHeader header = m_hdrBuilder.Build();
  91. DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body));
  92. return FinalizeMessage(header, protection);
  93. }
  94. public ProtectedPkiMessage Build(IMacFactory macFactory)
  95. {
  96. if (null == body)
  97. throw new InvalidOperationException("body must be set before building");
  98. IStreamCalculator<IBlockResult> calculator = macFactory.CreateCalculator();
  99. if (!(macFactory.AlgorithmDetails is AlgorithmIdentifier algorithmDetails))
  100. throw new ArgumentException("AlgorithmDetails is not AlgorithmIdentifier");
  101. FinalizeHeader(algorithmDetails);
  102. PkiHeader header = m_hdrBuilder.Build();
  103. DerBitString protection = new DerBitString(CalculateSignature(calculator, header, body));
  104. return FinalizeMessage(header, protection);
  105. }
  106. private void FinalizeHeader(AlgorithmIdentifier algorithmIdentifier)
  107. {
  108. m_hdrBuilder.SetProtectionAlg(algorithmIdentifier);
  109. if (generalInfos.Count > 0)
  110. {
  111. m_hdrBuilder.SetGeneralInfo(generalInfos.ToArray());
  112. }
  113. }
  114. private ProtectedPkiMessage FinalizeMessage(PkiHeader header, DerBitString protection)
  115. {
  116. if (extraCerts.Count < 1)
  117. return new ProtectedPkiMessage(new PkiMessage(header, body, protection));
  118. CmpCertificate[] cmpCertificates = new CmpCertificate[extraCerts.Count];
  119. for (int i = 0; i < cmpCertificates.Length; i++)
  120. {
  121. cmpCertificates[i] = new CmpCertificate(extraCerts[i].CertificateStructure);
  122. }
  123. return new ProtectedPkiMessage(new PkiMessage(header, body, protection, cmpCertificates));
  124. }
  125. private byte[] CalculateSignature(IStreamCalculator<IBlockResult> signer, PkiHeader header, PkiBody body)
  126. {
  127. new DerSequence(header, body).EncodeTo(signer.Stream);
  128. return signer.GetResult().Collect();
  129. }
  130. }
  131. }
  132. #pragma warning restore
  133. #endif