PkixAttrCertPathBuilder.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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.Asn1.X509;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security.Certificates;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Collections;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.X509;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.X509.Store;
  11. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Pkix
  12. {
  13. public class PkixAttrCertPathBuilder
  14. {
  15. /**
  16. * Build and validate a CertPath using the given parameter.
  17. *
  18. * @param params PKIXBuilderParameters object containing all information to
  19. * build the CertPath
  20. */
  21. public virtual PkixCertPathBuilderResult Build(
  22. PkixBuilderParameters pkixParams)
  23. {
  24. // search target certificates
  25. IX509Selector certSelect = pkixParams.GetTargetConstraints();
  26. if (!(certSelect is X509AttrCertStoreSelector))
  27. {
  28. throw new PkixCertPathBuilderException(
  29. "TargetConstraints must be an instance of "
  30. + typeof(X509AttrCertStoreSelector).FullName
  31. + " for "
  32. + typeof(PkixAttrCertPathBuilder).FullName + " class.");
  33. }
  34. ICollection targets;
  35. try
  36. {
  37. targets = PkixCertPathValidatorUtilities.FindCertificates(
  38. (X509AttrCertStoreSelector)certSelect, pkixParams.GetStores());
  39. }
  40. catch (Exception e)
  41. {
  42. throw new PkixCertPathBuilderException("Error finding target attribute certificate.", e);
  43. }
  44. if (targets.Count == 0)
  45. {
  46. throw new PkixCertPathBuilderException(
  47. "No attribute certificate found matching targetConstraints.");
  48. }
  49. PkixCertPathBuilderResult result = null;
  50. // check all potential target certificates
  51. foreach (IX509AttributeCertificate cert in targets)
  52. {
  53. X509CertStoreSelector selector = new X509CertStoreSelector();
  54. X509Name[] principals = cert.Issuer.GetPrincipals();
  55. ISet issuers = new HashSet();
  56. for (int i = 0; i < principals.Length; i++)
  57. {
  58. try
  59. {
  60. selector.Subject = principals[i];
  61. issuers.AddAll(PkixCertPathValidatorUtilities.FindCertificates(selector, pkixParams.GetStores()));
  62. }
  63. catch (Exception e)
  64. {
  65. throw new PkixCertPathBuilderException(
  66. "Public key certificate for attribute certificate cannot be searched.",
  67. e);
  68. }
  69. }
  70. if (issuers.IsEmpty)
  71. throw new PkixCertPathBuilderException("Public key certificate for attribute certificate cannot be found.");
  72. IList certPathList = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateArrayList();
  73. foreach (X509Certificate issuer in issuers)
  74. {
  75. result = Build(cert, issuer, pkixParams, certPathList);
  76. if (result != null)
  77. break;
  78. }
  79. if (result != null)
  80. break;
  81. }
  82. if (result == null && certPathException != null)
  83. {
  84. throw new PkixCertPathBuilderException(
  85. "Possible certificate chain could not be validated.",
  86. certPathException);
  87. }
  88. if (result == null && certPathException == null)
  89. {
  90. throw new PkixCertPathBuilderException(
  91. "Unable to find certificate chain.");
  92. }
  93. return result;
  94. }
  95. private Exception certPathException;
  96. private PkixCertPathBuilderResult Build(
  97. IX509AttributeCertificate attrCert,
  98. X509Certificate tbvCert,
  99. PkixBuilderParameters pkixParams,
  100. IList tbvPath)
  101. {
  102. // If tbvCert is readily present in tbvPath, it indicates having run
  103. // into a cycle in the
  104. // PKI graph.
  105. if (tbvPath.Contains(tbvCert))
  106. return null;
  107. // step out, the certificate is not allowed to appear in a certification
  108. // chain
  109. if (pkixParams.GetExcludedCerts().Contains(tbvCert))
  110. return null;
  111. // test if certificate path exceeds maximum length
  112. if (pkixParams.MaxPathLength != -1)
  113. {
  114. if (tbvPath.Count - 1 > pkixParams.MaxPathLength)
  115. return null;
  116. }
  117. tbvPath.Add(tbvCert);
  118. PkixCertPathBuilderResult builderResult = null;
  119. // X509CertificateParser certParser = new X509CertificateParser();
  120. PkixAttrCertPathValidator validator = new PkixAttrCertPathValidator();
  121. try
  122. {
  123. // check whether the issuer of <tbvCert> is a TrustAnchor
  124. if (PkixCertPathValidatorUtilities.IsIssuerTrustAnchor(tbvCert, pkixParams.GetTrustAnchors()))
  125. {
  126. PkixCertPath certPath = new PkixCertPath(tbvPath);
  127. PkixCertPathValidatorResult result;
  128. try
  129. {
  130. result = validator.Validate(certPath, pkixParams);
  131. }
  132. catch (Exception e)
  133. {
  134. throw new Exception("Certification path could not be validated.", e);
  135. }
  136. return new PkixCertPathBuilderResult(certPath, result.TrustAnchor,
  137. result.PolicyTree, result.SubjectPublicKey);
  138. }
  139. else
  140. {
  141. // add additional X.509 stores from locations in certificate
  142. try
  143. {
  144. PkixCertPathValidatorUtilities.AddAdditionalStoresFromAltNames(tbvCert, pkixParams);
  145. }
  146. catch (CertificateParsingException e)
  147. {
  148. throw new Exception("No additional X.509 stores can be added from certificate locations.", e);
  149. }
  150. // try to get the issuer certificate from one of the stores
  151. ISet issuers = new HashSet();
  152. try
  153. {
  154. issuers.AddAll(PkixCertPathValidatorUtilities.FindIssuerCerts(tbvCert, pkixParams));
  155. }
  156. catch (Exception e)
  157. {
  158. throw new Exception("Cannot find issuer certificate for certificate in certification path.", e);
  159. }
  160. if (issuers.IsEmpty)
  161. throw new Exception("No issuer certificate for certificate in certification path found.");
  162. foreach (X509Certificate issuer in issuers)
  163. {
  164. // if untrusted self signed certificate continue
  165. if (PkixCertPathValidatorUtilities.IsSelfIssued(issuer))
  166. continue;
  167. builderResult = Build(attrCert, issuer, pkixParams, tbvPath);
  168. if (builderResult != null)
  169. break;
  170. }
  171. }
  172. }
  173. catch (Exception e)
  174. {
  175. certPathException = new Exception("No valid certification path could be build.", e);
  176. }
  177. if (builderResult == null)
  178. {
  179. tbvPath.Remove(tbvCert);
  180. }
  181. return builderResult;
  182. }
  183. }
  184. }
  185. #pragma warning restore
  186. #endif