pubkeypin_test.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package pubkeypin
  14. import (
  15. "crypto/x509"
  16. "encoding/pem"
  17. "strings"
  18. "testing"
  19. )
  20. // testCertPEM is a simple self-signed test certificate issued with the openssl CLI:
  21. // openssl req -new -newkey rsa:2048 -days 36500 -nodes -x509 -keyout /dev/null -out test.crt
  22. const testCertPEM = `
  23. -----BEGIN CERTIFICATE-----
  24. MIIDRDCCAiygAwIBAgIJAJgVaCXvC6HkMA0GCSqGSIb3DQEBBQUAMB8xHTAbBgNV
  25. BAMTFGt1YmVhZG0ta2V5cGlucy10ZXN0MCAXDTE3MDcwNTE3NDMxMFoYDzIxMTcw
  26. NjExMTc0MzEwWjAfMR0wGwYDVQQDExRrdWJlYWRtLWtleXBpbnMtdGVzdDCCASIw
  27. DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK0ba8mHU9UtYlzM1Own2Fk/XGjR
  28. J4uJQvSeGLtz1hID1IA0dLwruvgLCPadXEOw/f/IWIWcmT+ZmvIHZKa/woq2iHi5
  29. +HLhXs7aG4tjKGLYhag1hLjBI7icqV7ovkjdGAt9pWkxEzhIYClFMXDjKpMSynu+
  30. YX6nZ9tic1cOkHmx2yiZdMkuriRQnpTOa7bb03OC1VfGl7gHlOAIYaj4539WCOr8
  31. +ACTUMJUFEHcRZ2o8a/v6F9GMK+7SC8SJUI+GuroXqlMAdhEv4lX5Co52enYaClN
  32. +D9FJLRpBv2YfiCQdJRaiTvCBSxEFz6BN+PtP5l2Hs703ZWEkOqCByM6HV8CAwEA
  33. AaOBgDB+MB0GA1UdDgQWBBRQgUX8MhK2rWBWQiPHWcKzoWDH5DBPBgNVHSMESDBG
  34. gBRQgUX8MhK2rWBWQiPHWcKzoWDH5KEjpCEwHzEdMBsGA1UEAxMUa3ViZWFkbS1r
  35. ZXlwaW5zLXRlc3SCCQCYFWgl7wuh5DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
  36. BQUAA4IBAQCaAUif7Pfx3X0F08cxhx8/Hdx4jcJw6MCq6iq6rsXM32ge43t8OHKC
  37. pJW08dk58a3O1YQSMMvD6GJDAiAfXzfwcwY6j258b1ZlI9Ag0VokvhMl/XfdCsdh
  38. AWImnL1t4hvU5jLaImUUMlYxMcSfHBGAm7WJIZ2LdEfg6YWfZh+WGbg1W7uxLxk6
  39. y4h5rWdNnzBHWAGf7zJ0oEDV6W6RSwNXtC0JNnLaeIUm/6xdSddJlQPwUv8YH4jX
  40. c1vuFqTnJBPcb7W//R/GI2Paicm1cmns9NLnPR35exHxFTy+D1yxmGokpoPMdife
  41. aH+sfuxT8xeTPb3kjzF9eJTlnEquUDLM
  42. -----END CERTIFICATE-----`
  43. // expectedHash can be verified using the openssl CLI:
  44. // openssl x509 -pubkey -in test.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex
  45. const expectedHash = `sha256:345959acb2c3b2feb87d281961c893f62a314207ef02599f1cc4a5fb255480b3`
  46. // testCert2PEM is a second test cert generated the same way as testCertPEM
  47. const testCert2PEM = `
  48. -----BEGIN CERTIFICATE-----
  49. MIID9jCCAt6gAwIBAgIJAN5MXZDic7qYMA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV
  50. BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
  51. aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCXRlc3RDZXJ0MjAgFw0xNzA3MjQxNjA0
  52. MDFaGA8yMTE3MDYzMDE2MDQwMVowWTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNv
  53. bWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAG
  54. A1UEAxMJdGVzdENlcnQyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
  55. 0brwpJYN2ytPWzRBtZSVc3dhkQlA59AzxzqeLLkano0Pxo9NIc3T/y58nnRI8uaS
  56. I1P7BzUfJTiUEvmAtX8NggqKK4ld/gPrU+IRww1CUYS4KCkA/0d0ctPy0JwBCjD+
  57. b57G3rmNE8c+0jns6J96ZzNtqmv6N+ZlFBAXm1p4S+k0kGi5+hoQ6H7SYXjk2lG+
  58. r/8jPQEjy/NSdw1dcCA0Nc6o+hPr32927dS6J9KOhBeXNYUNdbuDDmroM9/gN2e/
  59. YMSA1olLeDPQ7Xvhk0PIyEDnHh83AffPCx5yM3htVRGddjIsPAVUJEL3z5leJtxe
  60. fzyPghOhHJY0PXqznDQTcwIDAQABo4G+MIG7MB0GA1UdDgQWBBRP0IJqv/5rQ4Uf
  61. SByl77dJeEapRDCBiwYDVR0jBIGDMIGAgBRP0IJqv/5rQ4UfSByl77dJeEapRKFd
  62. pFswWTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoT
  63. GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAxMJdGVzdENlcnQyggkA
  64. 3kxdkOJzupgwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA0RIMHc10
  65. wHHPMh9UflqBgDMF7gfbOL0juJfGloAOcohWWfMZBBJ0CQKMy3xRyoK3HmbW1eeb
  66. iATjesw7t4VEAwf7mgKAd+eTfWYB952uq5qYJ2TI28mSofEq1Wz3RmrNkC1KCBs1
  67. u+YMFGwyl6necV9zKCeiju4jeovI1GA38TvH7MgYln6vMJ+FbgOXj7XCpek7dQiY
  68. KGaeSSH218mGNQaWRQw2Sm3W6cFdANoCJUph4w18s7gjtFpfV63s80hXRps+vEyv
  69. jEQMEQpG8Ss7HGJLGLBw/xAmG0e//XS/o2dDonbGbvzToFByz8OGxjMhk6yV6hdd
  70. +iyvsLAw/MYMSA==
  71. -----END CERTIFICATE-----
  72. `
  73. // testCert is a small helper to get a test x509.Certificate from the PEM constants
  74. func testCert(t *testing.T, pemString string) *x509.Certificate {
  75. // Decode the example certificate from a PEM file into a PEM block
  76. pemBlock, _ := pem.Decode([]byte(pemString))
  77. if pemBlock == nil {
  78. t.Fatal("failed to parse test certificate PEM")
  79. return nil
  80. }
  81. // Parse the PEM block into an x509.Certificate
  82. result, err := x509.ParseCertificate(pemBlock.Bytes)
  83. if err != nil {
  84. t.Fatalf("failed to parse test certificate: %v", err)
  85. return nil
  86. }
  87. return result
  88. }
  89. func TestSet(t *testing.T) {
  90. s := NewSet()
  91. if !s.Empty() {
  92. t.Error("expected a new set to be empty")
  93. return
  94. }
  95. err := s.Allow("xyz")
  96. if err == nil || !s.Empty() {
  97. t.Error("expected allowing junk to fail")
  98. return
  99. }
  100. err = s.Allow("0011223344")
  101. if err == nil || !s.Empty() {
  102. t.Error("expected allowing something too short to fail")
  103. return
  104. }
  105. err = s.Allow(expectedHash + expectedHash)
  106. if err == nil || !s.Empty() {
  107. t.Error("expected allowing something too long to fail")
  108. return
  109. }
  110. err = s.CheckAny([]*x509.Certificate{testCert(t, testCertPEM)})
  111. if err == nil {
  112. t.Error("expected test cert to not be allowed (yet)")
  113. return
  114. }
  115. err = s.Allow(strings.ToUpper(expectedHash))
  116. if err != nil || s.Empty() {
  117. t.Error("expected allowing uppercase expectedHash to succeed")
  118. return
  119. }
  120. err = s.CheckAny([]*x509.Certificate{testCert(t, testCertPEM)})
  121. if err != nil {
  122. t.Errorf("expected test cert to be allowed, but got back: %v", err)
  123. return
  124. }
  125. err = s.CheckAny([]*x509.Certificate{testCert(t, testCert2PEM)})
  126. if err == nil {
  127. t.Error("expected the second test cert to be disallowed")
  128. return
  129. }
  130. }
  131. func TestHash(t *testing.T) {
  132. actualHash := Hash(testCert(t, testCertPEM))
  133. if actualHash != expectedHash {
  134. t.Errorf(
  135. "failed to Hash() to the expected value\n\texpected: %q\n\t actual: %q",
  136. expectedHash,
  137. actualHash,
  138. )
  139. }
  140. }