Project 'ale/djrandom-py' was moved to 'ale/djrandom-py-deleted-112'. Please update any links and bookmarks that may still have the old path.
Select Git revision
marsyas_c_utils_wrap.cc
main.go 2.31 KiB
package main
import (
"encoding/base64"
"errors"
"flag"
"fmt"
"log"
"os"
"github.com/duo-labs/webauthn/protocol/webauthncose"
"github.com/fxamacker/cbor/v2"
"github.com/keys-pub/go-libfido2"
"golang.org/x/term"
)
var (
forceDevicePath = flag.String("device", "", "force usage of a specific HID device (default: autodetect)")
username = flag.String("username", os.Getenv("USER"), "username")
rpID = flag.String("rpid", "", "WebAuthN relying party identifier")
)
func readPIN() (string, error) {
fmt.Printf("\rPIN> ")
pw, err := term.ReadPassword(int(os.Stdin.Fd()))
fmt.Printf("\n")
return string(pw), err
}
func fido2ToCOSE(pk []byte) []byte {
var parsed webauthncose.EC2PublicKeyData
parsed.KeyType = int64(webauthncose.EllipticKey)
parsed.Algorithm = int64(webauthncose.AlgES256)
parsed.Curve = 0
parsed.XCoord = pk[:32]
parsed.YCoord = pk[32:]
data, _ := cbor.Marshal(&parsed)
return data
}
func main() {
log.SetFlags(0)
flag.Parse()
if *rpID == "" {
log.Fatal("must specify --rpid")
}
devicePath := *forceDevicePath
if devicePath == "" {
locs, err := libfido2.DeviceLocations()
if err != nil {
log.Fatal("error enumerating devices: %v", err)
}
if len(locs) == 0 {
log.Fatal("error: no FIDO2 devices found")
}
log.Printf("using %s %s", locs[0].Manufacturer, locs[0].Product)
devicePath = locs[0].Path
}
device, err := libfido2.NewDevice(devicePath)
if err != nil {
log.Fatal("error opening device: %v", err)
}
// Generate pseudorandom challenge and user ID.
challenge := libfido2.RandBytes(32)
userID := libfido2.RandBytes(32)
fmt.Println("touch the device (you may be asked for a pin first)......")
var pin string
var attest *libfido2.Attestation
for {
attest, err = device.MakeCredential(
challenge,
libfido2.RelyingParty{
ID: *rpID,
Name: *rpID,
},
libfido2.User{
ID: userID,
Name: *username,
},
libfido2.ES256,
pin,
nil,
)
if errors.Is(err, libfido2.ErrPinRequired) {
pin, err = readPIN()
if err != nil {
log.Fatalf("error reading PIN: %v", err)
}
continue
}
if err != nil {
log.Fatal(err)
}
break
}
fmt.Printf(
"key_handle: \"%s\"\npublic_key: \"%s\"\n",
base64.StdEncoding.EncodeToString(attest.CredentialID),
base64.StdEncoding.EncodeToString(fido2ToCOSE(attest.PubKey)),
)
}