Live video on the AT Protocol
1package cmd
2
3import (
4 "context"
5 "crypto"
6 "fmt"
7 "os"
8 "strconv"
9
10 "github.com/ThalesGroup/crypto11"
11 "golang.org/x/term"
12 "stream.place/streamplace/pkg/config"
13 "stream.place/streamplace/pkg/crypto/signers"
14 v0 "stream.place/streamplace/pkg/schema/v0"
15
16 "stream.place/streamplace/pkg/crypto/signers/eip712"
17 "stream.place/streamplace/pkg/log"
18)
19
20func createSigner(ctx context.Context, cli *config.CLI) (crypto.Signer, error) {
21 schema, err := v0.MakeV0Schema()
22 if err != nil {
23 return nil, err
24 }
25 eip712signer, err := eip712.MakeEIP712Signer(ctx, &eip712.EIP712SignerOptions{
26 Schema: schema,
27 EthKeystorePath: cli.EthKeystorePath,
28 EthAccountAddr: cli.EthAccountAddr,
29 EthKeystorePassword: cli.EthPassword,
30 })
31 if err != nil {
32 return nil, err
33 }
34 var signer crypto.Signer = eip712signer
35 if cli.PKCS11ModulePath != "" {
36 conf := &crypto11.Config{
37 Path: cli.PKCS11ModulePath,
38 }
39 count := 0
40 for _, val := range []string{cli.PKCS11TokenSlot, cli.PKCS11TokenLabel, cli.PKCS11TokenSerial} {
41 if val != "" {
42 count += 1
43 }
44 }
45 if count != 1 {
46 return nil, fmt.Errorf("need exactly one of pkcs11-token-slot, pkcs11-token-label, or pkcs11-token-serial (got %d)", count)
47 }
48 if cli.PKCS11TokenSlot != "" {
49 num, err := strconv.ParseInt(cli.PKCS11TokenSlot, 10, 16)
50 if err != nil {
51 return nil, fmt.Errorf("error parsing pkcs11-slot: %w", err)
52 }
53 numint := int(num)
54 // why does crypto11 want this as a reference? odd.
55 conf.SlotNumber = &numint
56 }
57 if cli.PKCS11TokenLabel != "" {
58 conf.TokenLabel = cli.PKCS11TokenLabel
59 }
60 if cli.PKCS11TokenSerial != "" {
61 conf.TokenSerial = cli.PKCS11TokenSerial
62 }
63 pin := cli.PKCS11Pin
64 if pin == "" {
65 fmt.Printf("Please enter PKCS11 PIN: ")
66 password, err := term.ReadPassword(int(os.Stdin.Fd()))
67 fmt.Println("")
68 if err != nil {
69 return nil, fmt.Errorf("error reading PKCS11 password: %w", err)
70 }
71 pin = string(password)
72 }
73 conf.Pin = pin
74
75 sc, err := crypto11.Configure(conf)
76 if err != nil {
77 return nil, fmt.Errorf("error initalizing PKCS11 HSM: %w", err)
78 }
79 var id []byte = nil
80 var label []byte = nil
81 if cli.PKCS11KeypairID != "" {
82 num, err := strconv.ParseInt(cli.PKCS11KeypairID, 10, 8)
83 if err != nil {
84 return nil, fmt.Errorf("error parsing pkcs11-keypair-id: %w", err)
85 }
86 id = []byte{byte(num)}
87 }
88 if cli.PKCS11KeypairLabel != "" {
89 label = []byte(cli.PKCS11KeypairLabel)
90 }
91 hwsigner, err := sc.FindKeyPair(id, label)
92 if err != nil {
93 return nil, fmt.Errorf("error finding keypair on PKCS11 token: %w", err)
94 }
95 if hwsigner == nil {
96 return nil, fmt.Errorf("keypair on token not found (tried id='%s' label='%s')", cli.PKCS11KeypairID, cli.PKCS11KeypairLabel)
97 }
98 addr, err := signers.HexAddrFromSigner(hwsigner)
99 if err != nil {
100 return nil, fmt.Errorf("error getting ethereum address for hardware keypair: %w", err)
101 }
102 log.Log(ctx, "successfully initialized hardware signer", "address", addr)
103 signer = hwsigner
104 }
105 return signer, nil
106}