refactor functions and merge in keyring
This commit is contained in:
parent
ef2f0e8340
commit
e1098f7d34
8 changed files with 143 additions and 126 deletions
|
|
@ -43,7 +43,7 @@ func TestGenerateKeyRings(t *testing.T) {
|
|||
t.Fatal("Cannot read RSA key:", err)
|
||||
}
|
||||
|
||||
rsaPublicKey, err = rsaPrivateKeyRing.ArmoredPublicKeyString()
|
||||
rsaPublicKey, err = rsaPrivateKeyRing.GetArmoredPublicKey()
|
||||
if err != nil {
|
||||
t.Fatal("Cannot extract RSA public key:", err)
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ func TestGenerateKeyRings(t *testing.T) {
|
|||
t.Fatal("Cannot read EC key:", err)
|
||||
}
|
||||
|
||||
ecPublicKey, err = ecPrivateKeyRing.ArmoredPublicKeyString()
|
||||
ecPublicKey, err = ecPrivateKeyRing.GetArmoredPublicKey()
|
||||
if err != nil {
|
||||
t.Fatal("Cannot extract EC public key:", err)
|
||||
}
|
||||
|
|
@ -142,4 +142,14 @@ func TestIsKeyExpired(t *testing.T) {
|
|||
|
||||
assert.Exactly(t, false, rsaRes)
|
||||
assert.Exactly(t, false, ecRes)
|
||||
|
||||
pmCrypto.UpdateTime(1557754627) // 2019-05-13T13:37:07+00:00
|
||||
|
||||
expRes, expErr := pmCrypto.IsKeyExpired(readTestFile("key_expiredKey"))
|
||||
futureRes, futureErr := pmCrypto.IsKeyExpired(readTestFile("key_futureKey"))
|
||||
|
||||
assert.Exactly(t, true, expRes)
|
||||
assert.Exactly(t, true, futureRes)
|
||||
assert.EqualError(t, expErr, "keys expired")
|
||||
assert.EqualError(t, futureErr, "keys expired")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
|
|
@ -456,8 +457,8 @@ func (kr *KeyRing) WriteArmoredPublicKey(w io.Writer) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// ArmoredPublicKeyString returns the armored public keys from this keyring.
|
||||
func (kr *KeyRing) ArmoredPublicKeyString() (s string, err error) {
|
||||
// GetArmoredPublicKey returns the armored public keys from this keyring.
|
||||
func (kr *KeyRing) GetArmoredPublicKey() (s string, err error) {
|
||||
b := &bytes.Buffer{}
|
||||
if err = kr.WriteArmoredPublicKey(b); err != nil {
|
||||
return
|
||||
|
|
@ -467,6 +468,60 @@ func (kr *KeyRing) ArmoredPublicKeyString() (s string, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// WritePublicKey outputs unarmored public keys from the keyring to w.
|
||||
func (kr *KeyRing) WritePublicKey(w io.Writer) (err error) {
|
||||
for _, e := range kr.entities {
|
||||
if err = e.Serialize(w); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetPublicKey returns the unarmored public keys from this keyring.
|
||||
func (kr *KeyRing) GetPublicKey() (b []byte, err error) {
|
||||
var outBuf bytes.Buffer
|
||||
if err = kr.WritePublicKey(&outBuf); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
b = outBuf.Bytes()
|
||||
return
|
||||
}
|
||||
|
||||
// GetFingerprint gets the fingerprint from the keyring
|
||||
func (kr *KeyRing) GetFingerprint() (string, error) {
|
||||
for _, entity := range kr.entities {
|
||||
fp := entity.PrimaryKey.Fingerprint
|
||||
return hex.EncodeToString(fp[:]), nil
|
||||
}
|
||||
return "", errors.New("can't find public key")
|
||||
}
|
||||
|
||||
// CheckPassphrase checks if private key passphrase ok
|
||||
func (kr *KeyRing) CheckPassphrase(passphrase string) bool {
|
||||
var keys []*packet.PrivateKey
|
||||
|
||||
for _, entity := range kr.entities {
|
||||
keys = append(keys, entity.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
|
||||
}
|
||||
|
||||
// readFrom reads unarmored and armored keys from r and adds them to the keyring.
|
||||
func (kr *KeyRing) readFrom(r io.Reader, armored bool) error {
|
||||
var err error
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ func TestKeyRing_Encrypt(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestKeyRing_ArmoredPublicKeyString(t *testing.T) {
|
||||
s, err := testPrivateKeyRing.ArmoredPublicKeyString()
|
||||
s, err := testPrivateKeyRing.GetArmoredPublicKey()
|
||||
if err != nil {
|
||||
t.Fatal("Expected no error while getting armored public key, got:", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,8 +61,8 @@ func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passp
|
|||
return outBuf.String(), nil
|
||||
}
|
||||
|
||||
// VerifyTextSignDetachedBinKey Verifies detached text - check if signature is valid using a given publicKey in binary format
|
||||
func (pm *PmCrypto) VerifyTextSignDetachedBinKey(signature string, plainText string, publicKey *KeyRing, verifyTime int64) (bool, error) {
|
||||
// VerifyTextDetachedSig verifies detached text - check if signature is valid using a given publicKey in binary format
|
||||
func (pm *PmCrypto) VerifyTextDetachedSig(signature string, plainText string, publicKey *KeyRing, verifyTime int64) (bool, error) {
|
||||
plainText = internal.TrimNewlines(plainText)
|
||||
origText := bytes.NewReader(bytes.NewBufferString(plainText).Bytes())
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
|
|||
}
|
||||
} else {
|
||||
config.Time = func() time.Time {
|
||||
return time.Unix(verifyTime + internal.CreationTimeOffset, 0)
|
||||
return time.Unix(verifyTime+internal.CreationTimeOffset, 0)
|
||||
}
|
||||
}
|
||||
signatureReader := strings.NewReader(signature)
|
||||
|
|
@ -112,8 +112,8 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// VerifyBinSignDetachedBinKey Verifies detached text in binary format - check if signature is valid using a given publicKey in binary format
|
||||
func (pm *PmCrypto) VerifyBinSignDetachedBinKey(signature string, plainData []byte, publicKey *KeyRing, verifyTime int64) (bool, error) {
|
||||
// VerifyBinDetachedSig verifies detached text in binary format - check if signature is valid using a given publicKey in binary format
|
||||
func (pm *PmCrypto) VerifyBinDetachedSig(signature string, plainData []byte, publicKey *KeyRing, verifyTime int64) (bool, error) {
|
||||
origText := bytes.NewReader(plainData)
|
||||
|
||||
return verifySignature(publicKey.entities, origText, signature, verifyTime)
|
||||
|
|
|
|||
13
crypto/testdata/key_expiredKey
vendored
Normal file
13
crypto/testdata/key_expiredKey
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
xcA4BAAAAAEBAgCgONc0J8rfO6cJw5YTP38x1ze2tAYIO7EcmRCNYwMkXngb
|
||||
0Qdzg34Q5RW0rNiR56VB6KElPUhePRPVklLFiIvHABEBAAEAAf9qabYMzsz/
|
||||
/LeRVZSsTgTljmJTdzd2ambUbpi+vt8MXJsbaWh71vjoLMWSXajaKSPDjVU5
|
||||
waFNt9kLqwGGGLqpAQD5ZdMH2XzTq6GU9Ka69iZs6Pbnzwdz59Vc3i8hXlUj
|
||||
zQEApHargCTsrtvSrm+hK/pN51/BHAy9lxCAw9f2etx+AeMA/RGrijkFZtYt
|
||||
jeWdv/usXL3mgHvEcJv63N5zcEvDX5X4W1bND3Rlc3QxIDxhQGIuY29tPsJ7
|
||||
BBABCAAvBQIAAAABBQMAAAU5BgsJBwgDAgkQzcF99nGrkAkEFQgKAgMWAgEC
|
||||
GQECGwMCHgEAABAlAfwPehmLZs+gOhOTTaSslqQ50bl/REjmv42Nyr1ZBlQS
|
||||
DECl1Qu4QyeXin29uEXWiekMpNlZVsEuc8icCw6ABhIZ
|
||||
=/7PI
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
55
crypto/testdata/key_futureKey
vendored
Normal file
55
crypto/testdata/key_futureKey
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
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
|
||||
0uyeibPdgJTjARMuQzDFA8bdbM540vBf5Q==
|
||||
=WLIN
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package key
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"github.com/ProtonMail/go-pm-crypto/armor"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
)
|
||||
|
||||
// GetFingerprint gets an armored public key fingerprint
|
||||
func GetFingerprint(publicKey string) (string, error) {
|
||||
rawPubKey, err := armor.Unarmor(publicKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return GetFingerprintBinKey(rawPubKey)
|
||||
}
|
||||
|
||||
// GetFingerprintBinKey gets an unarmored public key fingerprint
|
||||
func GetFingerprintBinKey(publicKey []byte) (string, error) {
|
||||
pubKeyReader := bytes.NewReader(publicKey)
|
||||
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, e := range pubKeyEntries {
|
||||
fp := e.PrimaryKey.Fingerprint
|
||||
return hex.EncodeToString(fp[:]), nil
|
||||
}
|
||||
return "", errors.New("can't find public key")
|
||||
}
|
||||
83
key/key.go
83
key/key.go
|
|
@ -1,83 +0,0 @@
|
|||
// Provides key manipulation helper methods
|
||||
package key
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/ProtonMail/go-pm-crypto/armor"
|
||||
"github.com/ProtonMail/go-pm-crypto/constants"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CheckPassphrase checks if private key passphrase ok
|
||||
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
|
||||
}
|
||||
|
||||
// PublicKey gets a public key from a private key
|
||||
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 {
|
||||
if err := e.Serialize(&outBuf); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
outString, err := armor.ArmorWithType(outBuf.Bytes(), constants.PublicKeyHeader)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return outString, nil
|
||||
}
|
||||
|
||||
// PublicKeyBinOut gets a public key from a private key
|
||||
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 {
|
||||
if err := e.Serialize(&outBuf); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return outBuf.Bytes(), nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue