porting all github actions from bluesky-social/indigo to tangled CI
at main 3.2 kB view raw
1package main 2 3import ( 4 "fmt" 5 6 "github.com/bluesky-social/indigo/atproto/crypto" 7 8 "github.com/urfave/cli/v2" 9) 10 11var cmdKey = &cli.Command{ 12 Name: "key", 13 Usage: "sub-commands for cryptographic keys", 14 Subcommands: []*cli.Command{ 15 &cli.Command{ 16 Name: "generate", 17 Usage: "outputs a new secret key", 18 Flags: []cli.Flag{ 19 &cli.StringFlag{ 20 Name: "type", 21 Aliases: []string{"t"}, 22 Usage: "indicate curve type (P-256 is default)", 23 }, 24 &cli.BoolFlag{ 25 Name: "terse", 26 Usage: "print just the secret key, in multikey format", 27 }, 28 }, 29 Action: runKeyGenerate, 30 }, 31 &cli.Command{ 32 Name: "inspect", 33 Usage: "parses and outputs metadata about a public or secret key", 34 ArgsUsage: `<key>`, 35 Action: runKeyInspect, 36 }, 37 }, 38} 39 40func runKeyGenerate(cctx *cli.Context) error { 41 var priv crypto.PrivateKey 42 var privMultibase string 43 switch cctx.String("type") { 44 case "", "P-256", "p256", "ES256", "secp256r1": 45 sec, err := crypto.GeneratePrivateKeyP256() 46 if err != nil { 47 return err 48 } 49 privMultibase = sec.Multibase() 50 priv = sec 51 case "K-256", "k256", "ES256K", "secp256k1": 52 sec, err := crypto.GeneratePrivateKeyK256() 53 if err != nil { 54 return err 55 } 56 privMultibase = sec.Multibase() 57 priv = sec 58 default: 59 return fmt.Errorf("unknown key type: %s", cctx.String("type")) 60 } 61 if cctx.Bool("terse") { 62 fmt.Println(privMultibase) 63 return nil 64 } 65 pub, err := priv.PublicKey() 66 if err != nil { 67 return err 68 } 69 fmt.Printf("Key Type: %s\n", descKeyType(priv)) 70 fmt.Printf("Secret Key (Multibase Syntax): save this securely (eg, add to password manager)\n\t%s\n", privMultibase) 71 fmt.Printf("Public Key (DID Key Syntax): share or publish this (eg, in DID document)\n\t%s\n", pub.DIDKey()) 72 return nil 73} 74 75func descKeyType(val interface{}) string { 76 switch val.(type) { 77 case *crypto.PublicKeyP256, crypto.PublicKeyP256: 78 return "P-256 / secp256r1 / ES256 public key" 79 case *crypto.PrivateKeyP256, crypto.PrivateKeyP256: 80 return "P-256 / secp256r1 / ES256 private key" 81 case *crypto.PublicKeyK256, crypto.PublicKeyK256: 82 return "K-256 / secp256k1 / ES256K public key" 83 case *crypto.PrivateKeyK256, crypto.PrivateKeyK256: 84 return "K-256 / secp256k1 / ES256K private key" 85 default: 86 return "unknown" 87 } 88} 89 90func runKeyInspect(cctx *cli.Context) error { 91 s := cctx.Args().First() 92 if s == "" { 93 return fmt.Errorf("need to provide key as an argument") 94 } 95 96 sec, err := crypto.ParsePrivateMultibase(s) 97 if nil == err { 98 fmt.Printf("Type: %s\n", descKeyType(sec)) 99 fmt.Printf("Encoding: multibase\n") 100 pub, err := sec.PublicKey() 101 if err != nil { 102 return err 103 } 104 fmt.Printf("Public (DID Key): %s\n", pub.DIDKey()) 105 return nil 106 } 107 108 pub, err := crypto.ParsePublicMultibase(s) 109 if nil == err { 110 fmt.Printf("Type: %s\n", descKeyType(pub)) 111 fmt.Printf("Encoding: multibase\n") 112 fmt.Printf("As DID Key: %s\n", pub.DIDKey()) 113 return nil 114 } 115 116 pub, err = crypto.ParsePublicDIDKey(s) 117 if nil == err { 118 fmt.Printf("Type: %s\n", descKeyType(pub)) 119 fmt.Printf("Encoding: DID Key\n") 120 fmt.Printf("As Multibase: %s\n", pub.Multibase()) 121 return nil 122 } 123 return fmt.Errorf("unknown key encoding or type") 124}