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:
zugzwang 2020-04-28 13:55:36 +02:00 committed by GitHub
parent 222decb919
commit ac8a49c114
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 252 additions and 265 deletions

View file

@ -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

View file

@ -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()

View file

@ -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)
}

View file

@ -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) {

View file

@ -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 {

View file

@ -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 {

View file

@ -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

View file

@ -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()
}
}

View file

@ -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
}

View file

@ -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
}