/
main.go
91 lines (84 loc) · 2.01 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package main
import (
"crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa"
"fmt"
"io"
"os"
virtual_fido "github.com/bulwarkid/virtual-fido"
"github.com/bulwarkid/virtual-fido/cose"
"github.com/spf13/cobra"
"golang.org/x/crypto/ssh"
)
var keyFilename string
func start(cmd *cobra.Command, args []string) {
if keyFilename == "" {
fmt.Println("No key specified")
return
}
keyFile, err := os.Open(keyFilename)
if err != nil {
fmt.Println("Could not find key file")
return
}
defer keyFile.Close()
keyBytes, err := io.ReadAll(keyFile)
if err != nil {
fmt.Println("Could not read key file")
return
}
key, err := ssh.ParseRawPrivateKey(keyBytes)
coseKey := cose.SupportedCOSEPrivateKey{}
if ecdsaKey, ok := key.(*ecdsa.PrivateKey); ok {
coseKey.ECDSA = ecdsaKey
} else if ed25519Key, ok := key.(*ed25519.PrivateKey); ok {
coseKey.Ed25519 = ed25519Key
} else if rsaKey, ok := key.(*rsa.PrivateKey); ok {
coseKey.RSA = rsaKey
} else {
fmt.Println("Unsupported key format. This application only supports ECDSA, Ed25519, and RSA private keys.")
return
}
client := NewSSHFIDOClient(&coseKey)
virtual_fido.SetLogOutput(os.Stdout)
done := make(chan bool)
go func() {
virtual_fido.Start(client)
done <- true
}()
go func() {
prog := usbipCommand()
prog.Stdin = os.Stdin
prog.Stdout = os.Stdout
prog.Stderr = os.Stderr
err := prog.Run()
if err != nil {
fmt.Printf("Error: %s\n", err)
}
done <- true
}()
<-done
<-done
}
var rootCmd = &cobra.Command{
Use: "ssh_passkey",
Short: "Create a FIDO authenticator using an SSH key",
Long: `ssh_passkey allows you to use your SSH key for the keys in CTAP2 for WebAuthN/Passkeys`,
}
func init() {
start := &cobra.Command{
Use: "start",
Short: "Start up FIDO device",
Run: start,
}
rootCmd.PersistentFlags().StringVar(&keyFilename, "key", "", "SSH private key to use")
rootCmd.MarkFlagRequired("key")
rootCmd.AddCommand(start)
}
func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}