mirror of
https://github.com/gravitational/teleport
synced 2024-10-20 17:23:22 +00:00
Make Hardware Key unit test interactive (#32235)
* Make yubikey unit test interactive and add to test plan. * Move yubikey hardware signer method tests to interactive yubikey test. * Remove hardware key interactive unit test from testplan
This commit is contained in:
parent
eb82a9b5db
commit
f87c46ad73
|
@ -1,5 +1,3 @@
|
|||
//go:build piv
|
||||
|
||||
/*
|
||||
Copyright 2022 Gravitational, Inc.
|
||||
|
||||
|
@ -19,11 +17,9 @@ limitations under the License.
|
|||
package keys_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -31,30 +27,10 @@ import (
|
|||
"github.com/gravitational/teleport/api/utils/keys"
|
||||
)
|
||||
|
||||
// TestHardwareSigner tests the HardwareSigner interface with hardware keys.
|
||||
func TestHardwareSigner(t *testing.T) {
|
||||
// The rest of the test expects a yubiKey to be connected with default PIV settings
|
||||
// and will overwrite any PIV data on the yubiKey.
|
||||
if os.Getenv("TELEPORT_TEST_YUBIKEY_PIV") == "" {
|
||||
t.Skipf("Skipping TestGenerateYubiKeyPrivateKey because TELEPORT_TEST_YUBIKEY_PIV is not set")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
resetYubikey(ctx, t)
|
||||
|
||||
// Generate a new YubiKeyPrivateKey. It should return a valid attestation statement and key policy.
|
||||
priv, err := keys.GetOrGenerateYubiKeyPrivateKey(false)
|
||||
require.NoError(t, err)
|
||||
|
||||
att, err := keys.GetAttestationStatement(priv)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, att)
|
||||
|
||||
policy := keys.GetPrivateKeyPolicy(priv)
|
||||
require.Equal(t, keys.PrivateKeyPolicyHardwareKey, policy)
|
||||
}
|
||||
|
||||
// TestNonHardwareSigner tests the HardwareSigner interface with non-hardware keys.
|
||||
//
|
||||
// HardwareSigners require the piv go tag and should be tested individually in tests
|
||||
// like `TestGetYubiKeyPrivateKey_Interactive`.
|
||||
func TestNonHardwareSigner(t *testing.T) {
|
||||
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/x509/pkix"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
|
@ -28,35 +29,57 @@ import (
|
|||
"github.com/gravitational/teleport/api/utils/prompt"
|
||||
)
|
||||
|
||||
// TestGetOrGenerateYubiKeyPrivateKey tests GetOrGenerateYubiKeyPrivateKey.
|
||||
func TestGetOrGenerateYubiKeyPrivateKey(t *testing.T) {
|
||||
// TestGetYubiKeyPrivateKey_Interactive tests generation and retrieval of YubiKey private keys.
|
||||
func TestGetYubiKeyPrivateKey_Interactive(t *testing.T) {
|
||||
// This test expects a yubiKey to be connected with default PIV
|
||||
// settings and will overwrite any PIV data on the yubiKey.
|
||||
if os.Getenv("TELEPORT_TEST_YUBIKEY_PIV") == "" {
|
||||
t.Skipf("Skipping TestGenerateYubiKeyPrivateKey because TELEPORT_TEST_YUBIKEY_PIV is not set")
|
||||
}
|
||||
|
||||
if !testing.Verbose() {
|
||||
t.Fatal("This test is interactive and must be called with the -v verbose flag to see touch prompts.")
|
||||
}
|
||||
fmt.Println("This test is interactive, tap your YubiKey when prompted.")
|
||||
|
||||
ctx := context.Background()
|
||||
resetYubikey(ctx, t)
|
||||
|
||||
// Generate a new YubiKeyPrivateKey.
|
||||
priv, err := keys.GetOrGenerateYubiKeyPrivateKey(false)
|
||||
require.NoError(t, err)
|
||||
for _, policy := range []keys.PrivateKeyPolicy{
|
||||
keys.PrivateKeyPolicyHardwareKey,
|
||||
keys.PrivateKeyPolicyHardwareKeyTouch,
|
||||
} {
|
||||
t.Run(fmt.Sprintf("policy:%q", policy), func(t *testing.T) {
|
||||
t.Cleanup(func() { resetYubikey(ctx, t) })
|
||||
|
||||
// Test creating a self signed certificate with the key.
|
||||
digest := make([]byte, 32)
|
||||
_, err = priv.Sign(rand.Reader, digest, nil)
|
||||
require.NoError(t, err)
|
||||
// GetYubiKeyPrivateKey should generate a new YubiKeyPrivateKey.
|
||||
priv, err := keys.GetOrGenerateYubiKeyPrivateKey(policy == keys.PrivateKeyPolicyHardwareKeyTouch)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Another call to GetOrGenerateYubiKeyPrivateKey should retrieve the previously generated key.
|
||||
retrievePriv, err := keys.GetOrGenerateYubiKeyPrivateKey(false)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, priv, retrievePriv)
|
||||
// test HardwareSigner methods
|
||||
getPolicy := keys.GetPrivateKeyPolicy(priv)
|
||||
require.Equal(t, policy, getPolicy)
|
||||
|
||||
// parsing the key's private key PEM should produce the same key as well.
|
||||
retrieveKey, err := keys.ParsePrivateKey(priv.PrivateKeyPEM())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, priv, retrieveKey)
|
||||
att, err := keys.GetAttestationStatement(priv)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, att)
|
||||
|
||||
// Test Sign.
|
||||
digest := make([]byte, 32)
|
||||
_, err = priv.Sign(rand.Reader, digest, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Another call to GetYubiKeyPrivateKey should retrieve the previously generated key.
|
||||
retrievePriv, err := keys.GetOrGenerateYubiKeyPrivateKey(policy == keys.PrivateKeyPolicyHardwareKeyTouch)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, priv.Public(), retrievePriv.Public())
|
||||
|
||||
// parsing the key's private key PEM should produce the same key as well.
|
||||
retrievePriv, err = keys.ParsePrivateKey(priv.PrivateKeyPEM())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, priv.Public(), retrievePriv.Public())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverwriteSlot(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue