RsaUtilities.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.IO;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Nist;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.Pkcs;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Asn1.X509;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  10. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl
  11. {
  12. public abstract class RsaUtilities
  13. {
  14. private static readonly byte[] RSAPSSParams_256_A, RSAPSSParams_384_A, RSAPSSParams_512_A;
  15. private static readonly byte[] RSAPSSParams_256_B, RSAPSSParams_384_B, RSAPSSParams_512_B;
  16. static RsaUtilities()
  17. {
  18. /*
  19. * RFC 4055
  20. */
  21. AlgorithmIdentifier sha256Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256);
  22. AlgorithmIdentifier sha384Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384);
  23. AlgorithmIdentifier sha512Identifier_A = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512);
  24. AlgorithmIdentifier sha256Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance);
  25. AlgorithmIdentifier sha384Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance);
  26. AlgorithmIdentifier sha512Identifier_B = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance);
  27. AlgorithmIdentifier mgf1SHA256Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha256Identifier_A);
  28. AlgorithmIdentifier mgf1SHA384Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha384Identifier_A);
  29. AlgorithmIdentifier mgf1SHA512Identifier_A = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha512Identifier_A);
  30. AlgorithmIdentifier mgf1SHA256Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha256Identifier_B);
  31. AlgorithmIdentifier mgf1SHA384Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha384Identifier_B);
  32. AlgorithmIdentifier mgf1SHA512Identifier_B = new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, sha512Identifier_B);
  33. DerInteger sha256Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha256));
  34. DerInteger sha384Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha384));
  35. DerInteger sha512Size = new DerInteger(TlsCryptoUtilities.GetHashOutputSize(CryptoHashAlgorithm.sha512));
  36. DerInteger trailerField = new DerInteger(1);
  37. try
  38. {
  39. RSAPSSParams_256_A = new RsassaPssParameters(sha256Identifier_A, mgf1SHA256Identifier_A, sha256Size, trailerField)
  40. .GetEncoded(Asn1Encodable.Der);
  41. RSAPSSParams_384_A = new RsassaPssParameters(sha384Identifier_A, mgf1SHA384Identifier_A, sha384Size, trailerField)
  42. .GetEncoded(Asn1Encodable.Der);
  43. RSAPSSParams_512_A = new RsassaPssParameters(sha512Identifier_A, mgf1SHA512Identifier_A, sha512Size, trailerField)
  44. .GetEncoded(Asn1Encodable.Der);
  45. RSAPSSParams_256_B = new RsassaPssParameters(sha256Identifier_B, mgf1SHA256Identifier_B, sha256Size, trailerField)
  46. .GetEncoded(Asn1Encodable.Der);
  47. RSAPSSParams_384_B = new RsassaPssParameters(sha384Identifier_B, mgf1SHA384Identifier_B, sha384Size, trailerField)
  48. .GetEncoded(Asn1Encodable.Der);
  49. RSAPSSParams_512_B = new RsassaPssParameters(sha512Identifier_B, mgf1SHA512Identifier_B, sha512Size, trailerField)
  50. .GetEncoded(Asn1Encodable.Der);
  51. }
  52. catch (IOException e)
  53. {
  54. throw new InvalidOperationException(e.Message);
  55. }
  56. }
  57. public static bool SupportsPkcs1(AlgorithmIdentifier pubKeyAlgID)
  58. {
  59. DerObjectIdentifier oid = pubKeyAlgID.Algorithm;
  60. return PkcsObjectIdentifiers.RsaEncryption.Equals(oid)
  61. || X509ObjectIdentifiers.IdEARsa.Equals(oid);
  62. }
  63. public static bool SupportsPss_Pss(short signatureAlgorithm, AlgorithmIdentifier pubKeyAlgID)
  64. {
  65. DerObjectIdentifier oid = pubKeyAlgID.Algorithm;
  66. if (!PkcsObjectIdentifiers.IdRsassaPss.Equals(oid))
  67. return false;
  68. /*
  69. * TODO ASN.1 NULL shouldn't really be allowed here; it's a workaround for e.g. Oracle JDK
  70. * 1.8.0_241, where the X.509 certificate implementation adds the NULL when re-encoding the
  71. * original parameters. It appears it was fixed at some later date (OpenJDK 12.0.2 does not
  72. * have the issue), but not sure exactly when.
  73. */
  74. Asn1Encodable pssParams = pubKeyAlgID.Parameters;
  75. if (null == pssParams || pssParams is DerNull)
  76. {
  77. switch (signatureAlgorithm)
  78. {
  79. case SignatureAlgorithm.rsa_pss_pss_sha256:
  80. case SignatureAlgorithm.rsa_pss_pss_sha384:
  81. case SignatureAlgorithm.rsa_pss_pss_sha512:
  82. return true;
  83. default:
  84. return false;
  85. }
  86. }
  87. byte[] encoded;
  88. try
  89. {
  90. encoded = pssParams.ToAsn1Object().GetEncoded(Asn1Encodable.Der);
  91. }
  92. catch (Exception)
  93. {
  94. return false;
  95. }
  96. byte[] expected_A, expected_B;
  97. switch (signatureAlgorithm)
  98. {
  99. case SignatureAlgorithm.rsa_pss_pss_sha256:
  100. expected_A = RSAPSSParams_256_A;
  101. expected_B = RSAPSSParams_256_B;
  102. break;
  103. case SignatureAlgorithm.rsa_pss_pss_sha384:
  104. expected_A = RSAPSSParams_384_A;
  105. expected_B = RSAPSSParams_384_B;
  106. break;
  107. case SignatureAlgorithm.rsa_pss_pss_sha512:
  108. expected_A = RSAPSSParams_512_A;
  109. expected_B = RSAPSSParams_512_B;
  110. break;
  111. default:
  112. return false;
  113. }
  114. return Arrays.AreEqual(expected_A, encoded)
  115. || Arrays.AreEqual(expected_B, encoded);
  116. }
  117. public static bool SupportsPss_Rsae(AlgorithmIdentifier pubKeyAlgID)
  118. {
  119. DerObjectIdentifier oid = pubKeyAlgID.Algorithm;
  120. return PkcsObjectIdentifiers.RsaEncryption.Equals(oid);
  121. }
  122. }
  123. }
  124. #pragma warning restore
  125. #endif