169 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Go
		
	
	
	
/*
 | 
						|
Copyright 2017 The Kubernetes Authors.
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
package pubkeypin
 | 
						|
 | 
						|
import (
 | 
						|
	"crypto/x509"
 | 
						|
	"encoding/pem"
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
)
 | 
						|
 | 
						|
// testCertPEM is a simple self-signed test certificate issued with the openssl CLI:
 | 
						|
// openssl req -new -newkey rsa:2048 -days 36500 -nodes -x509 -keyout /dev/null -out test.crt
 | 
						|
const testCertPEM = `
 | 
						|
-----BEGIN CERTIFICATE-----
 | 
						|
MIIDRDCCAiygAwIBAgIJAJgVaCXvC6HkMA0GCSqGSIb3DQEBBQUAMB8xHTAbBgNV
 | 
						|
BAMTFGt1YmVhZG0ta2V5cGlucy10ZXN0MCAXDTE3MDcwNTE3NDMxMFoYDzIxMTcw
 | 
						|
NjExMTc0MzEwWjAfMR0wGwYDVQQDExRrdWJlYWRtLWtleXBpbnMtdGVzdDCCASIw
 | 
						|
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK0ba8mHU9UtYlzM1Own2Fk/XGjR
 | 
						|
J4uJQvSeGLtz1hID1IA0dLwruvgLCPadXEOw/f/IWIWcmT+ZmvIHZKa/woq2iHi5
 | 
						|
+HLhXs7aG4tjKGLYhag1hLjBI7icqV7ovkjdGAt9pWkxEzhIYClFMXDjKpMSynu+
 | 
						|
YX6nZ9tic1cOkHmx2yiZdMkuriRQnpTOa7bb03OC1VfGl7gHlOAIYaj4539WCOr8
 | 
						|
+ACTUMJUFEHcRZ2o8a/v6F9GMK+7SC8SJUI+GuroXqlMAdhEv4lX5Co52enYaClN
 | 
						|
+D9FJLRpBv2YfiCQdJRaiTvCBSxEFz6BN+PtP5l2Hs703ZWEkOqCByM6HV8CAwEA
 | 
						|
AaOBgDB+MB0GA1UdDgQWBBRQgUX8MhK2rWBWQiPHWcKzoWDH5DBPBgNVHSMESDBG
 | 
						|
gBRQgUX8MhK2rWBWQiPHWcKzoWDH5KEjpCEwHzEdMBsGA1UEAxMUa3ViZWFkbS1r
 | 
						|
ZXlwaW5zLXRlc3SCCQCYFWgl7wuh5DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
 | 
						|
BQUAA4IBAQCaAUif7Pfx3X0F08cxhx8/Hdx4jcJw6MCq6iq6rsXM32ge43t8OHKC
 | 
						|
pJW08dk58a3O1YQSMMvD6GJDAiAfXzfwcwY6j258b1ZlI9Ag0VokvhMl/XfdCsdh
 | 
						|
AWImnL1t4hvU5jLaImUUMlYxMcSfHBGAm7WJIZ2LdEfg6YWfZh+WGbg1W7uxLxk6
 | 
						|
y4h5rWdNnzBHWAGf7zJ0oEDV6W6RSwNXtC0JNnLaeIUm/6xdSddJlQPwUv8YH4jX
 | 
						|
c1vuFqTnJBPcb7W//R/GI2Paicm1cmns9NLnPR35exHxFTy+D1yxmGokpoPMdife
 | 
						|
aH+sfuxT8xeTPb3kjzF9eJTlnEquUDLM
 | 
						|
-----END CERTIFICATE-----`
 | 
						|
 | 
						|
// expectedHash can be verified using the openssl CLI.
 | 
						|
const expectedHash = `sha256:345959acb2c3b2feb87d281961c893f62a314207ef02599f1cc4a5fb255480b3`
 | 
						|
 | 
						|
// testCert2PEM is a second test cert generated the same way as testCertPEM
 | 
						|
const testCert2PEM = `
 | 
						|
-----BEGIN CERTIFICATE-----
 | 
						|
MIID9jCCAt6gAwIBAgIJAN5MXZDic7qYMA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV
 | 
						|
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
 | 
						|
aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCXRlc3RDZXJ0MjAgFw0xNzA3MjQxNjA0
 | 
						|
MDFaGA8yMTE3MDYzMDE2MDQwMVowWTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNv
 | 
						|
bWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAG
 | 
						|
A1UEAxMJdGVzdENlcnQyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
 | 
						|
0brwpJYN2ytPWzRBtZSVc3dhkQlA59AzxzqeLLkano0Pxo9NIc3T/y58nnRI8uaS
 | 
						|
I1P7BzUfJTiUEvmAtX8NggqKK4ld/gPrU+IRww1CUYS4KCkA/0d0ctPy0JwBCjD+
 | 
						|
b57G3rmNE8c+0jns6J96ZzNtqmv6N+ZlFBAXm1p4S+k0kGi5+hoQ6H7SYXjk2lG+
 | 
						|
r/8jPQEjy/NSdw1dcCA0Nc6o+hPr32927dS6J9KOhBeXNYUNdbuDDmroM9/gN2e/
 | 
						|
YMSA1olLeDPQ7Xvhk0PIyEDnHh83AffPCx5yM3htVRGddjIsPAVUJEL3z5leJtxe
 | 
						|
fzyPghOhHJY0PXqznDQTcwIDAQABo4G+MIG7MB0GA1UdDgQWBBRP0IJqv/5rQ4Uf
 | 
						|
SByl77dJeEapRDCBiwYDVR0jBIGDMIGAgBRP0IJqv/5rQ4UfSByl77dJeEapRKFd
 | 
						|
pFswWTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoT
 | 
						|
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAxMJdGVzdENlcnQyggkA
 | 
						|
3kxdkOJzupgwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA0RIMHc10
 | 
						|
wHHPMh9UflqBgDMF7gfbOL0juJfGloAOcohWWfMZBBJ0CQKMy3xRyoK3HmbW1eeb
 | 
						|
iATjesw7t4VEAwf7mgKAd+eTfWYB952uq5qYJ2TI28mSofEq1Wz3RmrNkC1KCBs1
 | 
						|
u+YMFGwyl6necV9zKCeiju4jeovI1GA38TvH7MgYln6vMJ+FbgOXj7XCpek7dQiY
 | 
						|
KGaeSSH218mGNQaWRQw2Sm3W6cFdANoCJUph4w18s7gjtFpfV63s80hXRps+vEyv
 | 
						|
jEQMEQpG8Ss7HGJLGLBw/xAmG0e//XS/o2dDonbGbvzToFByz8OGxjMhk6yV6hdd
 | 
						|
+iyvsLAw/MYMSA==
 | 
						|
-----END CERTIFICATE-----
 | 
						|
`
 | 
						|
 | 
						|
// testCert is a small helper to get a test x509.Certificate from the PEM constants
 | 
						|
func testCert(t *testing.T, pemString string) *x509.Certificate {
 | 
						|
	// Decode the example certificate from a PEM file into a PEM block
 | 
						|
	pemBlock, _ := pem.Decode([]byte(pemString))
 | 
						|
	if pemBlock == nil {
 | 
						|
		t.Fatal("failed to parse test certificate PEM")
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	// Parse the PEM block into an x509.Certificate
 | 
						|
	result, err := x509.ParseCertificate(pemBlock.Bytes)
 | 
						|
	if err != nil {
 | 
						|
		t.Fatalf("failed to parse test certificate: %v", err)
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return result
 | 
						|
}
 | 
						|
 | 
						|
func TestSet(t *testing.T) {
 | 
						|
	s := NewSet()
 | 
						|
	if !s.Empty() {
 | 
						|
		t.Error("expected a new set to be empty")
 | 
						|
		return
 | 
						|
	}
 | 
						|
	err := s.Allow("xyz")
 | 
						|
	if err == nil || !s.Empty() {
 | 
						|
		t.Error("expected allowing junk to fail")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	err = s.Allow("0011223344")
 | 
						|
	if err == nil || !s.Empty() {
 | 
						|
		t.Error("expected allowing something too short to fail")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	err = s.Allow(expectedHash + expectedHash)
 | 
						|
	if err == nil || !s.Empty() {
 | 
						|
		t.Error("expected allowing something too long to fail")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	err = s.CheckAny([]*x509.Certificate{testCert(t, testCertPEM)})
 | 
						|
	if err == nil {
 | 
						|
		t.Error("expected test cert to not be allowed (yet)")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	err = s.Allow(strings.ToUpper(expectedHash))
 | 
						|
	if err != nil || s.Empty() {
 | 
						|
		t.Error("expected allowing uppercase expectedHash to succeed")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	err = s.CheckAny([]*x509.Certificate{testCert(t, testCertPEM)})
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("expected test cert to be allowed, but got back: %v", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	err = s.CheckAny([]*x509.Certificate{testCert(t, testCert2PEM)})
 | 
						|
	if err == nil {
 | 
						|
		t.Error("expected the second test cert to be disallowed")
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	s = NewSet() // keep set empty
 | 
						|
	hashes := []string{
 | 
						|
		`sha256:0000000000000000000000000000000000000000000000000000000000000000`,
 | 
						|
		`sha256:0000000000000000000000000000000000000000000000000000000000000001`,
 | 
						|
	}
 | 
						|
	err = s.Allow(hashes...)
 | 
						|
	if err != nil || len(s.sha256Hashes) != 2 {
 | 
						|
		t.Error("expected allowing multiple hashes to succeed")
 | 
						|
		return
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestHash(t *testing.T) {
 | 
						|
	actualHash := Hash(testCert(t, testCertPEM))
 | 
						|
	if actualHash != expectedHash {
 | 
						|
		t.Errorf(
 | 
						|
			"failed to Hash() to the expected value\n\texpected: %q\n\t  actual: %q",
 | 
						|
			expectedHash,
 | 
						|
			actualHash,
 | 
						|
		)
 | 
						|
	}
 | 
						|
}
 |