BcTlsCertificate.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  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.X509;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  9. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  10. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  11. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  12. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls.Crypto.Impl.BC
  13. {
  14. /// <summary>Implementation class for a single X.509 certificate based on the BC light-weight API.</summary>
  15. public class BcTlsCertificate
  16. : TlsCertificate
  17. {
  18. /// <exception cref="IOException"/>
  19. public static BcTlsCertificate Convert(BcTlsCrypto crypto, TlsCertificate certificate)
  20. {
  21. if (certificate is BcTlsCertificate)
  22. return (BcTlsCertificate)certificate;
  23. return new BcTlsCertificate(crypto, certificate.GetEncoded());
  24. }
  25. /// <exception cref="IOException"/>
  26. public static X509CertificateStructure ParseCertificate(byte[] encoding)
  27. {
  28. try
  29. {
  30. return X509CertificateStructure.GetInstance(encoding);
  31. }
  32. catch (Exception e)
  33. {
  34. throw new TlsFatalAlert(AlertDescription.bad_certificate, e);
  35. }
  36. }
  37. protected readonly BcTlsCrypto m_crypto;
  38. protected readonly X509CertificateStructure m_certificate;
  39. protected DHPublicKeyParameters m_pubKeyDH = null;
  40. protected ECPublicKeyParameters m_pubKeyEC = null;
  41. protected Ed25519PublicKeyParameters m_pubKeyEd25519 = null;
  42. protected Ed448PublicKeyParameters m_pubKeyEd448 = null;
  43. protected RsaKeyParameters m_pubKeyRsa = null;
  44. /// <exception cref="IOException"/>
  45. public BcTlsCertificate(BcTlsCrypto crypto, byte[] encoding)
  46. : this(crypto, ParseCertificate(encoding))
  47. {
  48. }
  49. public BcTlsCertificate(BcTlsCrypto crypto, X509CertificateStructure certificate)
  50. {
  51. this.m_crypto = crypto;
  52. this.m_certificate = certificate;
  53. }
  54. /// <exception cref="IOException"/>
  55. public virtual TlsEncryptor CreateEncryptor(int tlsCertificateRole)
  56. {
  57. ValidateKeyUsage(KeyUsage.KeyEncipherment);
  58. switch (tlsCertificateRole)
  59. {
  60. case TlsCertificateRole.RsaEncryption:
  61. {
  62. this.m_pubKeyRsa = GetPubKeyRsa();
  63. return new BcTlsRsaEncryptor(m_crypto, m_pubKeyRsa);
  64. }
  65. // TODO[gmssl]
  66. //case TlsCertificateRole.Sm2Encryption:
  67. //{
  68. // this.m_pubKeyEC = GetPubKeyEC();
  69. // return new BcTlsSM2Encryptor(m_crypto, m_pubKeyEC);
  70. //}
  71. }
  72. throw new TlsFatalAlert(AlertDescription.certificate_unknown);
  73. }
  74. /// <exception cref="IOException"/>
  75. public virtual TlsVerifier CreateVerifier(short signatureAlgorithm)
  76. {
  77. switch (signatureAlgorithm)
  78. {
  79. case SignatureAlgorithm.rsa_pss_rsae_sha256:
  80. case SignatureAlgorithm.rsa_pss_rsae_sha384:
  81. case SignatureAlgorithm.rsa_pss_rsae_sha512:
  82. case SignatureAlgorithm.ed25519:
  83. case SignatureAlgorithm.ed448:
  84. case SignatureAlgorithm.rsa_pss_pss_sha256:
  85. case SignatureAlgorithm.rsa_pss_pss_sha384:
  86. case SignatureAlgorithm.rsa_pss_pss_sha512:
  87. return CreateVerifier(SignatureScheme.From(HashAlgorithm.Intrinsic, signatureAlgorithm));
  88. }
  89. ValidateKeyUsage(KeyUsage.DigitalSignature);
  90. switch (signatureAlgorithm)
  91. {
  92. case SignatureAlgorithm.rsa:
  93. ValidateRsa_Pkcs1();
  94. return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa());
  95. case SignatureAlgorithm.dsa:
  96. return new BcTlsDsaVerifier(m_crypto, GetPubKeyDss());
  97. case SignatureAlgorithm.ecdsa:
  98. return new BcTlsECDsaVerifier(m_crypto, GetPubKeyEC());
  99. default:
  100. throw new TlsFatalAlert(AlertDescription.certificate_unknown);
  101. }
  102. }
  103. /// <exception cref="IOException"/>
  104. public virtual TlsVerifier CreateVerifier(int signatureScheme)
  105. {
  106. ValidateKeyUsage(KeyUsage.DigitalSignature);
  107. switch (signatureScheme)
  108. {
  109. case SignatureScheme.ecdsa_brainpoolP256r1tls13_sha256:
  110. case SignatureScheme.ecdsa_brainpoolP384r1tls13_sha384:
  111. case SignatureScheme.ecdsa_brainpoolP512r1tls13_sha512:
  112. case SignatureScheme.ecdsa_secp256r1_sha256:
  113. case SignatureScheme.ecdsa_secp384r1_sha384:
  114. case SignatureScheme.ecdsa_secp521r1_sha512:
  115. case SignatureScheme.ecdsa_sha1:
  116. return new BcTlsECDsa13Verifier(m_crypto, GetPubKeyEC(), signatureScheme);
  117. case SignatureScheme.ed25519:
  118. return new BcTlsEd25519Verifier(m_crypto, GetPubKeyEd25519());
  119. case SignatureScheme.ed448:
  120. return new BcTlsEd448Verifier(m_crypto, GetPubKeyEd448());
  121. case SignatureScheme.rsa_pkcs1_sha1:
  122. case SignatureScheme.rsa_pkcs1_sha256:
  123. case SignatureScheme.rsa_pkcs1_sha384:
  124. case SignatureScheme.rsa_pkcs1_sha512:
  125. {
  126. ValidateRsa_Pkcs1();
  127. return new BcTlsRsaVerifier(m_crypto, GetPubKeyRsa());
  128. }
  129. case SignatureScheme.rsa_pss_pss_sha256:
  130. case SignatureScheme.rsa_pss_pss_sha384:
  131. case SignatureScheme.rsa_pss_pss_sha512:
  132. {
  133. ValidateRsa_Pss_Pss(SignatureScheme.GetSignatureAlgorithm(signatureScheme));
  134. return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme);
  135. }
  136. case SignatureScheme.rsa_pss_rsae_sha256:
  137. case SignatureScheme.rsa_pss_rsae_sha384:
  138. case SignatureScheme.rsa_pss_rsae_sha512:
  139. {
  140. ValidateRsa_Pss_Rsae();
  141. return new BcTlsRsaPssVerifier(m_crypto, GetPubKeyRsa(), signatureScheme);
  142. }
  143. // TODO[RFC 8998]
  144. //case SignatureScheme.sm2sig_sm3:
  145. // return new BcTlsSM2Verifier(m_crypto, GetPubKeyEC(), Strings.ToByteArray("TLSv1.3+GM+Cipher+Suite"));
  146. default:
  147. throw new TlsFatalAlert(AlertDescription.certificate_unknown);
  148. }
  149. }
  150. /// <exception cref="IOException"/>
  151. public virtual byte[] GetEncoded()
  152. {
  153. return m_certificate.GetEncoded(Asn1Encodable.Der);
  154. }
  155. /// <exception cref="IOException"/>
  156. public virtual byte[] GetExtension(DerObjectIdentifier extensionOid)
  157. {
  158. X509Extensions extensions = m_certificate.TbsCertificate.Extensions;
  159. if (extensions != null)
  160. {
  161. X509Extension extension = extensions.GetExtension(extensionOid);
  162. if (extension != null)
  163. {
  164. return Arrays.Clone(extension.Value.GetOctets());
  165. }
  166. }
  167. return null;
  168. }
  169. public virtual BigInteger SerialNumber
  170. {
  171. get { return m_certificate.SerialNumber.Value; }
  172. }
  173. public virtual string SigAlgOid
  174. {
  175. get { return m_certificate.SignatureAlgorithm.Algorithm.Id; }
  176. }
  177. public virtual Asn1Encodable GetSigAlgParams()
  178. {
  179. return m_certificate.SignatureAlgorithm.Parameters;
  180. }
  181. /// <exception cref="IOException"/>
  182. public virtual short GetLegacySignatureAlgorithm()
  183. {
  184. AsymmetricKeyParameter publicKey = GetPublicKey();
  185. if (publicKey.IsPrivate)
  186. throw new TlsFatalAlert(AlertDescription.internal_error);
  187. if (!SupportsKeyUsage(KeyUsage.DigitalSignature))
  188. return -1;
  189. /*
  190. * RFC 5246 7.4.6. Client Certificate
  191. */
  192. /*
  193. * RSA public key; the certificate MUST allow the key to be used for signing with the
  194. * signature scheme and hash algorithm that will be employed in the certificate verify
  195. * message.
  196. */
  197. if (publicKey is RsaKeyParameters)
  198. return SignatureAlgorithm.rsa;
  199. /*
  200. * DSA public key; the certificate MUST allow the key to be used for signing with the
  201. * hash algorithm that will be employed in the certificate verify message.
  202. */
  203. if (publicKey is DsaPublicKeyParameters)
  204. return SignatureAlgorithm.dsa;
  205. /*
  206. * ECDSA-capable public key; the certificate MUST allow the key to be used for signing
  207. * with the hash algorithm that will be employed in the certificate verify message; the
  208. * public key MUST use a curve and point format supported by the server.
  209. */
  210. if (publicKey is ECPublicKeyParameters)
  211. {
  212. // TODO Check the curve and point format
  213. return SignatureAlgorithm.ecdsa;
  214. }
  215. return -1;
  216. }
  217. /// <exception cref="IOException"/>
  218. public virtual DHPublicKeyParameters GetPubKeyDH()
  219. {
  220. try
  221. {
  222. return (DHPublicKeyParameters)GetPublicKey();
  223. }
  224. catch (InvalidCastException e)
  225. {
  226. throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
  227. }
  228. }
  229. /// <exception cref="IOException"/>
  230. public virtual DsaPublicKeyParameters GetPubKeyDss()
  231. {
  232. try
  233. {
  234. return (DsaPublicKeyParameters)GetPublicKey();
  235. }
  236. catch (InvalidCastException e)
  237. {
  238. throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
  239. }
  240. }
  241. /// <exception cref="IOException"/>
  242. public virtual ECPublicKeyParameters GetPubKeyEC()
  243. {
  244. try
  245. {
  246. return (ECPublicKeyParameters)GetPublicKey();
  247. }
  248. catch (InvalidCastException e)
  249. {
  250. throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
  251. }
  252. }
  253. /// <exception cref="IOException"/>
  254. public virtual Ed25519PublicKeyParameters GetPubKeyEd25519()
  255. {
  256. try
  257. {
  258. return (Ed25519PublicKeyParameters)GetPublicKey();
  259. }
  260. catch (InvalidCastException e)
  261. {
  262. throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
  263. }
  264. }
  265. /// <exception cref="IOException"/>
  266. public virtual Ed448PublicKeyParameters GetPubKeyEd448()
  267. {
  268. try
  269. {
  270. return (Ed448PublicKeyParameters)GetPublicKey();
  271. }
  272. catch (InvalidCastException e)
  273. {
  274. throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
  275. }
  276. }
  277. /// <exception cref="IOException"/>
  278. public virtual RsaKeyParameters GetPubKeyRsa()
  279. {
  280. try
  281. {
  282. return (RsaKeyParameters)GetPublicKey();
  283. }
  284. catch (InvalidCastException e)
  285. {
  286. throw new TlsFatalAlert(AlertDescription.certificate_unknown, e);
  287. }
  288. }
  289. /// <exception cref="IOException"/>
  290. public virtual bool SupportsSignatureAlgorithm(short signatureAlgorithm)
  291. {
  292. return SupportsSignatureAlgorithm(signatureAlgorithm, KeyUsage.DigitalSignature);
  293. }
  294. /// <exception cref="IOException"/>
  295. public virtual bool SupportsSignatureAlgorithmCA(short signatureAlgorithm)
  296. {
  297. return SupportsSignatureAlgorithm(signatureAlgorithm, KeyUsage.KeyCertSign);
  298. }
  299. /// <exception cref="IOException"/>
  300. public virtual TlsCertificate CheckUsageInRole(int tlsCertificateRole)
  301. {
  302. switch (tlsCertificateRole)
  303. {
  304. case TlsCertificateRole.DH:
  305. {
  306. ValidateKeyUsage(KeyUsage.KeyAgreement);
  307. this.m_pubKeyDH = GetPubKeyDH();
  308. return this;
  309. }
  310. case TlsCertificateRole.ECDH:
  311. {
  312. ValidateKeyUsage(KeyUsage.KeyAgreement);
  313. this.m_pubKeyEC = GetPubKeyEC();
  314. return this;
  315. }
  316. }
  317. throw new TlsFatalAlert(AlertDescription.certificate_unknown);
  318. }
  319. /// <exception cref="IOException"/>
  320. protected virtual AsymmetricKeyParameter GetPublicKey()
  321. {
  322. SubjectPublicKeyInfo keyInfo = m_certificate.SubjectPublicKeyInfo;
  323. try
  324. {
  325. return PublicKeyFactory.CreateKey(keyInfo);
  326. }
  327. catch (Exception e)
  328. {
  329. throw new TlsFatalAlert(AlertDescription.unsupported_certificate, e);
  330. }
  331. }
  332. protected virtual bool SupportsKeyUsage(int keyUsageBits)
  333. {
  334. X509Extensions exts = m_certificate.TbsCertificate.Extensions;
  335. if (exts != null)
  336. {
  337. KeyUsage ku = KeyUsage.FromExtensions(exts);
  338. if (ku != null)
  339. {
  340. int bits = ku.GetBytes()[0] & 0xff;
  341. if ((bits & keyUsageBits) != keyUsageBits)
  342. return false;
  343. }
  344. }
  345. return true;
  346. }
  347. protected virtual bool SupportsRsa_Pkcs1()
  348. {
  349. AlgorithmIdentifier pubKeyAlgID = m_certificate.SubjectPublicKeyInfo.AlgorithmID;
  350. return RsaUtilities.SupportsPkcs1(pubKeyAlgID);
  351. }
  352. protected virtual bool SupportsRsa_Pss_Pss(short signatureAlgorithm)
  353. {
  354. AlgorithmIdentifier pubKeyAlgID = m_certificate.SubjectPublicKeyInfo.AlgorithmID;
  355. return RsaUtilities.SupportsPss_Pss(signatureAlgorithm, pubKeyAlgID);
  356. }
  357. protected virtual bool SupportsRsa_Pss_Rsae()
  358. {
  359. AlgorithmIdentifier pubKeyAlgID = m_certificate.SubjectPublicKeyInfo.AlgorithmID;
  360. return RsaUtilities.SupportsPss_Rsae(pubKeyAlgID);
  361. }
  362. /// <exception cref="IOException"/>
  363. protected virtual bool SupportsSignatureAlgorithm(short signatureAlgorithm, int keyUsage)
  364. {
  365. if (!SupportsKeyUsage(keyUsage))
  366. return false;
  367. AsymmetricKeyParameter publicKey = GetPublicKey();
  368. switch (signatureAlgorithm)
  369. {
  370. case SignatureAlgorithm.rsa:
  371. return SupportsRsa_Pkcs1()
  372. && publicKey is RsaKeyParameters;
  373. case SignatureAlgorithm.dsa:
  374. return publicKey is DsaPublicKeyParameters;
  375. case SignatureAlgorithm.ecdsa:
  376. case SignatureAlgorithm.ecdsa_brainpoolP256r1tls13_sha256:
  377. case SignatureAlgorithm.ecdsa_brainpoolP384r1tls13_sha384:
  378. case SignatureAlgorithm.ecdsa_brainpoolP512r1tls13_sha512:
  379. return publicKey is ECPublicKeyParameters;
  380. case SignatureAlgorithm.ed25519:
  381. return publicKey is Ed25519PublicKeyParameters;
  382. case SignatureAlgorithm.ed448:
  383. return publicKey is Ed448PublicKeyParameters;
  384. case SignatureAlgorithm.rsa_pss_rsae_sha256:
  385. case SignatureAlgorithm.rsa_pss_rsae_sha384:
  386. case SignatureAlgorithm.rsa_pss_rsae_sha512:
  387. return SupportsRsa_Pss_Rsae()
  388. && publicKey is RsaKeyParameters;
  389. case SignatureAlgorithm.rsa_pss_pss_sha256:
  390. case SignatureAlgorithm.rsa_pss_pss_sha384:
  391. case SignatureAlgorithm.rsa_pss_pss_sha512:
  392. return SupportsRsa_Pss_Pss(signatureAlgorithm)
  393. && publicKey is RsaKeyParameters;
  394. default:
  395. return false;
  396. }
  397. }
  398. /// <exception cref="IOException"/>
  399. public virtual void ValidateKeyUsage(int keyUsageBits)
  400. {
  401. if (!SupportsKeyUsage(keyUsageBits))
  402. throw new TlsFatalAlert(AlertDescription.certificate_unknown);
  403. }
  404. /// <exception cref="IOException"/>
  405. protected virtual void ValidateRsa_Pkcs1()
  406. {
  407. if (!SupportsRsa_Pkcs1())
  408. throw new TlsFatalAlert(AlertDescription.certificate_unknown);
  409. }
  410. /// <exception cref="IOException"/>
  411. protected virtual void ValidateRsa_Pss_Pss(short signatureAlgorithm)
  412. {
  413. if (!SupportsRsa_Pss_Pss(signatureAlgorithm))
  414. throw new TlsFatalAlert(AlertDescription.certificate_unknown);
  415. }
  416. /// <exception cref="IOException"/>
  417. protected virtual void ValidateRsa_Pss_Rsae()
  418. {
  419. if (!SupportsRsa_Pss_Rsae())
  420. throw new TlsFatalAlert(AlertDescription.certificate_unknown);
  421. }
  422. }
  423. }
  424. #pragma warning restore
  425. #endif