123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- package ubiquity
- // In this file, we include chain ranking functions based on security and performance
- import (
- "crypto/ecdsa"
- "crypto/elliptic"
- "crypto/rsa"
- "crypto/x509"
- "time"
- "github.com/cloudflare/cfssl/helpers"
- )
- // Compute the priority of different hash algorithm based on security
- // SHA2 > SHA1 >> MD = Others = Unknown
- func hashPriority(cert *x509.Certificate) int {
- switch cert.SignatureAlgorithm {
- case x509.ECDSAWithSHA1, x509.DSAWithSHA1, x509.SHA1WithRSA:
- return 10
- case x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512,
- x509.DSAWithSHA256, x509.SHA256WithRSA, x509.SHA384WithRSA,
- x509.SHA512WithRSA:
- return 100
- default:
- return 0
- }
- }
- // Compute the priority of different key algorithm based performance and security
- // ECDSA>RSA>DSA>Unknown
- func keyAlgoPriority(cert *x509.Certificate) int {
- switch cert.PublicKeyAlgorithm {
- case x509.ECDSA:
- switch cert.PublicKey.(*ecdsa.PublicKey).Curve {
- case elliptic.P256():
- return 100
- case elliptic.P384():
- return 120
- case elliptic.P521():
- return 140
- default:
- return 100
- }
- case x509.RSA:
- switch cert.PublicKey.(*rsa.PublicKey).N.BitLen() {
- case 4096:
- return 70
- case 3072:
- return 50
- case 2048:
- return 30
- // key size <= 1024 are discouraged.
- default:
- return 0
- }
- // we do not want to bundle a DSA cert.
- case x509.DSA:
- return 0
- default:
- return 0
- }
- }
- // HashPriority returns the hash priority of the chain as the average of hash priority of certs in it.
- func HashPriority(certs []*x509.Certificate) int {
- ret := 0.0
- for i, cert := range certs {
- f1 := 1.0 / (float64(i) + 1.0)
- f2 := 1.0 - f1
- ret = ret*f2 + float64(hashPriority(cert))*f1
- }
- return int(ret)
- }
- // KeyAlgoPriority returns the key algorithm priority of the chain as the average of key algorithm priority of certs in it.
- func KeyAlgoPriority(certs []*x509.Certificate) int {
- ret := 0.0
- for i, cert := range certs {
- f1 := 1.0 / (float64(i) + 1.0)
- f2 := 1.0 - f1
- ret = float64(keyAlgoPriority(cert))*f1 + ret*f2
- }
- return int(ret)
- }
- // CompareChainHashPriority ranks chains with more current hash functions higher.
- func CompareChainHashPriority(chain1, chain2 []*x509.Certificate) int {
- hp1 := HashPriority(chain1)
- hp2 := HashPriority(chain2)
- return hp1 - hp2
- }
- // CompareChainKeyAlgoPriority ranks chains with more current key algorithm higher.
- func CompareChainKeyAlgoPriority(chain1, chain2 []*x509.Certificate) int {
- kap1 := KeyAlgoPriority(chain1)
- kap2 := KeyAlgoPriority(chain2)
- return kap1 - kap2
- }
- // CompareChainCryptoSuite ranks chains with more current crypto suite higher.
- func CompareChainCryptoSuite(chain1, chain2 []*x509.Certificate) int {
- cs1 := HashPriority(chain1) + KeyAlgoPriority(chain1)
- cs2 := HashPriority(chain2) + KeyAlgoPriority(chain2)
- return cs1 - cs2
- }
- // CompareChainLength ranks shorter chain higher.
- func CompareChainLength(chain1, chain2 []*x509.Certificate) int {
- return len(chain2) - len(chain1)
- }
- func compareTime(t1, t2 time.Time) int {
- if t1.After(t2) {
- return 1
- } else if t1.Before(t2) {
- return -1
- }
- return 0
- }
- // CompareChainExpiry ranks chain that lasts longer higher.
- func CompareChainExpiry(chain1, chain2 []*x509.Certificate) int {
- t1 := helpers.ExpiryTime(chain1)
- t2 := helpers.ExpiryTime(chain2)
- return compareTime(t1, t2)
- }
|