2018-11-05 22:55:45 +01:00
|
|
|
// Provides key manipulation helper methods
|
2018-09-11 11:09:28 +02:00
|
|
|
package key
|
|
|
|
|
|
|
|
|
|
import (
|
2018-11-01 17:03:43 +01:00
|
|
|
"bytes"
|
2018-09-11 11:09:28 +02:00
|
|
|
"fmt"
|
2018-11-01 17:03:43 +01:00
|
|
|
"github.com/ProtonMail/go-pm-crypto/armor"
|
2019-03-07 16:56:12 +01:00
|
|
|
"github.com/ProtonMail/go-pm-crypto/constants"
|
2018-11-01 17:03:43 +01:00
|
|
|
"golang.org/x/crypto/openpgp"
|
2018-09-11 11:09:28 +02:00
|
|
|
"golang.org/x/crypto/openpgp/packet"
|
2018-11-01 17:03:43 +01:00
|
|
|
"strings"
|
2018-09-11 11:09:28 +02:00
|
|
|
)
|
|
|
|
|
|
2019-05-13 12:33:01 +00:00
|
|
|
// CheckPassphrase checks if private key passphrase ok
|
2018-09-11 11:09:28 +02:00
|
|
|
func CheckPassphrase(privateKey string, passphrase string) bool {
|
|
|
|
|
privKeyReader := strings.NewReader(privateKey)
|
|
|
|
|
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var keys []*packet.PrivateKey
|
|
|
|
|
|
|
|
|
|
for _, e := range entries {
|
|
|
|
|
keys = append(keys, e.PrivateKey)
|
|
|
|
|
}
|
|
|
|
|
var decryptError error
|
|
|
|
|
var n int
|
|
|
|
|
for _, key := range keys {
|
|
|
|
|
if !key.Encrypted {
|
|
|
|
|
continue // Key already decrypted
|
|
|
|
|
}
|
|
|
|
|
if decryptError = key.Decrypt([]byte(passphrase)); decryptError == nil {
|
|
|
|
|
n++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if n == 0 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-13 12:33:01 +00:00
|
|
|
// PublicKey gets a public key from a private key
|
2018-09-11 11:09:28 +02:00
|
|
|
func PublicKey(privateKey string) (string, error) {
|
|
|
|
|
privKeyReader := strings.NewReader(privateKey)
|
|
|
|
|
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var outBuf bytes.Buffer
|
|
|
|
|
for _, e := range entries {
|
2019-05-13 12:42:29 +00:00
|
|
|
if err := e.Serialize(&outBuf); err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
2018-09-11 11:09:28 +02:00
|
|
|
}
|
|
|
|
|
|
2019-03-07 16:56:12 +01:00
|
|
|
outString, err := armor.ArmorWithType(outBuf.Bytes(), constants.PublicKeyHeader)
|
2018-09-11 11:09:28 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return "", nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return outString, nil
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-13 12:33:01 +00:00
|
|
|
// PublicKeyBinOut gets a public key from a private key
|
2018-09-11 11:09:28 +02:00
|
|
|
func PublicKeyBinOut(privateKey string) ([]byte, error) {
|
|
|
|
|
privKeyReader := strings.NewReader(privateKey)
|
|
|
|
|
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var outBuf bytes.Buffer
|
|
|
|
|
for _, e := range entries {
|
2019-05-13 12:42:29 +00:00
|
|
|
if err := e.Serialize(&outBuf); err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
2018-09-11 11:09:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return outBuf.Bytes(), nil
|
|
|
|
|
}
|