diff --git a/close.go b/close.go index ec4cd82..374592b 100644 --- a/close.go +++ b/close.go @@ -1,6 +1,8 @@ package sshvault import ( + "bytes" + "encoding/base64" "fmt" "io/ioutil" ) @@ -11,11 +13,16 @@ func (v *vault) Close(data []byte) error { if err != nil { return err } + + var payload bytes.Buffer + payload.WriteString(base64.StdEncoding.EncodeToString(p)) + payload.WriteString(";") + payload.WriteString(base64.StdEncoding.EncodeToString(data)) + err = ioutil.WriteFile(v.vault, - []byte(fmt.Sprintf("$SSH-VAULT;AES256;%s\n%x;%x", + []byte(fmt.Sprintf("SSH-VAULT;AES256;%s\n%s\n", v.Fingerprint, - p, - data)), + v.Encode(payload.String(), 64))), 0600, ) if err != nil { diff --git a/encode.go b/encode.go new file mode 100644 index 0000000..f3083fa --- /dev/null +++ b/encode.go @@ -0,0 +1,16 @@ +package sshvault + +import "bytes" + +// Encode return base64 string with line break every 64 chars +func (v *vault) Encode(b string, n int) []byte { + a := []rune(b) + var buffer bytes.Buffer + for i, r := range a { + buffer.WriteRune(r) + if i > 0 && (i+1)%64 == 0 { + buffer.WriteRune('\n') + } + } + return buffer.Bytes() +} diff --git a/view.go b/view.go index 4c74b2f..72b8fe3 100644 --- a/view.go +++ b/view.go @@ -1,14 +1,17 @@ package sshvault import ( + "bufio" + "bytes" "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" - "encoding/hex" + "encoding/base64" "encoding/pem" "fmt" "io/ioutil" + "os" "strings" "syscall" @@ -17,20 +20,33 @@ import ( // View decrypts data and print it to stdout func (v *vault) View() ([]byte, error) { - file, err := ioutil.ReadFile(v.vault) + file, err := os.Open(v.vault) if err != nil { return nil, err } - vault := string(file) + defer file.Close() - // header+payload - parts := strings.Split(vault, "\n") + var ( + // ssh-vault;AES256;fingerprint + header []string + rawPayload bytes.Buffer + ) - // ssh-vault;AES256;fingerprint - header := strings.Split(parts[0], ";") + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanLines) + l := 1 + for scanner.Scan() { + line := scanner.Text() + if l == 1 { + header = strings.Split(line, ";") + } else { + rawPayload.WriteString(line) + } + l++ + } // password, body - payload := strings.Split(parts[1], ";") + payload := strings.Split(rawPayload.String(), ";") // use private key only if strings.HasSuffix(v.key, ".pub") { @@ -65,7 +81,7 @@ func (v *vault) View() ([]byte, error) { return nil, err } - ciphertext, err := hex.DecodeString(payload[0]) + ciphertext, err := base64.StdEncoding.DecodeString(payload[0]) if err != nil { return nil, err } @@ -75,7 +91,7 @@ func (v *vault) View() ([]byte, error) { return nil, err } - ciphertext, err = hex.DecodeString(payload[1]) + ciphertext, err = base64.StdEncoding.DecodeString(payload[1]) if err != nil { return nil, err }