...

Source file src/github.com/sigstore/cosign/v2/test/piv_test.go

Documentation: github.com/sigstore/cosign/v2/test

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

View as plain text