Update lint (#44)
* Reduce complexity of SignatureCollector.Accept * Add stylecheck linter, and lint accordingly * Rephrase some comments * godot - Top level comments should end with a dot. * nestif - Reduce nested complexity of code * Review changes Co-authored-by: Aron Wussler <aron@wussler.it>
This commit is contained in:
parent
222decb919
commit
ac8a49c114
15 changed files with 252 additions and 265 deletions
|
|
@ -22,14 +22,14 @@ type AttachmentProcessor struct {
|
|||
err error
|
||||
}
|
||||
|
||||
// Process writes attachment data to be encrypted
|
||||
// Process writes attachment data to be encrypted.
|
||||
func (ap *AttachmentProcessor) Process(plainData []byte) {
|
||||
if _, err := (*ap.w).Write(plainData); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Finish closes the attachment and returns the encrypted data
|
||||
// Finish closes the attachment and returns the encrypted data.
|
||||
func (ap *AttachmentProcessor) Finish() (*PGPSplitMessage, error) {
|
||||
if ap.err != nil {
|
||||
return nil, ap.err
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import (
|
|||
packet "golang.org/x/crypto/openpgp/packet"
|
||||
)
|
||||
|
||||
// Key contains a single private or public key
|
||||
// Key contains a single private or public key.
|
||||
type Key struct {
|
||||
// PGP entities in this keyring.
|
||||
entity *openpgp.Entity
|
||||
|
|
@ -50,12 +50,12 @@ func NewKeyFromReader(r io.Reader) (key *Key, err error) {
|
|||
return key, nil
|
||||
}
|
||||
|
||||
// NewKey creates a new key from the first key in the unarmored binary data
|
||||
// NewKey creates a new key from the first key in the unarmored binary data.
|
||||
func NewKey(binKeys []byte) (key *Key, err error) {
|
||||
return NewKeyFromReader(bytes.NewReader(clone(binKeys)))
|
||||
}
|
||||
|
||||
// NewKeyFromArmored creates a new key from the first key in an armored
|
||||
// NewKeyFromArmored creates a new key from the first key in an armored string.
|
||||
func NewKeyFromArmored(armored string) (key *Key, err error) {
|
||||
return NewKeyFromArmoredReader(strings.NewReader(armored))
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ func (key *Key) Lock(passphrase []byte) (*Key, error) {
|
|||
return lockedKey, nil
|
||||
}
|
||||
|
||||
// Unlock unlocks a copy of the key
|
||||
// Unlock unlocks a copy of the key.
|
||||
func (key *Key) Unlock(passphrase []byte) (*Key, error) {
|
||||
isLocked, err := key.IsLocked()
|
||||
if err != nil {
|
||||
|
|
@ -234,12 +234,12 @@ func (key *Key) IsExpired() bool {
|
|||
return !ok
|
||||
}
|
||||
|
||||
// IsPrivate returns true if the key is private
|
||||
// IsPrivate returns true if the key is private.
|
||||
func (key *Key) IsPrivate() bool {
|
||||
return key.entity.PrivateKey != nil
|
||||
}
|
||||
|
||||
// IsLocked checks if a private key is locked
|
||||
// IsLocked checks if a private key is locked.
|
||||
func (key *Key) IsLocked() (bool, error) {
|
||||
if key.entity.PrivateKey == nil {
|
||||
return true, errors.New("gopenpgp: a public key cannot be locked")
|
||||
|
|
@ -254,7 +254,7 @@ func (key *Key) IsLocked() (bool, error) {
|
|||
return key.entity.PrivateKey.Encrypted, nil
|
||||
}
|
||||
|
||||
// IsUnlocked checks if a private key is unlocked
|
||||
// IsUnlocked checks if a private key is unlocked.
|
||||
func (key *Key) IsUnlocked() (bool, error) {
|
||||
if key.entity.PrivateKey == nil {
|
||||
return true, errors.New("gopenpgp: a public key cannot be unlocked")
|
||||
|
|
@ -269,7 +269,8 @@ func (key *Key) IsUnlocked() (bool, error) {
|
|||
return !key.entity.PrivateKey.Encrypted, nil
|
||||
}
|
||||
|
||||
// Check verifies if the public keys match the private key parameters by signing and verifying
|
||||
// Check verifies if the public keys match the private key parameters by
|
||||
// signing and verifying.
|
||||
func (key *Key) Check() (bool, error) {
|
||||
var err error
|
||||
testSign := bytes.Repeat([]byte{0x01}, 64)
|
||||
|
|
@ -314,22 +315,22 @@ func (key *Key) PrintFingerprints() {
|
|||
fmt.Println("PrimaryKey:" + hex.EncodeToString(key.entity.PrimaryKey.Fingerprint[:]))
|
||||
}
|
||||
|
||||
// GetHexKeyID returns the key ID, hex encoded as a string
|
||||
// GetHexKeyID returns the key ID, hex encoded as a string.
|
||||
func (key *Key) GetHexKeyID() string {
|
||||
return strconv.FormatUint(key.GetKeyID(), 16)
|
||||
}
|
||||
|
||||
// GetKeyID returns the key ID, encoded as 8-byte int
|
||||
// GetKeyID returns the key ID, encoded as 8-byte int.
|
||||
func (key *Key) GetKeyID() uint64 {
|
||||
return key.entity.PrimaryKey.KeyId
|
||||
}
|
||||
|
||||
// GetFingerprint gets the fingerprint from the key
|
||||
// GetFingerprint gets the fingerprint from the key.
|
||||
func (key *Key) GetFingerprint() string {
|
||||
return hex.EncodeToString(key.entity.PrimaryKey.Fingerprint[:])
|
||||
}
|
||||
|
||||
// GetSHA256Fingerprints computes the SHA256 fingerprints of the key and subkeys
|
||||
// GetSHA256Fingerprints computes the SHA256 fingerprints of the key and subkeys.
|
||||
func (key *Key) GetSHA256Fingerprints() (fingerprints []string) {
|
||||
fingerprints = append(fingerprints, hex.EncodeToString(getSHA256FingerprintBytes(key.entity.PrimaryKey)))
|
||||
for _, sub := range key.entity.Subkeys {
|
||||
|
|
@ -340,7 +341,8 @@ func (key *Key) GetSHA256Fingerprints() (fingerprints []string) {
|
|||
|
||||
// --- Internal methods
|
||||
|
||||
// getSHA256FingerprintBytes computes the SHA256 fingerprint of a public key object
|
||||
// getSHA256FingerprintBytes computes the SHA256 fingerprint of a public key
|
||||
// object.
|
||||
func getSHA256FingerprintBytes(pk *packet.PublicKey) []byte {
|
||||
fingerPrint := sha256.New()
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ type Identity struct {
|
|||
|
||||
// --- New keyrings
|
||||
|
||||
// NewKeyRing creates a new KeyRing, empty if key is nil
|
||||
// NewKeyRing creates a new KeyRing, empty if key is nil.
|
||||
func NewKeyRing(key *Key) (*KeyRing, error) {
|
||||
keyRing := &KeyRing{}
|
||||
var err error
|
||||
|
|
@ -36,7 +36,7 @@ func NewKeyRing(key *Key) (*KeyRing, error) {
|
|||
return keyRing, err
|
||||
}
|
||||
|
||||
// --- Add keys to keyring
|
||||
// AddKey adds the given key to the keyring.
|
||||
func (keyRing *KeyRing) AddKey(key *Key) error {
|
||||
if key.IsPrivate() {
|
||||
unlocked, err := key.IsUnlocked()
|
||||
|
|
@ -91,17 +91,17 @@ func (keyRing *KeyRing) getSigningEntity() (*openpgp.Entity, error) {
|
|||
|
||||
// --- Extract info from key
|
||||
|
||||
// CountEntities returns the number of entities in the keyring
|
||||
// CountEntities returns the number of entities in the keyring.
|
||||
func (keyRing *KeyRing) CountEntities() int {
|
||||
return len(keyRing.entities)
|
||||
}
|
||||
|
||||
// CountDecryptionEntities returns the number of entities in the keyring
|
||||
// CountDecryptionEntities returns the number of entities in the keyring.
|
||||
func (keyRing *KeyRing) CountDecryptionEntities() int {
|
||||
return len(keyRing.entities.DecryptionKeys())
|
||||
}
|
||||
|
||||
// Identities returns the list of identities associated with this key ring.
|
||||
// GetIdentities returns the list of identities associated with this key ring.
|
||||
func (keyRing *KeyRing) GetIdentities() []*Identity {
|
||||
var identities []*Identity
|
||||
for _, e := range keyRing.entities {
|
||||
|
|
@ -172,7 +172,7 @@ func FilterExpiredKeys(contactKeys []*KeyRing) (filteredKeys []*KeyRing, err err
|
|||
return filteredKeys, nil
|
||||
}
|
||||
|
||||
// FirstKey returns a KeyRing with only the first key of the original one
|
||||
// FirstKey returns a KeyRing with only the first key of the original one.
|
||||
func (keyRing *KeyRing) FirstKey() (*KeyRing, error) {
|
||||
if len(keyRing.entities) == 0 {
|
||||
return nil, errors.New("gopenpgp: No key available in this keyring")
|
||||
|
|
@ -183,7 +183,7 @@ func (keyRing *KeyRing) FirstKey() (*KeyRing, error) {
|
|||
return newKeyRing.Copy()
|
||||
}
|
||||
|
||||
// Copy creates a deep copy of the keyring
|
||||
// Copy creates a deep copy of the keyring.
|
||||
func (keyRing *KeyRing) Copy() (*KeyRing, error) {
|
||||
newKeyRing := &KeyRing{}
|
||||
|
||||
|
|
@ -223,7 +223,7 @@ func (keyRing *KeyRing) ClearPrivateParams() {
|
|||
|
||||
// INTERNAL FUNCTIONS
|
||||
|
||||
// append appends a key to the keyring
|
||||
// appendKey appends a key to the keyring.
|
||||
func (keyRing *KeyRing) appendKey(key *Key) {
|
||||
keyRing.entities = append(keyRing.entities, key.entity)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import (
|
|||
|
||||
// Encrypt encrypts a PlainMessage, outputs a PGPMessage.
|
||||
// If an unlocked private key is also provided it will also sign the message.
|
||||
// * message : The plaintext input as a PlainMessage
|
||||
// * privateKey : (optional) an unlocked private keyring to include signature in the message
|
||||
// * message : The plaintext input as a PlainMessage.
|
||||
// * privateKey : (optional) an unlocked private keyring to include signature in the message.
|
||||
func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PGPMessage, error) {
|
||||
encrypted, err := asymmetricEncrypt(message.GetBinary(), keyRing, privateKey, message.IsBinary())
|
||||
if err != nil {
|
||||
|
|
@ -28,7 +28,8 @@ func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PG
|
|||
// * verifyKey : Public key for signature verification (optional)
|
||||
// * verifyTime : Time at verification (necessary only if verifyKey is not nil)
|
||||
//
|
||||
// When verifyKey is not provided, then verifyTime should be zero, and signature verification will be ignored
|
||||
// When verifyKey is not provided, then verifyTime should be zero, and
|
||||
// signature verification will be ignored.
|
||||
func (keyRing *KeyRing) Decrypt(
|
||||
message *PGPMessage, verifyKey *KeyRing, verifyTime int64,
|
||||
) (*PlainMessage, error) {
|
||||
|
|
@ -37,7 +38,7 @@ func (keyRing *KeyRing) Decrypt(
|
|||
return NewPlainMessage(decrypted), err
|
||||
}
|
||||
|
||||
// SignDetached generates and returns a PGPSignature for a given PlainMessage
|
||||
// SignDetached generates and returns a PGPSignature for a given PlainMessage.
|
||||
func (keyRing *KeyRing) SignDetached(message *PlainMessage) (*PGPSignature, error) {
|
||||
signEntity, err := keyRing.getSigningEntity()
|
||||
if err != nil {
|
||||
|
|
@ -55,7 +56,7 @@ func (keyRing *KeyRing) SignDetached(message *PlainMessage) (*PGPSignature, erro
|
|||
}
|
||||
|
||||
// VerifyDetached verifies a PlainMessage with embedded a PGPSignature
|
||||
// and returns a SignatureVerificationError if fails
|
||||
// and returns a SignatureVerificationError if fails.
|
||||
func (keyRing *KeyRing) VerifyDetached(message *PlainMessage, signature *PGPSignature, verifyTime int64) error {
|
||||
return verifySignature(
|
||||
keyRing.entities,
|
||||
|
|
@ -67,7 +68,7 @@ func (keyRing *KeyRing) VerifyDetached(message *PlainMessage, signature *PGPSign
|
|||
|
||||
// ------ INTERNAL FUNCTIONS -------
|
||||
|
||||
// Core for encryption+signature functions
|
||||
// Core for encryption+signature functions.
|
||||
func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isBinary bool) ([]byte, error) {
|
||||
var outBuf bytes.Buffer
|
||||
var encryptWriter io.WriteCloser
|
||||
|
|
@ -111,7 +112,7 @@ func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isB
|
|||
return outBuf.Bytes(), nil
|
||||
}
|
||||
|
||||
// Core for decryption+verification functions
|
||||
// Core for decryption+verification functions.
|
||||
func asymmetricDecrypt(
|
||||
encryptedIO io.Reader, privateKey *KeyRing, verifyKey *KeyRing, verifyTime int64,
|
||||
) (plaintext []byte, err error) {
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ type PGPSplitMessage struct {
|
|||
KeyPacket []byte
|
||||
}
|
||||
|
||||
// ClearTextMessage, split signed clear text message container.
|
||||
// A Cleartext message is a signed PGP message, that is not encrypted,
|
||||
// A ClearTextMessage is a signed but not encrypted PGP message,
|
||||
// i.e. the ones beginning with -----BEGIN PGP SIGNED MESSAGE-----
|
||||
type ClearTextMessage struct {
|
||||
Data []byte
|
||||
|
|
@ -126,7 +125,8 @@ func NewPGPSignature(data []byte) *PGPSignature {
|
|||
}
|
||||
}
|
||||
|
||||
// NewPGPSignatureFromArmored generates a new PGPSignature from the armored string ready for verification.
|
||||
// NewPGPSignatureFromArmored generates a new PGPSignature from the armored
|
||||
// string ready for verification.
|
||||
func NewPGPSignatureFromArmored(armored string) (*PGPSignature, error) {
|
||||
encryptedIO, err := internal.Unarmor(armored)
|
||||
if err != nil {
|
||||
|
|
@ -143,7 +143,8 @@ func NewPGPSignatureFromArmored(armored string) (*PGPSignature, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// NewClearTextMessage generates a new ClearTextMessage from data and signature
|
||||
// NewClearTextMessage generates a new ClearTextMessage from data and
|
||||
// signature.
|
||||
func NewClearTextMessage(data []byte, signature []byte) *ClearTextMessage {
|
||||
return &ClearTextMessage{
|
||||
Data: clone(data),
|
||||
|
|
@ -151,7 +152,8 @@ func NewClearTextMessage(data []byte, signature []byte) *ClearTextMessage {
|
|||
}
|
||||
}
|
||||
|
||||
// NewClearTextMessageFromArmored returns the message body and unarmored signature from a clearsigned message.
|
||||
// NewClearTextMessageFromArmored returns the message body and unarmored
|
||||
// signature from a clearsigned message.
|
||||
func NewClearTextMessageFromArmored(signedMessage string) (*ClearTextMessage, error) {
|
||||
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
|
||||
if len(rest) != 0 {
|
||||
|
|
@ -168,79 +170,84 @@ func NewClearTextMessageFromArmored(signedMessage string) (*ClearTextMessage, er
|
|||
|
||||
// ---- MODEL METHODS -----
|
||||
|
||||
// GetBinary returns the binary content of the message as a []byte
|
||||
// GetBinary returns the binary content of the message as a []byte.
|
||||
func (msg *PlainMessage) GetBinary() []byte {
|
||||
return msg.Data
|
||||
}
|
||||
|
||||
// GetString returns the content of the message as a string
|
||||
// GetString returns the content of the message as a string.
|
||||
func (msg *PlainMessage) GetString() string {
|
||||
return string(msg.Data)
|
||||
}
|
||||
|
||||
// GetBase64 returns the base-64 encoded binary content of the message as a string
|
||||
// GetBase64 returns the base-64 encoded binary content of the message as a
|
||||
// string.
|
||||
func (msg *PlainMessage) GetBase64() string {
|
||||
return base64.StdEncoding.EncodeToString(msg.Data)
|
||||
}
|
||||
|
||||
// NewReader returns a New io.Reader for the binary data of the message
|
||||
// NewReader returns a New io.Reader for the binary data of the message.
|
||||
func (msg *PlainMessage) NewReader() io.Reader {
|
||||
return bytes.NewReader(msg.GetBinary())
|
||||
}
|
||||
|
||||
// IsText returns whether the message is a text message
|
||||
// IsText returns whether the message is a text message.
|
||||
func (msg *PlainMessage) IsText() bool {
|
||||
return msg.TextType
|
||||
}
|
||||
|
||||
// IsBinary returns whether the message is a binary message
|
||||
// IsBinary returns whether the message is a binary message.
|
||||
func (msg *PlainMessage) IsBinary() bool {
|
||||
return !msg.TextType
|
||||
}
|
||||
|
||||
// GetBinary returns the unarmored binary content of the message as a []byte
|
||||
// GetBinary returns the unarmored binary content of the message as a []byte.
|
||||
func (msg *PGPMessage) GetBinary() []byte {
|
||||
return msg.Data
|
||||
}
|
||||
|
||||
// NewReader returns a New io.Reader for the unarmored binary data of the message
|
||||
// NewReader returns a New io.Reader for the unarmored binary data of the
|
||||
// message.
|
||||
func (msg *PGPMessage) NewReader() io.Reader {
|
||||
return bytes.NewReader(msg.GetBinary())
|
||||
}
|
||||
|
||||
// GetArmored returns the armored message as a string
|
||||
// GetArmored returns the armored message as a string.
|
||||
func (msg *PGPMessage) GetArmored() (string, error) {
|
||||
return armor.ArmorWithType(msg.Data, constants.PGPMessageHeader)
|
||||
}
|
||||
|
||||
// GetBinaryDataPacket returns the unarmored binary datapacket as a []byte
|
||||
// GetBinaryDataPacket returns the unarmored binary datapacket as a []byte.
|
||||
func (msg *PGPSplitMessage) GetBinaryDataPacket() []byte {
|
||||
return msg.DataPacket
|
||||
}
|
||||
|
||||
// GetBinaryKeyPacket returns the unarmored binary keypacket as a []byte
|
||||
// GetBinaryKeyPacket returns the unarmored binary keypacket as a []byte.
|
||||
func (msg *PGPSplitMessage) GetBinaryKeyPacket() []byte {
|
||||
return msg.KeyPacket
|
||||
}
|
||||
|
||||
// GetBinary returns the unarmored binary joined packets as a []byte
|
||||
// GetBinary returns the unarmored binary joined packets as a []byte.
|
||||
func (msg *PGPSplitMessage) GetBinary() []byte {
|
||||
return append(msg.KeyPacket, msg.DataPacket...)
|
||||
}
|
||||
|
||||
// GetArmored returns the armored message as a string, with joined data and key packets
|
||||
// GetArmored returns the armored message as a string, with joined data and key
|
||||
// packets.
|
||||
func (msg *PGPSplitMessage) GetArmored() (string, error) {
|
||||
return armor.ArmorWithType(msg.GetBinary(), constants.PGPMessageHeader)
|
||||
}
|
||||
|
||||
// GetPGPMessage joins asymmetric session key packet with the symmetric data packet to obtain a PGP message
|
||||
// GetPGPMessage joins asymmetric session key packet with the symmetric data
|
||||
// packet to obtain a PGP message.
|
||||
func (msg *PGPSplitMessage) GetPGPMessage() *PGPMessage {
|
||||
return NewPGPMessage(append(msg.KeyPacket, msg.DataPacket...))
|
||||
}
|
||||
|
||||
// SeparateKeyAndData returns the first keypacket and the (hopefully unique) dataPacket (not verified)
|
||||
// * estimatedLength is the estimate length of the message
|
||||
// * garbageCollector > 0 activates the garbage collector
|
||||
// SeparateKeyAndData returns the first keypacket and the (hopefully unique)
|
||||
// dataPacket (not verified).
|
||||
// * estimatedLength is the estimate length of the message.
|
||||
// * garbageCollector > 0 activates the garbage collector.
|
||||
func (msg *PGPMessage) SeparateKeyAndData(estimatedLength, garbageCollector int) (outSplit *PGPSplitMessage, err error) {
|
||||
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
|
||||
packets := packet.NewReader(bytes.NewReader(msg.Data))
|
||||
|
|
@ -334,32 +341,33 @@ func (msg *PGPMessage) SeparateKeyAndData(estimatedLength, garbageCollector int)
|
|||
return outSplit, nil
|
||||
}
|
||||
|
||||
// GetBinary returns the unarmored binary content of the signature as a []byte
|
||||
// GetBinary returns the unarmored binary content of the signature as a []byte.
|
||||
func (msg *PGPSignature) GetBinary() []byte {
|
||||
return msg.Data
|
||||
}
|
||||
|
||||
// GetArmored returns the armored signature as a string
|
||||
// GetArmored returns the armored signature as a string.
|
||||
func (msg *PGPSignature) GetArmored() (string, error) {
|
||||
return armor.ArmorWithType(msg.Data, constants.PGPSignatureHeader)
|
||||
}
|
||||
|
||||
// GetBinary returns the unarmored signed data as a []byte
|
||||
// GetBinary returns the unarmored signed data as a []byte.
|
||||
func (msg *ClearTextMessage) GetBinary() []byte {
|
||||
return msg.Data
|
||||
}
|
||||
|
||||
// GetString returns the unarmored signed data as a string
|
||||
// GetString returns the unarmored signed data as a string.
|
||||
func (msg *ClearTextMessage) GetString() string {
|
||||
return string(msg.Data)
|
||||
}
|
||||
|
||||
// GetBinarySignature returns the unarmored binary signature as a []byte
|
||||
// GetBinarySignature returns the unarmored binary signature as a []byte.
|
||||
func (msg *ClearTextMessage) GetBinarySignature() []byte {
|
||||
return msg.Signature
|
||||
}
|
||||
|
||||
// GetArmored armors plaintext and signature with the PGP SIGNED MESSAGE armoring
|
||||
// GetArmored armors plaintext and signature with the PGP SIGNED MESSAGE
|
||||
// armoring.
|
||||
func (msg *ClearTextMessage) GetArmored() (string, error) {
|
||||
armSignature, err := armor.ArmorWithType(msg.GetBinarySignature(), constants.PGPSignatureHeader)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,11 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Encrypt encrypts a PlainMessage to PGPMessage with a SymmetricKey
|
||||
// * message : The plain data as a PlainMessage
|
||||
// * password: A password that will be derived into an encryption key
|
||||
// * output : The encrypted data as PGPMessage
|
||||
// EncryptMessageWithPassword encrypts a PlainMessage to PGPMessage with a
|
||||
// SymmetricKey.
|
||||
// * message : The plain data as a PlainMessage.
|
||||
// * password: A password that will be derived into an encryption key.
|
||||
// * output : The encrypted data as PGPMessage.
|
||||
func EncryptMessageWithPassword(message *PlainMessage, password []byte) (*PGPMessage, error) {
|
||||
encrypted, err := passwordEncrypt(message.GetBinary(), password, message.IsBinary())
|
||||
if err != nil {
|
||||
|
|
@ -23,10 +24,10 @@ func EncryptMessageWithPassword(message *PlainMessage, password []byte) (*PGPMes
|
|||
return NewPGPMessage(encrypted), nil
|
||||
}
|
||||
|
||||
// Decrypt decrypts password protected pgp binary messages
|
||||
// * encrypted: The encrypted data as PGPMessage
|
||||
// * password: A password that will be derived into an encryption key
|
||||
// * output: The decrypted data as PlainMessage
|
||||
// DecryptMessageWithPassword decrypts password protected pgp binary messages.
|
||||
// * encrypted: The encrypted data as PGPMessage.
|
||||
// * password: A password that will be derived into an encryption key.
|
||||
// * output: The decrypted data as PlainMessage.
|
||||
func DecryptMessageWithPassword(message *PGPMessage, password []byte) (*PlainMessage, error) {
|
||||
decrypted, err := passwordDecrypt(message.NewReader(), password)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func (sk *SessionKey) GetBase64Key() string {
|
|||
return base64.StdEncoding.EncodeToString(sk.Key)
|
||||
}
|
||||
|
||||
// RandomToken generates a random token with the specified key size
|
||||
// RandomToken generates a random token with the specified key size.
|
||||
func RandomToken(size int) ([]byte, error) {
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||
symKey := make([]byte, size)
|
||||
|
|
@ -55,7 +55,8 @@ func RandomToken(size int) ([]byte, error) {
|
|||
return symKey, nil
|
||||
}
|
||||
|
||||
// GenerateSessionKeyAlgo generates a random key of the correct length for the specified algorithm
|
||||
// GenerateSessionKeyAlgo generates a random key of the correct length for the
|
||||
// specified algorithm.
|
||||
func GenerateSessionKeyAlgo(algo string) (sk *SessionKey, err error) {
|
||||
cf, ok := symKeyAlgos[algo]
|
||||
if !ok {
|
||||
|
|
@ -73,7 +74,7 @@ func GenerateSessionKeyAlgo(algo string) (sk *SessionKey, err error) {
|
|||
return sk, nil
|
||||
}
|
||||
|
||||
// GenerateSessionKey generates a random key for the default cipher
|
||||
// GenerateSessionKey generates a random key for the default cipher.
|
||||
func GenerateSessionKey() (*SessionKey, error) {
|
||||
return GenerateSessionKeyAlgo(constants.AES256)
|
||||
}
|
||||
|
|
@ -105,9 +106,9 @@ func newSessionKeyFromEncrypted(ek *packet.EncryptedKey) (*SessionKey, error) {
|
|||
return symmetricKey, nil
|
||||
}
|
||||
|
||||
// Encrypt encrypts a PlainMessage to PGPMessage with a SessionKey
|
||||
// * message : The plain data as a PlainMessage
|
||||
// * output : The encrypted data as PGPMessage
|
||||
// Encrypt encrypts a PlainMessage to PGPMessage with a SessionKey.
|
||||
// * message : The plain data as a PlainMessage.
|
||||
// * output : The encrypted data as PGPMessage.
|
||||
func (sk *SessionKey) Encrypt(message *PlainMessage) ([]byte, error) {
|
||||
var encBuf bytes.Buffer
|
||||
var encryptWriter io.WriteCloser
|
||||
|
|
@ -152,9 +153,9 @@ func (sk *SessionKey) Encrypt(message *PlainMessage) ([]byte, error) {
|
|||
return encBuf.Bytes(), nil
|
||||
}
|
||||
|
||||
// Decrypt decrypts password protected pgp binary messages
|
||||
// * encrypted: PGPMessage
|
||||
// * output: PlainMessage
|
||||
// Decrypt decrypts password protected pgp binary messages.
|
||||
// * encrypted: PGPMessage.
|
||||
// * output: PlainMessage.
|
||||
func (sk *SessionKey) Decrypt(dataPacket []byte) (*PlainMessage, error) {
|
||||
var messageReader = bytes.NewReader(dataPacket)
|
||||
var decrypted io.ReadCloser
|
||||
|
|
|
|||
|
|
@ -15,13 +15,14 @@ import (
|
|||
"github.com/ProtonMail/gopenpgp/v2/internal"
|
||||
)
|
||||
|
||||
// SignatureVerificationError is returned from Decrypt and VerifyDetached functions when signature verification fails
|
||||
// SignatureVerificationError is returned from Decrypt and VerifyDetached
|
||||
// functions when signature verification fails.
|
||||
type SignatureVerificationError struct {
|
||||
Status int
|
||||
Message string
|
||||
}
|
||||
|
||||
// Error is the base method for all errors
|
||||
// Error is the base method for all errors.
|
||||
func (e SignatureVerificationError) Error() string {
|
||||
return fmt.Sprintf("Signature Verification Error: %v", e.Message)
|
||||
}
|
||||
|
|
@ -30,7 +31,8 @@ func (e SignatureVerificationError) Error() string {
|
|||
// Internal functions
|
||||
// ------------------
|
||||
|
||||
// newSignatureFailed creates a new SignatureVerificationError, type SIGNATURE_FAILED
|
||||
// newSignatureFailed creates a new SignatureVerificationError, type
|
||||
// SignatureFailed.
|
||||
func newSignatureFailed() SignatureVerificationError {
|
||||
return SignatureVerificationError{
|
||||
constants.SIGNATURE_FAILED,
|
||||
|
|
@ -38,7 +40,8 @@ func newSignatureFailed() SignatureVerificationError {
|
|||
}
|
||||
}
|
||||
|
||||
// newSignatureNotSigned creates a new SignatureVerificationError, type SIGNATURE_NOT_SIGNED
|
||||
// newSignatureNotSigned creates a new SignatureVerificationError, type
|
||||
// SignatureNotSigned.
|
||||
func newSignatureNotSigned() SignatureVerificationError {
|
||||
return SignatureVerificationError{
|
||||
constants.SIGNATURE_NOT_SIGNED,
|
||||
|
|
@ -46,7 +49,8 @@ func newSignatureNotSigned() SignatureVerificationError {
|
|||
}
|
||||
}
|
||||
|
||||
// newSignatureNoVerifier creates a new SignatureVerificationError, type SIGNATURE_NO_VERIFIER
|
||||
// newSignatureNoVerifier creates a new SignatureVerificationError, type
|
||||
// SignatureNoVerifier.
|
||||
func newSignatureNoVerifier() SignatureVerificationError {
|
||||
return SignatureVerificationError{
|
||||
constants.SIGNATURE_NO_VERIFIER,
|
||||
|
|
@ -54,50 +58,46 @@ func newSignatureNoVerifier() SignatureVerificationError {
|
|||
}
|
||||
}
|
||||
|
||||
// processSignatureExpiration handles signature time verification manually, so we can add a margin to the
|
||||
// creationTime check.
|
||||
// processSignatureExpiration handles signature time verification manually, so
|
||||
// we can add a margin to the creationTime check.
|
||||
func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
|
||||
if md.SignatureError == pgpErrors.ErrSignatureExpired {
|
||||
if verifyTime > 0 {
|
||||
created := md.Signature.CreationTime.Unix()
|
||||
expires := int64(math.MaxInt64)
|
||||
if md.Signature.SigLifetimeSecs != nil {
|
||||
expires = int64(*md.Signature.SigLifetimeSecs) + created
|
||||
}
|
||||
if created-internal.CreationTimeOffset <= verifyTime && verifyTime <= expires {
|
||||
md.SignatureError = nil
|
||||
}
|
||||
} else {
|
||||
// verifyTime = 0: time check disabled, everything is okay
|
||||
md.SignatureError = nil
|
||||
}
|
||||
if md.SignatureError != pgpErrors.ErrSignatureExpired {
|
||||
return
|
||||
}
|
||||
if verifyTime == 0 {
|
||||
// verifyTime = 0: time check disabled, everything is okay
|
||||
md.SignatureError = nil
|
||||
return
|
||||
}
|
||||
created := md.Signature.CreationTime.Unix()
|
||||
expires := int64(math.MaxInt64)
|
||||
if md.Signature.SigLifetimeSecs != nil {
|
||||
expires = int64(*md.Signature.SigLifetimeSecs) + created
|
||||
}
|
||||
if created-internal.CreationTimeOffset <= verifyTime && verifyTime <= expires {
|
||||
md.SignatureError = nil
|
||||
}
|
||||
}
|
||||
|
||||
// verifyDetailsSignature verifies signature from message details
|
||||
// verifyDetailsSignature verifies signature from message details.
|
||||
func verifyDetailsSignature(md *openpgp.MessageDetails, verifierKey *KeyRing) error {
|
||||
if md.IsSigned {
|
||||
if md.SignedBy != nil {
|
||||
if len(verifierKey.entities) > 0 {
|
||||
matches := verifierKey.entities.KeysById(md.SignedByKeyId)
|
||||
if len(matches) > 0 {
|
||||
if md.SignatureError == nil {
|
||||
return nil
|
||||
}
|
||||
return newSignatureFailed()
|
||||
}
|
||||
} else {
|
||||
return newSignatureNoVerifier()
|
||||
}
|
||||
} else {
|
||||
if md.SignedBy == nil || len(verifierKey.entities) == 0 {
|
||||
return newSignatureNoVerifier()
|
||||
}
|
||||
matches := verifierKey.entities.KeysById(md.SignedByKeyId)
|
||||
if len(matches) > 0 {
|
||||
if md.SignatureError == nil {
|
||||
return nil
|
||||
}
|
||||
return newSignatureFailed()
|
||||
}
|
||||
}
|
||||
|
||||
return newSignatureNoVerifier()
|
||||
}
|
||||
|
||||
// verifySignature verifies if a signature is valid with the entity list
|
||||
// verifySignature verifies if a signature is valid with the entity list.
|
||||
func verifySignature(pubKeyEntries openpgp.EntityList, origText io.Reader, signature []byte, verifyTime int64) error {
|
||||
config := &packet.Config{}
|
||||
if verifyTime == 0 {
|
||||
|
|
@ -113,23 +113,22 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText io.Reader, signa
|
|||
|
||||
signer, err := openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
|
||||
|
||||
if err == pgpErrors.ErrSignatureExpired && signer != nil {
|
||||
if verifyTime > 0 { // if verifyTime = 0: time check disabled, everything is okay
|
||||
// Maybe the creation time offset pushed it over the edge
|
||||
// Retry with the actual verification time
|
||||
config.Time = func() time.Time {
|
||||
return time.Unix(verifyTime, 0)
|
||||
}
|
||||
if err == pgpErrors.ErrSignatureExpired && signer != nil && verifyTime > 0 {
|
||||
// if verifyTime = 0: time check disabled, everything is okay
|
||||
// Maybe the creation time offset pushed it over the edge
|
||||
// Retry with the actual verification time
|
||||
config.Time = func() time.Time {
|
||||
return time.Unix(verifyTime, 0)
|
||||
}
|
||||
|
||||
_, err = signatureReader.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
return newSignatureFailed()
|
||||
}
|
||||
_, err = signatureReader.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
return newSignatureFailed()
|
||||
}
|
||||
|
||||
signer, err = openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
|
||||
if err != nil {
|
||||
return newSignatureFailed()
|
||||
}
|
||||
signer, err = openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
|
||||
if err != nil {
|
||||
return newSignatureFailed()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
"golang.org/x/crypto/openpgp/packet"
|
||||
)
|
||||
|
||||
// SignatureCollector structure
|
||||
// SignatureCollector structure.
|
||||
type SignatureCollector struct {
|
||||
config *packet.Config
|
||||
keyring openpgp.KeyRing
|
||||
|
|
@ -32,91 +32,85 @@ func newSignatureCollector(
|
|||
}
|
||||
}
|
||||
|
||||
// Accept collects the signature
|
||||
// Accept collects the signature.
|
||||
func (sc *SignatureCollector) Accept(
|
||||
part io.Reader, header textproto.MIMEHeader,
|
||||
hasPlainSibling, isFirst, isLast bool,
|
||||
) (err error) {
|
||||
parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||
if parentMediaType == "multipart/signed" {
|
||||
newPart, rawBody := gomime.GetRawMimePart(part, "--"+params["boundary"])
|
||||
var multiparts []io.Reader
|
||||
var multipartHeaders []textproto.MIMEHeader
|
||||
if multiparts, multipartHeaders, err = gomime.GetMultipartParts(newPart, params); err == nil {
|
||||
hasPlainChild := false
|
||||
for _, header := range multipartHeaders {
|
||||
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||
if mediaType == "text/plain" {
|
||||
hasPlainChild = true
|
||||
}
|
||||
}
|
||||
if len(multiparts) != 2 {
|
||||
sc.verified = newSignatureNotSigned()
|
||||
// Invalid multipart/signed format just pass along
|
||||
_, err = ioutil.ReadAll(rawBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, p := range multiparts {
|
||||
if err = sc.target.Accept(p, multipartHeaders[i], hasPlainChild, true, true); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if parentMediaType != "multipart/signed" {
|
||||
return sc.target.Accept(part, header, hasPlainSibling, isFirst, isLast)
|
||||
}
|
||||
|
||||
newPart, rawBody := gomime.GetRawMimePart(part, "--"+params["boundary"])
|
||||
multiparts, multipartHeaders, err := gomime.GetMultipartParts(newPart, params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
hasPlainChild := false
|
||||
for _, header := range multipartHeaders {
|
||||
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||
hasPlainChild = (mediaType == "text/plain")
|
||||
}
|
||||
if len(multiparts) != 2 {
|
||||
sc.verified = newSignatureNotSigned()
|
||||
// Invalid multipart/signed format just pass along
|
||||
if _, err = ioutil.ReadAll(rawBody); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, p := range multiparts {
|
||||
if err = sc.target.Accept(p, multipartHeaders[i], hasPlainChild, true, true); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// actual multipart/signed format
|
||||
err = sc.target.Accept(multiparts[0], multipartHeaders[0], hasPlainChild, true, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
partData, err := ioutil.ReadAll(multiparts[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
decodedPart := gomime.DecodeContentEncoding(
|
||||
bytes.NewReader(partData),
|
||||
multipartHeaders[1].Get("Content-Transfer-Encoding"))
|
||||
|
||||
buffer, err := ioutil.ReadAll(decodedPart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||
buffer, err = gomime.DecodeCharset(buffer, mediaType, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sc.signature = string(buffer)
|
||||
str, _ := ioutil.ReadAll(rawBody)
|
||||
rawBody = bytes.NewReader(str)
|
||||
if sc.keyring != nil {
|
||||
_, err = openpgp.CheckArmoredDetachedSignature(sc.keyring, rawBody, bytes.NewReader(buffer), sc.config)
|
||||
|
||||
if err != nil {
|
||||
sc.verified = newSignatureFailed()
|
||||
} else {
|
||||
sc.verified = nil
|
||||
}
|
||||
} else {
|
||||
sc.verified = newSignatureNoVerifier()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
err = sc.target.Accept(part, header, hasPlainSibling, isFirst, isLast)
|
||||
|
||||
// actual multipart/signed format
|
||||
err = sc.target.Accept(multiparts[0], multipartHeaders[0], hasPlainChild, true, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
partData, err := ioutil.ReadAll(multiparts[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
decodedPart := gomime.DecodeContentEncoding(
|
||||
bytes.NewReader(partData),
|
||||
multipartHeaders[1].Get("Content-Transfer-Encoding"))
|
||||
|
||||
buffer, err := ioutil.ReadAll(decodedPart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||
buffer, err = gomime.DecodeCharset(buffer, mediaType, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sc.signature = string(buffer)
|
||||
str, _ := ioutil.ReadAll(rawBody)
|
||||
rawBody = bytes.NewReader(str)
|
||||
if sc.keyring != nil {
|
||||
_, err = openpgp.CheckArmoredDetachedSignature(sc.keyring, rawBody, bytes.NewReader(buffer), sc.config)
|
||||
|
||||
if err != nil {
|
||||
sc.verified = newSignatureFailed()
|
||||
} else {
|
||||
sc.verified = nil
|
||||
}
|
||||
} else {
|
||||
sc.verified = newSignatureNoVerifier()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// GetSignature collected by Accept
|
||||
// GetSignature collected by Accept.
|
||||
func (sc SignatureCollector) GetSignature() string {
|
||||
return sc.signature
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,25 +5,25 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// UpdateTime updates cached time
|
||||
// UpdateTime updates cached time.
|
||||
func UpdateTime(newTime int64) {
|
||||
pgp.latestServerTime = newTime
|
||||
pgp.latestClientTime = time.Now()
|
||||
}
|
||||
|
||||
// GetUnixTime gets latest cached time
|
||||
// GetUnixTime gets latest cached time.
|
||||
func GetUnixTime() int64 {
|
||||
return getNow().Unix()
|
||||
}
|
||||
|
||||
// GetTime gets latest cached time
|
||||
// GetTime gets latest cached time.
|
||||
func GetTime() time.Time {
|
||||
return getNow()
|
||||
}
|
||||
|
||||
// ----- INTERNAL FUNCTIONS -----
|
||||
|
||||
// getNow returns current time
|
||||
// getNow returns current time.
|
||||
func getNow() time.Time {
|
||||
extrapolate, err := getDiff()
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ func getDiff() (int64, error) {
|
|||
return 0, errors.New("gopenpgp: latest server time not available")
|
||||
}
|
||||
|
||||
// getTimeGenerator Returns a time generator function
|
||||
// getTimeGenerator Returns a time generator function.
|
||||
func getTimeGenerator() func() time.Time {
|
||||
return getNow
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue