1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
// Copyright 2021 The Sigstore 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.
//go:build resetyubikey && e2e && !pivkeydisabled
// +build resetyubikey,e2e,!pivkeydisabled
// DANGER
// This test requires a yubikey to be present. It WILL reset the yubikey to exercise functionality.
// DO NOT RUN THIS TEST IF YOU DO NOT WANT TO RESET YOUR YUBIKEY
// This requires the "resetyubikey" tag to be passed to go test.
// See https://docs.sigstore.dev/key_management/hardware-based-tokens/#tested-devices
package test
import (
"context"
"crypto/x509"
"testing"
// Import the functions directly for testing.
. "github.com/sigstore/cosign/v2/cmd/cosign/cli/pivcli"
)
func TestSetManagementKeyCmd(t *testing.T) {
ctx := context.Background()
Confirm = func(_ string) bool { return true }
must(ResetKeyCmd(ctx), t)
// The key should be the default management key so this should fail
mustErr(SetManagementKeyCmd(ctx, "foobar", "newkey", false), t)
must(SetManagementKeyCmd(ctx, "", "newkey", false), t)
// Now it should fail with the wrong key
mustErr(SetManagementKeyCmd(ctx, "", "otherkey", false), t)
// But pass if we use the right key
must(SetManagementKeyCmd(ctx, "newkey", "otherkey", false), t)
// Reset and try a random key too!
must(ResetKeyCmd(ctx), t)
must(SetManagementKeyCmd(ctx, "", "", true), t)
mustErr(SetManagementKeyCmd(ctx, "", "", true), t)
}
func TestSetPUKCmd(t *testing.T) {
ctx := context.Background()
Confirm = func(_ string) bool { return true }
must(ResetKeyCmd(ctx), t)
// The PUK should be the default key so this should fail
mustErr(SetPukCmd(ctx, "11111111", "12121212"), t)
must(SetPukCmd(ctx, "", "12121212"), t)
// Now it should fail with the wrong key
mustErr(SetPukCmd(ctx, "", "43214321"), t)
// But pass if we use the right key
must(SetPukCmd(ctx, "12121212", "43214321"), t)
}
func TestSetPinCmd(t *testing.T) {
ctx := context.Background()
Confirm = func(_ string) bool { return true }
must(ResetKeyCmd(ctx), t)
// The PIN should be the default PIN so this should fail
mustErr(SetPinCmd(ctx, "111111", "222222"), t)
must(SetPinCmd(ctx, "", "222222"), t)
// Now it should fail with the wrong key
mustErr(SetPinCmd(ctx, "333333", "444444"), t)
// But pass if we use the right key
must(SetPinCmd(ctx, "222222", "111111"), t)
}
func TestUnblockCmd(t *testing.T) {
ctx := context.Background()
Confirm = func(_ string) bool { return true }
must(ResetKeyCmd(ctx), t)
// Set a PUK
must(SetPukCmd(ctx, "", "43214321"), t)
// Set the pin to something, then lock the device by trying the wrong one too many times.
must(SetPinCmd(ctx, "", "111111"), t)
for i := 0; i < 5; i++ {
mustErr(SetPinCmd(ctx, "222222", "333333"), t)
}
// Now even with the right PIN it should be stuck
mustErr(SetPinCmd(ctx, "111111", "222222"), t)
// But we can unblock it
must(UnblockCmd(ctx, "43214321", "222222"), t)
must(SetPinCmd(ctx, "222222", "333333"), t)
}
func TestGenerateKeyCmd(t *testing.T) {
ctx := context.Background()
Confirm = func(_ string) bool { return true }
must(ResetKeyCmd(ctx), t)
// This should work with the default key
must(GenerateKeyCmd(ctx, "", false, "", "", ""), t)
// Set the key to something other than the default
must(SetManagementKeyCmd(ctx, "", "mynewkey", false), t)
// Now this should fail
mustErr(GenerateKeyCmd(ctx, "", false, "", "", ""), t)
// Unless we use the right key
must(GenerateKeyCmd(ctx, "mynewkey", false, "", "", ""), t)
// Now if we use a random key it should set a new one
must(GenerateKeyCmd(ctx, "mynewkey", true, "", "", ""), t)
// The old one shouldn't work.
mustErr(GenerateKeyCmd(ctx, "mynewkey", false, "", "", ""), t)
}
func TestAttestationCmd(t *testing.T) {
ctx := context.Background()
Confirm = func(_ string) bool { return true }
must(ResetKeyCmd(ctx), t)
must(GenerateKeyCmd(ctx, "", false, "", "", ""), t)
attestations, err := AttestationCmd(ctx, "")
if err != nil {
t.Fatal(err)
}
root := x509.NewCertPool()
if !root.AppendCertsFromPEM([]byte(yubicoCert)) {
t.Fatal("error adding roots")
}
// Check the device against the manufacturer
if _, err := attestations.DeviceCert.Verify(x509.VerifyOptions{
Roots: root,
}); err != nil {
t.Fatal(err)
}
intermediate := x509.NewCertPool()
intermediate.AddCert(attestations.DeviceCert)
// Now check the key, with the device as a chain
if _, err := attestations.KeyCert.Verify(x509.VerifyOptions{
Roots: root,
Intermediates: intermediate,
}); err != nil {
// This is known to fail on YubiKey firmware 4.3
// See https://labanskoller.se/blog/2019/12/30/pki-is-hard-how-yubico-trusted-openssl-and-got-it-wrong/
//
if attestations.KeyAttestation.Version.Major == 4 &&
attestations.KeyAttestation.Version.Minor == 3 {
t.Skipf("key attestation cert chain verification is known to be broken on firmware 4.3")
} else {
t.Fatal(err)
}
}
}
const yubicoCert = `-----BEGIN CERTIFICATE-----
MIIDFzCCAf+gAwIBAgIDBAZHMA0GCSqGSIb3DQEBCwUAMCsxKTAnBgNVBAMMIFl1
YmljbyBQSVYgUm9vdCBDQSBTZXJpYWwgMjYzNzUxMCAXDTE2MDMxNDAwMDAwMFoY
DzIwNTIwNDE3MDAwMDAwWjArMSkwJwYDVQQDDCBZdWJpY28gUElWIFJvb3QgQ0Eg
U2VyaWFsIDI2Mzc1MTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMN2
cMTNR6YCdcTFRxuPy31PabRn5m6pJ+nSE0HRWpoaM8fc8wHC+Tmb98jmNvhWNE2E
ilU85uYKfEFP9d6Q2GmytqBnxZsAa3KqZiCCx2LwQ4iYEOb1llgotVr/whEpdVOq
joU0P5e1j1y7OfwOvky/+AXIN/9Xp0VFlYRk2tQ9GcdYKDmqU+db9iKwpAzid4oH
BVLIhmD3pvkWaRA2H3DA9t7H/HNq5v3OiO1jyLZeKqZoMbPObrxqDg+9fOdShzgf
wCqgT3XVmTeiwvBSTctyi9mHQfYd2DwkaqxRnLbNVyK9zl+DzjSGp9IhVPiVtGet
X02dxhQnGS7K6BO0Qe8CAwEAAaNCMEAwHQYDVR0OBBYEFMpfyvLEojGc6SJf8ez0
1d8Cv4O/MA8GA1UdEwQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBCwUAA4IBAQBc7Ih8Bc1fkC+FyN1fhjWioBCMr3vjneh7MLbA6kSoyWF70N3s
XhbXvT4eRh0hvxqvMZNjPU/VlRn6gLVtoEikDLrYFXN6Hh6Wmyy1GTnspnOvMvz2
lLKuym9KYdYLDgnj3BeAvzIhVzzYSeU77/Cupofj093OuAswW0jYvXsGTyix6B3d
bW5yWvyS9zNXaqGaUmP3U9/b6DlHdDogMLu3VLpBB9bm5bjaKWWJYgWltCVgUbFq
Fqyi4+JE014cSgR57Jcu3dZiehB6UtAPgad9L5cNvua/IWRmm+ANy3O2LH++Pyl8
SREzU8onbBsjMg9QDiSf5oJLKvd/Ren+zGY7
-----END CERTIFICATE-----`
|