50 lines
1.1 KiB
Go
50 lines
1.1 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
|
|
"code.google.com/p/gopass"
|
|
)
|
|
|
|
// ReadPrivateKey attempts to read your private key and possibly decrypt it if it
|
|
// requires a passphrase.
|
|
// This function will prompt for a passphrase on STDIN if the environment variable (`IDENTITY_PASSPHRASE`),
|
|
// is not set.
|
|
func ReadPrivateKey(path string) ([]byte, error) {
|
|
privateKey, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to load identity: %v", err)
|
|
}
|
|
|
|
block, rest := pem.Decode(privateKey)
|
|
if len(rest) > 0 {
|
|
return nil, fmt.Errorf("extra data when decoding private key")
|
|
}
|
|
if !x509.IsEncryptedPEMBlock(block) {
|
|
return privateKey, nil
|
|
}
|
|
|
|
passphrase := os.Getenv("IDENTITY_PASSPHRASE")
|
|
if passphrase == "" {
|
|
passphrase, err = gopass.GetPass("Enter passphrase: ")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("couldn't read passphrase: %v", err)
|
|
}
|
|
}
|
|
der, err := x509.DecryptPEMBlock(block, []byte(passphrase))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("decrypt failed: %v", err)
|
|
}
|
|
|
|
privateKey = pem.EncodeToMemory(&pem.Block{
|
|
Type: block.Type,
|
|
Bytes: der,
|
|
})
|
|
|
|
return privateKey, nil
|
|
}
|