X509V2AttributeCertificate.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  7. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  8. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  9. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Operators;
  10. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
  11. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
  12. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
  13. using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  14. namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.X509
  15. {
  16. /// <summary>An implementation of a version 2 X.509 Attribute Certificate.</summary>
  17. public class X509V2AttributeCertificate
  18. : X509ExtensionBase
  19. {
  20. private readonly AttributeCertificate cert;
  21. private readonly DateTime notBefore;
  22. private readonly DateTime notAfter;
  23. private static AttributeCertificate GetObject(Stream input)
  24. {
  25. try
  26. {
  27. return AttributeCertificate.GetInstance(Asn1Object.FromStream(input));
  28. }
  29. catch (IOException e)
  30. {
  31. throw e;
  32. }
  33. catch (Exception e)
  34. {
  35. throw new IOException("exception decoding certificate structure", e);
  36. }
  37. }
  38. public X509V2AttributeCertificate(
  39. Stream encIn)
  40. : this(GetObject(encIn))
  41. {
  42. }
  43. public X509V2AttributeCertificate(
  44. byte[] encoded)
  45. : this(new MemoryStream(encoded, false))
  46. {
  47. }
  48. public X509V2AttributeCertificate(AttributeCertificate cert)
  49. {
  50. this.cert = cert;
  51. try
  52. {
  53. this.notAfter = cert.ACInfo.AttrCertValidityPeriod.NotAfterTime.ToDateTime();
  54. this.notBefore = cert.ACInfo.AttrCertValidityPeriod.NotBeforeTime.ToDateTime();
  55. }
  56. catch (Exception e)
  57. {
  58. throw new IOException("invalid data structure in certificate!", e);
  59. }
  60. }
  61. public virtual AttributeCertificate AttributeCertificate
  62. {
  63. get { return cert; }
  64. }
  65. public virtual int Version
  66. {
  67. get { return cert.ACInfo.Version.IntValueExact + 1; }
  68. }
  69. public virtual BigInteger SerialNumber
  70. {
  71. get { return cert.ACInfo.SerialNumber.Value; }
  72. }
  73. public virtual AttributeCertificateHolder Holder
  74. {
  75. get
  76. {
  77. return new AttributeCertificateHolder((Asn1Sequence)cert.ACInfo.Holder.ToAsn1Object());
  78. }
  79. }
  80. public virtual AttributeCertificateIssuer Issuer
  81. {
  82. get
  83. {
  84. return new AttributeCertificateIssuer(cert.ACInfo.Issuer);
  85. }
  86. }
  87. public virtual DateTime NotBefore
  88. {
  89. get { return notBefore; }
  90. }
  91. public virtual DateTime NotAfter
  92. {
  93. get { return notAfter; }
  94. }
  95. public virtual bool[] GetIssuerUniqueID()
  96. {
  97. DerBitString id = cert.ACInfo.IssuerUniqueID;
  98. if (id != null)
  99. {
  100. byte[] bytes = id.GetBytes();
  101. bool[] boolId = new bool[bytes.Length * 8 - id.PadBits];
  102. for (int i = 0; i != boolId.Length; i++)
  103. {
  104. //boolId[i] = (bytes[i / 8] & (0x80 >>> (i % 8))) != 0;
  105. boolId[i] = (bytes[i / 8] & (0x80 >> (i % 8))) != 0;
  106. }
  107. return boolId;
  108. }
  109. return null;
  110. }
  111. public virtual bool IsValidNow
  112. {
  113. get { return IsValid(DateTime.UtcNow); }
  114. }
  115. public virtual bool IsValid(
  116. DateTime date)
  117. {
  118. return date.CompareTo(NotBefore) >= 0 && date.CompareTo(NotAfter) <= 0;
  119. }
  120. public virtual void CheckValidity()
  121. {
  122. this.CheckValidity(DateTime.UtcNow);
  123. }
  124. public virtual void CheckValidity(
  125. DateTime date)
  126. {
  127. if (date.CompareTo(NotAfter) > 0)
  128. throw new CertificateExpiredException("certificate expired on " + NotAfter);
  129. if (date.CompareTo(NotBefore) < 0)
  130. throw new CertificateNotYetValidException("certificate not valid until " + NotBefore);
  131. }
  132. public virtual AlgorithmIdentifier SignatureAlgorithm
  133. {
  134. get { return cert.SignatureAlgorithm; }
  135. }
  136. public virtual byte[] GetSignature()
  137. {
  138. return cert.GetSignatureOctets();
  139. }
  140. public virtual void Verify(
  141. AsymmetricKeyParameter key)
  142. {
  143. CheckSignature(new Asn1VerifierFactory(cert.SignatureAlgorithm, key));
  144. }
  145. /// <summary>
  146. /// Verify the certificate's signature using a verifier created using the passed in verifier provider.
  147. /// </summary>
  148. /// <param name="verifierProvider">An appropriate provider for verifying the certificate's signature.</param>
  149. /// <returns>True if the signature is valid.</returns>
  150. /// <exception cref="Exception">If verifier provider is not appropriate or the certificate algorithm is invalid.</exception>
  151. public virtual void Verify(
  152. IVerifierFactoryProvider verifierProvider)
  153. {
  154. CheckSignature(verifierProvider.CreateVerifierFactory(cert.SignatureAlgorithm));
  155. }
  156. protected virtual void CheckSignature(
  157. IVerifierFactory verifier)
  158. {
  159. // TODO Compare IsAlgIDEqual in X509Certificate.CheckSignature
  160. if (!cert.SignatureAlgorithm.Equals(cert.ACInfo.Signature))
  161. throw new CertificateException("Signature algorithm in certificate info not same as outer certificate");
  162. IStreamCalculator<IVerifier> streamCalculator = verifier.CreateCalculator();
  163. try
  164. {
  165. byte[] b = this.cert.ACInfo.GetEncoded();
  166. using (var stream = streamCalculator.Stream)
  167. {
  168. stream.Write(b, 0, b.Length);
  169. }
  170. }
  171. catch (IOException e)
  172. {
  173. throw new SignatureException("Exception encoding certificate info object", e);
  174. }
  175. if (!streamCalculator.GetResult().IsVerified(this.GetSignature()))
  176. throw new InvalidKeyException("Public key presented not for certificate signature");
  177. }
  178. public virtual byte[] GetEncoded()
  179. {
  180. return cert.GetEncoded();
  181. }
  182. protected override X509Extensions GetX509Extensions()
  183. {
  184. return cert.ACInfo.Extensions;
  185. }
  186. public virtual X509Attribute[] GetAttributes()
  187. {
  188. Asn1Sequence seq = cert.ACInfo.Attributes;
  189. X509Attribute[] attrs = new X509Attribute[seq.Count];
  190. for (int i = 0; i != seq.Count; i++)
  191. {
  192. attrs[i] = new X509Attribute((Asn1Encodable)seq[i]);
  193. }
  194. return attrs;
  195. }
  196. public virtual X509Attribute[] GetAttributes(
  197. string oid)
  198. {
  199. Asn1Sequence seq = cert.ACInfo.Attributes;
  200. var list = new List<X509Attribute>();
  201. for (int i = 0; i != seq.Count; i++)
  202. {
  203. X509Attribute attr = new X509Attribute((Asn1Encodable)seq[i]);
  204. if (attr.Oid.Equals(oid))
  205. {
  206. list.Add(attr);
  207. }
  208. }
  209. if (list.Count < 1)
  210. {
  211. return null;
  212. }
  213. return list.ToArray();
  214. }
  215. public override bool Equals(object obj)
  216. {
  217. if (obj == this)
  218. return true;
  219. X509V2AttributeCertificate other = obj as X509V2AttributeCertificate;
  220. if (other == null)
  221. return false;
  222. return cert.Equals(other.cert);
  223. // NB: May prefer this implementation of Equals if more than one certificate implementation in play
  224. //return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded());
  225. }
  226. public override int GetHashCode()
  227. {
  228. return cert.GetHashCode();
  229. }
  230. }
  231. }
  232. #pragma warning restore
  233. #endif