SignedData.cs 8.7 KB

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