ubiquity_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. package ubiquity
  2. import (
  3. "crypto/x509"
  4. "fmt"
  5. "os"
  6. "testing"
  7. "time"
  8. "github.com/cloudflare/cfssl/helpers"
  9. )
  10. const (
  11. rsa1024 = "testdata/rsa1024sha1.pem"
  12. rsa2048 = "testdata/rsa2048sha2.pem"
  13. rsa3072 = "testdata/rsa3072sha2.pem"
  14. rsa4096 = "testdata/rsa4096sha2.pem"
  15. ecdsa256 = "testdata/ecdsa256sha2.pem"
  16. ecdsa384 = "testdata/ecdsa384sha2.pem"
  17. ecdsa521 = "testdata/ecdsa521sha2.pem"
  18. caMetadata = "testdata/ca.pem.metadata"
  19. )
  20. var rsa1024Cert, rsa2048Cert, rsa3072Cert, rsa4096Cert, ecdsa256Cert, ecdsa384Cert, ecdsa521Cert *x509.Certificate
  21. func readCert(filename string) *x509.Certificate {
  22. bytes, _ := os.ReadFile(filename)
  23. cert, _ := helpers.ParseCertificatePEM(bytes)
  24. return cert
  25. }
  26. func init() {
  27. rsa1024Cert = readCert(rsa1024)
  28. rsa2048Cert = readCert(rsa2048)
  29. rsa3072Cert = readCert(rsa3072)
  30. rsa4096Cert = readCert(rsa4096)
  31. ecdsa256Cert = readCert(ecdsa256)
  32. ecdsa384Cert = readCert(ecdsa384)
  33. ecdsa521Cert = readCert(ecdsa521)
  34. }
  35. func TestCertHashPriority(t *testing.T) {
  36. if hashPriority(rsa1024Cert) > hashPriority(rsa2048Cert) {
  37. t.Fatal("Incorrect hash priority")
  38. }
  39. if hashPriority(rsa2048Cert) > hashPriority(rsa3072Cert) {
  40. t.Fatal("Incorrect hash priority")
  41. }
  42. if hashPriority(rsa3072Cert) > hashPriority(rsa4096Cert) {
  43. t.Fatal("Incorrect hash priority")
  44. }
  45. if hashPriority(rsa4096Cert) > hashPriority(ecdsa256Cert) {
  46. t.Fatal("Incorrect hash priority")
  47. }
  48. if hashPriority(ecdsa256Cert) > hashPriority(ecdsa384Cert) {
  49. t.Fatal("Incorrect hash priority")
  50. }
  51. if hashPriority(ecdsa384Cert) > hashPriority(ecdsa256Cert) {
  52. t.Fatal("Incorrect hash priority")
  53. }
  54. }
  55. func TestCertKeyAlgoPriority(t *testing.T) {
  56. if keyAlgoPriority(rsa2048Cert) > keyAlgoPriority(rsa3072Cert) {
  57. t.Fatal("Incorrect hash priority")
  58. }
  59. if keyAlgoPriority(rsa3072Cert) > keyAlgoPriority(rsa4096Cert) {
  60. t.Fatal("Incorrect hash priority")
  61. }
  62. if keyAlgoPriority(rsa4096Cert) > keyAlgoPriority(ecdsa256Cert) {
  63. t.Fatal("Incorrect hash priority")
  64. }
  65. if keyAlgoPriority(ecdsa256Cert) > keyAlgoPriority(ecdsa384Cert) {
  66. t.Fatal("Incorrect hash priority")
  67. }
  68. if keyAlgoPriority(ecdsa384Cert) > keyAlgoPriority(ecdsa521Cert) {
  69. t.Fatal("Incorrect hash priority")
  70. }
  71. }
  72. func TestChainHashPriority(t *testing.T) {
  73. var chain []*x509.Certificate
  74. var p int
  75. chain = []*x509.Certificate{rsa2048Cert, rsa3072Cert}
  76. p = HashPriority(chain)
  77. if p != (hashPriority(rsa2048Cert)+hashPriority(rsa3072Cert))/2 {
  78. t.Fatal("Incorrect chain hash priority")
  79. }
  80. }
  81. func TestChainKeyAlgoPriority(t *testing.T) {
  82. var chain []*x509.Certificate
  83. var p int
  84. chain = []*x509.Certificate{rsa2048Cert, rsa3072Cert}
  85. p = KeyAlgoPriority(chain)
  86. if p != (keyAlgoPriority(rsa2048Cert)+keyAlgoPriority(rsa3072Cert))/2 {
  87. t.Fatal("Incorrect chain key algo priority")
  88. }
  89. }
  90. func TestCertHashUbiquity(t *testing.T) {
  91. if hashUbiquity(rsa2048Cert) != SHA2Ubiquity {
  92. t.Fatal("incorrect hash ubiquity")
  93. }
  94. if hashUbiquity(rsa3072Cert) != SHA2Ubiquity {
  95. t.Fatal("incorrect hash ubiquity")
  96. }
  97. if hashUbiquity(rsa4096Cert) != SHA2Ubiquity {
  98. t.Fatal("incorrect hash ubiquity")
  99. }
  100. if hashUbiquity(rsa2048Cert) < hashUbiquity(rsa3072Cert) {
  101. t.Fatal("incorrect hash ubiquity")
  102. }
  103. if hashUbiquity(rsa3072Cert) < hashUbiquity(rsa4096Cert) {
  104. t.Fatal("Incorrect hash ubiquity")
  105. }
  106. if hashUbiquity(rsa4096Cert) < hashUbiquity(ecdsa256Cert) {
  107. t.Fatal("Incorrect hash ubiquity")
  108. }
  109. if hashUbiquity(ecdsa256Cert) < hashUbiquity(ecdsa384Cert) {
  110. t.Fatal("Incorrect hash ubiquity")
  111. }
  112. if hashUbiquity(ecdsa384Cert) < hashUbiquity(ecdsa256Cert) {
  113. t.Fatal("Incorrect hash ubiquity")
  114. }
  115. }
  116. func TestCertKeyAlgoUbiquity(t *testing.T) {
  117. if keyAlgoUbiquity(rsa2048Cert) != RSAUbiquity {
  118. t.Fatal("incorrect hash ubiquity")
  119. }
  120. if keyAlgoUbiquity(rsa3072Cert) != RSAUbiquity {
  121. t.Fatal("incorrect hash ubiquity")
  122. }
  123. if keyAlgoUbiquity(rsa4096Cert) != RSAUbiquity {
  124. t.Fatal("incorrect hash ubiquity")
  125. }
  126. if keyAlgoUbiquity(ecdsa256Cert) != ECDSA256Ubiquity {
  127. t.Fatal("incorrect hash ubiquity")
  128. }
  129. if keyAlgoUbiquity(ecdsa384Cert) != ECDSA384Ubiquity {
  130. t.Fatal("incorrect hash ubiquity")
  131. }
  132. if keyAlgoUbiquity(ecdsa521Cert) != ECDSA521Ubiquity {
  133. t.Fatal("incorrect hash ubiquity")
  134. }
  135. if keyAlgoUbiquity(rsa2048Cert) < keyAlgoUbiquity(rsa3072Cert) {
  136. t.Fatal("incorrect hash ubiquity")
  137. }
  138. if keyAlgoUbiquity(rsa3072Cert) < keyAlgoUbiquity(rsa4096Cert) {
  139. t.Fatal("Incorrect hash ubiquity")
  140. }
  141. if keyAlgoUbiquity(rsa4096Cert) < keyAlgoUbiquity(ecdsa256Cert) {
  142. t.Fatal("Incorrect hash ubiquity")
  143. }
  144. if keyAlgoUbiquity(ecdsa256Cert) < keyAlgoUbiquity(ecdsa384Cert) {
  145. t.Fatal("Incorrect hash ubiquity")
  146. }
  147. if keyAlgoUbiquity(ecdsa384Cert) < keyAlgoUbiquity(ecdsa256Cert) {
  148. t.Fatal("Incorrect hash ubiquity")
  149. }
  150. }
  151. func TestChainHashUbiquity(t *testing.T) {
  152. chain := []*x509.Certificate{rsa1024Cert, rsa2048Cert}
  153. if ChainHashUbiquity(chain) != hashUbiquity(rsa2048Cert) {
  154. t.Fatal("Incorrect chain hash ubiquity")
  155. }
  156. }
  157. func TestChainKeyAlgoUbiquity(t *testing.T) {
  158. chain := []*x509.Certificate{rsa1024Cert, rsa2048Cert}
  159. if ChainKeyAlgoUbiquity(chain) != keyAlgoUbiquity(rsa2048Cert) {
  160. t.Fatal("Incorrect chain hash ubiquity")
  161. }
  162. chain = []*x509.Certificate{ecdsa256Cert, rsa2048Cert}
  163. if ChainKeyAlgoUbiquity(chain) != keyAlgoUbiquity(ecdsa256Cert) {
  164. t.Fatal("Incorrect chain hash ubiquity")
  165. }
  166. }
  167. func TestChainExpiryUbiquity(t *testing.T) {
  168. // rsa1024Cert expires at year 2024
  169. // rsa2048Cert expires at year 2019
  170. // ecdsa256Cert expires at year 2019
  171. chain1 := []*x509.Certificate{ecdsa256Cert, rsa2048Cert}
  172. chain2 := []*x509.Certificate{ecdsa256Cert, rsa1024Cert}
  173. // CompareExpiryUbiquity should return > 0 because chain1
  174. // has a better expiry ubiquity than chain2.
  175. if CompareExpiryUbiquity(chain1, chain2) <= 0 {
  176. t.Fatal("Incorrect chain expiry ubiquity")
  177. }
  178. // CompareExpiryUbiquity should return < 0 because chain1 has
  179. // a better expiry ubiquity than chain2.
  180. if CompareExpiryUbiquity(chain2, chain1) >= 0 {
  181. t.Fatal("Incorrect chain expiry ubiquity")
  182. }
  183. if CompareExpiryUbiquity(chain1, chain1) != 0 {
  184. t.Fatal("Incorrect chain expiry ubiquity")
  185. }
  186. }
  187. func TestCompareChainExpiry(t *testing.T) {
  188. // rsa1024Cert expires at 2024
  189. // rsa2048Cert expires at 2019
  190. // ecdsa256Cert expires at 2019
  191. // both chain expires at year 2019.
  192. chain1 := []*x509.Certificate{ecdsa256Cert, rsa2048Cert}
  193. chain2 := []*x509.Certificate{ecdsa256Cert, rsa1024Cert}
  194. if CompareChainExpiry(chain1, chain2) != 0 {
  195. t.Fatal("Incorrect chain expiry")
  196. }
  197. if CompareExpiryUbiquity(chain1, chain1) != 0 {
  198. t.Fatal("Incorrect chain expiry")
  199. }
  200. }
  201. func TestCompareChainLength(t *testing.T) {
  202. chain1 := []*x509.Certificate{ecdsa256Cert, rsa2048Cert}
  203. chain2 := []*x509.Certificate{rsa1024Cert}
  204. chain3 := []*x509.Certificate{rsa2048Cert}
  205. // longer chain is ranked lower
  206. if CompareChainLength(chain1, chain2) >= 0 {
  207. t.Fatal("Incorrect chain length comparison")
  208. }
  209. if CompareChainLength(chain2, chain3) != 0 {
  210. t.Fatal("Incorrect chain length comparison")
  211. }
  212. }
  213. func TestPlatformKeyStoreUbiquity(t *testing.T) {
  214. cert1 := rsa1024Cert
  215. cert2 := rsa2048Cert
  216. cert3 := ecdsa256Cert
  217. // load Platforms with test data
  218. // "Macrosoft" has all three certs.
  219. // "Godzilla" has two certs, cert1 and cert2.
  220. // "Pineapple" has cert1.
  221. // "Colorful" has no key store data, default to trust any cert
  222. // All platforms support the same crypto suite.
  223. platformA := Platform{Name: "MacroSoft", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: "testdata/macrosoft.pem"}
  224. platformB := Platform{Name: "Godzilla", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: "testdata/godzilla.pem"}
  225. platformC := Platform{Name: "Pineapple", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: "testdata/pineapple.pem"}
  226. platformD := Platform{Name: "Colorful", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: ""}
  227. platformA.ParseAndLoad()
  228. platformB.ParseAndLoad()
  229. platformC.ParseAndLoad()
  230. platformD.ParseAndLoad()
  231. Platforms = []Platform{platformA, platformB, platformC, platformD}
  232. // chain1 with root cert1 (RSA1024, SHA1), has the largest platform coverage.
  233. // chain2 with root cert2 (RSA2048, SHA2), has the second largest coverage.
  234. // chain3 with root cert3 (ECDSA256, SHA2), has the least coverage.
  235. chain1 := []*x509.Certificate{cert1}
  236. chain2 := []*x509.Certificate{cert1, cert2}
  237. chain3 := []*x509.Certificate{cert1, cert2, cert3}
  238. if CrossPlatformUbiquity(chain1) < CrossPlatformUbiquity(chain2) {
  239. t.Fatal("Incorrect cross platform ubiquity")
  240. }
  241. if CrossPlatformUbiquity(chain2) < CrossPlatformUbiquity(chain3) {
  242. t.Fatal("Incorrect cross platform ubiquity")
  243. }
  244. if ComparePlatformUbiquity(chain1, chain2) < 0 {
  245. t.Fatal("Incorrect cross platform ubiquity")
  246. }
  247. if ComparePlatformUbiquity(chain2, chain3) < 0 {
  248. t.Fatal("Incorrect cross platform ubiquity")
  249. }
  250. // test UntrustedPlatforms()
  251. u1 := UntrustedPlatforms(cert1)
  252. if len(u1) != 0 {
  253. t.Fatal("Incorrect UntrustedPlatforms")
  254. }
  255. u2 := UntrustedPlatforms(cert2)
  256. if len(u2) != 1 {
  257. t.Fatal("Incorrect UntrustedPlatforms")
  258. }
  259. u3 := UntrustedPlatforms(cert3)
  260. if len(u3) != 2 {
  261. t.Fatal("Incorrect UntrustedPlatforms")
  262. }
  263. }
  264. func TestEmptyPlatformList(t *testing.T) {
  265. Platforms = []Platform{}
  266. cert := rsa1024Cert
  267. chain := []*x509.Certificate{cert}
  268. if CrossPlatformUbiquity(chain) != 0 {
  269. t.Fatal("Incorrect cross platform ubiquity when Platforms is empty")
  270. }
  271. // test UntrustedPlatforms()
  272. u1 := UntrustedPlatforms(cert)
  273. if len(u1) != 0 {
  274. t.Fatal("Incorrect UntrustedPlatforms when Platforms is empty")
  275. }
  276. }
  277. func TestLoadPlatforms(t *testing.T) {
  278. err := LoadPlatforms(caMetadata)
  279. if err != nil {
  280. t.Fatal(err)
  281. }
  282. }
  283. func TestPlatformCryptoUbiquity(t *testing.T) {
  284. cert1 := rsa1024Cert
  285. cert2 := rsa2048Cert
  286. cert3 := ecdsa256Cert
  287. // load Platforms with test data
  288. // All platforms have the same trust store but are with various crypto suite.
  289. platformA := Platform{Name: "TinySoft", Weight: 100, HashAlgo: "SHA1", KeyAlgo: "RSA", KeyStoreFile: "testdata/macrosoft.pem"}
  290. platformB := Platform{Name: "SmallSoft", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "RSA", KeyStoreFile: "testdata/macrosoft.pem"}
  291. platformC := Platform{Name: "LargeSoft", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA256", KeyStoreFile: "testdata/macrosoft.pem"}
  292. platformD := Platform{Name: "MediumSoft", Weight: 100, HashAlgo: "SHA2", KeyAlgo: "ECDSA384", KeyStoreFile: "testdata/macrosoft.pem"}
  293. platformA.ParseAndLoad()
  294. platformB.ParseAndLoad()
  295. platformC.ParseAndLoad()
  296. platformD.ParseAndLoad()
  297. Platforms = []Platform{platformA, platformB, platformC}
  298. // chain1 with root cert1 (RSA1024, SHA1), has the largest platform coverage.
  299. // chain2 with root cert2 (RSA2048, SHA2), has the second largest coverage.
  300. // chain3 with root cert3 (ECDSA256, SHA2), has the least coverage.
  301. chain1 := []*x509.Certificate{cert1}
  302. chain2 := []*x509.Certificate{cert1, cert2}
  303. chain3 := []*x509.Certificate{cert1, cert2, cert3}
  304. if CrossPlatformUbiquity(chain1) < CrossPlatformUbiquity(chain2) {
  305. t.Fatal("Incorrect cross platform ubiquity")
  306. }
  307. if CrossPlatformUbiquity(chain2) < CrossPlatformUbiquity(chain3) {
  308. t.Fatal("Incorrect cross platform ubiquity")
  309. }
  310. if ComparePlatformUbiquity(chain1, chain2) < 0 {
  311. t.Fatal("Incorrect cross platform ubiquity")
  312. }
  313. if ComparePlatformUbiquity(chain1, chain2) < 0 {
  314. t.Fatal("Incorrect cross platform ubiquity")
  315. }
  316. }
  317. func TestSHA2Homogeneity(t *testing.T) {
  318. // root-only chain is always SHA2-Homogeneous.
  319. chain0 := []*x509.Certificate{rsa1024Cert}
  320. if SHA2Homogeneity(chain0) != 1 {
  321. t.Fatal("SHA2Homogeneity(chain0) != 1")
  322. }
  323. chain1 := []*x509.Certificate{rsa1024Cert, rsa2048Cert, rsa1024Cert}
  324. if SHA2Homogeneity(chain1) != 0 {
  325. t.Fatal("SHA2Homogeneity(chain1) != 0")
  326. }
  327. chain2 := []*x509.Certificate{rsa2048Cert, rsa2048Cert, rsa1024Cert}
  328. if SHA2Homogeneity(chain2) != 1 {
  329. t.Fatal("SHA2Homogeneity(chain2) != 1")
  330. }
  331. chain3 := []*x509.Certificate{ecdsa256Cert, rsa2048Cert, rsa1024Cert}
  332. if SHA2Homogeneity(chain3) != 1 {
  333. t.Fatal("SHA2Homogeneity(chain3) != 1")
  334. }
  335. chain4 := []*x509.Certificate{ecdsa256Cert, ecdsa384Cert, rsa1024Cert}
  336. if SHA2Homogeneity(chain4) != 1 {
  337. t.Fatal("SHA2Homogeneity(chain4) != 1")
  338. }
  339. }
  340. func TestCompareSHA2Homogeneity(t *testing.T) {
  341. chain1 := []*x509.Certificate{rsa1024Cert, rsa2048Cert, rsa1024Cert}
  342. chain2 := []*x509.Certificate{rsa2048Cert, rsa2048Cert, rsa1024Cert}
  343. chain3 := []*x509.Certificate{ecdsa256Cert, rsa2048Cert, rsa1024Cert}
  344. chain4 := []*x509.Certificate{ecdsa256Cert, ecdsa384Cert, rsa1024Cert}
  345. if CompareSHA2Homogeneity(chain1, chain2) >= 0 {
  346. t.Fatal("CompareSHA2Homogeneity(chain1, chain2) >= 0")
  347. }
  348. if CompareSHA2Homogeneity(chain1, chain3) >= 0 {
  349. t.Fatal("CompareSHA2Homogeneity(chain1, chain3) >= 0")
  350. }
  351. if CompareSHA2Homogeneity(chain1, chain4) >= 0 {
  352. t.Fatal("CompareSHA2Homogeneity(chain1, chain4) >= 0")
  353. }
  354. if CompareSHA2Homogeneity(chain2, chain3) != 0 || CompareSHA2Homogeneity(chain3, chain4) != 0 {
  355. t.Fatal("CompareSHA2Homogeneity failed.")
  356. }
  357. }
  358. func TestFilterTrivial(t *testing.T) {
  359. var chain []*x509.Certificate
  360. var chains [][]*x509.Certificate
  361. ret := Filter(chains, CompareChainHashPriority)
  362. if len(ret) != 0 {
  363. t.Fatal("Incorrect filtering")
  364. }
  365. chain = []*x509.Certificate{rsa2048Cert}
  366. chains = [][]*x509.Certificate{chain}
  367. ret = Filter(chains, CompareChainHashPriority)
  368. if len(ret) != 1 {
  369. t.Fatal("Incorrect filtering")
  370. }
  371. }
  372. func TestFilterChainHashPriority(t *testing.T) {
  373. var chain1, chain2 []*x509.Certificate
  374. chain1 = []*x509.Certificate{rsa2048Cert} // SHA256
  375. chain2 = []*x509.Certificate{ecdsa384Cert} // SHA384
  376. // SHA256 <= SHA384
  377. if CompareChainHashPriority(chain1, chain2) > 0 {
  378. t.Fatal("Incorrect chain hash priority comparison")
  379. }
  380. chains := [][]*x509.Certificate{chain2, chain1}
  381. ret := Filter(chains, CompareChainHashPriority)
  382. // check there is no reordering
  383. if ret[0][0] != ecdsa384Cert {
  384. t.Fatal("Incorrect chain hash priority filtering")
  385. }
  386. }
  387. func TestFilterChainKeyAlgoPriority(t *testing.T) {
  388. var chain1, chain2 []*x509.Certificate
  389. chain1 = []*x509.Certificate{rsa2048Cert} // RSA
  390. chain2 = []*x509.Certificate{ecdsa384Cert} // ECDSA
  391. // RSA <= ECDSA
  392. if CompareChainKeyAlgoPriority(chain1, chain2) >= 0 {
  393. t.Fatal("Incorrect chain key algo priority comparison")
  394. }
  395. chains := [][]*x509.Certificate{chain1, chain2}
  396. ret := Filter(chains, CompareChainKeyAlgoPriority)
  397. // check there is reordering
  398. if ret[0][0] != ecdsa384Cert {
  399. t.Fatal("Incorrect chain key algo priority filtering")
  400. }
  401. }
  402. func TestFilterChainCipherSuite(t *testing.T) {
  403. var chain1, chain2 []*x509.Certificate
  404. chain1 = []*x509.Certificate{rsa2048Cert}
  405. chain2 = []*x509.Certificate{ecdsa384Cert}
  406. // RSA2048 < ECDSA384
  407. if CompareChainCryptoSuite(chain1, chain2) >= 0 {
  408. t.Fatal("Incorrect chain key algo priority comparison")
  409. }
  410. chains := [][]*x509.Certificate{chain1, chain2}
  411. ret := Filter(chains, CompareChainCryptoSuite)
  412. // check there is reordering
  413. if ret[0][0] != ecdsa384Cert {
  414. t.Fatal("Incorrect chain key algo priority filtering")
  415. }
  416. }
  417. func TestFilterChainHashUbiquity(t *testing.T) {
  418. var chain1, chain2 []*x509.Certificate
  419. chain1 = []*x509.Certificate{rsa2048Cert} // SHA256
  420. chain2 = []*x509.Certificate{ecdsa384Cert} // SHA384
  421. // SHA256 == SHA384
  422. if CompareChainHashUbiquity(chain1, chain2) != 0 {
  423. t.Fatal("Incorrect chain hash priority comparison")
  424. }
  425. chains := [][]*x509.Certificate{chain2, chain1}
  426. ret := Filter(chains, CompareChainHashUbiquity)
  427. // check there is no reordering
  428. if ret[0][0] != ecdsa384Cert {
  429. t.Fatal("Incorrect chain hash priority filtering")
  430. }
  431. }
  432. func TestFilterChainKeyAlgoUbiquity(t *testing.T) {
  433. var chain1, chain2 []*x509.Certificate
  434. chain1 = []*x509.Certificate{rsa2048Cert} // RSA
  435. chain2 = []*x509.Certificate{ecdsa384Cert} // ECDSA
  436. // RSA >= ECDSA
  437. if CompareChainKeyAlgoUbiquity(chain1, chain2) < 0 {
  438. t.Fatal("Incorrect chain key algo priority comparison")
  439. }
  440. chains := [][]*x509.Certificate{chain1, chain2}
  441. ret := Filter(chains, CompareChainKeyAlgoUbiquity)
  442. // check there is no reordering
  443. if ret[0][0] != rsa2048Cert {
  444. t.Fatal("Incorrect chain key algo priority filtering")
  445. }
  446. }
  447. func TestFlagBySHA1DeprecationPolicy(t *testing.T) {
  448. cert1 := rsa1024Cert
  449. cert2 := rsa2048Cert
  450. Jan1st2014 := time.Date(2014, time.January, 1, 0, 0, 0, 0, time.UTC)
  451. Jan1st2100 := time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC)
  452. policy1 := SHA1DeprecationPolicy{
  453. Description: "SHA1 should be gone years ago",
  454. ExpiryDeadline: Jan1st2014,
  455. }
  456. policy2 := SHA1DeprecationPolicy{
  457. Description: "SHA1 is perfect for another century",
  458. ExpiryDeadline: Jan1st2100,
  459. }
  460. policy3 := SHA1DeprecationPolicy{
  461. Description: "effectively one century later, reject SHA1 expires on 2014",
  462. EffectiveDate: Jan1st2100,
  463. ExpiryDeadline: Jan1st2014,
  464. }
  465. policy4 := SHA1DeprecationPolicy{
  466. Description: "no more new SHA1 cert",
  467. NeverIssueAfter: Jan1st2014,
  468. }
  469. // chain1 is accepted univerally. It's not flagged because root cert is not subject to SHA1 deprecation.
  470. chain1 := []*x509.Certificate{cert1}
  471. if policy1.Flag(chain1) || policy2.Flag(chain1) || policy3.Flag(chain1) || policy4.Flag(chain1) {
  472. t.Fatal("Incorrect SHA1 deprecation")
  473. }
  474. // chain2 is accepted by policy2 and policy3. It's flagged by policy1 and policy4
  475. chain2 := []*x509.Certificate{cert1, cert1}
  476. if !policy1.Flag(chain2) || policy2.Flag(chain2) || policy3.Flag(chain2) || !policy4.Flag(chain2) {
  477. t.Fatal("Incorrect SHA1 deprecation")
  478. }
  479. // chain3 is accepted by universally since the leaf cert and the intermediate are signed by SHA-256
  480. chain3 := []*x509.Certificate{cert2, cert2, cert1}
  481. if policy1.Flag(chain3) || policy2.Flag(chain3) || policy3.Flag(chain3) || policy4.Flag(chain3) {
  482. t.Fatal("Incorrect SHA1 deprecation")
  483. }
  484. }
  485. func TestSHA1DeprecationMessages(t *testing.T) {
  486. cert1 := rsa1024Cert
  487. cert2 := rsa2048Cert
  488. chain1 := []*x509.Certificate{cert1}
  489. chain2 := []*x509.Certificate{cert1, cert1}
  490. chain3 := []*x509.Certificate{cert2, cert1, cert1}
  491. chain4 := []*x509.Certificate{cert2, cert2, cert1}
  492. var messages []string
  493. Jan1st2014 := time.Date(2014, time.January, 1, 0, 0, 0, 0, time.UTC)
  494. Jan1st2100 := time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC)
  495. policy1 := SHA1DeprecationPolicy{
  496. Platform: "Browser A",
  497. Description: "minor warning",
  498. Severity: Low,
  499. ExpiryDeadline: Jan1st2014,
  500. }
  501. policy2 := SHA1DeprecationPolicy{
  502. Platform: "Browser A",
  503. Description: "minor warning",
  504. Severity: Medium,
  505. ExpiryDeadline: Jan1st2014,
  506. }
  507. policy3 := SHA1DeprecationPolicy{
  508. Platform: "Browser B",
  509. Description: "reject",
  510. Severity: High,
  511. NeverIssueAfter: Jan1st2014,
  512. }
  513. policy4 := SHA1DeprecationPolicy{
  514. Platform: "Browser C",
  515. Description: "reject but not now",
  516. Severity: High,
  517. NeverIssueAfter: Jan1st2014,
  518. EffectiveDate: Jan1st2100,
  519. }
  520. // The only policy has severity low
  521. SHA1DeprecationPolicys = []SHA1DeprecationPolicy{policy1}
  522. messages = SHA1DeprecationMessages(chain1)
  523. // chain1 with only root is not subject to deprecation
  524. if len(messages) != 0 {
  525. t.Fatal("Incorrect SHA1 deprecation reporting")
  526. }
  527. // chain2 has SHA-1 leaf cert, subject to deprecation
  528. messages = SHA1DeprecationMessages(chain2)
  529. if len(messages) != 1 {
  530. t.Fatal("Incorrect SHA1 deprecation reporting")
  531. }
  532. // chain3 has SHA-1 intermediate cert, subject to deprecation
  533. messages = SHA1DeprecationMessages(chain3)
  534. if len(messages) != 1 {
  535. t.Fatal("Incorrect SHA1 deprecation reporting")
  536. }
  537. // chain4 has no SHA-1 leaf or intermediate, not subject to deprecation
  538. messages = SHA1DeprecationMessages(chain4)
  539. if len(messages) != 0 {
  540. t.Fatal("Incorrect SHA1 deprecation reporting")
  541. }
  542. // A second policy that has higher severity , so it should takes effect and override lower one.
  543. SHA1DeprecationPolicys = []SHA1DeprecationPolicy{policy1, policy2}
  544. // chain1 only has root cert, not subject to deprecation policy
  545. messages = SHA1DeprecationMessages(chain1)
  546. if len(messages) != 0 {
  547. t.Fatal("Incorrect SHA1 deprecation reporting")
  548. }
  549. // chain2 has a SHA-1 leaf cert, will have a message from policy2
  550. messages = SHA1DeprecationMessages(chain2)
  551. if len(messages) != 1 ||
  552. messages[0] != fmt.Sprintf("%s %s due to SHA-1 deprecation", policy2.Platform, policy2.Description) {
  553. t.Fatal("Incorrect SHA1 deprecation reporting")
  554. }
  555. // chain3 has a SHA-1 intermediate cert, will have a message from policy2
  556. messages = SHA1DeprecationMessages(chain3)
  557. if len(messages) != 1 ||
  558. messages[0] != fmt.Sprintf("%s %s due to SHA-1 deprecation", policy2.Platform, policy2.Description) {
  559. t.Fatal("Incorrect SHA1 deprecation reporting")
  560. }
  561. // chain4 is not subject to any deprecation policy
  562. messages = SHA1DeprecationMessages(chain4)
  563. if len(messages) != 0 {
  564. t.Fatal("Incorrect SHA1 deprecation reporting")
  565. }
  566. // Add two policies. One tests for newly issued leaf certificate after a deadline, the other is the same,
  567. // but takes effect at the 22nd century.
  568. SHA1DeprecationPolicys = []SHA1DeprecationPolicy{policy1, policy2, policy3, policy4}
  569. // chain1 only has root cert, not subject to any deprecation policy
  570. messages = SHA1DeprecationMessages(chain1)
  571. if len(messages) != 0 {
  572. t.Fatal("Incorrect SHA1 deprecation reporting")
  573. }
  574. // chain2 now is flagged by two policies: policy2 and policy3
  575. messages = SHA1DeprecationMessages(chain2)
  576. if len(messages) != 2 {
  577. t.Fatal("Incorrect SHA1 deprecation reporting")
  578. }
  579. // chain3 is not flagged by policy3 but policy2
  580. messages = SHA1DeprecationMessages(chain3)
  581. if len(messages) != 1 ||
  582. messages[0] != fmt.Sprintf("%s %s due to SHA-1 deprecation", policy2.Platform, policy2.Description) {
  583. t.Fatal("Incorrect SHA1 deprecation reporting")
  584. }
  585. // chain4 is not subject to any deprecation policy
  586. messages = SHA1DeprecationMessages(chain4)
  587. if len(messages) != 0 {
  588. t.Fatal("Incorrect SHA1 deprecation reporting")
  589. }
  590. }