1
0
mirror of https://github.com/ssh-vault/ssh-vault.git synced 2025-07-03 03:22:34 +03:00
Files
ssh-vault/view.go
nbari a78f6fae70 deleted: aes.go
modified:   close.go
	modified:   cmd/ssh-vault/main.go
	modified:   vault.go
	modified:   vault_test.go
	modified:   view.go
2016-10-22 14:12:00 +02:00

106 lines
2.2 KiB
Go

package sshvault
import (
"bufio"
"bytes"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"io/ioutil"
"os"
"strings"
"syscall"
"github.com/ssh-vault/crypto/aead"
"github.com/ssh-vault/crypto/oaep"
"golang.org/x/crypto/ssh/terminal"
)
// View decrypts data and print it to stdout
func (v *vault) View() ([]byte, error) {
file, err := os.Open(v.vault)
if err != nil {
return nil, err
}
defer file.Close()
var (
// ssh-vault;AES256;fingerprint
header []string
rawPayload bytes.Buffer
)
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(rawPayload.String(), ";")
// use private key only
if strings.HasSuffix(v.key, ".pub") {
v.key = strings.Trim(v.key, ".pub")
}
keyFile, err := ioutil.ReadFile(v.key)
if err != nil {
return nil, fmt.Errorf("Error reading private key: %s", err)
}
block, _ := pem.Decode(keyFile)
if block == nil || block.Type != "RSA PRIVATE KEY" {
return nil, fmt.Errorf("No valid PEM (private key) data found")
}
if x509.IsEncryptedPEMBlock(block) {
fmt.Print("Enter key password: ")
keyPassword, err := terminal.ReadPassword(int(syscall.Stdin))
if err != nil {
return nil, err
}
fmt.Println()
block.Bytes, err = x509.DecryptPEMBlock(block, keyPassword)
if err != nil {
return nil, fmt.Errorf("Password incorrect, Decryption failed.")
}
}
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
ciphertext, err := base64.StdEncoding.DecodeString(payload[0])
if err != nil {
return nil, err
}
v.Password, err = oaep.Decrypt(privateKey, ciphertext, []byte(""))
if err != nil {
return nil, fmt.Errorf("Decryption failed, use private key with fingerprint: %s", v.Fingerprint)
}
ciphertext, err = base64.StdEncoding.DecodeString(payload[1])
if err != nil {
return nil, err
}
// decrypt ciphertext using fingerprint as additionalData
data, err := aead.Decrypt(v.Password, ciphertext, []byte(header[2]))
if err != nil {
return nil, err
}
return data, nil
}