Skip to content

Commit

Permalink
Fix encrypt and decrypt cmds, commit shortened quorum key, allow for …
Browse files Browse the repository at this point in the history
…quorum key override, and allow empty User for decryption
  • Loading branch information
r-n-o committed May 14, 2024
1 parent 906a31d commit c7ebbd6
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 20 deletions.
24 changes: 15 additions & 9 deletions src/cmd/turnkey/pkg/decrypt.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package pkg

import (
"crypto/ecdsa"

"github.com/rotisserie/eris"
"github.com/spf13/cobra"
"github.com/tkhq/go-sdk/pkg/enclave_encrypt"
"github.com/tkhq/go-sdk/pkg/encryptionkey"
)

var (
// Filepath to write the export bundle to.
// Filepath to read the export bundle from.
exportBundlePath string

// EncryptionKeypair is the loaded Encryption Keypair.
Expand All @@ -18,6 +20,7 @@ var (
func init() {
decryptCmd.Flags().StringVar(&exportBundlePath, "export-bundle-input", "", "filepath to read the export bundle from.")
decryptCmd.Flags().StringVar(&plaintextPath, "plaintext-output", "", "optional filepath to write the plaintext from that will be decrypted.")
decryptCmd.Flags().StringVar(&signerPublicKeyOverride, "signer-quorum-key", "", "optional override for the signer quorum key. This option should be used for testing only. Leave this value empty for production decryptions.")

rootCmd.AddCommand(decryptCmd)
}
Expand Down Expand Up @@ -49,13 +52,18 @@ var decryptCmd = &cobra.Command{
OutputError(eris.Wrap(err, "failed to decode encryption private key"))
}

// set up enclave encrypt client
signerPublic, err := hexToPublicKey(signerPublicKey)
var signerKey *ecdsa.PublicKey
if signerPublicKeyOverride != "" {
signerKey, err = hexToPublicKey(signerPublicKeyOverride)
} else {
signerKey, err = hexToPublicKey(signerProductionPublicKey)
}
if err != nil {
OutputError(err)
}

encryptClient, err := enclave_encrypt.NewEnclaveEncryptClientFromTargetKey(signerPublic, *kemPrivateKey)
// set up enclave encrypt client
encryptClient, err := enclave_encrypt.NewEnclaveEncryptClientFromTargetKey(signerKey, *kemPrivateKey)
if err != nil {
OutputError(err)
}
Expand All @@ -81,7 +89,7 @@ var decryptCmd = &cobra.Command{
},
}

// LoadEncryptionKeypair require-loads the keypair referenced by the given name or as referenced form the global KeyName variable, if name is empty.
// LoadEncryptionKeypair require-loads the keypair referenced by the given name or as referenced from the global EncryptionKeyName variable, if name is empty.
func LoadEncryptionKeypair(name string) {
if name == "" {
name = EncryptionKeyName
Expand Down Expand Up @@ -117,8 +125,6 @@ func LoadEncryptionKeypair(name string) {
User = encryptionKey.User
}

// If user is _still_ empty, the encryption key is not usable.
if User == "" {
OutputError(eris.New("failed to associate the encryption key with a user; please manually specify the user ID"))
}
// If user is _still_ empty, the encryption key is still usable in some cases where user ID isn't needed (export)
// Hence we do not error out here if encryptionKey.User is empty.
}
14 changes: 12 additions & 2 deletions src/cmd/turnkey/pkg/encrypt.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pkg

import (
"crypto/ecdsa"
"encoding/hex"
"encoding/json"

Expand All @@ -26,6 +27,9 @@ var (

// Format to apply to the plaintext key before it's encrypted: `mnemonic`, `hexadecimal`, `solana`. Defaults to `mnemonic`.
keyFormat string

// Signer quorum key in hex, uncompressed format
signerPublicKeyOverride string
)

func init() {
Expand All @@ -34,6 +38,7 @@ func init() {
encryptCmd.Flags().StringVar(&plaintextPath, "plaintext-input", "", "filepath to read the plaintext from that will be encrypted.")
encryptCmd.Flags().StringVar(&keyFormat, "key-format", "mnemonic", "optional formatting to apply to the plaintext before it is encrypted.")
encryptCmd.Flags().StringVar(&User, "user", "", "ID of user to encrypting the plaintext.")
encryptCmd.Flags().StringVar(&signerPublicKeyOverride, "signer-quorum-key", "", "optional override for the signer quorum key. This option should be used for testing only. Leave this value empty for production encryptions.")

rootCmd.AddCommand(encryptCmd)
}
Expand Down Expand Up @@ -67,12 +72,17 @@ var encryptCmd = &cobra.Command{
}

// set up enclave encrypt client
signerPublic, err := hexToPublicKey(signerPublicKey)
var signerKey *ecdsa.PublicKey
if signerPublicKeyOverride != "" {
signerKey, err = hexToPublicKey(signerPublicKeyOverride)
} else {
signerKey, err = hexToPublicKey(signerProductionPublicKey)
}
if err != nil {
OutputError(err)
}

encryptClient, err := enclave_encrypt.NewEnclaveEncryptClient(signerPublic)
encryptClient, err := enclave_encrypt.NewEnclaveEncryptClient(signerKey)
if err != nil {
OutputError(err)
}
Expand Down
13 changes: 6 additions & 7 deletions src/cmd/turnkey/pkg/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var (
)

// Turnkey Signer enclave's quorum public key.
const signerPublicKey = "04ca7c0d624c75de6f34af342e87a21e0d8c83efd1bd5b5da0c0177c147f744fba6f01f9f37356f9c617659aafa55f6e0af8d169a8f054d153ab3201901fb63ecb04cf288fe433cc4e1aa0ce1632feac4ea26bf2f5a09dcfe5a42c398e06898710330f0572882f4dbdf0f5304b8fc8703acd69adca9a4bbf7f5d00d20a5e364b2569"
const signerProductionPublicKey = "04cf288fe433cc4e1aa0ce1632feac4ea26bf2f5a09dcfe5a42c398e06898710330f0572882f4dbdf0f5304b8fc8703acd69adca9a4bbf7f5d00d20a5e364b2569"

func init() {
rootCmd.PersistentFlags().StringVarP(&apiKeysDirectory, "keys-folder", "d", local.DefaultAPIKeysDir(), "directory in which to locate API keys")
Expand Down Expand Up @@ -253,10 +253,9 @@ func hexToPublicKey(hexString string) (*ecdsa.PublicKey, error) {
}

// second half is the public key bytes for the enclave quorum encryption key
if len(publicKeyBytes) != 130 {
return nil, eris.New("invalid public key length")
if len(publicKeyBytes) != 65 {
return nil, eris.Errorf("invalid public key length. Expected 65 bytes but got %d (hex string: \"%s\")", len(publicKeyBytes), publicKeyBytes)
}
encryptionPublicKeyBytes := publicKeyBytes[65:130]

// init curve instance
curve := elliptic.P256()
Expand All @@ -265,14 +264,14 @@ func hexToPublicKey(hexString string) (*ecdsa.PublicKey, error) {
byteLen := (curve.Params().BitSize + 7) / 8

// ensure the public key bytes have the correct length
if len(encryptionPublicKeyBytes) != 1+2*byteLen {
if len(publicKeyBytes) != 1+2*byteLen {
return nil, eris.New("invalid encryption public key length")
}

// extract X and Y coordinates from the public key bytes
// ignore first byte (prefix)
x := new(big.Int).SetBytes(encryptionPublicKeyBytes[1 : 1+byteLen])
y := new(big.Int).SetBytes(encryptionPublicKeyBytes[1+byteLen:])
x := new(big.Int).SetBytes(publicKeyBytes[1 : 1+byteLen])
y := new(big.Int).SetBytes(publicKeyBytes[1+byteLen:])

return &ecdsa.PublicKey{
Curve: curve,
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/turnkey/pkg/wallets.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ var walletsCmd = &cobra.Command{
PersistentPreRun: func(cmd *cobra.Command, args []string) {
basicSetup(cmd)
LoadKeypair("")
LoadEncryptionKeypair("")
LoadClient()
LoadEncryptionKeypair("")
},
Aliases: []string{},
}
Expand Down Expand Up @@ -145,7 +145,7 @@ var walletExportCmd = &cobra.Command{
}

if exportBundlePath == "" {
OutputError(eris.New("export bundle path must be specified"))
OutputError(eris.New("--export-bundle-output must be specified"))
}
},
Run: func(cmd *cobra.Command, args []string) {
Expand Down

0 comments on commit c7ebbd6

Please sign in to comment.