karmada/pkg/util/lifted/pubkeypin/pubkeypin_test.go

177 lines
6.4 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:3072 -days 36500 -nodes -x509 -keyout /dev/null -out test.crt
const testCertPEM = `
-----BEGIN CERTIFICATE-----
MIIEbTCCAtWgAwIBAgIULwXa4OSKT/GklPt0JMn2GUZYClMwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0yNDA1MjAwMjIzNTdaGA8yMTI0
MDQyNjAyMjM1N1owRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCAaIwDQYJKoZIhvcN
AQEBBQADggGPADCCAYoCggGBAMXIMrjc7AKSa1Q/gmJzyXUwg0CNtmbWwz9cxWW3
5DYxRsirnOc9EVMMI6hSl9k1dOh8DQ1uIZLM8EHtSol7o/CP3MCBT6SkaniXpFON
UUZkKY3Yo7t8AOcuRoLRrnye2YrpQOEQ8eb+dXnzibFrJuSw6fXBoXdutmaWWMmN
XPICC1s8l/GxT7jjvm7Y5iVFq+sZco/qxv1ZeBNmUcWWXEtT2KppCBRXk/23OcV2
fvCDS/3bUIgeBxphUnASv8r5W5orbtl/HGgn/uv7LyYDVVWgYVxXuXaW6blc+oLB
bFbiPlfg7EIrcbkV1qBl9SesMPrp8lQH3+PEMCxF6Q0kxDfJteiIUQsWhmyV6/VA
t7XVIU0Dl99zN7WoZLsstjI9/7b+TjBqMRWVTtoAeHMzH9lLx75rTUfAXzcM2Zpy
AsEmlNXzcysyTgqhZg1bQwbHZVzH3ctfMxw/DDzpvyhPfHM5eQp06HPSMhv0v4uZ
pz3mNOxCffRxj4A1v9pWn0YyoQIDAQABo1MwUTAdBgNVHQ4EFgQUvBTsnQ7yih79
Jz7d0VZmSvAnRWAwHwYDVR0jBBgwFoAUvBTsnQ7yih79Jz7d0VZmSvAnRWAwDwYD
VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAYEAoR0w2y1v4QlE4rQ+LPAi
Am576mClL5gCpSEdBP32htSJOEz4VHeUn/zpGWoO6ezEeMOqosuax2LP2sv62zOj
OyYXxZ6uBV6jz+hvpufgIqnFj9sRckS6wXsDb726fOaKvv1PCdQUQPMgF9sX3vQD
YeWqg0ga1OGfeXdJMdS2AmTidR0m83EIE1PvX2nddhh1xOC0XCoUuwv/O8aSvfqg
iBBDZt0FFMlkSsSkNwbYylmaY0MR11bMCx6OZTCQ43zkcxg9k8ItvxOvSkRjfTlh
QaPa/qIkto4XQCrTHPcMRVSYfIFOi5hpiwXVuC1T/uFDKqvhGAijGX8xTi/FYJV6
Bgm0D8TXpEBqhvS7Fkf9mUdOF8FenGhJrJtY8jqCCsietGC6tuabl0tFVgDV+6nu
0sQVRzYWcvk/21vps+LiO/+EifDbq8KpmEALOWp59kZPYalLmFlyavXHNlpxd9Tm
sOVrkbwM/dtdTqzqQ6YW2uRGfTfmb3pfOBN4H6kiu6RD
-----END CERTIFICATE-----`
// expectedHash can be verified using the openssl CLI.
const expectedHash = `sha256:d597b45a039e09054649e094dc3da2997475827404cf67a886459724c4e35d38`
// testCert2PEM is a second test cert generated the same way as testCertPEM
const testCert2PEM = `
-----BEGIN CERTIFICATE-----
MIIEbTCCAtWgAwIBAgIULEFzXomJO9a0Tv+pC6/7L6voZjEwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0yNDA1MjAwMjI1MzRaGA8yMTI0
MDQyNjAyMjUzNFowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCAaIwDQYJKoZIhvcN
AQEBBQADggGPADCCAYoCggGBANJPAabiDP66oTZGPajoAtwbJKCpixekZdGX4xlO
X+ymnVeKuawiX/pXQB0ZMg0imQ1KgUTNdHzVJzuPtkJDeGvAwGzgPBFrM3XjUs+1
kl2KlG9WEqLViF/J0NjPDCAJRgQNor0ycjiHSr5dg9QlrCduuaro3SCNfT4xuci7
k2UHxzFhguYXn+Ef+6ZqdtsM9x8aQhWa2Aw3I1yEuOSKT8HmcDkYyeI4XaI299Gz
LFz4+lR72jkAJRA2Dk5pKBwYJz8i3Wmr6wyXUizlSly3796tUMfzgXxnNkCRXaLz
4uiqUatnmCd1/pZ47I4oSUCCjj7Mq7EFfKFmXfCoaXAfNGxMdYtwjl299h2PtKKU
wlBwv1BUJICWkJ+OyB3Tv9YuZqNWoYY2x4qPV3/QWaUgtv5/LKdYR6Ivzc4gwMJD
PWjpb27KtnKrlw6VwrrjfyMEDVkVkibXJWAnoJv0KJ275rIre5vQH4DKFC0isfNR
sLVOKfiyWudqIVFiVDUCufDnPQIDAQABo1MwUTAdBgNVHQ4EFgQU14xkgPnKLiqe
gS/blBgvJTc8qO8wHwYDVR0jBBgwFoAU14xkgPnKLiqegS/blBgvJTc8qO8wDwYD
VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAYEAFf4Fc5ScyZMqkcoVuYvh
1WISAbM6k+5aHX/KA+Br35Zxh4B3s+NGGG48RXVt4xMs/x9fCU1OpWKLiAzJwSBM
hFidIBshCrrVnVKy+ws1tOAcw4f21k5n0S/Sw+uYWNpamcpD7X3kFpTMIzYGdO5c
hffYHQ+oP3tQTD9GMuNVAlagrMqabk6JZXz36ow+aPASdnCjrA0WpuQ+XeldGc+N
4hfU6rTKdFO8Uu9iaMgd5tFlZdIYEBP+wJ9APKtjjwuolsKcQKaHHLorMnNXO5Ct
TA7YgpW7oic1AMtmD+Z+ucT9OpGHEXQa4TEtmr0fiEAUFjwcwyy7LO7x18buUPt4
Rzq+T+QEdf3BmBL4p5ArKyLcOeZNK4MjPbbjKYnibJBGDYgtrz7GLgF//P4S4/lP
0lmm5cBxIDEaeE6WjQZUrx+TvJFIQ8GTu0vG8h7JDKqO6UbBL8OAMZ2fO9iPXlYH
0EZLIWXX1p8W8w7+dmr0CGpLdascEdxXkf/XYIsAP68K
-----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,
)
}
}