1
0
mirror of https://github.com/ssh-vault/ssh-vault.git synced 2025-04-19 07:42:18 +03:00
ssh-vault/vault.go
2017-08-24 22:56:48 +02:00

111 lines
2.2 KiB
Go

package sshvault
import (
"crypto/md5"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"regexp"
"strconv"
"strings"
"github.com/ssh-vault/ssh2pem"
)
// Vault structure
type vault struct {
Password []byte
PublicKey *rsa.PublicKey
Fingerprint string
key string
vault string
}
// GITHUB https://github.com/<username>.keys
const GITHUB = "https://github.com"
// isURL regex to match if user is an URL
var isURL = regexp.MustCompile(`^https?://`)
// New initialize vault parameters
func New(f, k, u, o, v string) (*vault, error) {
var (
err error
keyPath = k
)
cache := Cache()
s := Locksmith{GITHUB}
if u != "" {
// use -k N where N is the index to use when multiple keys
// are available
var ki int
if ki, err = strconv.Atoi(k); err != nil {
ki = 1
}
if ki <= 1 {
ki = 1
}
keyPath, err = cache.Get(s, u, f, ki)
if err != nil {
return nil, err
}
} else if !cache.IsFile(keyPath) && !isURL.MatchString(k) {
return nil, fmt.Errorf("SSH key %q not found or unable to read", keyPath)
}
switch o {
case "create":
if v != "" && cache.IsFile(v) {
return nil, fmt.Errorf("File already exists: %q", v)
}
case "view":
if isURL.MatchString(k) {
keyPath, err = cache.Get(s, k, "", 0)
if err != nil {
return nil, err
}
}
}
return &vault{
key: keyPath,
vault: v,
}, nil
}
// PKCS8 convert ssh public key to PEM PKCS8
func (v *vault) PKCS8() (*pem.Block, error) {
out, err := ssh2pem.GetPem(v.key)
if err != nil {
return nil, err
}
p, rest := pem.Decode(out)
if p == nil {
return nil, fmt.Errorf("Could not create a PEM from the ssh key, %q", rest)
}
return p, nil
}
// Fingerprint return fingerprint of ssh-key
func (v *vault) GenFingerprint(p *pem.Block) (string, error) {
fingerPrint := md5.New()
fingerPrint.Write(p.Bytes)
return strings.Replace(fmt.Sprintf("% x",
fingerPrint.Sum(nil)),
" ",
":",
-1), nil
}
// GetRSAPublicKey return rsa.PublicKey
func (v *vault) GetRSAPublicKey(p *pem.Block) (*rsa.PublicKey, error) {
pubkeyInterface, err := x509.ParsePKIXPublicKey(p.Bytes)
if err != nil {
return nil, err
}
rsaPublicKey, ok := pubkeyInterface.(*rsa.PublicKey)
if !ok {
return nil, fmt.Errorf("No Public key found")
}
return rsaPublicKey, nil
}