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
|
|
@ -11,44 +11,17 @@ issues:
|
||||||
exclude-use-default: false
|
exclude-use-default: false
|
||||||
exclude:
|
exclude:
|
||||||
- Using the variable on range scope `tt` in function literal
|
- Using the variable on range scope `tt` in function literal
|
||||||
|
- GetJsonSHA256Fingerprints should be GetJSONSHA256Fingerprints
|
||||||
|
- ST1003 # CamelCase variables; see constants/cipher.go
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
enable:
|
enable-all: true
|
||||||
- deadcode # Finds unused code [fast: true, auto-fix: false]
|
|
||||||
- errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases [fast: true, auto-fix: false]
|
|
||||||
- gosimple # Linter for Go source code that specializes in simplifying a code [fast: true, auto-fix: false]
|
|
||||||
- govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string [fast: true, auto-fix: false]
|
|
||||||
- ineffassign # Detects when assignments to existing variables are not used [fast: true, auto-fix: false]
|
|
||||||
- staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks [fast: true, auto-fix: false]
|
|
||||||
- structcheck # Finds unused struct fields [fast: true, auto-fix: false]
|
|
||||||
- typecheck # Like the front-end of a Go compiler, parses and type-checks Go code [fast: true, auto-fix: false]
|
|
||||||
- unused # Checks Go code for unused constants, variables, functions and types [fast: false, auto-fix: false]
|
|
||||||
- varcheck # Finds unused global variables and constants [fast: true, auto-fix: false]
|
|
||||||
- depguard # Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]
|
|
||||||
- dogsled # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]
|
|
||||||
# - dupl # Tool for code clone detection [fast: true, auto-fix: false]
|
|
||||||
- funlen # Tool for detection of long functions [fast: true, auto-fix: false]
|
|
||||||
# - gochecknoglobals # Checks that no globals are present in Go code [fast: true, auto-fix: false]
|
|
||||||
# - gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
|
|
||||||
- goconst # Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]
|
|
||||||
- gocritic # The most opinionated Go source code linter [fast: true, auto-fix: false]
|
|
||||||
- gocyclo # Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]
|
|
||||||
- godox # Tool for detection of FIXME, TODO and other comment keywords [fast: true, auto-fix: false]
|
|
||||||
- gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true, auto-fix: true]
|
|
||||||
- goimports # Goimports does everything that gofmt does. Additionally it checks unused imports [fast: true, auto-fix: true]
|
|
||||||
# - golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: true, auto-fix: false]
|
|
||||||
- gosec # Inspects source code for security problems [fast: true, auto-fix: false]
|
|
||||||
- interfacer # Linter that suggests narrower interface types [fast: true, auto-fix: false]
|
|
||||||
- maligned # Tool to detect Go structs that would take less memory if their fields were sorted [fast: true, auto-fix: false]
|
|
||||||
- misspell # Finds commonly misspelled English words in comments [fast: true, auto-fix: true]
|
|
||||||
- nakedret # Finds naked returns in functions greater than a specified function length [fast: true, auto-fix: false]
|
|
||||||
- prealloc # Finds slice declarations that could potentially be preallocated [fast: true, auto-fix: false]
|
|
||||||
- scopelint # Scopelint checks for unpinned variables in go programs [fast: true, auto-fix: false]
|
|
||||||
# - stylecheck # Stylecheck is a replacement for golint [fast: true, auto-fix: false]
|
|
||||||
- unconvert # Remove unnecessary type conversions [fast: true, auto-fix: false]
|
|
||||||
- unparam # Reports unused function parameters [fast: true, auto-fix: false]
|
|
||||||
- whitespace # Tool for detection of leading and trailing whitespace [fast: true, auto-fix: true]
|
|
||||||
|
|
||||||
disable:
|
disable:
|
||||||
|
- dupl # Tool for code clone detection [fast: true, auto-fix: false]
|
||||||
|
- gochecknoglobals # Checks that no globals are present in Go code [fast: true, auto-fix: false]
|
||||||
|
- gochecknoinits # Checks that no init functions are present in Go code [fast: true, auto-fix: false]
|
||||||
|
- golint # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: true, auto-fix: false]
|
||||||
|
- gomnd # An analyzer to detect magic numbers. [fast: true, auto-fix: false]
|
||||||
|
- lll # Reports long lines [fast: true, auto-fix: false]
|
||||||
|
- testpackage # Makes you use a separate _test package [fast: true, auto-fix: false]
|
||||||
- wsl # Whitespace Linter - Forces you to use empty lines! [fast: true, auto-fix: false]
|
- wsl # Whitespace Linter - Forces you to use empty lines! [fast: true, auto-fix: false]
|
||||||
- lll # Reports long lines [fast: true, auto-fix: false]\
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## Changed
|
## Changed
|
||||||
- Providing empty passphrase does no longer throw an error when unlocking an unencrypted private key
|
- Providing empty passphrase does no longer throw an error when unlocking an unencrypted private key
|
||||||
|
- Improved code linter
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- SHA256 fingerprint support
|
- SHA256 fingerprint support
|
||||||
|
|
|
||||||
|
|
@ -22,14 +22,14 @@ type AttachmentProcessor struct {
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process writes attachment data to be encrypted
|
// 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 closes the attachment and returns the encrypted data
|
// Finish closes the attachment and returns the encrypted data.
|
||||||
func (ap *AttachmentProcessor) Finish() (*PGPSplitMessage, error) {
|
func (ap *AttachmentProcessor) Finish() (*PGPSplitMessage, error) {
|
||||||
if ap.err != nil {
|
if ap.err != nil {
|
||||||
return nil, ap.err
|
return nil, ap.err
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import (
|
||||||
packet "golang.org/x/crypto/openpgp/packet"
|
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 {
|
type Key struct {
|
||||||
// PGP entities in this keyring.
|
// PGP entities in this keyring.
|
||||||
entity *openpgp.Entity
|
entity *openpgp.Entity
|
||||||
|
|
@ -50,12 +50,12 @@ func NewKeyFromReader(r io.Reader) (key *Key, err error) {
|
||||||
return key, nil
|
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) {
|
func NewKey(binKeys []byte) (key *Key, err error) {
|
||||||
return NewKeyFromReader(bytes.NewReader(clone(binKeys)))
|
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) {
|
func NewKeyFromArmored(armored string) (key *Key, err error) {
|
||||||
return NewKeyFromArmoredReader(strings.NewReader(armored))
|
return NewKeyFromArmoredReader(strings.NewReader(armored))
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +132,7 @@ func (key *Key) Lock(passphrase []byte) (*Key, error) {
|
||||||
return lockedKey, nil
|
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) {
|
func (key *Key) Unlock(passphrase []byte) (*Key, error) {
|
||||||
isLocked, err := key.IsLocked()
|
isLocked, err := key.IsLocked()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -234,12 +234,12 @@ func (key *Key) IsExpired() bool {
|
||||||
return !ok
|
return !ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsPrivate returns true if the key is private
|
// IsPrivate returns true if the key is private.
|
||||||
func (key *Key) IsPrivate() bool {
|
func (key *Key) IsPrivate() bool {
|
||||||
return key.entity.PrivateKey != nil
|
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) {
|
func (key *Key) IsLocked() (bool, error) {
|
||||||
if key.entity.PrivateKey == nil {
|
if key.entity.PrivateKey == nil {
|
||||||
return true, errors.New("gopenpgp: a public key cannot be locked")
|
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
|
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) {
|
func (key *Key) IsUnlocked() (bool, error) {
|
||||||
if key.entity.PrivateKey == nil {
|
if key.entity.PrivateKey == nil {
|
||||||
return true, errors.New("gopenpgp: a public key cannot be unlocked")
|
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
|
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) {
|
func (key *Key) Check() (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
testSign := bytes.Repeat([]byte{0x01}, 64)
|
testSign := bytes.Repeat([]byte{0x01}, 64)
|
||||||
|
|
@ -314,22 +315,22 @@ func (key *Key) PrintFingerprints() {
|
||||||
fmt.Println("PrimaryKey:" + hex.EncodeToString(key.entity.PrimaryKey.Fingerprint[:]))
|
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 {
|
func (key *Key) GetHexKeyID() string {
|
||||||
return strconv.FormatUint(key.GetKeyID(), 16)
|
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 {
|
func (key *Key) GetKeyID() uint64 {
|
||||||
return key.entity.PrimaryKey.KeyId
|
return key.entity.PrimaryKey.KeyId
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFingerprint gets the fingerprint from the key
|
// GetFingerprint gets the fingerprint from the key.
|
||||||
func (key *Key) GetFingerprint() string {
|
func (key *Key) GetFingerprint() string {
|
||||||
return hex.EncodeToString(key.entity.PrimaryKey.Fingerprint[:])
|
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) {
|
func (key *Key) GetSHA256Fingerprints() (fingerprints []string) {
|
||||||
fingerprints = append(fingerprints, hex.EncodeToString(getSHA256FingerprintBytes(key.entity.PrimaryKey)))
|
fingerprints = append(fingerprints, hex.EncodeToString(getSHA256FingerprintBytes(key.entity.PrimaryKey)))
|
||||||
for _, sub := range key.entity.Subkeys {
|
for _, sub := range key.entity.Subkeys {
|
||||||
|
|
@ -340,7 +341,8 @@ func (key *Key) GetSHA256Fingerprints() (fingerprints []string) {
|
||||||
|
|
||||||
// --- Internal methods
|
// --- 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 {
|
func getSHA256FingerprintBytes(pk *packet.PublicKey) []byte {
|
||||||
fingerPrint := sha256.New()
|
fingerPrint := sha256.New()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ type Identity struct {
|
||||||
|
|
||||||
// --- New keyrings
|
// --- 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) {
|
func NewKeyRing(key *Key) (*KeyRing, error) {
|
||||||
keyRing := &KeyRing{}
|
keyRing := &KeyRing{}
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -36,7 +36,7 @@ func NewKeyRing(key *Key) (*KeyRing, error) {
|
||||||
return keyRing, err
|
return keyRing, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Add keys to keyring
|
// AddKey adds the given key to the keyring.
|
||||||
func (keyRing *KeyRing) AddKey(key *Key) error {
|
func (keyRing *KeyRing) AddKey(key *Key) error {
|
||||||
if key.IsPrivate() {
|
if key.IsPrivate() {
|
||||||
unlocked, err := key.IsUnlocked()
|
unlocked, err := key.IsUnlocked()
|
||||||
|
|
@ -91,17 +91,17 @@ func (keyRing *KeyRing) getSigningEntity() (*openpgp.Entity, error) {
|
||||||
|
|
||||||
// --- Extract info from key
|
// --- 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 {
|
func (keyRing *KeyRing) CountEntities() int {
|
||||||
return len(keyRing.entities)
|
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 {
|
func (keyRing *KeyRing) CountDecryptionEntities() int {
|
||||||
return len(keyRing.entities.DecryptionKeys())
|
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 {
|
func (keyRing *KeyRing) GetIdentities() []*Identity {
|
||||||
var identities []*Identity
|
var identities []*Identity
|
||||||
for _, e := range keyRing.entities {
|
for _, e := range keyRing.entities {
|
||||||
|
|
@ -172,7 +172,7 @@ func FilterExpiredKeys(contactKeys []*KeyRing) (filteredKeys []*KeyRing, err err
|
||||||
return filteredKeys, nil
|
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) {
|
func (keyRing *KeyRing) FirstKey() (*KeyRing, error) {
|
||||||
if len(keyRing.entities) == 0 {
|
if len(keyRing.entities) == 0 {
|
||||||
return nil, errors.New("gopenpgp: No key available in this keyring")
|
return nil, errors.New("gopenpgp: No key available in this keyring")
|
||||||
|
|
@ -183,7 +183,7 @@ func (keyRing *KeyRing) FirstKey() (*KeyRing, error) {
|
||||||
return newKeyRing.Copy()
|
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) {
|
func (keyRing *KeyRing) Copy() (*KeyRing, error) {
|
||||||
newKeyRing := &KeyRing{}
|
newKeyRing := &KeyRing{}
|
||||||
|
|
||||||
|
|
@ -223,7 +223,7 @@ func (keyRing *KeyRing) ClearPrivateParams() {
|
||||||
|
|
||||||
// INTERNAL FUNCTIONS
|
// INTERNAL FUNCTIONS
|
||||||
|
|
||||||
// append appends a key to the keyring
|
// appendKey appends a key to the keyring.
|
||||||
func (keyRing *KeyRing) appendKey(key *Key) {
|
func (keyRing *KeyRing) appendKey(key *Key) {
|
||||||
keyRing.entities = append(keyRing.entities, key.entity)
|
keyRing.entities = append(keyRing.entities, key.entity)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ import (
|
||||||
|
|
||||||
// Encrypt encrypts a PlainMessage, outputs a PGPMessage.
|
// Encrypt encrypts a PlainMessage, outputs a PGPMessage.
|
||||||
// If an unlocked private key is also provided it will also sign the message.
|
// If an unlocked private key is also provided it will also sign the message.
|
||||||
// * message : The plaintext input as a PlainMessage
|
// * message : The plaintext input as a PlainMessage.
|
||||||
// * privateKey : (optional) an unlocked private keyring to include signature in the message
|
// * privateKey : (optional) an unlocked private keyring to include signature in the message.
|
||||||
func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PGPMessage, error) {
|
func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PGPMessage, error) {
|
||||||
encrypted, err := asymmetricEncrypt(message.GetBinary(), keyRing, privateKey, message.IsBinary())
|
encrypted, err := asymmetricEncrypt(message.GetBinary(), keyRing, privateKey, message.IsBinary())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -28,7 +28,8 @@ func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PG
|
||||||
// * verifyKey : Public key for signature verification (optional)
|
// * verifyKey : Public key for signature verification (optional)
|
||||||
// * verifyTime : Time at verification (necessary only if verifyKey is not nil)
|
// * 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(
|
func (keyRing *KeyRing) Decrypt(
|
||||||
message *PGPMessage, verifyKey *KeyRing, verifyTime int64,
|
message *PGPMessage, verifyKey *KeyRing, verifyTime int64,
|
||||||
) (*PlainMessage, error) {
|
) (*PlainMessage, error) {
|
||||||
|
|
@ -37,7 +38,7 @@ func (keyRing *KeyRing) Decrypt(
|
||||||
return NewPlainMessage(decrypted), err
|
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) {
|
func (keyRing *KeyRing) SignDetached(message *PlainMessage) (*PGPSignature, error) {
|
||||||
signEntity, err := keyRing.getSigningEntity()
|
signEntity, err := keyRing.getSigningEntity()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -55,7 +56,7 @@ func (keyRing *KeyRing) SignDetached(message *PlainMessage) (*PGPSignature, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyDetached verifies a PlainMessage with embedded a PGPSignature
|
// 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 {
|
func (keyRing *KeyRing) VerifyDetached(message *PlainMessage, signature *PGPSignature, verifyTime int64) error {
|
||||||
return verifySignature(
|
return verifySignature(
|
||||||
keyRing.entities,
|
keyRing.entities,
|
||||||
|
|
@ -67,7 +68,7 @@ func (keyRing *KeyRing) VerifyDetached(message *PlainMessage, signature *PGPSign
|
||||||
|
|
||||||
// ------ INTERNAL FUNCTIONS -------
|
// ------ INTERNAL FUNCTIONS -------
|
||||||
|
|
||||||
// Core for encryption+signature functions
|
// Core for encryption+signature functions.
|
||||||
func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isBinary bool) ([]byte, error) {
|
func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isBinary bool) ([]byte, error) {
|
||||||
var outBuf bytes.Buffer
|
var outBuf bytes.Buffer
|
||||||
var encryptWriter io.WriteCloser
|
var encryptWriter io.WriteCloser
|
||||||
|
|
@ -111,7 +112,7 @@ func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isB
|
||||||
return outBuf.Bytes(), nil
|
return outBuf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Core for decryption+verification functions
|
// Core for decryption+verification functions.
|
||||||
func asymmetricDecrypt(
|
func asymmetricDecrypt(
|
||||||
encryptedIO io.Reader, privateKey *KeyRing, verifyKey *KeyRing, verifyTime int64,
|
encryptedIO io.Reader, privateKey *KeyRing, verifyKey *KeyRing, verifyTime int64,
|
||||||
) (plaintext []byte, err error) {
|
) (plaintext []byte, err error) {
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,7 @@ type PGPSplitMessage struct {
|
||||||
KeyPacket []byte
|
KeyPacket []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearTextMessage, split signed clear text message container.
|
// A ClearTextMessage is a signed but not encrypted PGP message,
|
||||||
// A Cleartext message is a signed PGP message, that is not encrypted,
|
|
||||||
// i.e. the ones beginning with -----BEGIN PGP SIGNED MESSAGE-----
|
// i.e. the ones beginning with -----BEGIN PGP SIGNED MESSAGE-----
|
||||||
type ClearTextMessage struct {
|
type ClearTextMessage struct {
|
||||||
Data []byte
|
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) {
|
func NewPGPSignatureFromArmored(armored string) (*PGPSignature, error) {
|
||||||
encryptedIO, err := internal.Unarmor(armored)
|
encryptedIO, err := internal.Unarmor(armored)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -143,7 +143,8 @@ func NewPGPSignatureFromArmored(armored string) (*PGPSignature, error) {
|
||||||
}, nil
|
}, 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 {
|
func NewClearTextMessage(data []byte, signature []byte) *ClearTextMessage {
|
||||||
return &ClearTextMessage{
|
return &ClearTextMessage{
|
||||||
Data: clone(data),
|
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) {
|
func NewClearTextMessageFromArmored(signedMessage string) (*ClearTextMessage, error) {
|
||||||
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
|
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
|
||||||
if len(rest) != 0 {
|
if len(rest) != 0 {
|
||||||
|
|
@ -168,79 +170,84 @@ func NewClearTextMessageFromArmored(signedMessage string) (*ClearTextMessage, er
|
||||||
|
|
||||||
// ---- MODEL METHODS -----
|
// ---- 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 {
|
func (msg *PlainMessage) GetBinary() []byte {
|
||||||
return msg.Data
|
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 {
|
func (msg *PlainMessage) GetString() string {
|
||||||
return string(msg.Data)
|
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 {
|
func (msg *PlainMessage) GetBase64() string {
|
||||||
return base64.StdEncoding.EncodeToString(msg.Data)
|
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 {
|
func (msg *PlainMessage) NewReader() io.Reader {
|
||||||
return bytes.NewReader(msg.GetBinary())
|
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 {
|
func (msg *PlainMessage) IsText() bool {
|
||||||
return msg.TextType
|
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 {
|
func (msg *PlainMessage) IsBinary() bool {
|
||||||
return !msg.TextType
|
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 {
|
func (msg *PGPMessage) GetBinary() []byte {
|
||||||
return msg.Data
|
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 {
|
func (msg *PGPMessage) NewReader() io.Reader {
|
||||||
return bytes.NewReader(msg.GetBinary())
|
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) {
|
func (msg *PGPMessage) GetArmored() (string, error) {
|
||||||
return armor.ArmorWithType(msg.Data, constants.PGPMessageHeader)
|
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 {
|
func (msg *PGPSplitMessage) GetBinaryDataPacket() []byte {
|
||||||
return msg.DataPacket
|
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 {
|
func (msg *PGPSplitMessage) GetBinaryKeyPacket() []byte {
|
||||||
return msg.KeyPacket
|
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 {
|
func (msg *PGPSplitMessage) GetBinary() []byte {
|
||||||
return append(msg.KeyPacket, msg.DataPacket...)
|
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) {
|
func (msg *PGPSplitMessage) GetArmored() (string, error) {
|
||||||
return armor.ArmorWithType(msg.GetBinary(), constants.PGPMessageHeader)
|
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 {
|
func (msg *PGPSplitMessage) GetPGPMessage() *PGPMessage {
|
||||||
return NewPGPMessage(append(msg.KeyPacket, msg.DataPacket...))
|
return NewPGPMessage(append(msg.KeyPacket, msg.DataPacket...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SeparateKeyAndData returns the first keypacket and the (hopefully unique) dataPacket (not verified)
|
// SeparateKeyAndData returns the first keypacket and the (hopefully unique)
|
||||||
// * estimatedLength is the estimate length of the message
|
// dataPacket (not verified).
|
||||||
// * garbageCollector > 0 activates the garbage collector
|
// * 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) {
|
func (msg *PGPMessage) SeparateKeyAndData(estimatedLength, garbageCollector int) (outSplit *PGPSplitMessage, err error) {
|
||||||
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
|
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
|
||||||
packets := packet.NewReader(bytes.NewReader(msg.Data))
|
packets := packet.NewReader(bytes.NewReader(msg.Data))
|
||||||
|
|
@ -334,32 +341,33 @@ func (msg *PGPMessage) SeparateKeyAndData(estimatedLength, garbageCollector int)
|
||||||
return outSplit, nil
|
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 {
|
func (msg *PGPSignature) GetBinary() []byte {
|
||||||
return msg.Data
|
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) {
|
func (msg *PGPSignature) GetArmored() (string, error) {
|
||||||
return armor.ArmorWithType(msg.Data, constants.PGPSignatureHeader)
|
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 {
|
func (msg *ClearTextMessage) GetBinary() []byte {
|
||||||
return msg.Data
|
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 {
|
func (msg *ClearTextMessage) GetString() string {
|
||||||
return string(msg.Data)
|
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 {
|
func (msg *ClearTextMessage) GetBinarySignature() []byte {
|
||||||
return msg.Signature
|
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) {
|
func (msg *ClearTextMessage) GetArmored() (string, error) {
|
||||||
armSignature, err := armor.ArmorWithType(msg.GetBinarySignature(), constants.PGPSignatureHeader)
|
armSignature, err := armor.ArmorWithType(msg.GetBinarySignature(), constants.PGPSignatureHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,11 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Encrypt encrypts a PlainMessage to PGPMessage with a SymmetricKey
|
// EncryptMessageWithPassword encrypts a PlainMessage to PGPMessage with a
|
||||||
// * message : The plain data as a PlainMessage
|
// SymmetricKey.
|
||||||
// * password: A password that will be derived into an encryption key
|
// * message : The plain data as a PlainMessage.
|
||||||
// * output : The encrypted data as PGPMessage
|
// * 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) {
|
func EncryptMessageWithPassword(message *PlainMessage, password []byte) (*PGPMessage, error) {
|
||||||
encrypted, err := passwordEncrypt(message.GetBinary(), password, message.IsBinary())
|
encrypted, err := passwordEncrypt(message.GetBinary(), password, message.IsBinary())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -23,10 +24,10 @@ func EncryptMessageWithPassword(message *PlainMessage, password []byte) (*PGPMes
|
||||||
return NewPGPMessage(encrypted), nil
|
return NewPGPMessage(encrypted), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt decrypts password protected pgp binary messages
|
// DecryptMessageWithPassword decrypts password protected pgp binary messages.
|
||||||
// * encrypted: The encrypted data as PGPMessage
|
// * encrypted: The encrypted data as PGPMessage.
|
||||||
// * password: A password that will be derived into an encryption key
|
// * password: A password that will be derived into an encryption key.
|
||||||
// * output: The decrypted data as PlainMessage
|
// * output: The decrypted data as PlainMessage.
|
||||||
func DecryptMessageWithPassword(message *PGPMessage, password []byte) (*PlainMessage, error) {
|
func DecryptMessageWithPassword(message *PGPMessage, password []byte) (*PlainMessage, error) {
|
||||||
decrypted, err := passwordDecrypt(message.NewReader(), password)
|
decrypted, err := passwordDecrypt(message.NewReader(), password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ func (sk *SessionKey) GetBase64Key() string {
|
||||||
return base64.StdEncoding.EncodeToString(sk.Key)
|
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) {
|
func RandomToken(size int) ([]byte, error) {
|
||||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||||
symKey := make([]byte, size)
|
symKey := make([]byte, size)
|
||||||
|
|
@ -55,7 +55,8 @@ func RandomToken(size int) ([]byte, error) {
|
||||||
return symKey, nil
|
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) {
|
func GenerateSessionKeyAlgo(algo string) (sk *SessionKey, err error) {
|
||||||
cf, ok := symKeyAlgos[algo]
|
cf, ok := symKeyAlgos[algo]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -73,7 +74,7 @@ func GenerateSessionKeyAlgo(algo string) (sk *SessionKey, err error) {
|
||||||
return sk, nil
|
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) {
|
func GenerateSessionKey() (*SessionKey, error) {
|
||||||
return GenerateSessionKeyAlgo(constants.AES256)
|
return GenerateSessionKeyAlgo(constants.AES256)
|
||||||
}
|
}
|
||||||
|
|
@ -105,9 +106,9 @@ func newSessionKeyFromEncrypted(ek *packet.EncryptedKey) (*SessionKey, error) {
|
||||||
return symmetricKey, nil
|
return symmetricKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt encrypts a PlainMessage to PGPMessage with a SessionKey
|
// Encrypt encrypts a PlainMessage to PGPMessage with a SessionKey.
|
||||||
// * message : The plain data as a PlainMessage
|
// * message : The plain data as a PlainMessage.
|
||||||
// * output : The encrypted data as PGPMessage
|
// * output : The encrypted data as PGPMessage.
|
||||||
func (sk *SessionKey) Encrypt(message *PlainMessage) ([]byte, error) {
|
func (sk *SessionKey) Encrypt(message *PlainMessage) ([]byte, error) {
|
||||||
var encBuf bytes.Buffer
|
var encBuf bytes.Buffer
|
||||||
var encryptWriter io.WriteCloser
|
var encryptWriter io.WriteCloser
|
||||||
|
|
@ -152,9 +153,9 @@ func (sk *SessionKey) Encrypt(message *PlainMessage) ([]byte, error) {
|
||||||
return encBuf.Bytes(), nil
|
return encBuf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt decrypts password protected pgp binary messages
|
// Decrypt decrypts password protected pgp binary messages.
|
||||||
// * encrypted: PGPMessage
|
// * encrypted: PGPMessage.
|
||||||
// * output: PlainMessage
|
// * output: PlainMessage.
|
||||||
func (sk *SessionKey) Decrypt(dataPacket []byte) (*PlainMessage, error) {
|
func (sk *SessionKey) Decrypt(dataPacket []byte) (*PlainMessage, error) {
|
||||||
var messageReader = bytes.NewReader(dataPacket)
|
var messageReader = bytes.NewReader(dataPacket)
|
||||||
var decrypted io.ReadCloser
|
var decrypted io.ReadCloser
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,14 @@ import (
|
||||||
"github.com/ProtonMail/gopenpgp/v2/internal"
|
"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 {
|
type SignatureVerificationError struct {
|
||||||
Status int
|
Status int
|
||||||
Message string
|
Message string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error is the base method for all errors
|
// Error is the base method for all errors.
|
||||||
func (e SignatureVerificationError) Error() string {
|
func (e SignatureVerificationError) Error() string {
|
||||||
return fmt.Sprintf("Signature Verification Error: %v", e.Message)
|
return fmt.Sprintf("Signature Verification Error: %v", e.Message)
|
||||||
}
|
}
|
||||||
|
|
@ -30,7 +31,8 @@ func (e SignatureVerificationError) Error() string {
|
||||||
// Internal functions
|
// Internal functions
|
||||||
// ------------------
|
// ------------------
|
||||||
|
|
||||||
// newSignatureFailed creates a new SignatureVerificationError, type SIGNATURE_FAILED
|
// newSignatureFailed creates a new SignatureVerificationError, type
|
||||||
|
// SignatureFailed.
|
||||||
func newSignatureFailed() SignatureVerificationError {
|
func newSignatureFailed() SignatureVerificationError {
|
||||||
return SignatureVerificationError{
|
return SignatureVerificationError{
|
||||||
constants.SIGNATURE_FAILED,
|
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 {
|
func newSignatureNotSigned() SignatureVerificationError {
|
||||||
return SignatureVerificationError{
|
return SignatureVerificationError{
|
||||||
constants.SIGNATURE_NOT_SIGNED,
|
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 {
|
func newSignatureNoVerifier() SignatureVerificationError {
|
||||||
return SignatureVerificationError{
|
return SignatureVerificationError{
|
||||||
constants.SIGNATURE_NO_VERIFIER,
|
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
|
// processSignatureExpiration handles signature time verification manually, so
|
||||||
// creationTime check.
|
// we can add a margin to the creationTime check.
|
||||||
func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
|
func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
|
||||||
if md.SignatureError == pgpErrors.ErrSignatureExpired {
|
if md.SignatureError != pgpErrors.ErrSignatureExpired {
|
||||||
if verifyTime > 0 {
|
return
|
||||||
created := md.Signature.CreationTime.Unix()
|
}
|
||||||
expires := int64(math.MaxInt64)
|
if verifyTime == 0 {
|
||||||
if md.Signature.SigLifetimeSecs != nil {
|
// verifyTime = 0: time check disabled, everything is okay
|
||||||
expires = int64(*md.Signature.SigLifetimeSecs) + created
|
md.SignatureError = nil
|
||||||
}
|
return
|
||||||
if created-internal.CreationTimeOffset <= verifyTime && verifyTime <= expires {
|
}
|
||||||
md.SignatureError = nil
|
created := md.Signature.CreationTime.Unix()
|
||||||
}
|
expires := int64(math.MaxInt64)
|
||||||
} else {
|
if md.Signature.SigLifetimeSecs != nil {
|
||||||
// verifyTime = 0: time check disabled, everything is okay
|
expires = int64(*md.Signature.SigLifetimeSecs) + created
|
||||||
md.SignatureError = nil
|
}
|
||||||
}
|
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 {
|
func verifyDetailsSignature(md *openpgp.MessageDetails, verifierKey *KeyRing) error {
|
||||||
if md.IsSigned {
|
if md.IsSigned {
|
||||||
if md.SignedBy != nil {
|
if md.SignedBy == nil || len(verifierKey.entities) == 0 {
|
||||||
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 {
|
|
||||||
return newSignatureNoVerifier()
|
return newSignatureNoVerifier()
|
||||||
}
|
}
|
||||||
|
matches := verifierKey.entities.KeysById(md.SignedByKeyId)
|
||||||
|
if len(matches) > 0 {
|
||||||
|
if md.SignatureError == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return newSignatureFailed()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newSignatureNoVerifier()
|
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 {
|
func verifySignature(pubKeyEntries openpgp.EntityList, origText io.Reader, signature []byte, verifyTime int64) error {
|
||||||
config := &packet.Config{}
|
config := &packet.Config{}
|
||||||
if verifyTime == 0 {
|
if verifyTime == 0 {
|
||||||
|
|
@ -113,23 +113,22 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText io.Reader, signa
|
||||||
|
|
||||||
signer, err := openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
|
signer, err := openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
|
||||||
|
|
||||||
if err == pgpErrors.ErrSignatureExpired && signer != nil {
|
if err == pgpErrors.ErrSignatureExpired && signer != nil && verifyTime > 0 {
|
||||||
if verifyTime > 0 { // if verifyTime = 0: time check disabled, everything is okay
|
// if verifyTime = 0: time check disabled, everything is okay
|
||||||
// Maybe the creation time offset pushed it over the edge
|
// Maybe the creation time offset pushed it over the edge
|
||||||
// Retry with the actual verification time
|
// Retry with the actual verification time
|
||||||
config.Time = func() time.Time {
|
config.Time = func() time.Time {
|
||||||
return time.Unix(verifyTime, 0)
|
return time.Unix(verifyTime, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = signatureReader.Seek(0, io.SeekStart)
|
_, err = signatureReader.Seek(0, io.SeekStart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newSignatureFailed()
|
return newSignatureFailed()
|
||||||
}
|
}
|
||||||
|
|
||||||
signer, err = openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
|
signer, err = openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return newSignatureFailed()
|
return newSignatureFailed()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignatureCollector structure
|
// SignatureCollector structure.
|
||||||
type SignatureCollector struct {
|
type SignatureCollector struct {
|
||||||
config *packet.Config
|
config *packet.Config
|
||||||
keyring openpgp.KeyRing
|
keyring openpgp.KeyRing
|
||||||
|
|
@ -32,91 +32,85 @@ func newSignatureCollector(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept collects the signature
|
// Accept collects the signature.
|
||||||
func (sc *SignatureCollector) Accept(
|
func (sc *SignatureCollector) Accept(
|
||||||
part io.Reader, header textproto.MIMEHeader,
|
part io.Reader, header textproto.MIMEHeader,
|
||||||
hasPlainSibling, isFirst, isLast bool,
|
hasPlainSibling, isFirst, isLast bool,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
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 parentMediaType != "multipart/signed" {
|
||||||
if err = sc.target.Accept(p, multipartHeaders[i], hasPlainChild, true, true); err != nil {
|
return sc.target.Accept(part, header, hasPlainSibling, isFirst, isLast)
|
||||||
return
|
}
|
||||||
}
|
|
||||||
}
|
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
|
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
|
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 {
|
if err != nil {
|
||||||
return err
|
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 {
|
func (sc SignatureCollector) GetSignature() string {
|
||||||
return sc.signature
|
return sc.signature
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,25 +5,25 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdateTime updates cached time
|
// UpdateTime updates cached time.
|
||||||
func UpdateTime(newTime int64) {
|
func UpdateTime(newTime int64) {
|
||||||
pgp.latestServerTime = newTime
|
pgp.latestServerTime = newTime
|
||||||
pgp.latestClientTime = time.Now()
|
pgp.latestClientTime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUnixTime gets latest cached time
|
// GetUnixTime gets latest cached time.
|
||||||
func GetUnixTime() int64 {
|
func GetUnixTime() int64 {
|
||||||
return getNow().Unix()
|
return getNow().Unix()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTime gets latest cached time
|
// GetTime gets latest cached time.
|
||||||
func GetTime() time.Time {
|
func GetTime() time.Time {
|
||||||
return getNow()
|
return getNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----- INTERNAL FUNCTIONS -----
|
// ----- INTERNAL FUNCTIONS -----
|
||||||
|
|
||||||
// getNow returns current time
|
// getNow returns current time.
|
||||||
func getNow() time.Time {
|
func getNow() time.Time {
|
||||||
extrapolate, err := getDiff()
|
extrapolate, err := getDiff()
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ func getDiff() (int64, error) {
|
||||||
return 0, errors.New("gopenpgp: latest server time not available")
|
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 {
|
func getTimeGenerator() func() time.Time {
|
||||||
return getNow
|
return getNow
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@ import (
|
||||||
"github.com/ProtonMail/gopenpgp/v2/internal"
|
"github.com/ProtonMail/gopenpgp/v2/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignCleartextMessageArmored signs text given a private key and its passphrase, canonicalizes and trims the newlines,
|
// SignCleartextMessageArmored signs text given a private key and its
|
||||||
// and returns the PGP-compliant special armoring
|
// passphrase, canonicalizes and trims the newlines, and returns the
|
||||||
|
// PGP-compliant special armoring.
|
||||||
func SignCleartextMessageArmored(privateKey string, passphrase []byte, text string) (string, error) {
|
func SignCleartextMessageArmored(privateKey string, passphrase []byte, text string) (string, error) {
|
||||||
signingKey, err := crypto.NewKeyFromArmored(privateKey)
|
signingKey, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -29,8 +30,9 @@ func SignCleartextMessageArmored(privateKey string, passphrase []byte, text stri
|
||||||
return SignCleartextMessage(keyRing, text)
|
return SignCleartextMessage(keyRing, text)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyCleartextMessageArmored verifies PGP-compliant armored signed plain text given the public key
|
// VerifyCleartextMessageArmored verifies PGP-compliant armored signed plain
|
||||||
// and returns the text or err if the verification fails
|
// text given the public key and returns the text or err if the verification
|
||||||
|
// fails.
|
||||||
func VerifyCleartextMessageArmored(publicKey, armored string, verifyTime int64) (string, error) {
|
func VerifyCleartextMessageArmored(publicKey, armored string, verifyTime int64) (string, error) {
|
||||||
signingKey, err := crypto.NewKeyFromArmored(publicKey)
|
signingKey, err := crypto.NewKeyFromArmored(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -45,8 +47,8 @@ func VerifyCleartextMessageArmored(publicKey, armored string, verifyTime int64)
|
||||||
return VerifyCleartextMessage(verifyKeyRing, armored, verifyTime)
|
return VerifyCleartextMessage(verifyKeyRing, armored, verifyTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignCleartextMessage signs text given a private keyring, canonicalizes and trims the newlines,
|
// SignCleartextMessage signs text given a private keyring, canonicalizes and
|
||||||
// and returns the PGP-compliant special armoring
|
// trims the newlines, and returns the PGP-compliant special armoring.
|
||||||
func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error) {
|
func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error) {
|
||||||
text = canonicalizeAndTrim(text)
|
text = canonicalizeAndTrim(text)
|
||||||
message := crypto.NewPlainMessageFromString(text)
|
message := crypto.NewPlainMessageFromString(text)
|
||||||
|
|
@ -59,8 +61,9 @@ func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error)
|
||||||
return crypto.NewClearTextMessage(message.GetBinary(), signature.GetBinary()).GetArmored()
|
return crypto.NewClearTextMessage(message.GetBinary(), signature.GetBinary()).GetArmored()
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyCleartextMessage verifies PGP-compliant armored signed plain text given the public keyring
|
// VerifyCleartextMessage verifies PGP-compliant armored signed plain text
|
||||||
// and returns the text or err if the verification fails
|
// given the public keyring and returns the text or err if the verification
|
||||||
|
// fails.
|
||||||
func VerifyCleartextMessage(keyRing *crypto.KeyRing, armored string, verifyTime int64) (string, error) {
|
func VerifyCleartextMessage(keyRing *crypto.KeyRing, armored string, verifyTime int64) (string, error) {
|
||||||
clearTextMessage, err := crypto.NewClearTextMessageFromArmored(armored)
|
clearTextMessage, err := crypto.NewClearTextMessageFromArmored(armored)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -79,7 +82,7 @@ func VerifyCleartextMessage(keyRing *crypto.KeyRing, armored string, verifyTime
|
||||||
|
|
||||||
// ----- INTERNAL FUNCTIONS -----
|
// ----- INTERNAL FUNCTIONS -----
|
||||||
|
|
||||||
// canonicalizeAndTrim alters a string canonicalizing and trimming the newlines
|
// canonicalizeAndTrim alters a string canonicalizing and trimming the newlines.
|
||||||
func canonicalizeAndTrim(text string) string {
|
func canonicalizeAndTrim(text string) string {
|
||||||
text = internal.TrimNewlines(text)
|
text = internal.TrimNewlines(text)
|
||||||
text = strings.Replace(strings.Replace(text, "\r\n", "\n", -1), "\n", "\r\n", -1)
|
text = strings.Replace(strings.Replace(text, "\r\n", "\n", -1), "\n", "\r\n", -1)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// helper contains several functions with a simple interface to extend usability and compatibility with gomobile
|
// Package helper contains several functions with a simple interface to extend usability and compatibility with gomobile
|
||||||
package helper
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EncryptMessageWithPassword encrypts a string with a passphrase using AES256
|
// EncryptMessageWithPassword encrypts a string with a passphrase using AES256.
|
||||||
func EncryptMessageWithPassword(password []byte, plaintext string) (ciphertext string, err error) {
|
func EncryptMessageWithPassword(password []byte, plaintext string) (ciphertext string, err error) {
|
||||||
var pgpMessage *crypto.PGPMessage
|
var pgpMessage *crypto.PGPMessage
|
||||||
|
|
||||||
|
|
@ -41,7 +41,8 @@ func DecryptMessageWithPassword(password []byte, ciphertext string) (plaintext s
|
||||||
return message.GetString(), nil
|
return message.GetString(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptMessageArmored generates an armored PGP message given a plaintext and an armored public key
|
// EncryptMessageArmored generates an armored PGP message given a plaintext and
|
||||||
|
// an armored public key.
|
||||||
func EncryptMessageArmored(key, plaintext string) (ciphertext string, err error) {
|
func EncryptMessageArmored(key, plaintext string) (ciphertext string, err error) {
|
||||||
var publicKey *crypto.Key
|
var publicKey *crypto.Key
|
||||||
var publicKeyRing *crypto.KeyRing
|
var publicKeyRing *crypto.KeyRing
|
||||||
|
|
@ -68,8 +69,8 @@ func EncryptMessageArmored(key, plaintext string) (ciphertext string, err error)
|
||||||
return ciphertext, nil
|
return ciphertext, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptSignMessageArmored generates an armored signed PGP message given a plaintext and an armored public key
|
// EncryptSignMessageArmored generates an armored signed PGP message given a
|
||||||
// a private key and its passphrase
|
// plaintext and an armored public key a private key and its passphrase.
|
||||||
func EncryptSignMessageArmored(
|
func EncryptSignMessageArmored(
|
||||||
publicKey, privateKey string, passphrase []byte, plaintext string,
|
publicKey, privateKey string, passphrase []byte, plaintext string,
|
||||||
) (ciphertext string, err error) {
|
) (ciphertext string, err error) {
|
||||||
|
|
@ -111,7 +112,8 @@ func EncryptSignMessageArmored(
|
||||||
return ciphertext, nil
|
return ciphertext, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptMessageArmored decrypts an armored PGP message given a private key and its passphrase
|
// DecryptMessageArmored decrypts an armored PGP message given a private key
|
||||||
|
// and its passphrase.
|
||||||
func DecryptMessageArmored(
|
func DecryptMessageArmored(
|
||||||
privateKey string, passphrase []byte, ciphertext string,
|
privateKey string, passphrase []byte, ciphertext string,
|
||||||
) (plaintext string, err error) {
|
) (plaintext string, err error) {
|
||||||
|
|
@ -144,9 +146,9 @@ func DecryptMessageArmored(
|
||||||
return message.GetString(), nil
|
return message.GetString(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptVerifyMessageArmored decrypts an armored PGP message given a private key and its passphrase
|
// DecryptVerifyMessageArmored decrypts an armored PGP message given a private
|
||||||
// and verifies the embedded signature.
|
// key and its passphrase and verifies the embedded signature. Returns the
|
||||||
// Returns the plain data or an error on signature verification failure.
|
// plain data or an error on signature verification failure.
|
||||||
func DecryptVerifyMessageArmored(
|
func DecryptVerifyMessageArmored(
|
||||||
publicKey, privateKey string, passphrase []byte, ciphertext string,
|
publicKey, privateKey string, passphrase []byte, ciphertext string,
|
||||||
) (plaintext string, err error) {
|
) (plaintext string, err error) {
|
||||||
|
|
@ -187,9 +189,10 @@ func DecryptVerifyMessageArmored(
|
||||||
return message.GetString(), nil
|
return message.GetString(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptVerifyAttachment decrypts and verifies an attachment split into the keyPacket, dataPacket
|
// DecryptVerifyAttachment decrypts and verifies an attachment split into the
|
||||||
// and an armored (!) signature, given a publicKey, and a privateKey with its passphrase.
|
// keyPacket, dataPacket and an armored (!) signature, given a publicKey, and a
|
||||||
// Returns the plain data or an error on signature verification failure.
|
// privateKey with its passphrase. Returns the plain data or an error on
|
||||||
|
// signature verification failure.
|
||||||
func DecryptVerifyAttachment(
|
func DecryptVerifyAttachment(
|
||||||
publicKey, privateKey string,
|
publicKey, privateKey string,
|
||||||
passphrase, keyPacket, dataPacket []byte,
|
passphrase, keyPacket, dataPacket []byte,
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ type ExplicitVerifyMessage struct {
|
||||||
SignatureVerificationError *crypto.SignatureVerificationError
|
SignatureVerificationError *crypto.SignatureVerificationError
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptVerifyMessageArmored decrypts an armored PGP message given a private key and its passphrase
|
// DecryptExplicitVerify decrypts an armored PGP message given a private key
|
||||||
// and verifies the embedded signature.
|
// and its passphrase and verifies the embedded signature. Returns the plain
|
||||||
// Returns the plain data or an error on signature verification failure.
|
// data or an error on signature verification failure.
|
||||||
func DecryptExplicitVerify(
|
func DecryptExplicitVerify(
|
||||||
pgpMessage *crypto.PGPMessage,
|
pgpMessage *crypto.PGPMessage,
|
||||||
privateKeyRing, publicKeyRing *crypto.KeyRing,
|
privateKeyRing, publicKeyRing *crypto.KeyRing,
|
||||||
|
|
@ -57,8 +57,9 @@ func DecryptAttachment(keyPacket []byte, dataPacket []byte, keyRing *crypto.KeyR
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptAttachment encrypts a file given a plainData and a fileName.
|
// EncryptAttachment encrypts a file given a plainData and a fileName.
|
||||||
// Returns a PGPSplitMessage containing a session key packet and symmetrically encrypted data.
|
// Returns a PGPSplitMessage containing a session key packet and symmetrically
|
||||||
// Specifically designed for attachments rather than text messages.
|
// encrypted data. Specifically designed for attachments rather than text
|
||||||
|
// messages.
|
||||||
func EncryptAttachment(plainData []byte, fileName string, keyRing *crypto.KeyRing) (*crypto.PGPSplitMessage, error) {
|
func EncryptAttachment(plainData []byte, fileName string, keyRing *crypto.KeyRing) (*crypto.PGPSplitMessage, error) {
|
||||||
plainMessage := crypto.NewPlainMessage(plainData)
|
plainMessage := crypto.NewPlainMessage(plainData)
|
||||||
decrypted, err := keyRing.EncryptAttachment(plainMessage, fileName)
|
decrypted, err := keyRing.EncryptAttachment(plainMessage, fileName)
|
||||||
|
|
@ -68,8 +69,8 @@ func EncryptAttachment(plainData []byte, fileName string, keyRing *crypto.KeyRin
|
||||||
return decrypted, nil
|
return decrypted, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetJsonSHA256Fingerprints returns the SHA256 fingeprints of key and subkeys, encoded in JSON, since gomobile can not
|
// GetJsonSHA256Fingerprints returns the SHA256 fingeprints of key and subkeys,
|
||||||
// handle arrays
|
// encoded in JSON, since gomobile can not handle arrays.
|
||||||
func GetJsonSHA256Fingerprints(publicKey string) ([]byte, error) {
|
func GetJsonSHA256Fingerprints(publicKey string) ([]byte, error) {
|
||||||
key, err := crypto.NewKeyFromArmored(publicKey)
|
key, err := crypto.NewKeyFromArmored(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue