diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index c234f1d8..9a784633 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -52,7 +52,7 @@ jobs:
go-version: 1.19
check-latest: true
- - name: Test Sign and Verify commit
+ - name: Install Gitsign
run: |
set -e
@@ -72,6 +72,9 @@ jobs:
# Verify tool is on our path
gitsign -h
+ - name: Test Sign and Verify commit
+ run: |
+ set -e
# Sign commit
git commit --allow-empty -S --message="Signed commit"
@@ -79,6 +82,21 @@ jobs:
# Verify commit
git verify-commit HEAD
+ # Extra debug info
+ git cat-file commit HEAD | sed -n '/BEGIN/, /END/p' | sed 's/^ //g' | sed 's/gpgsig //g' | sed 's/SIGNED MESSAGE/PKCS7/g' | openssl pkcs7 -print -print_certs -text
+ - name: Test Timestamped Commit
+ env:
+ # See https://knowledge.digicert.com/generalinformation/INFO4231.html
+ GITSIGN_TIMESTAMP_AUTHORITY: "http://timestamp.digicert.com"
+ run: |
+ set -e
+
+ # Sign commit
+ git commit --allow-empty -S --message="Signed timestamp commit"
+
+ # Verify commit
+ git verify-commit HEAD
+
# Extra debug info
git cat-file commit HEAD | sed -n '/BEGIN/, /END/p' | sed 's/^ //g' | sed 's/gpgsig //g' | sed 's/SIGNED MESSAGE/PKCS7/g' | openssl pkcs7 -print -print_certs -text
- name: Debug log
diff --git a/README.md b/README.md
index 01efc0e5..016446ba 100644
--- a/README.md
+++ b/README.md
@@ -58,28 +58,30 @@ $ git config --local gitsign.fulcio https://fulcio.example.com
The following config options are supported:
-| Option | Default | Description |
-| ----------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| fulcio | https://fulcio.sigstore.dev | Address of Fulcio server |
-| logPath | | Path to log status output. Helpful for debugging when no TTY is available in the environment. |
-| clientID | sigstore | OIDC client ID for application |
-| issuer | https://oauth2.sigstore.dev/auth | OIDC provider to be used to issue ID token |
-| redirectURL | | OIDC Redirect URL |
-| rekor | https://rekor.sigstore.dev | Address of Rekor server |
-| connectorID | | Optional Connector ID to auto-select to pre-select auth flow to use. For the public sigstore instance, valid values are:
- `https://github.com/login/oauth`
- `https://accounts.google.com`
- `https://login.microsoftonline.com` |
+| Option | Default | Description |
+| ------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| fulcio | https://fulcio.sigstore.dev | Address of Fulcio server |
+| logPath | | Path to log status output. Helpful for debugging when no TTY is available in the environment. |
+| clientID | sigstore | OIDC client ID for application |
+| issuer | https://oauth2.sigstore.dev/auth | OIDC provider to be used to issue ID token |
+| redirectURL | | OIDC Redirect URL |
+| rekor | https://rekor.sigstore.dev | Address of Rekor server |
+| connectorID | | Optional Connector ID to auto-select to pre-select auth flow to use. For the public sigstore instance, valid values are:
- `https://github.com/login/oauth`
- `https://accounts.google.com`
- `https://login.microsoftonline.com` |
+| timestampAuthority | | Optional address of timestamping authority. If set, a trusted timestamp will be included in the signature. |
### Environment Variables
-| Environment Variable | Sigstore
Prefix | Default | Description |
-| ------------------------- | ------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| GITSIGN_CREDENTIAL_CACHE | ❌ | | Optional path to [gitsign-credential-cache](cmd/gitsign-credential-cache/README.md) socket. |
-| GITSIGN_CONNECTOR_ID | ✅ | | Optional Connector ID to auto-select to pre-select auth flow to use. For the public sigstore instance, valid values are:
- `https://github.com/login/oauth`
- `https://accounts.google.com`
- `https://login.microsoftonline.com` |
-| GITSIGN_FULCIO_URL | ✅ | https://fulcio.sigstore.dev | Address of Fulcio server |
-| GITSIGN_LOG | ❌ | | Path to log status output. Helpful for debugging when no TTY is available in the environment. |
-| GITSIGN_OIDC_CLIENT_ID | ✅ | sigstore | OIDC client ID for application |
-| GITSIGN_OIDC_ISSUER | ✅ | https://oauth2.sigstore.dev/auth | OIDC provider to be used to issue ID token |
-| GITSIGN_OIDC_REDIRECT_URL | ✅ | | OIDC Redirect URL |
-| GITSIGN_REKOR_URL | ✅ | https://rekor.sigstore.dev | Address of Rekor server |
+| Environment Variable | Sigstore
Prefix | Default | Description |
+| --------------------------- | ------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| GITSIGN_CREDENTIAL_CACHE | ❌ | | Optional path to [gitsign-credential-cache](cmd/gitsign-credential-cache/README.md) socket. |
+| GITSIGN_CONNECTOR_ID | ✅ | | Optional Connector ID to auto-select to pre-select auth flow to use. For the public sigstore instance, valid values are:
- `https://github.com/login/oauth`
- `https://accounts.google.com`
- `https://login.microsoftonline.com` |
+| GITSIGN_FULCIO_URL | ✅ | https://fulcio.sigstore.dev | Address of Fulcio server |
+| GITSIGN_LOG | ❌ | | Path to log status output. Helpful for debugging when no TTY is available in the environment. |
+| GITSIGN_OIDC_CLIENT_ID | ✅ | sigstore | OIDC client ID for application |
+| GITSIGN_OIDC_ISSUER | ✅ | https://oauth2.sigstore.dev/auth | OIDC provider to be used to issue ID token |
+| GITSIGN_OIDC_REDIRECT_URL | ✅ | | OIDC Redirect URL |
+| GITSIGN_REKOR_URL | ✅ | https://rekor.sigstore.dev | Address of Rekor server |
+| GITSIGN_TIMESTAMP_AUTHORITY | ✅ | | Optional address of timestamping authority. If set, a trusted timestamp will be included in the signature. |
For environment variables that support `Sigstore Prefix`, the values may be
provided with either a `GITSIGN_` or `SIGSTORE_` prefix - e.g.
diff --git a/command_sign.go b/command_sign.go
index 808af45b..5501c419 100644
--- a/command_sign.go
+++ b/command_sign.go
@@ -63,7 +63,7 @@ func commandSign(cfg *config.Config) error {
sig, cert, err := git.Sign(ctx, rekor, userIdent, dataBuf.Bytes(), signature.SignOptions{
Detached: *detachSignFlag,
- TimestampAuthority: *tsaOpt,
+ TimestampAuthority: cfg.TimestampAuthority,
Armor: *armorFlag,
IncludeCerts: *includeCertsOpt,
})
diff --git a/internal/config/config.go b/internal/config/config.go
index b4061a39..10e96228 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -48,6 +48,9 @@ type Config struct {
// for more details.
ConnectorID string
+ // Timestamp Authority address to use to get a trusted timestamp
+ TimestampAuthority string
+
// Path to log status output. Helpful for debugging when no TTY is available in the environment.
LogPath string
}
@@ -83,6 +86,7 @@ func Get() (*Config, error) {
out.RedirectURL = envOrValue(fmt.Sprintf("%s_OIDC_REDIRECT_URL", prefix), out.RedirectURL)
out.Issuer = envOrValue(fmt.Sprintf("%s_OIDC_ISSUER", prefix), out.Issuer)
out.ConnectorID = envOrValue(fmt.Sprintf("%s_CONNECTOR_ID", prefix), out.ConnectorID)
+ out.TimestampAuthority = envOrValue(fmt.Sprintf("%s_TIMESTAMP_AUTHORITY", prefix), out.TimestampAuthority)
}
out.LogPath = envOrValue("GITSIGN_LOG", out.LogPath)
diff --git a/internal/signature/sign.go b/internal/signature/sign.go
index ca5fe4c1..e48486d6 100644
--- a/internal/signature/sign.go
+++ b/internal/signature/sign.go
@@ -90,13 +90,13 @@ func Sign(ident Identity, body []byte, opts SignOptions) ([]byte, *x509.Certific
chain, err := ident.CertificateChain()
if err != nil {
- return nil, nil, fmt.Errorf("failed to get idenity certificate chain: %w", err)
+ return nil, nil, fmt.Errorf("failed to get identity certificate chain: %w", err)
}
// TODO: look into adding back support for opts.IncludeCerts here.
// This was removed due to unstable ordering in the cert chain when
// intermediates were included.
if chain, err = certsForSignature(chain, 1); err != nil {
- return nil, nil, err
+ return nil, nil, fmt.Errorf("failed to extract certificates from chain: %w", err)
}
if err := sd.SetCertificates(chain); err != nil {
return nil, nil, fmt.Errorf("failed to set certificates: %w", err)
diff --git a/main.go b/main.go
index 507a8631..ca93012a 100644
--- a/main.go
+++ b/main.go
@@ -20,6 +20,7 @@ import (
"fmt"
"io"
"os"
+ "runtime/debug"
"github.com/mattn/go-tty"
"github.com/pborman/getopt/v2"
@@ -29,11 +30,6 @@ import (
"github.com/sigstore/gitsign/internal/config"
)
-const (
- // TODO: Use fulcio as timestamp authority.
- defaultTSA = ""
-)
-
var (
// Action flags
helpFlag = getopt.BoolLong("help", 'h', "print this help message")
@@ -46,7 +42,6 @@ var (
detachSignFlag = getopt.BoolLong("detach-sign", 'b', "make a detached signature")
armorFlag = getopt.BoolLong("armor", 'a', "create ascii armored output")
statusFdOpt = getopt.IntLong("status-fd", 0, -1, "write special status strings to the file descriptor n.", "n")
- tsaOpt = getopt.StringLong("timestamp-authority", 't', defaultTSA, "URL of RFC3161 timestamp authority to use for timestamping", "url")
includeCertsOpt = getopt.IntLong("include-certs", 0, -2, "-3 is the same as -2, but ommits issuer when cert has Authority Information Access extension. -2 includes all certs except root. -1 includes all certs. 0 includes no certs. 1 includes leaf cert. >1 includes n from the leaf. Default -2.", "n")
// Remaining arguments
@@ -104,7 +99,7 @@ func wrapIO(cfg *config.Config, fn func(*config.Config) error) error {
// Log any panics to ttyout, since otherwise they will be lost to os.Stderr.
defer func() {
if r := recover(); r != nil {
- fmt.Fprintln(ttyout, r)
+ fmt.Fprintln(ttyout, string(debug.Stack()), r)
}
}()