Source File
read.go
Belonging Package
golang.org/x/crypto/openpgp
package openpgp // import "golang.org/x/crypto/openpgp"
import (
_
)
var SignatureType = "PGP SIGNATURE"
type MessageDetails struct {
IsEncrypted bool // true if the message was encrypted.
EncryptedToKeyIds []uint64 // the list of recipient key ids.
IsSymmetricallyEncrypted bool // true if a passphrase could have decrypted the message.
DecryptedWith Key // the private key used to decrypt the message, if any.
IsSigned bool // true if the message is signed.
SignedByKeyId uint64 // the key id of the signer, if any.
SignedBy *Key // the key of the signer, if available.
LiteralData *packet.LiteralData // the metadata of the contents
UnverifiedBody io.Reader // the contents of the message.
SignatureError error // nil if the signature is good.
Signature *packet.Signature // the signature packet itself, if v4 (default)
SignatureV3 *packet.SignatureV3 // the signature packet if it is a v2 or v3 signature
decrypted io.ReadCloser
}
type PromptFunction func(keys []Key, symmetric bool) ([]byte, error)
type keyEnvelopePair struct {
key Key
encryptedKey *packet.EncryptedKey
}
func ( io.Reader, KeyRing, PromptFunction, *packet.Config) ( *MessageDetails, error) {
var packet.Packet
var []*packet.SymmetricKeyEncrypted
var []keyEnvelopePair
var *packet.SymmetricallyEncrypted
:= packet.NewReader()
= new(MessageDetails)
.IsEncrypted = true
.IsSymmetricallyEncrypted = true
= append(, )
.EncryptedToKeyIds = append(.EncryptedToKeyIds, .KeyId)
switch .Algo {
case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal:
break
default:
continue
}
var []Key
if .KeyId == 0 {
= .DecryptionKeys()
} else {
= .KeysById(.KeyId)
}
for , := range {
= append(, keyEnvelopePair{, })
}
case *packet.SymmetricallyEncrypted:
=
break
if len() != 0 || len() != 0 {
return nil, errors.StructuralError("key material not followed by encrypted message")
}
.Unread()
return readSignedMessage(, nil, )
}
}
var []Key
var io.ReadCloser
:
= [:0]
:= make(map[string]bool)
for , := range {
if .key.PrivateKey == nil {
continue
}
if !.key.PrivateKey.Encrypted {
if len(.encryptedKey.Key) == 0 {
.encryptedKey.Decrypt(.key.PrivateKey, )
}
if len(.encryptedKey.Key) == 0 {
continue
}
, = .Decrypt(.encryptedKey.CipherFunc, .encryptedKey.Key)
if != nil && != errors.ErrKeyIncorrect {
return nil,
}
if != nil {
.DecryptedWith = .key
break
}
} else {
:= string(.key.PublicKey.Fingerprint[:])
if := []; {
continue
}
= append(, .key)
[] = true
}
}
if len() == 0 && len() == 0 {
return nil, errors.ErrKeyIncorrect
}
if == nil {
return nil, errors.ErrKeyIncorrect
}
, := (, len() != 0)
if != nil {
return nil,
}
func ( *packet.Reader, *MessageDetails, KeyRing) ( *MessageDetails, error) {
if == nil {
= new(MessageDetails)
}
=
var packet.Packet
var hash.Hash
var hash.Hash
:
for {
, = .Next()
if != nil {
return nil,
}
switch p := .(type) {
case *packet.Compressed:
if := .Push(.Body); != nil {
return nil,
}
case *packet.OnePassSignature:
if !.IsLast {
return nil, errors.UnsupportedError("nested signatures")
}
, , = hashForSignature(.Hash, .SigType)
if != nil {
= nil
return
}
.IsSigned = true
.SignedByKeyId = .KeyId
:= .KeysByIdUsage(.KeyId, packet.KeyFlagSign)
if len() > 0 {
.SignedBy = &[0]
}
case *packet.LiteralData:
.LiteralData =
break
}
}
if .SignedBy != nil {
.UnverifiedBody = &signatureCheckReader{, , , }
} else if .decrypted != nil {
.UnverifiedBody = checkReader{}
} else {
.UnverifiedBody = .LiteralData.Body
}
return , nil
}
func ( crypto.Hash, packet.SignatureType) (hash.Hash, hash.Hash, error) {
if !.Available() {
return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int()))
}
:= .New()
switch {
case packet.SigTypeBinary:
return , , nil
case packet.SigTypeText:
return , NewCanonicalTextHash(), nil
}
return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int()))
}
type checkReader struct {
md *MessageDetails
}
func ( checkReader) ( []byte) ( int, error) {
, = .md.LiteralData.Body.Read()
if == io.EOF {
:= .md.decrypted.Close()
if != nil {
=
}
}
return
}
type signatureCheckReader struct {
packets *packet.Reader
h, wrappedHash hash.Hash
md *MessageDetails
}
func ( *signatureCheckReader) ( []byte) ( int, error) {
, = .md.LiteralData.Body.Read()
.wrappedHash.Write([:])
if == io.EOF {
var packet.Packet
, .md.SignatureError = .packets.Next()
if .md.SignatureError != nil {
return
}
var bool
if .md.Signature, = .(*packet.Signature); {
.md.SignatureError = .md.SignedBy.PublicKey.VerifySignature(.h, .md.Signature)
} else if .md.SignatureV3, = .(*packet.SignatureV3); {
.md.SignatureError = .md.SignedBy.PublicKey.VerifySignatureV3(.h, .md.SignatureV3)
} else {
.md.SignatureError = errors.StructuralError("LiteralData not followed by Signature")
return
}
func ( KeyRing, , io.Reader) ( *Entity, error) {
var uint64
var crypto.Hash
var packet.SignatureType
var []Key
var packet.Packet
:= packet.NewReader()
for {
, = .Next()
if == io.EOF {
return nil, errors.ErrUnknownIssuer
}
if != nil {
return nil,
}
switch sig := .(type) {
case *packet.Signature:
if .IssuerKeyId == nil {
return nil, errors.StructuralError("signature doesn't have an issuer")
}
= *.IssuerKeyId
= .Hash
= .SigType
case *packet.SignatureV3:
= .IssuerKeyId
= .Hash
= .SigType
default:
return nil, errors.StructuralError("non signature packet found")
}
= .KeysByIdUsage(, packet.KeyFlagSign)
if len() > 0 {
break
}
}
if len() == 0 {
panic("unreachable")
}
, , := hashForSignature(, )
if != nil {
return nil,
}
if , := io.Copy(, ); != nil && != io.EOF {
return nil,
}
for , := range {
switch sig := .(type) {
case *packet.Signature:
= .PublicKey.VerifySignature(, )
case *packet.SignatureV3:
= .PublicKey.VerifySignatureV3(, )
default:
panic("unreachable")
}
if == nil {
return .Entity, nil
}
}
return nil,
}
func ( KeyRing, , io.Reader) ( *Entity, error) {
, := readArmored(, SignatureType)
if != nil {
return
}
return CheckDetachedSignature(, , )
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |