Renamed DecryptSign -> SSHSignWith, added tests for SSHSignWith and Usages

This commit is contained in:
Andrew Buss
2015-12-05 23:17:06 -08:00
committed by Kyle Isom
parent 4571399c6f
commit 186092a44e
6 changed files with 248 additions and 13 deletions

View File

@@ -254,14 +254,14 @@ func (c *RemoteServer) Decrypt(req core.DecryptRequest) (*core.ResponseData, err
}
// DecryptSign issues an decrypt-sign request to the remote server
func (c *RemoteServer) DecryptSign(req core.DecryptSignRequest) (*core.ResponseData, error) {
// SSHSignWith issues an SSH-sign-with request to the remote server
func (c *RemoteServer) SSHSignWith(req core.SSHSignWithRequest) (*core.ResponseData, error) {
reqBytes, err := json.Marshal(req)
if err != nil {
return nil, err
}
respBytes, err := c.doAction("decrypt-sign", reqBytes)
respBytes, err := c.doAction("ssh-sign-with", reqBytes)
if err != nil {
return nil, err
}

View File

@@ -29,14 +29,14 @@ func (signer ROSigner) PublicKey() ssh.PublicKey {
}
func (signer ROSigner) Sign(rand io.Reader, msg []byte) (signature *ssh.Signature, err error) {
req := core.DecryptSignRequest{
req := core.SSHSignWithRequest{
Name: signer.user,
Password: signer.pswd,
Data: signer.encryptedKey,
TBSData: msg,
}
resp, err := signer.server.DecryptSign(req)
resp, err := signer.server.SSHSignWith(req)
if err != nil {
return nil, err
}
@@ -45,14 +45,12 @@ func (signer ROSigner) Sign(rand io.Reader, msg []byte) (signature *ssh.Signatur
return nil, errors.New("response status error")
}
var respMsg core.DecryptSignWithDelegates
var respMsg core.SSHSignatureWithDelegates
err = json.Unmarshal(resp.Response, &respMsg)
if err != nil {
return nil, err
}
respSignature := ssh.Signature{Format: respMsg.SignatureFormat, Blob: respMsg.Signature}
return &respSignature, nil
return &respMsg.Signature, nil
}
type ROAgent struct {

View File

@@ -16,6 +16,7 @@ import (
"github.com/cloudflare/redoctober/config"
"github.com/cloudflare/redoctober/passvault"
"github.com/cloudflare/redoctober/persist"
"golang.org/x/crypto/ssh"
)
func tempName(t *testing.T) string {
@@ -445,6 +446,8 @@ func TestEncryptDecrypt(t *testing.T) {
encryptJson := []byte("{\"Name\":\"Carol\",\"Password\":\"Hello\",\"Minimum\":2,\"Owners\":[\"Alice\",\"Bob\",\"Carol\"],\"Data\":\"SGVsbG8gSmVsbG8=\"}")
encryptJson2 := []byte("{\"Name\":\"Alice\",\"Password\":\"Hello\",\"Minimum\":2,\"Owners\":[\"Alice\",\"Bob\",\"Carol\"],\"Data\":\"SGVsbG8gSmVsbG8=\",\"Labels\":[\"blue\",\"red\"]}")
encryptJson3 := []byte("{\"Name\":\"Alice\",\"Password\":\"Hello\",\"Minimum\":1,\"Owners\":[\"Alice\"],\"Data\":\"SGVsbG8gSmVsbG8=\"}")
encryptJson4 := []byte("{\"Name\":\"Alice\",\"Password\":\"Hello\",\"Minimum\":1,\"Owners\":[\"Alice\"],\"Data\":\"SGVsbG8gSmVsbG8=\",\"Usages\":[\"decrypt\"]}")
encryptJson5 := []byte("{\"Name\":\"Alice\",\"Password\":\"Hello\",\"Minimum\":1,\"Owners\":[\"Alice\"],\"Data\":\"SGVsbG8gSmVsbG8=\",\"Usages\":[\"unused\"]}")
cfg := config.New()
Init("memory", cfg)
@@ -670,6 +673,92 @@ func TestEncryptDecrypt(t *testing.T) {
if s.Status != "ok" {
t.Fatalf("Error in decrypt, %v", s.Status)
}
// Encrypt with "decrypt" usage
respJson, err = Encrypt(encryptJson4)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in encrypt, %v", s.Status)
}
respJson, err = Delegate(delegateJson6)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
// decrypt file
decryptJson3, err := json.Marshal(DecryptRequest{Name: "Alice", Password: "Hello", Data: s.Response})
if err != nil {
t.Fatalf("Error in marshalling decryption, %v", err)
}
respJson2, err = Decrypt(decryptJson3)
if err != nil {
t.Fatalf("Error in decrypt, %v", err)
}
err = json.Unmarshal(respJson2, &s)
if err != nil {
t.Fatalf("Error in decrypt, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in decrypt, %v", s.Status)
}
// Encrypt with "unused" usage
respJson, err = Encrypt(encryptJson5)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in encrypt, %v", s.Status)
}
respJson, err = Delegate(delegateJson6)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
// decrypt file
decryptJson4, err := json.Marshal(DecryptRequest{Name: "Alice", Password: "Hello", Data: s.Response})
if err != nil {
t.Fatalf("Error in marshalling decryption, %v", err)
}
respJson2, err = Decrypt(decryptJson4)
if err != nil {
t.Fatalf("Error in decrypt, %v", err)
}
err = json.Unmarshal(respJson2, &s)
if err != nil {
t.Fatalf("Error in decrypt, %v", err)
}
if s.Status == "ok" {
t.Fatalf("Expected error decrypting blob without \"decrypt\" usage")
}
}
func TestReEncrypt(t *testing.T) {
@@ -1195,6 +1284,142 @@ func TestValidateName(t *testing.T) {
}
}
func TestSSHSignWith(t *testing.T) {
delegateJson := []byte("{\"Name\":\"Alice\",\"Password\":\"Hello\",\"Time\":\"10s\",\"Uses\":10}")
cfg := config.New()
Init("memory", cfg)
// check for summary of initialized vault with new member
var s ResponseData
respJson, err := Create(delegateJson)
if err != nil {
t.Fatalf("Error in creating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in creating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in creating account, %v", s.Status)
}
respJson, err = Delegate(delegateJson)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in delegating account, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in delegating account, %v", s.Status)
}
sshKey, err := ioutil.ReadFile("../testdata/ssh_key")
if err != nil {
t.Fatalf("Error loading test SSH key, %v", err)
}
sshPubKeyBytes, err := ioutil.ReadFile("../testdata/ssh_key.pub")
if err != nil {
t.Fatalf("Error loading test SSH pubkey, %v", err)
}
sshPubKey, _, _, _, err := ssh.ParseAuthorizedKey(sshPubKeyBytes)
if err != nil {
t.Fatalf("Error loading test SSH pubkey, %v", err)
}
e := EncryptRequest{Name: "Alice", Password: "Hello",
Owners: []string{"Alice"}, Minimum: 1, Data: sshKey}
encryptJson, err := json.Marshal(e)
if err != nil {
t.Fatalf("Error marshalling encrypt request, %v", err)
}
// Encrypt SSH key
respJson, err = Encrypt(encryptJson)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in encrypt, %v", s.Status)
}
// try to generate a signature
sshSignWithJson, err := json.Marshal(SSHSignWithRequest{Name: "Alice", Password: "Hello", Data: s.Response, TBSData: []byte("signme")})
if err != nil {
t.Fatalf("Error marshalling ssh-sign-with request, %v", err)
}
respJson, err = SSHSignWith(sshSignWithJson)
if err != nil {
t.Fatalf("Error in ssh-sign-with, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in ssh-sign-with, %v", err)
}
if s.Status != "cannot sign with this file" {
t.Fatalf("Expected error using ssh-sign-with without 'ssh-sign-with' usage, got %v", s.Status)
}
e.Usages = []string{"ssh-sign-with"}
encryptJson, err = json.Marshal(e)
if err != nil {
t.Fatalf("Error marshalling encrypt request, %v", err)
}
respJson, err = Encrypt(encryptJson)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in encrypt, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in encrypt, %v", s.Status)
}
sshSignWithJson, err = json.Marshal(SSHSignWithRequest{Name: "Alice", Password: "Hello", Data: s.Response, TBSData: []byte("signme")})
if err != nil {
t.Fatalf("Error marshalling ssh-sign-with request, %v", err)
}
respJson, err = SSHSignWith(sshSignWithJson)
if err != nil {
t.Fatalf("Error in ssh-sign-with, %v", err)
}
err = json.Unmarshal(respJson, &s)
if err != nil {
t.Fatalf("Error in ssh-sign-with, %v", err)
}
if s.Status != "ok" {
t.Fatalf("Error in ssh-sign-with, %v", s.Status)
}
var sshSignWithResponse SSHSignatureWithDelegates
err = json.Unmarshal(s.Response, &sshSignWithResponse)
if err != nil {
t.Fatalf("Error unmarshalling ssh-sign-with response, %v", err)
}
sshSignature := ssh.Signature{
Format: sshSignWithResponse.SignatureFormat,
Blob: sshSignWithResponse.Signature,
}
err = sshPubKey.Verify([]byte("signme"), &sshSignature)
if err != nil {
t.Fatalf("Error verifying ssh-sign-with signature, %v", err)
}
}
// Create a vault for the restore tests.
func restoreCreateVault(t *testing.T, pstore, file string) {
cfg := config.New()

View File

@@ -223,10 +223,6 @@ func (encrypted *EncryptedData) computeHmac(key []byte) []byte {
mac.Write([]byte(usage))
}
for index := range encrypted.Usages {
mac.Write([]byte(encrypted.Usages[index]))
}
return mac.Sum(nil)
}

15
testdata/ssh_key vendored Normal file
View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCz2+6OyTyo4Qo/hCtaBLT9gczJPzPhu7CzYWOSqRjbFs2/16y0
YOuyPesO/e84ZasMlzFJMogNddnq5uJxcM6+f3XzUs2yIL26cw0rcespNg1UUpZg
OSxSluXoJapB/SQhcIuO+uD0snvjNQrAMUz7oK+b6Uv3fYu3DmgI8CrSlwIDAQAB
AoGAYs8ci8z6Sjz3iFVwC5AybmL0wkq6kfSu6p1COrwzL4mjlxVBiAcG9XEWxbGz
zmPsSIp3RSNBo0NvaKFXHcM/kHRMsZG9FmmQBikoOkMTaEeCdbw/9k3Xzh1aFPo7
eCAMbMAO/6nZb8wjARZZ2EHFAo4fXcORwj7dY4/hR3r7KEECQQDdOioQLThTVXXT
tV24cE0WVezC8xcnSOE0MIMyFyxjD0aGtzrBKoXewocfRe+zvzoMJzrWM0CIEP5U
IbSUTGX5AkEA0CEuJxOpc3yw3I9hy3isqcA9rR6Pa7gvG/H8dLkmhyK6knzuUHU0
kW+aTg/LqH22hdCe8SQbUuIWoblSetnhDwJAZOPhyv7UcSzIT4Sm+TY98bG+CCpU
pNXX3rVBH9bxpzuQLl/hq7Z41t5gQSLj7lWHY4OAka9N/r/BPR0h/X/aAQJAKbHL
9iYZNzqOj9DljYaCSItrj6fkoXbHcTi8E4IX9tB9QeVnNJUWT+BksCi36uwsSYhu
nu5VzvfeAs4GePf2/wJATHu5znRyBkegvvn702wodqfhbPd8pmnNT0vXKcD90jsz
ZDe0VlX/kmE4fbORozMDRURUGaVDhFIiEsa4gct2mA==
-----END RSA PRIVATE KEY-----

1
testdata/ssh_key.pub vendored Normal file
View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCz2+6OyTyo4Qo/hCtaBLT9gczJPzPhu7CzYWOSqRjbFs2/16y0YOuyPesO/e84ZasMlzFJMogNddnq5uJxcM6+f3XzUs2yIL26cw0rcespNg1UUpZgOSxSluXoJapB/SQhcIuO+uD0snvjNQrAMUz7oK+b6Uv3fYu3DmgI8CrSlw==