performance.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package ubiquity
  2. // In this file, we include chain ranking functions based on security and performance
  3. import (
  4. "crypto/ecdsa"
  5. "crypto/elliptic"
  6. "crypto/rsa"
  7. "crypto/x509"
  8. "time"
  9. "github.com/cloudflare/cfssl/helpers"
  10. )
  11. // Compute the priority of different hash algorithm based on security
  12. // SHA2 > SHA1 >> MD = Others = Unknown
  13. func hashPriority(cert *x509.Certificate) int {
  14. switch cert.SignatureAlgorithm {
  15. case x509.ECDSAWithSHA1, x509.DSAWithSHA1, x509.SHA1WithRSA:
  16. return 10
  17. case x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512,
  18. x509.DSAWithSHA256, x509.SHA256WithRSA, x509.SHA384WithRSA,
  19. x509.SHA512WithRSA:
  20. return 100
  21. default:
  22. return 0
  23. }
  24. }
  25. // Compute the priority of different key algorithm based performance and security
  26. // ECDSA>RSA>DSA>Unknown
  27. func keyAlgoPriority(cert *x509.Certificate) int {
  28. switch cert.PublicKeyAlgorithm {
  29. case x509.ECDSA:
  30. switch cert.PublicKey.(*ecdsa.PublicKey).Curve {
  31. case elliptic.P256():
  32. return 100
  33. case elliptic.P384():
  34. return 120
  35. case elliptic.P521():
  36. return 140
  37. default:
  38. return 100
  39. }
  40. case x509.RSA:
  41. switch cert.PublicKey.(*rsa.PublicKey).N.BitLen() {
  42. case 4096:
  43. return 70
  44. case 3072:
  45. return 50
  46. case 2048:
  47. return 30
  48. // key size <= 1024 are discouraged.
  49. default:
  50. return 0
  51. }
  52. // we do not want to bundle a DSA cert.
  53. case x509.DSA:
  54. return 0
  55. default:
  56. return 0
  57. }
  58. }
  59. // HashPriority returns the hash priority of the chain as the average of hash priority of certs in it.
  60. func HashPriority(certs []*x509.Certificate) int {
  61. ret := 0.0
  62. for i, cert := range certs {
  63. f1 := 1.0 / (float64(i) + 1.0)
  64. f2 := 1.0 - f1
  65. ret = ret*f2 + float64(hashPriority(cert))*f1
  66. }
  67. return int(ret)
  68. }
  69. // KeyAlgoPriority returns the key algorithm priority of the chain as the average of key algorithm priority of certs in it.
  70. func KeyAlgoPriority(certs []*x509.Certificate) int {
  71. ret := 0.0
  72. for i, cert := range certs {
  73. f1 := 1.0 / (float64(i) + 1.0)
  74. f2 := 1.0 - f1
  75. ret = float64(keyAlgoPriority(cert))*f1 + ret*f2
  76. }
  77. return int(ret)
  78. }
  79. // CompareChainHashPriority ranks chains with more current hash functions higher.
  80. func CompareChainHashPriority(chain1, chain2 []*x509.Certificate) int {
  81. hp1 := HashPriority(chain1)
  82. hp2 := HashPriority(chain2)
  83. return hp1 - hp2
  84. }
  85. // CompareChainKeyAlgoPriority ranks chains with more current key algorithm higher.
  86. func CompareChainKeyAlgoPriority(chain1, chain2 []*x509.Certificate) int {
  87. kap1 := KeyAlgoPriority(chain1)
  88. kap2 := KeyAlgoPriority(chain2)
  89. return kap1 - kap2
  90. }
  91. // CompareChainCryptoSuite ranks chains with more current crypto suite higher.
  92. func CompareChainCryptoSuite(chain1, chain2 []*x509.Certificate) int {
  93. cs1 := HashPriority(chain1) + KeyAlgoPriority(chain1)
  94. cs2 := HashPriority(chain2) + KeyAlgoPriority(chain2)
  95. return cs1 - cs2
  96. }
  97. // CompareChainLength ranks shorter chain higher.
  98. func CompareChainLength(chain1, chain2 []*x509.Certificate) int {
  99. return len(chain2) - len(chain1)
  100. }
  101. func compareTime(t1, t2 time.Time) int {
  102. if t1.After(t2) {
  103. return 1
  104. } else if t1.Before(t2) {
  105. return -1
  106. }
  107. return 0
  108. }
  109. // CompareChainExpiry ranks chain that lasts longer higher.
  110. func CompareChainExpiry(chain1, chain2 []*x509.Certificate) int {
  111. t1 := helpers.ExpiryTime(chain1)
  112. t2 := helpers.ExpiryTime(chain2)
  113. return compareTime(t1, t2)
  114. }