package static import ( "context" "testing" "github.com/hashicorp/boundary/internal/credential" "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/kms" wrapping "github.com/hashicorp/go-kms-wrapping/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) const ( TestSshPrivateKeyPem = ` -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACDxfwhEAZKrnsbQxOjVA3PFiB3bW3tSpNKx8TdMiCqlzQAAAJDmpbfr5qW3 6wAAAAtzc2gtZWQyNTUxOQAAACDxfwhEAZKrnsbQxOjVA3PFiB3bW3tSpNKx8TdMiCqlzQ AAAEBvvkQkH06ad2GpX1VVARzu9NkHA6gzamAaQ/hkn5FuZvF/CEQBkquextDE6NUDc8WI Hdtbe1Kk0rHxN0yIKqXNAAAACWplZmZAYXJjaAECAwQ= -----END OPENSSH PRIVATE KEY----- ` TestLargeSshPrivateKeyPem = ` -----BEGIN OPENSSH PRIVATE KEY----- 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 -----END OPENSSH PRIVATE KEY----- ` ) // TestCredentialStore creates a static credential store in the provided DB with // the provided scope and any values passed in through the Options vars. // If any errors are encountered during the creation of the store, the test will fail. func TestCredentialStore(t testing.TB, conn *db.DB, wrapper wrapping.Wrapper, scopeId string, opt ...Option) *CredentialStore { t.Helper() ctx := context.Background() kmsCache := kms.TestKms(t, conn, wrapper) w := db.New(conn) databaseWrapper, err := kmsCache.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase) assert.NoError(t, err) require.NotNil(t, databaseWrapper) cs, err := NewCredentialStore(scopeId, opt...) assert.NoError(t, err) require.NotNil(t, cs) opts := getOpts(opt...) id := opts.withPublicId if id == "" { id, err = newCredentialStoreId(ctx) assert.NoError(t, err) require.NotEmpty(t, id) } cs.PublicId = id _, err2 := w.DoTx(ctx, db.StdRetryCnt, db.ExpBackoff{}, func(_ db.Reader, iw db.Writer) error { require.NoError(t, iw.Create(ctx, cs)) return nil }, ) require.NoError(t, err2) return cs } // TestCredentialStores creates count number of static credential stores in // the provided DB with the provided scope id. If any errors are // encountered during the creation of the credential stores, the test will // fail. func TestCredentialStores(t testing.TB, conn *db.DB, wrapper wrapping.Wrapper, scopeId string, count int) []*CredentialStore { t.Helper() ctx := context.Background() kmsCache := kms.TestKms(t, conn, wrapper) databaseWrapper, err := kmsCache.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase) assert.NoError(t, err) require.NotNil(t, databaseWrapper) css := make([]*CredentialStore, 0, count) for i := 0; i < count; i++ { css = append(css, TestCredentialStore(t, conn, wrapper, scopeId)) } return css } // TestUsernamePasswordCredential creates a username password credential in the provided DB with // the provided scope and any values passed in through. // If any errors are encountered during the creation of the store, the test will fail. func TestUsernamePasswordCredential( t testing.TB, conn *db.DB, wrapper wrapping.Wrapper, username, password, storeId, scopeId string, opt ...Option, ) *UsernamePasswordCredential { t.Helper() ctx := context.Background() kmsCache := kms.TestKms(t, conn, wrapper) w := db.New(conn) opts := getOpts(opt...) databaseWrapper, err := kmsCache.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase) assert.NoError(t, err) require.NotNil(t, databaseWrapper) cred, err := NewUsernamePasswordCredential(storeId, username, credential.Password(password), opt...) require.NoError(t, err) require.NotNil(t, cred) id := opts.withPublicId if id == "" { id, err = credential.NewUsernamePasswordCredentialId(ctx) require.NoError(t, err) } cred.PublicId = id err = cred.encrypt(ctx, databaseWrapper) require.NoError(t, err) _, err2 := w.DoTx(ctx, db.StdRetryCnt, db.ExpBackoff{}, func(_ db.Reader, iw db.Writer) error { require.NoError(t, iw.Create(ctx, cred)) return nil }, ) require.NoError(t, err2) return cred } // TestUsernamePasswordCredentials creates count number of username password credentials in // the provided DB with the provided scope id. If any errors are // encountered during the creation of the credentials, the test will fail. func TestUsernamePasswordCredentials( t testing.TB, conn *db.DB, wrapper wrapping.Wrapper, username, password, storeId, scopeId string, count int, ) []*UsernamePasswordCredential { t.Helper() ctx := context.Background() kmsCache := kms.TestKms(t, conn, wrapper) databaseWrapper, err := kmsCache.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase) assert.NoError(t, err) require.NotNil(t, databaseWrapper) creds := make([]*UsernamePasswordCredential, 0, count) for i := 0; i < count; i++ { creds = append(creds, TestUsernamePasswordCredential(t, conn, wrapper, username, password, storeId, scopeId)) } return creds } // TestSshPrivateKeyCredential creates an ssh private key credential in the // provided DB with the provided scope and any values passed in through. If any // errors are encountered during the creation of the store, the test will fail. func TestSshPrivateKeyCredential( t testing.TB, conn *db.DB, wrapper wrapping.Wrapper, username, privateKey, storeId, scopeId string, opt ...Option, ) *SshPrivateKeyCredential { t.Helper() ctx := context.Background() kmsCache := kms.TestKms(t, conn, wrapper) w := db.New(conn) opts := getOpts(opt...) databaseWrapper, err := kmsCache.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase) assert.NoError(t, err) require.NotNil(t, databaseWrapper) cred, err := NewSshPrivateKeyCredential(ctx, storeId, username, credential.PrivateKey(privateKey), opt...) require.NoError(t, err) require.NotNil(t, cred) id := opts.withPublicId if id == "" { id, err = credential.NewSshPrivateKeyCredentialId(ctx) require.NoError(t, err) } cred.PublicId = id err = cred.encrypt(ctx, databaseWrapper) require.NoError(t, err) _, err2 := w.DoTx(ctx, db.StdRetryCnt, db.ExpBackoff{}, func(_ db.Reader, iw db.Writer) error { require.NoError(t, iw.Create(ctx, cred)) return nil }, ) require.NoError(t, err2) return cred } // TestSshPrivateKeyCredentials creates count number of ssh private key // credentials in the provided DB with the provided scope id. If any errors are // encountered during the creation of the credentials, the test will fail. func TestSshPrivateKeyCredentials( t testing.TB, conn *db.DB, wrapper wrapping.Wrapper, username, privateKey, storeId, scopeId string, count int, ) []*SshPrivateKeyCredential { t.Helper() ctx := context.Background() kmsCache := kms.TestKms(t, conn, wrapper) databaseWrapper, err := kmsCache.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase) assert.NoError(t, err) require.NotNil(t, databaseWrapper) creds := make([]*SshPrivateKeyCredential, 0, count) for i := 0; i < count; i++ { creds = append(creds, TestSshPrivateKeyCredential(t, conn, wrapper, username, privateKey, storeId, scopeId)) } return creds }