Skip to content

Instantly share code, notes, and snippets.

@hazcod
Created August 2, 2021 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hazcod/59af44bc4ad88b43e035ba54ed010c81 to your computer and use it in GitHub Desktop.
Save hazcod/59af44bc4ad88b43e035ba54ed010c81 to your computer and use it in GitHub Desktop.
YubiKey example
package main
import (
"flag"
"fmt"
"github.com/go-piv/piv-go/piv"
conf "github.com/hazcod/sop/config"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"os"
"os/exec"
"strings"
)
func getActiveDevice(filter string, devices []string) (string, error) {
if len(devices) == 0 {
return "", errors.New("no devices detected")
}
if len(devices) == 1 && filter == "" {
return devices[0], nil
}
for _, deviceName := range devices {
if strings.EqualFold(filter, deviceName) {
return deviceName, nil
}
}
return "", errors.Errorf("device not found: '%s'", filter)
}
func addKey(secondsRemaining int, pubKeyPath, privKeyPath string) error {
cmd := exec.Command("ssh-add", "-t", fmt.Sprintf("%d", secondsRemaining), privKeyPath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
if err := cmd.Run(); err != nil {
return errors.Wrap(err, "could not add key into ssh-add")
}
return nil
}
func main() {
configPath := flag.String("config", "", "Path to your config file.")
logLevelStr := flag.String("log", "info", "Log level.")
flag.Parse()
if len(os.Args) < 2 {
logrus.Fatalf("expected a 'new' or 'ssh' command")
}
command := os.Args[1]
logLevel, err := logrus.ParseLevel(*logLevelStr)
if err != nil {
logrus.WithError(err).Fatal("could not parse log level")
}
logrus.SetLevel(logLevel)
logrus.Debugf("log level set to %s", logLevel.String())
config, err := conf.LoadConfig(logrus.StandardLogger(), *configPath)
if err != nil {
logrus.Fatalf("could not load configuration: %s", err)
}
if err := config.Validate(); err != nil {
logrus.WithError(err).Fatal("configuration failed")
}
cardNames, err := piv.Cards()
if err != nil {
logrus.WithError(err).Fatal("could not retrieve security device(s)")
}
logrus.Debugf("devices detected: %+v", cardNames)
deviceName, err := getActiveDevice(config.Device, cardNames)
if err != nil {
logrus.WithError(err).Fatal("could not get device")
}
logrus.Debugf("found device: %s", deviceName)
yubi, err := piv.Open(deviceName)
if err != nil {
logrus.WithError(err).Fatal("could not open security device")
}
defer func(){ _ = yubi.Close() }()
if command == "new" {
key := piv.Key{
Algorithm: piv.AlgorithmEC384,
PINPolicy: piv.PINPolicyOnce,
TouchPolicy: piv.TouchPolicyNever,
}
newPubKey, err := yubi.GenerateKey(piv.DefaultManagementKey, piv.SlotAuthentication, key)
if err != nil {
logrus.WithError(err).Fatal("could not generate new key on the security device")
}
auth := piv.KeyAuth{PIN: piv.DefaultPIN}
if _, err = yubi.PrivateKey(piv.SlotAuthentication, newPubKey, auth); err != nil {
logrus.WithError(err).Fatal("could not generate new private key on the security device")
}
//logrus.Debugf("%s", x509.MarshalPKCS1PublicKey(newPubKey))
logrus.Info("generated new keypair on the security device")
os.Exit(0)
}
if command == "add" {
// TODO
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment