Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use git config to read tsa server and include-certs #64

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ language: go

go:
- 1.12.x
- 1.13.x
- 1.14.x
- 1.x
- master

git:
depth: false

install: ''
install:
- brew install libgit2

script:
- GIT_VERSION=$(git describe --tags)
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,32 @@ You can download prebuilt Windows binaries [here](https://github.com/github/smim
- You'll probably want to put `$GOPATH/bin` on your `$PATH`.
- Run `go get github.com/github/smimesign`

## Standalone usage

```sh
$ smimesign --help
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

Usage: smimesign [-abhsv] [--include-certs n] [--keyid-format {long}] [--list-keys] [--status-fd n] [-t url] [-u USER-ID] [--verify] [files]
-a, --armor create ascii armored output
-b, --detach-sign make a detached signature
-h, --help print this help message
--include-certs=n -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.
--keyid-format={long} select how to display key IDs.
--list-keys show keys
-s, --sign make a signature
--status-fd=n write special status strings to the file
descriptor n.
-t, --timestamp-authority=url URL of RFC3161 timestamp authority to
use for timestamping
-u, --local-user=USER-ID use USER-ID to sign
--verify verify a signature
-v, --version print the version number
```

## Configuring Git

Git needs to be told to sign commits and tags using smimesign instead of GnuPG. This can be configured on a global or per-repository level. The Git configuration directives for changing signing tools was changed in version 2.19.
Expand Down Expand Up @@ -96,6 +122,15 @@ $ git config --get user.email
$ smimesign --list-keys
```

**Add smimesign options**

Currently only `tsa` and `include-certs` options are supported.

```bash
$ git config --global gpg.x509.smimesign.timestamp-authority http://timestamp.digicert.com
$ git config --global gpg.x509.smimesign.include-certs -1
bufferoverflow marked this conversation as resolved.
Show resolved Hide resolved
```

## Smart cards (PIV/CAC/Yubikey)

Many large organizations and government agencies distribute certificates and keys to end users via smart cards. These cards allow applications on the user's computer to use private keys for signing or encryption without giving them the ability to export those keys. The native certificate stores on both Windows and macOS can talk to smart cards, though special drivers or middleware may be required.
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.12
require (
github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261
github.com/davecgh/go-spew v1.1.1
github.com/libgit2/git2go/v30 v30.0.1
github.com/github/certstore v0.1.0
github.com/github/fakeca v0.1.0
github.com/github/ietf-cms v0.1.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEex
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/libgit2/git2go/v30 v30.0.1 h1:uvQkdor2u7WKG9p8vAZNWFRlhQx/OxRinj8ucydrTJ4=
github.com/libgit2/git2go/v30 v30.0.1/go.mod h1:YReiQ7xhMoyAL4ISYFLZt+OGqn6xtLqvTC1xJ9oAH7Y=
github.com/github/certstore v0.1.0 h1:oZF2PcqgBo6YNp7gCUDfF6vP9c0kTxh5VhUNrW6d2wc=
github.com/github/certstore v0.1.0/go.mod h1:Sgb3YVYOB2iCO06NJ6We5gjXe7uxxM3zPYoEXjuTKno=
github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I=
Expand Down
21 changes: 21 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"os"

git "github.com/libgit2/git2go/v30"
"github.com/github/certstore"
"github.com/pborman/getopt/v2"
"github.com/pkg/errors"
Expand Down Expand Up @@ -72,6 +73,26 @@ func runCommand() error {
return nil
}

// read tsa and include-certs from gitconfig
path, err := os.Getwd()
if err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we want to "fail open" here and not return if an error is returned?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read tsa and include-cert should be optional, so just use the defaults if these are not defined within git config

repo, err := git.OpenRepository(path)
if err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question about failing open. The idiom used throughout is err != nil and returning an error. Is the idea here that we may not be in a repo and hence shouldn't fail? I'm not sure if the libgit2 bindings have helpers for this..but if we determine we aren't in a repo and/or there is no .gitconfig for that repo, wouldn't the most idiomatic thing be to check the user global and then system .gitconfig instead?

config, err := repo.Config()

tsa, err := config.LookupString("gpg.x509.smimesign.timestamp-authority")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do we get from LookupString if the config value isn't set? Do we get an empty string (i.e. we match the default value)?

if err == nil {
tsaOpt = &tsa
}

includeCerts32, err := config.LookupInt32("gpg.x509.smimesign.include-certs")
if err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here..if no such setting is set..do we get 0 here?

var includeCerts int = int(includeCerts32)
includeCertsOpt = &includeCerts
}
}
}

// Open certificate store
store, err := certstore.Open()
if err != nil {
Expand Down