mirror of
https://github.com/Luzifer/shareport.git
synced 2024-11-08 14:20:09 +00:00
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"crypto/x509"
|
||
|
"encoding/pem"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
|
||
|
"golang.org/x/crypto/ssh"
|
||
|
)
|
||
|
|
||
|
func signerFromPem(pemBytes []byte, password []byte) (ssh.Signer, error) {
|
||
|
|
||
|
// read pem block
|
||
|
err := errors.New("Pem decode failed, no key found")
|
||
|
pemBlock, _ := pem.Decode(pemBytes)
|
||
|
if pemBlock == nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// handle encrypted key
|
||
|
if x509.IsEncryptedPEMBlock(pemBlock) {
|
||
|
// decrypt PEM
|
||
|
pemBlock.Bytes, err = x509.DecryptPEMBlock(pemBlock, password)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("Decrypting PEM block failed %v", err)
|
||
|
}
|
||
|
|
||
|
// get RSA, EC or DSA key
|
||
|
key, err := parsePemBlock(pemBlock)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
// generate signer instance from key
|
||
|
signer, err := ssh.NewSignerFromKey(key)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("Creating signer from encrypted key failed %v", err)
|
||
|
}
|
||
|
|
||
|
return signer, nil
|
||
|
} else {
|
||
|
// generate signer instance from plain key
|
||
|
signer, err := ssh.ParsePrivateKey(pemBytes)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("Parsing plain private key failed %v", err)
|
||
|
}
|
||
|
|
||
|
return signer, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func parsePemBlock(block *pem.Block) (interface{}, error) {
|
||
|
switch block.Type {
|
||
|
case "RSA PRIVATE KEY":
|
||
|
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("Parsing PKCS private key failed %v", err)
|
||
|
} else {
|
||
|
return key, nil
|
||
|
}
|
||
|
case "EC PRIVATE KEY":
|
||
|
key, err := x509.ParseECPrivateKey(block.Bytes)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("Parsing EC private key failed %v", err)
|
||
|
} else {
|
||
|
return key, nil
|
||
|
}
|
||
|
case "DSA PRIVATE KEY":
|
||
|
key, err := ssh.ParseDSAPrivateKey(block.Bytes)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("Parsing DSA private key failed %v", err)
|
||
|
} else {
|
||
|
return key, nil
|
||
|
}
|
||
|
default:
|
||
|
return nil, fmt.Errorf("Parsing private key failed, unsupported key type %q", block.Type)
|
||
|
}
|
||
|
}
|