diff --git a/crypto/keyring.go b/crypto/keyring.go index 2d6e172..c6a31cf 100644 --- a/crypto/keyring.go +++ b/crypto/keyring.go @@ -8,6 +8,7 @@ import ( "errors" "io" "io/ioutil" + "regexp" "strings" "time" @@ -32,6 +33,9 @@ type pmKeyObject struct { Primary int } +// Armored type for PGP encrypted messages. +const PGP_MESSAGE_TYPE = "PGP MESSAGE" + func (ko *pmKeyObject) PrivateKeyReader() io.Reader { return strings.NewReader(ko.PrivateKey) } @@ -266,6 +270,20 @@ func (kr *KeyRing) DecryptString(encrypted string) (SignedString, error) { return SignedString{String: s, Signed: signed}, nil } +// Decrypt data if has PGP MESSAGE format, if not return original data. +// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors), +// contents are still provided if library clients wish to process this message further +func (kr *KeyRing) DecryptStringIfNeeded(data string) (decrypted string, err error) { + if re := regexp.MustCompile("^-----BEGIN " + PGP_MESSAGE_TYPE + "-----(?s:.+)-----END " + PGP_MESSAGE_TYPE + "-----"); re.MatchString(data) { + var signed SignedString + signed, err = kr.DecryptString(data) + decrypted = signed.String + } else { + decrypted = data + } + return +} + // Sign a string message, using this KeyRing. canonicalizeText identifies if newlines are canonicalized func (kr *KeyRing) SignString(message string, canonicalizeText bool) (signed string, err error) {