mirror of
https://github.com/ssh-vault/ssh-vault.git
synced 2025-04-19 07:42:18 +03:00
111 lines
2.2 KiB
Go
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
|
|
}
|