SignedData.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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.Utilities;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Cms
  7. {
  8. /**
  9. * a signed data object.
  10. */
  11. public class SignedData
  12. : Asn1Encodable
  13. {
  14. private static readonly DerInteger Version1 = new DerInteger(1);
  15. private static readonly DerInteger Version3 = new DerInteger(3);
  16. private static readonly DerInteger Version4 = new DerInteger(4);
  17. private static readonly DerInteger Version5 = new DerInteger(5);
  18. private readonly DerInteger version;
  19. private readonly Asn1Set digestAlgorithms;
  20. private readonly ContentInfo contentInfo;
  21. private readonly Asn1Set certificates;
  22. private readonly Asn1Set crls;
  23. private readonly Asn1Set signerInfos;
  24. private readonly bool certsBer;
  25. private readonly bool crlsBer;
  26. public static SignedData GetInstance(object obj)
  27. {
  28. if (obj is SignedData)
  29. return (SignedData)obj;
  30. if (obj == null)
  31. return null;
  32. return new SignedData(Asn1Sequence.GetInstance(obj));
  33. }
  34. public SignedData(
  35. Asn1Set digestAlgorithms,
  36. ContentInfo contentInfo,
  37. Asn1Set certificates,
  38. Asn1Set crls,
  39. Asn1Set signerInfos)
  40. {
  41. this.version = CalculateVersion(contentInfo.ContentType, certificates, crls, signerInfos);
  42. this.digestAlgorithms = digestAlgorithms;
  43. this.contentInfo = contentInfo;
  44. this.certificates = certificates;
  45. this.crls = crls;
  46. this.signerInfos = signerInfos;
  47. this.crlsBer = crls is BerSet;
  48. this.certsBer = certificates is BerSet;
  49. }
  50. // RFC3852, section 5.1:
  51. // IF ((certificates is present) AND
  52. // (any certificates with a type of other are present)) OR
  53. // ((crls is present) AND
  54. // (any crls with a type of other are present))
  55. // THEN version MUST be 5
  56. // ELSE
  57. // IF (certificates is present) AND
  58. // (any version 2 attribute certificates are present)
  59. // THEN version MUST be 4
  60. // ELSE
  61. // IF ((certificates is present) AND
  62. // (any version 1 attribute certificates are present)) OR
  63. // (any SignerInfo structures are version 3) OR
  64. // (encapContentInfo eContentType is other than id-data)
  65. // THEN version MUST be 3
  66. // ELSE version MUST be 1
  67. //
  68. private DerInteger CalculateVersion(
  69. DerObjectIdentifier contentOid,
  70. Asn1Set certs,
  71. Asn1Set crls,
  72. Asn1Set signerInfs)
  73. {
  74. bool otherCert = false;
  75. bool otherCrl = false;
  76. bool attrCertV1Found = false;
  77. bool attrCertV2Found = false;
  78. if (certs != null)
  79. {
  80. foreach (object obj in certs)
  81. {
  82. if (obj is Asn1TaggedObject)
  83. {
  84. Asn1TaggedObject tagged = (Asn1TaggedObject)obj;
  85. if (tagged.TagNo == 1)
  86. {
  87. attrCertV1Found = true;
  88. }
  89. else if (tagged.TagNo == 2)
  90. {
  91. attrCertV2Found = true;
  92. }
  93. else if (tagged.TagNo == 3)
  94. {
  95. otherCert = true;
  96. break;
  97. }
  98. }
  99. }
  100. }
  101. if (otherCert)
  102. {
  103. return Version5;
  104. }
  105. if (crls != null)
  106. {
  107. foreach (object obj in crls)
  108. {
  109. if (obj is Asn1TaggedObject)
  110. {
  111. otherCrl = true;
  112. break;
  113. }
  114. }
  115. }
  116. if (otherCrl)
  117. {
  118. return Version5;
  119. }
  120. if (attrCertV2Found)
  121. {
  122. return Version4;
  123. }
  124. if (attrCertV1Found || !CmsObjectIdentifiers.Data.Equals(contentOid) || CheckForVersion3(signerInfs))
  125. {
  126. return Version3;
  127. }
  128. return Version1;
  129. }
  130. private bool CheckForVersion3(
  131. Asn1Set signerInfs)
  132. {
  133. foreach (object obj in signerInfs)
  134. {
  135. SignerInfo s = SignerInfo.GetInstance(obj);
  136. if (s.Version.HasValue(3))
  137. {
  138. return true;
  139. }
  140. }
  141. return false;
  142. }
  143. private SignedData(
  144. Asn1Sequence seq)
  145. {
  146. IEnumerator e = seq.GetEnumerator();
  147. e.MoveNext();
  148. version = (DerInteger)e.Current;
  149. e.MoveNext();
  150. digestAlgorithms = ((Asn1Set)e.Current);
  151. e.MoveNext();
  152. contentInfo = ContentInfo.GetInstance(e.Current);
  153. while (e.MoveNext())
  154. {
  155. Asn1Object o = (Asn1Object)e.Current;
  156. //
  157. // an interesting feature of SignedData is that there appear
  158. // to be varying implementations...
  159. // for the moment we ignore anything which doesn't fit.
  160. //
  161. if (o is Asn1TaggedObject)
  162. {
  163. Asn1TaggedObject tagged = (Asn1TaggedObject)o;
  164. switch (tagged.TagNo)
  165. {
  166. case 0:
  167. certsBer = tagged is BerTaggedObject;
  168. certificates = Asn1Set.GetInstance(tagged, false);
  169. break;
  170. case 1:
  171. crlsBer = tagged is BerTaggedObject;
  172. crls = Asn1Set.GetInstance(tagged, false);
  173. break;
  174. default:
  175. throw new ArgumentException("unknown tag value " + tagged.TagNo);
  176. }
  177. }
  178. else
  179. {
  180. signerInfos = (Asn1Set) o;
  181. }
  182. }
  183. }
  184. public DerInteger Version
  185. {
  186. get { return version; }
  187. }
  188. public Asn1Set DigestAlgorithms
  189. {
  190. get { return digestAlgorithms; }
  191. }
  192. public ContentInfo EncapContentInfo
  193. {
  194. get { return contentInfo; }
  195. }
  196. public Asn1Set Certificates
  197. {
  198. get { return certificates; }
  199. }
  200. public Asn1Set CRLs
  201. {
  202. get { return crls; }
  203. }
  204. public Asn1Set SignerInfos
  205. {
  206. get { return signerInfos; }
  207. }
  208. /**
  209. * Produce an object suitable for an Asn1OutputStream.
  210. * <pre>
  211. * SignedData ::= Sequence {
  212. * version CMSVersion,
  213. * digestAlgorithms DigestAlgorithmIdentifiers,
  214. * encapContentInfo EncapsulatedContentInfo,
  215. * certificates [0] IMPLICIT CertificateSet OPTIONAL,
  216. * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
  217. * signerInfos SignerInfos
  218. * }
  219. * </pre>
  220. */
  221. public override Asn1Object ToAsn1Object()
  222. {
  223. Asn1EncodableVector v = new Asn1EncodableVector(
  224. version, digestAlgorithms, contentInfo);
  225. if (certificates != null)
  226. {
  227. if (certsBer)
  228. {
  229. v.Add(new BerTaggedObject(false, 0, certificates));
  230. }
  231. else
  232. {
  233. v.Add(new DerTaggedObject(false, 0, certificates));
  234. }
  235. }
  236. if (crls != null)
  237. {
  238. if (crlsBer)
  239. {
  240. v.Add(new BerTaggedObject(false, 1, crls));
  241. }
  242. else
  243. {
  244. v.Add(new DerTaggedObject(false, 1, crls));
  245. }
  246. }
  247. v.Add(signerInfos);
  248. return new BerSequence(v);
  249. }
  250. }
  251. }
  252. #pragma warning restore
  253. #endif