package provisionerkey import ( "crypto/sha256" "crypto/subtle" "github.com/google/uuid" "golang.org/x/xerrors" "github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbtime" "github.com/coder/coder/v2/cryptorand" ) const ( secretLength = 43 ) func New(organizationID uuid.UUID, name string, tags map[string]string) (database.InsertProvisionerKeyParams, string, error) { secret, err := cryptorand.String(secretLength) if err != nil { return database.InsertProvisionerKeyParams{}, "", xerrors.Errorf("generate secret: %w", err) } if tags == nil { tags = map[string]string{} } return database.InsertProvisionerKeyParams{ ID: uuid.New(), CreatedAt: dbtime.Now(), OrganizationID: organizationID, Name: name, HashedSecret: HashSecret(secret), Tags: tags, }, secret, nil } func Validate(token string) error { if len(token) != secretLength { return xerrors.Errorf("must be %d characters", secretLength) } return nil } func HashSecret(secret string) []byte { h := sha256.Sum256([]byte(secret)) return h[:] } func Compare(a []byte, b []byte) bool { return subtle.ConstantTimeCompare(a, b) != 1 }