Improve documentation and naming
- Rename pmmime to gomime - Rename pmKeyObject to pgpKeyObject
This commit is contained in:
parent
30ee92e63b
commit
7d9930b8e0
13 changed files with 108 additions and 99 deletions
|
|
@ -15,7 +15,8 @@ import (
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AttachmentProcessor to encrypt an attachment
|
// AttachmentProcessor keeps track of the progress of encrypting an attachment
|
||||||
|
// (optimized for encrypting large files).
|
||||||
type AttachmentProcessor struct {
|
type AttachmentProcessor struct {
|
||||||
w *io.WriteCloser
|
w *io.WriteCloser
|
||||||
pipe *io.PipeWriter
|
pipe *io.PipeWriter
|
||||||
|
|
@ -25,14 +26,14 @@ type AttachmentProcessor struct {
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process allows the attachment processor to write the encrypted attachment
|
// Process writes attachment data to be encrypted
|
||||||
func (ap *AttachmentProcessor) Process(plainData []byte) {
|
func (ap *AttachmentProcessor) Process(plainData []byte) {
|
||||||
if _, err := (*ap.w).Write(plainData); err != nil {
|
if _, err := (*ap.w).Write(plainData); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish attachment process
|
// Finish closes the attachment and returns the encrypted data
|
||||||
func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
|
func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
|
||||||
if ap.err != nil {
|
if ap.err != nil {
|
||||||
return nil, ap.err
|
return nil, ap.err
|
||||||
|
|
@ -46,12 +47,13 @@ func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
|
||||||
return ap.split, nil
|
return ap.split, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// encryptAttachment takes input data from file
|
// encryptAttachment creates an AttachmentProcessor which can be used to encrypt
|
||||||
|
// a file. It takes an estimatedSize and fileName as hints about the file.
|
||||||
func (pgp *GopenPGP) encryptAttachment(
|
func (pgp *GopenPGP) encryptAttachment(
|
||||||
estimatedSize int, fileName string, publicKey *KeyRing, garbageCollector int,
|
estimatedSize int, fileName string, publicKey *KeyRing, garbageCollector int,
|
||||||
) (*AttachmentProcessor, error) {
|
) (*AttachmentProcessor, error) {
|
||||||
attachmentProc := &AttachmentProcessor{}
|
attachmentProc := &AttachmentProcessor{}
|
||||||
// you can also add these one at a time if you need to
|
// You could also add these one at a time if needed.
|
||||||
attachmentProc.done.Add(1)
|
attachmentProc.done.Add(1)
|
||||||
attachmentProc.garbageCollector = garbageCollector
|
attachmentProc.garbageCollector = garbageCollector
|
||||||
|
|
||||||
|
|
@ -88,8 +90,7 @@ func (pgp *GopenPGP) encryptAttachment(
|
||||||
return attachmentProc, nil
|
return attachmentProc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptAttachment encrypts attachment. Takes input data and key data in
|
// EncryptAttachment encrypts a file. fileName
|
||||||
// binary form
|
|
||||||
func (pgp *GopenPGP) EncryptAttachment(
|
func (pgp *GopenPGP) EncryptAttachment(
|
||||||
plainData []byte, fileName string, publicKey *KeyRing,
|
plainData []byte, fileName string, publicKey *KeyRing,
|
||||||
) (*models.EncryptedSplit, error) {
|
) (*models.EncryptedSplit, error) {
|
||||||
|
|
@ -105,14 +106,18 @@ func (pgp *GopenPGP) EncryptAttachment(
|
||||||
return split, nil
|
return split, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptAttachmentLowMemory with garbage collected every megabyte
|
// EncryptAttachmentLowMemory creates an AttachmentProcessor which can be used
|
||||||
|
// to encrypt a file. It takes an estimatedSize and fileName as hints about the
|
||||||
|
// file. It is optimized for low-memory environments and collects garbage every
|
||||||
|
// megabyte.
|
||||||
func (pgp *GopenPGP) EncryptAttachmentLowMemory(
|
func (pgp *GopenPGP) EncryptAttachmentLowMemory(
|
||||||
estimatedSize int, fileName string, publicKey *KeyRing,
|
estimatedSize int, fileName string, publicKey *KeyRing,
|
||||||
) (*AttachmentProcessor, error) {
|
) (*AttachmentProcessor, error) {
|
||||||
return pgp.encryptAttachment(estimatedSize, fileName, publicKey, 1<<20)
|
return pgp.encryptAttachment(estimatedSize, fileName, publicKey, 1<<20)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SplitArmor is a Helper method. Splits armored pgp session into key and packet data
|
// SplitArmor is a helper method which splits an armored message into its
|
||||||
|
// session key packet and symmetrically encrypted data packet.
|
||||||
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
|
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|
@ -126,8 +131,9 @@ func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
|
||||||
return SeparateKeyAndData(nil, encryptedReader, len(encrypted), -1)
|
return SeparateKeyAndData(nil, encryptedReader, len(encrypted), -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptAttachment takes input data and key data in binary form. The
|
// DecryptAttachment takes a session key packet and symmetrically encrypted data
|
||||||
// privateKeys can contains more keys. The passphrase is used to unlock keys
|
// packet. privateKeys is a KeyRing that can contain multiple keys. The
|
||||||
|
// passphrase is used to unlock keys in privateKeys.
|
||||||
func (pgp *GopenPGP) DecryptAttachment(
|
func (pgp *GopenPGP) DecryptAttachment(
|
||||||
keyPacket, dataPacket []byte,
|
keyPacket, dataPacket []byte,
|
||||||
kr *KeyRing, passphrase string,
|
kr *KeyRing, passphrase string,
|
||||||
|
|
@ -135,7 +141,7 @@ func (pgp *GopenPGP) DecryptAttachment(
|
||||||
privKeyEntries := kr.entities
|
privKeyEntries := kr.entities
|
||||||
|
|
||||||
if err := kr.Unlock([]byte(passphrase)); err != nil {
|
if err := kr.Unlock([]byte(passphrase)); err != nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot decrypt attachment: %v", err)
|
err = fmt.Errorf("gopenpgp: cannot decrypt attachment: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ func TestAttachmentGetKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAttachmentSetKey(t *testing.T) {
|
func TestAttachmentSetKey(t *testing.T) {
|
||||||
packets, err := SetKey(testPublicKeyRing, testSymmetricKey)
|
packets, err := testPublicKeyRing.EncryptKey(testSymmetricKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Expected no error while encrypting attachment key, got:", err)
|
t.Fatal("Expected no error while encrypting attachment key, got:", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,11 @@
|
||||||
// Package crypto contains all methods and classes needed for manipulation
|
// Package crypto provides a high-level API for common OpenPGP functionality.
|
||||||
// with underlying cryptographic operations. It uses low-level openpgp functions
|
|
||||||
// and provides higher level views. It uses models of messages, attachments
|
|
||||||
// and other higher-level entities
|
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// GopenPGP structure is used to manage server time shift. It should be also used for any
|
// GopenPGP is used as a "namespace" for many of the functions in this package.
|
||||||
// other specific general cryptographic entities.
|
// It is a struct that keeps track of time skew between server and client.
|
||||||
type GopenPGP struct {
|
type GopenPGP struct {
|
||||||
//latestServerTime unix time cache
|
|
||||||
latestServerTime int64
|
latestServerTime int64
|
||||||
latestClientTime time.Time
|
latestClientTime time.Time
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,12 @@ import (
|
||||||
|
|
||||||
// SymmetricKey stores a decrypted session key.
|
// SymmetricKey stores a decrypted session key.
|
||||||
type SymmetricKey struct {
|
type SymmetricKey struct {
|
||||||
// The clear base64-encoded key.
|
// The decrypted binary session key.
|
||||||
Key []byte
|
Key []byte
|
||||||
// The algorithm used by this key.
|
// The symmetric encryption algorithm used with this key.
|
||||||
Algo string
|
Algo string
|
||||||
}
|
}
|
||||||
|
|
||||||
// SymmetricallyEncryptedTag is 18 with the 2 highest order bits set to 1
|
|
||||||
const SymmetricallyEncryptedTag = 210
|
|
||||||
|
|
||||||
var symKeyAlgos = map[string]packet.CipherFunction{
|
var symKeyAlgos = map[string]packet.CipherFunction{
|
||||||
constants.ThreeDES: packet.Cipher3DES,
|
constants.ThreeDES: packet.Cipher3DES,
|
||||||
constants.TripleDES: packet.Cipher3DES,
|
constants.TripleDES: packet.Cipher3DES,
|
||||||
|
|
@ -41,18 +38,18 @@ var symKeyAlgos = map[string]packet.CipherFunction{
|
||||||
constants.AES256: packet.CipherAES256,
|
constants.AES256: packet.CipherAES256,
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCipherFunc returns function corresponding to an algorithm used in
|
// GetCipherFunc returns the cipher function corresponding to the algorithm used
|
||||||
// this SymmetricKey
|
// with this SymmetricKey.
|
||||||
func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
|
func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
|
||||||
cf, ok := symKeyAlgos[sk.Algo]
|
cf, ok := symKeyAlgos[sk.Algo]
|
||||||
if ok {
|
if ok {
|
||||||
return cf
|
return cf
|
||||||
}
|
}
|
||||||
|
|
||||||
panic("pm-crypto: unsupported cipher function: " + sk.Algo)
|
panic("gopenpgp: unsupported cipher function: " + sk.Algo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBase64Key returns a key as base64 encoded string
|
// GetBase64Key returns the session key as base64 encoded string.
|
||||||
func (sk *SymmetricKey) GetBase64Key() string {
|
func (sk *SymmetricKey) GetBase64Key() string {
|
||||||
return base64.StdEncoding.EncodeToString(sk.Key)
|
return base64.StdEncoding.EncodeToString(sk.Key)
|
||||||
}
|
}
|
||||||
|
|
@ -66,7 +63,7 @@ func newSymmetricKey(ek *packet.EncryptedKey) *SymmetricKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if algo == "" {
|
if algo == "" {
|
||||||
panic(fmt.Sprintf("pm-crypto: unsupported cipher function: %v", ek.CipherFunc))
|
panic(fmt.Sprintf("gopenpgp: unsupported cipher function: %v", ek.CipherFunc))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &SymmetricKey{
|
return &SymmetricKey{
|
||||||
|
|
@ -75,7 +72,8 @@ func newSymmetricKey(ek *packet.EncryptedKey) *SymmetricKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptAttKey and returns a symmetric key
|
// DecryptAttKey decrypts a public-key encrypted session key and returns the
|
||||||
|
// decrypted symmetric session key.
|
||||||
func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error) {
|
func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error) {
|
||||||
r := base64.NewDecoder(base64.StdEncoding, strings.NewReader(keyPacket))
|
r := base64.NewDecoder(base64.StdEncoding, strings.NewReader(keyPacket))
|
||||||
packets := packet.NewReader(r)
|
packets := packet.NewReader(r)
|
||||||
|
|
@ -100,7 +98,7 @@ func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
if decryptErr != nil {
|
if decryptErr != nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot decrypt encrypted key packet: %v", decryptErr)
|
err = fmt.Errorf("gopenpgp: cannot decrypt encrypted key packet: %v", decryptErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +106,8 @@ func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// SeparateKeyAndData from packets in a pgp session
|
// SeparateKeyAndData reads a binary PGP message from r and splits it into its
|
||||||
|
// session key packet and symmetrically encrypted data packet.
|
||||||
func SeparateKeyAndData(
|
func SeparateKeyAndData(
|
||||||
kr *KeyRing, r io.Reader,
|
kr *KeyRing, r io.Reader,
|
||||||
estimatedLength, garbageCollector int,
|
estimatedLength, garbageCollector int,
|
||||||
|
|
@ -118,7 +117,7 @@ func SeparateKeyAndData(
|
||||||
outSplit = &models.EncryptedSplit{}
|
outSplit = &models.EncryptedSplit{}
|
||||||
gcCounter := 0
|
gcCounter := 0
|
||||||
|
|
||||||
// Save encrypted key and signature apart
|
// Store encrypted key and symmetrically encrypted packet separately
|
||||||
var ek *packet.EncryptedKey
|
var ek *packet.EncryptedKey
|
||||||
var decryptErr error
|
var decryptErr error
|
||||||
for {
|
for {
|
||||||
|
|
@ -199,18 +198,18 @@ func SeparateKeyAndData(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if decryptErr != nil {
|
if decryptErr != nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot decrypt encrypted key packet: %v", decryptErr)
|
err = fmt.Errorf("gopenpgp: cannot decrypt encrypted key packet: %v", decryptErr)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if ek == nil {
|
if ek == nil {
|
||||||
err = errors.New("pm-crypto: packets don't include an encrypted key packet")
|
err = errors.New("gopenpgp: packets don't include an encrypted key packet")
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if kr == nil {
|
if kr == nil {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := ek.Serialize(&buf); err != nil {
|
if err := ek.Serialize(&buf); err != nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot serialize encrypted key: %v", err)
|
err = fmt.Errorf("gopenpgp: cannot serialize encrypted key: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
outSplit.KeyPacket = buf.Bytes()
|
outSplit.KeyPacket = buf.Bytes()
|
||||||
|
|
@ -223,15 +222,15 @@ func SeparateKeyAndData(
|
||||||
return outSplit, nil
|
return outSplit, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetKey encrypts the provided key.
|
// EncryptKey encrypts the provided key.
|
||||||
func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
|
func (kr *KeyRing) EncryptKey(symKey *SymmetricKey) (packets string, err error) {
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
w := base64.NewEncoder(base64.StdEncoding, b)
|
w := base64.NewEncoder(base64.StdEncoding, b)
|
||||||
|
|
||||||
cf := symKey.GetCipherFunc()
|
cf := symKey.GetCipherFunc()
|
||||||
|
|
||||||
if len(kr.entities) == 0 {
|
if len(kr.entities) == 0 {
|
||||||
err = fmt.Errorf("pm-crypto: cannot set key: key ring is empty")
|
err = fmt.Errorf("gopenpgp: cannot set key: key ring is empty")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,24 +256,24 @@ func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if pub == nil {
|
if pub == nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot set key: no public key available")
|
err = fmt.Errorf("gopenpgp: cannot set key: no public key available")
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = packet.SerializeEncryptedKey(w, pub, cf, symKey.Key, nil); err != nil {
|
if err = packet.SerializeEncryptedKey(w, pub, cf, symKey.Key, nil); err != nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot set key: %v", err)
|
err = fmt.Errorf("gopenpgp: cannot set key: %v", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = w.Close(); err != nil {
|
if err = w.Close(); err != nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot set key: %v", err)
|
err = fmt.Errorf("gopenpgp: cannot set key: %v", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.String(), nil
|
return b.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsKeyExpiredBin checks if the given key is expired. Input in binary format
|
// IsKeyExpiredBin checks whether the given (unarmored, binary) key is expired.
|
||||||
func (pgp *GopenPGP) IsKeyExpiredBin(publicKey []byte) (bool, error) {
|
func (pgp *GopenPGP) IsKeyExpiredBin(publicKey []byte) (bool, error) {
|
||||||
now := pgp.getNow()
|
now := pgp.getNow()
|
||||||
pubKeyReader := bytes.NewReader(publicKey)
|
pubKeyReader := bytes.NewReader(publicKey)
|
||||||
|
|
@ -333,7 +332,7 @@ const (
|
||||||
failed = 3
|
failed = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsKeyExpired checks if the given key is expired. Input in armored format
|
// IsKeyExpired checks whether the given armored key is expired.
|
||||||
func (pgp *GopenPGP) IsKeyExpired(publicKey string) (bool, error) {
|
func (pgp *GopenPGP) IsKeyExpired(publicKey string) (bool, error) {
|
||||||
rawPubKey, err := armor.Unarmor(publicKey)
|
rawPubKey, err := armor.Unarmor(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -416,7 +415,7 @@ func (pgp *GopenPGP) generateKey(
|
||||||
return armor.ArmorWithType(serialized, constants.PrivateKeyHeader)
|
return armor.ArmorWithType(serialized, constants.PrivateKeyHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateRSAKeyWithPrimes generates RSA key with given primes.
|
// GenerateRSAKeyWithPrimes generates a RSA key using the given primes.
|
||||||
func (pgp *GopenPGP) GenerateRSAKeyWithPrimes(
|
func (pgp *GopenPGP) GenerateRSAKeyWithPrimes(
|
||||||
userName, domain, passphrase string,
|
userName, domain, passphrase string,
|
||||||
bits int,
|
bits int,
|
||||||
|
|
@ -425,13 +424,16 @@ func (pgp *GopenPGP) GenerateRSAKeyWithPrimes(
|
||||||
return pgp.generateKey(userName, domain, passphrase, "rsa", bits, primeone, primetwo, primethree, primefour)
|
return pgp.generateKey(userName, domain, passphrase, "rsa", bits, primeone, primetwo, primethree, primefour)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateKey and generate primes
|
// GenerateKey generates a key of the given keyType ("rsa" or "x25519"). If
|
||||||
|
// keyType is "rsa", bits is the RSA bitsize of the key. If keyType is "x25519",
|
||||||
|
// bits is unused.
|
||||||
func (pgp *GopenPGP) GenerateKey(userName, domain, passphrase, keyType string, bits int) (string, error) {
|
func (pgp *GopenPGP) GenerateKey(userName, domain, passphrase, keyType string, bits int) (string, error) {
|
||||||
return pgp.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
|
return pgp.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePrivateKeyPassphrase decrypts the given private key with oldPhrase and
|
// UpdatePrivateKeyPassphrase decrypts the given armored privateKey with
|
||||||
// re-encrypts with the newPassphrase
|
// oldPassphrase, re-encrypts it with newPassphrase, and returns the new armored
|
||||||
|
// key.
|
||||||
func (pgp *GopenPGP) UpdatePrivateKeyPassphrase(
|
func (pgp *GopenPGP) UpdatePrivateKeyPassphrase(
|
||||||
privateKey string, oldPassphrase string, newPassphrase string,
|
privateKey string, oldPassphrase string, newPassphrase string,
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
|
|
@ -477,7 +479,8 @@ func (pgp *GopenPGP) UpdatePrivateKeyPassphrase(
|
||||||
return armor.ArmorWithType(serialized, constants.PrivateKeyHeader)
|
return armor.ArmorWithType(serialized, constants.PrivateKeyHeader)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckKey prints out the key and subkey fingerprint
|
// CheckKey is a debug helper function that prints the key and subkey
|
||||||
|
// fingerprints.
|
||||||
func (pgp *GopenPGP) CheckKey(pubKey string) (string, error) {
|
func (pgp *GopenPGP) CheckKey(pubKey string) (string, error) {
|
||||||
pubKeyReader := strings.NewReader(pubKey)
|
pubKeyReader := strings.NewReader(pubKey)
|
||||||
entries, err := openpgp.ReadArmoredKeyRing(pubKeyReader)
|
entries, err := openpgp.ReadArmoredKeyRing(pubKeyReader)
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ func TestEncryptDecryptKeys(t *testing.T) {
|
||||||
Algo: constants.AES256,
|
Algo: constants.AES256,
|
||||||
}
|
}
|
||||||
|
|
||||||
packet, err := SetKey(rsaPublicKeyRing, testSymmetricKey)
|
packet, err := rsaPublicKeyRing.EncryptKey(testSymmetricKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Cannot encrypt keypacket with RSA keyring", err)
|
t.Fatal("Cannot encrypt keypacket with RSA keyring", err)
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ func TestEncryptDecryptKeys(t *testing.T) {
|
||||||
}
|
}
|
||||||
assert.Exactly(t, testSymmetricKey, rsaTestSymmetricKey)
|
assert.Exactly(t, testSymmetricKey, rsaTestSymmetricKey)
|
||||||
|
|
||||||
packet, err = SetKey(ecPublicKeyRing, testSymmetricKey)
|
packet, err = ecPublicKeyRing.EncryptKey(testSymmetricKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Cannot encrypt keypacket with EC keyring", err)
|
t.Fatal("Cannot encrypt keypacket with EC keyring", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,19 +25,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// A keypair contains a private key and a public key.
|
// A keypair contains a private key and a public key.
|
||||||
type pmKeyObject struct {
|
type pgpKeyObject struct {
|
||||||
ID string
|
ID string
|
||||||
Version int
|
Version int
|
||||||
Flags int
|
Flags int
|
||||||
Fingerprint string
|
Fingerprint string
|
||||||
PublicKey string `json:",omitempty"`
|
PublicKey string `json:",omitempty"`
|
||||||
PrivateKey string
|
PrivateKey string
|
||||||
//Activation string // Undocumented
|
|
||||||
Primary int
|
Primary int
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrivateKeyReader
|
// PrivateKeyReader
|
||||||
func (ko *pmKeyObject) PrivateKeyReader() io.Reader {
|
func (ko *pgpKeyObject) PrivateKeyReader() io.Reader {
|
||||||
return strings.NewReader(ko.PrivateKey)
|
return strings.NewReader(ko.PrivateKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +60,7 @@ type SignedString struct {
|
||||||
Signed *Signature
|
Signed *Signature
|
||||||
}
|
}
|
||||||
|
|
||||||
var errKeyringNotUnlocked = errors.New("pm-crypto: cannot sign message, key ring is not unlocked")
|
var errKeyringNotUnlocked = errors.New("gopenpgp: cannot sign message, key ring is not unlocked")
|
||||||
|
|
||||||
// Err returns a non-nil error if the signature is invalid.
|
// Err returns a non-nil error if the signature is invalid.
|
||||||
func (s *Signature) Err() error {
|
func (s *Signature) Err() error {
|
||||||
|
|
@ -377,7 +376,7 @@ func (kr *KeyRing) DecryptArmored(r io.Reader) (decrypted io.Reader, signed *Sig
|
||||||
}
|
}
|
||||||
|
|
||||||
if block.Type != constants.PGPMessageHeader {
|
if block.Type != constants.PGPMessageHeader {
|
||||||
err = errors.New("pm-crypto: not an armored PGP message")
|
err = errors.New("gopenpgp: not an armored PGP message")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -510,7 +509,7 @@ func (kr *KeyRing) readFrom(r io.Reader, armored bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(entities) == 0 {
|
if len(entities) == 0 {
|
||||||
return errors.New("pm-crypto: key ring doesn't contain any key")
|
return errors.New("gopenpgp: key ring doesn't contain any key")
|
||||||
}
|
}
|
||||||
|
|
||||||
kr.entities = append(kr.entities, entities...)
|
kr.entities = append(kr.entities, entities...)
|
||||||
|
|
@ -547,7 +546,7 @@ func (pgp *GopenPGP) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
|
||||||
func (kr *KeyRing) UnmarshalJSON(b []byte) (err error) {
|
func (kr *KeyRing) UnmarshalJSON(b []byte) (err error) {
|
||||||
kr.entities = nil
|
kr.entities = nil
|
||||||
|
|
||||||
keyObjs := []pmKeyObject{}
|
keyObjs := []pgpKeyObject{}
|
||||||
if err = json.Unmarshal(b, &keyObjs); err != nil {
|
if err = json.Unmarshal(b, &keyObjs); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,11 +121,11 @@ func TestKeyRing_ArmoredPublicKeyString(t *testing.T) {
|
||||||
|
|
||||||
func TestCheckPassphrase(t *testing.T) {
|
func TestCheckPassphrase(t *testing.T) {
|
||||||
encryptedKeyRing, _ := ReadArmoredKeyRing(strings.NewReader(readTestFile("keyring_privateKey", false)))
|
encryptedKeyRing, _ := ReadArmoredKeyRing(strings.NewReader(readTestFile("keyring_privateKey", false)))
|
||||||
is_correct := encryptedKeyRing.CheckPassphrase("Wrong password")
|
isCorrect := encryptedKeyRing.CheckPassphrase("Wrong password")
|
||||||
assert.Exactly(t, false, is_correct)
|
assert.Exactly(t, false, isCorrect)
|
||||||
|
|
||||||
is_correct = encryptedKeyRing.CheckPassphrase(testMailboxPassword)
|
isCorrect = encryptedKeyRing.CheckPassphrase(testMailboxPassword)
|
||||||
assert.Exactly(t, true, is_correct)
|
assert.Exactly(t, true, isCorrect)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIdentities(t *testing.T) {
|
func TestIdentities(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ func decryptCore(
|
||||||
) (*openpgp.MessageDetails, error) {
|
) (*openpgp.MessageDetails, error) {
|
||||||
rawPwd := []byte(passphrase)
|
rawPwd := []byte(passphrase)
|
||||||
if err := privKey.Unlock(rawPwd); err != nil {
|
if err := privKey.Unlock(rawPwd); err != nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot decrypt passphrase: %v", err)
|
err = fmt.Errorf("gopenpgp: cannot decrypt passphrase: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
pmmime "github.com/ProtonMail/go-mime"
|
gomime "github.com/ProtonMail/go-mime"
|
||||||
|
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
func (pgp GopenPGP) parseMIME(
|
func (pgp GopenPGP) parseMIME(
|
||||||
mimeBody string, verifierKey *KeyRing,
|
mimeBody string, verifierKey *KeyRing,
|
||||||
) (*pmmime.BodyCollector, int, []string, []string, error) {
|
) (*gomime.BodyCollector, int, []string, []string, error) {
|
||||||
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
|
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, nil, nil, err
|
return nil, 0, nil, nil, err
|
||||||
|
|
@ -28,10 +28,10 @@ func (pgp GopenPGP) parseMIME(
|
||||||
return nil, 0, nil, nil, err
|
return nil, 0, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
printAccepter := pmmime.NewMIMEPrinter()
|
printAccepter := gomime.NewMIMEPrinter()
|
||||||
bodyCollector := pmmime.NewBodyCollector(printAccepter)
|
bodyCollector := gomime.NewBodyCollector(printAccepter)
|
||||||
attachmentsCollector := pmmime.NewAttachmentsCollector(bodyCollector)
|
attachmentsCollector := gomime.NewAttachmentsCollector(bodyCollector)
|
||||||
mimeVisitor := pmmime.NewMimeVisitor(attachmentsCollector)
|
mimeVisitor := gomime.NewMimeVisitor(attachmentsCollector)
|
||||||
|
|
||||||
var pgpKering openpgp.KeyRing
|
var pgpKering openpgp.KeyRing
|
||||||
if verifierKey != nil {
|
if verifierKey != nil {
|
||||||
|
|
@ -40,7 +40,7 @@ func (pgp GopenPGP) parseMIME(
|
||||||
|
|
||||||
signatureCollector := newSignatureCollector(mimeVisitor, pgpKering, config)
|
signatureCollector := newSignatureCollector(mimeVisitor, pgpKering, config)
|
||||||
|
|
||||||
err = pmmime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
|
err = gomime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
|
||||||
|
|
||||||
verified := signatureCollector.verified
|
verified := signatureCollector.verified
|
||||||
body := bodyCollector
|
body := bodyCollector
|
||||||
|
|
@ -50,17 +50,17 @@ func (pgp GopenPGP) parseMIME(
|
||||||
return body, verified, atts, attHeaders, err
|
return body, verified, atts, attHeaders, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIMECallbacks defines a call back methods to process MIME message
|
// MIMECallbacks defines callback methods to process a MIME message.
|
||||||
type MIMECallbacks interface {
|
type MIMECallbacks interface {
|
||||||
OnBody(body string, mimetype string)
|
OnBody(body string, mimetype string)
|
||||||
OnAttachment(headers string, data []byte)
|
OnAttachment(headers string, data []byte)
|
||||||
// Encrypted headers can be an attachment and thus be placed at the end of the mime structure
|
// Encrypted headers can be in an attachment and thus be placed at the end of the mime structure.
|
||||||
OnEncryptedHeaders(headers string)
|
OnEncryptedHeaders(headers string)
|
||||||
OnVerified(verified int)
|
OnVerified(verified int)
|
||||||
OnError(err error)
|
OnError(err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptMIMEMessage decrypts a MIME message
|
// DecryptMIMEMessage decrypts a MIME message.
|
||||||
func (pgp *GopenPGP) DecryptMIMEMessage(
|
func (pgp *GopenPGP) DecryptMIMEMessage(
|
||||||
encryptedText string, verifierKey, privateKeyRing *KeyRing,
|
encryptedText string, verifierKey, privateKeyRing *KeyRing,
|
||||||
passphrase string, callbacks MIMECallbacks, verifyTime int64,
|
passphrase string, callbacks MIMECallbacks, verifyTime int64,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RandomToken with a default key size
|
// RandomToken generates a random token with the key size of the default cipher.
|
||||||
func (pgp *GopenPGP) RandomToken() ([]byte, error) {
|
func (pgp *GopenPGP) RandomToken() ([]byte, error) {
|
||||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||||
keySize := config.DefaultCipher.KeySize()
|
keySize := config.DefaultCipher.KeySize()
|
||||||
|
|
@ -24,7 +24,7 @@ func (pgp *GopenPGP) RandomToken() ([]byte, error) {
|
||||||
return symKey, nil
|
return symKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RandomTokenWith a given key size
|
// RandomTokenWith generates a random token with the given key size.
|
||||||
func (pgp *GopenPGP) RandomTokenWith(size int) ([]byte, error) {
|
func (pgp *GopenPGP) RandomTokenWith(size int) ([]byte, error) {
|
||||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||||
symKey := make([]byte, size)
|
symKey := make([]byte, size)
|
||||||
|
|
@ -34,12 +34,13 @@ func (pgp *GopenPGP) RandomTokenWith(size int) ([]byte, error) {
|
||||||
return symKey, nil
|
return symKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSessionFromKeyPacket gets session key no encoding in and out
|
// GetSessionFromKeyPacket returns the decrypted session key from a binary
|
||||||
|
// public-key encrypted session key packet.
|
||||||
func (pgp *GopenPGP) GetSessionFromKeyPacket(
|
func (pgp *GopenPGP) GetSessionFromKeyPacket(
|
||||||
keyPackage []byte, privateKey *KeyRing, passphrase string,
|
keyPacket []byte, privateKey *KeyRing, passphrase string,
|
||||||
) (*SymmetricKey,
|
) (*SymmetricKey,
|
||||||
error) {
|
error) {
|
||||||
keyReader := bytes.NewReader(keyPackage)
|
keyReader := bytes.NewReader(keyPacket)
|
||||||
packets := packet.NewReader(keyReader)
|
packets := packet.NewReader(keyReader)
|
||||||
|
|
||||||
var p packet.Packet
|
var p packet.Packet
|
||||||
|
|
@ -72,7 +73,8 @@ func (pgp *GopenPGP) GetSessionFromKeyPacket(
|
||||||
return getSessionSplit(ek)
|
return getSessionSplit(ek)
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyPacketWithPublicKey returns binary packet from symmetric key and armored public key
|
// KeyPacketWithPublicKey encrypts the session key with the armored publicKey
|
||||||
|
// and returns a binary public-key encrypted session key packet.
|
||||||
func (pgp *GopenPGP) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey string) ([]byte, error) {
|
func (pgp *GopenPGP) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey string) ([]byte, error) {
|
||||||
pubkeyRaw, err := armor.Unarmor(publicKey)
|
pubkeyRaw, err := armor.Unarmor(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -81,7 +83,8 @@ func (pgp *GopenPGP) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKe
|
||||||
return pgp.KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw)
|
return pgp.KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw)
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyPacketWithPublicKeyBin returns binary packet from symmetric key and binary public key
|
// KeyPacketWithPublicKeyBin encrypts the session key with the unarmored
|
||||||
|
// publicKey and returns a binary public-key encrypted session key packet.
|
||||||
func (pgp *GopenPGP) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publicKey []byte) ([]byte, error) {
|
func (pgp *GopenPGP) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publicKey []byte) ([]byte, error) {
|
||||||
publicKeyReader := bytes.NewReader(publicKey)
|
publicKeyReader := bytes.NewReader(publicKey)
|
||||||
pubKeyEntries, err := openpgp.ReadKeyRing(publicKeyReader)
|
pubKeyEntries, err := openpgp.ReadKeyRing(publicKeyReader)
|
||||||
|
|
@ -123,15 +126,16 @@ func (pgp *GopenPGP) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publi
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = packet.SerializeEncryptedKey(outbuf, pub, cf, sessionSplit.Key, nil); err != nil {
|
if err = packet.SerializeEncryptedKey(outbuf, pub, cf, sessionSplit.Key, nil); err != nil {
|
||||||
err = fmt.Errorf("pm-crypto: cannot set key: %v", err)
|
err = fmt.Errorf("gopenpgp: cannot set key: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return outbuf.Bytes(), nil
|
return outbuf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSessionFromSymmetricPacket extracts symmentric key from binary packet
|
// GetSessionFromSymmetricPacket decrypts the binary symmetrically encrypted
|
||||||
func (pgp *GopenPGP) GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*SymmetricKey, error) {
|
// session key packet and returns the session key.
|
||||||
keyReader := bytes.NewReader(keyPackage)
|
func (pgp *GopenPGP) GetSessionFromSymmetricPacket(keyPacket []byte, password string) (*SymmetricKey, error) {
|
||||||
|
keyReader := bytes.NewReader(keyPacket)
|
||||||
packets := packet.NewReader(keyReader)
|
packets := packet.NewReader(keyReader)
|
||||||
|
|
||||||
var symKeys []*packet.SymmetricKeyEncrypted
|
var symKeys []*packet.SymmetricKeyEncrypted
|
||||||
|
|
@ -167,7 +171,8 @@ func (pgp *GopenPGP) GetSessionFromSymmetricPacket(keyPackage []byte, password s
|
||||||
return nil, errors.New("password incorrect")
|
return nil, errors.New("password incorrect")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SymmetricKeyPacketWithPassword return binary packet from symmetric key and password
|
// SymmetricKeyPacketWithPassword encrypts the session key with the password and
|
||||||
|
// returns a binary symmetrically encrypted session key packet.
|
||||||
func (pgp *GopenPGP) SymmetricKeyPacketWithPassword(sessionSplit *SymmetricKey, password string) ([]byte, error) {
|
func (pgp *GopenPGP) SymmetricKeyPacketWithPassword(sessionSplit *SymmetricKey, password string) ([]byte, error) {
|
||||||
outbuf := &bytes.Buffer{}
|
outbuf := &bytes.Buffer{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"mime"
|
"mime"
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
|
|
||||||
"github.com/ProtonMail/go-mime"
|
gomime "github.com/ProtonMail/go-mime"
|
||||||
|
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
|
|
@ -17,13 +17,13 @@ import (
|
||||||
type SignatureCollector struct {
|
type SignatureCollector struct {
|
||||||
config *packet.Config
|
config *packet.Config
|
||||||
keyring openpgp.KeyRing
|
keyring openpgp.KeyRing
|
||||||
target pmmime.VisitAcceptor
|
target gomime.VisitAcceptor
|
||||||
signature string
|
signature string
|
||||||
verified int
|
verified int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSignatureCollector(
|
func newSignatureCollector(
|
||||||
targetAcceptor pmmime.VisitAcceptor, keyring openpgp.KeyRing, config *packet.Config,
|
targetAcceptor gomime.VisitAcceptor, keyring openpgp.KeyRing, config *packet.Config,
|
||||||
) *SignatureCollector {
|
) *SignatureCollector {
|
||||||
return &SignatureCollector{
|
return &SignatureCollector{
|
||||||
target: targetAcceptor,
|
target: targetAcceptor,
|
||||||
|
|
@ -39,10 +39,10 @@ func (sc *SignatureCollector) Accept(
|
||||||
) (err error) {
|
) (err error) {
|
||||||
parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||||
if parentMediaType == "multipart/signed" {
|
if parentMediaType == "multipart/signed" {
|
||||||
newPart, rawBody := pmmime.GetRawMimePart(part, "--"+params["boundary"])
|
newPart, rawBody := gomime.GetRawMimePart(part, "--"+params["boundary"])
|
||||||
var multiparts []io.Reader
|
var multiparts []io.Reader
|
||||||
var multipartHeaders []textproto.MIMEHeader
|
var multipartHeaders []textproto.MIMEHeader
|
||||||
if multiparts, multipartHeaders, err = pmmime.GetMultipartParts(newPart, params); err == nil {
|
if multiparts, multipartHeaders, err = gomime.GetMultipartParts(newPart, params); err == nil {
|
||||||
hasPlainChild := false
|
hasPlainChild := false
|
||||||
for _, header := range multipartHeaders {
|
for _, header := range multipartHeaders {
|
||||||
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||||
|
|
@ -77,7 +77,7 @@ func (sc *SignatureCollector) Accept(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
decodedPart := pmmime.DecodeContentEncoding(
|
decodedPart := gomime.DecodeContentEncoding(
|
||||||
bytes.NewReader(partData),
|
bytes.NewReader(partData),
|
||||||
multipartHeaders[1].Get("Content-Transfer-Encoding"))
|
multipartHeaders[1].Get("Content-Transfer-Encoding"))
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ func (sc *SignatureCollector) Accept(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
buffer, err = pmmime.DecodeCharset(buffer, params)
|
buffer, err = gomime.DecodeCharset(buffer, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
package: proton/gopenpgp
|
package: github.com/ProtonMail/gopenpgp
|
||||||
import:
|
import:
|
||||||
- package: golang.org/x/crypto
|
- package: golang.org/x/crypto
|
||||||
version: master
|
|
||||||
repo: https://github.com/ProtonMail/crypto.git
|
repo: https://github.com/ProtonMail/crypto.git
|
||||||
version: 9e4251120d8c43f10024d798bc6dde21d40704a0
|
version: master
|
||||||
- package: github.com/ProtonMail/go-mime
|
- package: github.com/ProtonMail/go-mime
|
||||||
repo: https://github.com/ProtonMail/go-mime.git
|
repo: https://github.com/ProtonMail/go-mime.git
|
||||||
|
version: master
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ProtonMail/gopenpgp/constants"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/ProtonMail/gopenpgp/constants"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TrimNewlines removes a whitespace in the end of string (don't stop on linebreak)
|
// TrimNewlines removes a whitespace in the end of string (don't stop on linebreak)
|
||||||
|
|
@ -15,7 +16,7 @@ func TrimNewlines(input string) string {
|
||||||
// created in the future, to compensate for clock skew
|
// created in the future, to compensate for clock skew
|
||||||
const CreationTimeOffset = int64(60 * 60 * 24 * 2)
|
const CreationTimeOffset = int64(60 * 60 * 24 * 2)
|
||||||
|
|
||||||
// ArmorHeaders from golang pm-crypto
|
// ArmorHeaders from gopenpgp
|
||||||
var ArmorHeaders = map[string]string{
|
var ArmorHeaders = map[string]string{
|
||||||
"Version": constants.ArmorHeaderVersion,
|
"Version": constants.ArmorHeaderVersion,
|
||||||
"Comment": constants.ArmorHeaderComment,
|
"Comment": constants.ArmorHeaderComment,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue