1// Copyright 2011 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Package openpgp implements high level operations on OpenPGP messages. 6package openpgp // import "github.com/ProtonMail/go-crypto/openpgp" 7 8import ( 9 "crypto" 10 _ "crypto/sha256" 11 "hash" 12 "io" 13 "strconv" 14 15 "github.com/ProtonMail/go-crypto/openpgp/armor" 16 "github.com/ProtonMail/go-crypto/openpgp/errors" 17 "github.com/ProtonMail/go-crypto/openpgp/packet" 18) 19 20// SignatureType is the armor type for a PGP signature. 21var SignatureType = "PGP SIGNATURE" 22 23// readArmored reads an armored block with the given type. 24func readArmored(r io.Reader, expectedType string) (body io.Reader, err error) { 25 block, err := armor.Decode(r) 26 if err != nil { 27 return 28 } 29 30 if block.Type != expectedType { 31 return nil, errors.InvalidArgumentError("expected '" + expectedType + "', got: " + block.Type) 32 } 33 34 return block.Body, nil 35} 36 37// MessageDetails contains the result of parsing an OpenPGP encrypted and/or 38// signed message. 39type MessageDetails struct { 40 IsEncrypted bool // true if the message was encrypted. 41 EncryptedToKeyIds []uint64 // the list of recipient key ids. 42 IsSymmetricallyEncrypted bool // true if a passphrase could have decrypted the message. 43 DecryptedWith Key // the private key used to decrypt the message, if any. 44 IsSigned bool // true if the message is signed. 45 SignedByKeyId uint64 // the key id of the signer, if any. 46 SignedBy *Key // the key of the signer, if available. 47 LiteralData *packet.LiteralData // the metadata of the contents 48 UnverifiedBody io.Reader // the contents of the message. 49 50 // If IsSigned is true and SignedBy is non-zero then the signature will 51 // be verified as UnverifiedBody is read. The signature cannot be 52 // checked until the whole of UnverifiedBody is read so UnverifiedBody 53 // must be consumed until EOF before the data can be trusted. Even if a 54 // message isn't signed (or the signer is unknown) the data may contain 55 // an authentication code that is only checked once UnverifiedBody has 56 // been consumed. Once EOF has been seen, the following fields are 57 // valid. (An authentication code failure is reported as a 58 // SignatureError error when reading from UnverifiedBody.) 59 Signature *packet.Signature // the signature packet itself. 60 SignatureError error // nil if the signature is good. 61 UnverifiedSignatures []*packet.Signature // all other unverified signature packets. 62 63 decrypted io.ReadCloser 64} 65 66// A PromptFunction is used as a callback by functions that may need to decrypt 67// a private key, or prompt for a passphrase. It is called with a list of 68// acceptable, encrypted private keys and a boolean that indicates whether a 69// passphrase is usable. It should either decrypt a private key or return a 70// passphrase to try. If the decrypted private key or given passphrase isn't 71// correct, the function will be called again, forever. Any error returned will 72// be passed up. 73type PromptFunction func(keys []Key, symmetric bool) ([]byte, error) 74 75// A keyEnvelopePair is used to store a private key with the envelope that 76// contains a symmetric key, encrypted with that key. 77type keyEnvelopePair struct { 78 key Key 79 encryptedKey *packet.EncryptedKey 80} 81 82// ReadMessage parses an OpenPGP message that may be signed and/or encrypted. 83// The given KeyRing should contain both public keys (for signature 84// verification) and, possibly encrypted, private keys for decrypting. 85// If config is nil, sensible defaults will be used. 86func ReadMessage(r io.Reader, keyring KeyRing, prompt PromptFunction, config *packet.Config) (md *MessageDetails, err error) { 87 var p packet.Packet 88 89 var symKeys []*packet.SymmetricKeyEncrypted 90 var pubKeys []keyEnvelopePair 91 // Integrity protected encrypted packet: SymmetricallyEncrypted or AEADEncrypted 92 var edp packet.EncryptedDataPacket 93 94 packets := packet.NewReader(r) 95 md = new(MessageDetails) 96 md.IsEncrypted = true 97 98 // The message, if encrypted, starts with a number of packets 99 // containing an encrypted decryption key. The decryption key is either 100 // encrypted to a public key, or with a passphrase. This loop 101 // collects these packets. 102ParsePackets: 103 for { 104 p, err = packets.Next() 105 if err != nil { 106 return nil, err 107 } 108 switch p := p.(type) { 109 case *packet.SymmetricKeyEncrypted: 110 // This packet contains the decryption key encrypted with a passphrase. 111 md.IsSymmetricallyEncrypted = true 112 symKeys = append(symKeys, p) 113 case *packet.EncryptedKey: 114 // This packet contains the decryption key encrypted to a public key. 115 md.EncryptedToKeyIds = append(md.EncryptedToKeyIds, p.KeyId) 116 switch p.Algo { 117 case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoElGamal, packet.PubKeyAlgoECDH: 118 break 119 default: 120 continue 121 } 122 var keys []Key 123 if p.KeyId == 0 { 124 keys = keyring.DecryptionKeys() 125 } else { 126 keys = keyring.KeysById(p.KeyId) 127 } 128 for _, k := range keys { 129 pubKeys = append(pubKeys, keyEnvelopePair{k, p}) 130 } 131 case *packet.SymmetricallyEncrypted, *packet.AEADEncrypted: 132 edp = p.(packet.EncryptedDataPacket) 133 break ParsePackets 134 case *packet.Compressed, *packet.LiteralData, *packet.OnePassSignature: 135 // This message isn't encrypted. 136 if len(symKeys) != 0 || len(pubKeys) != 0 { 137 return nil, errors.StructuralError("key material not followed by encrypted message") 138 } 139 packets.Unread(p) 140 return readSignedMessage(packets, nil, keyring, config) 141 } 142 } 143 144 var candidates []Key 145 var decrypted io.ReadCloser 146 147 // Now that we have the list of encrypted keys we need to decrypt at 148 // least one of them or, if we cannot, we need to call the prompt 149 // function so that it can decrypt a key or give us a passphrase. 150FindKey: 151 for { 152 // See if any of the keys already have a private key available 153 candidates = candidates[:0] 154 candidateFingerprints := make(map[string]bool) 155 156 for _, pk := range pubKeys { 157 if pk.key.PrivateKey == nil { 158 continue 159 } 160 if !pk.key.PrivateKey.Encrypted { 161 if len(pk.encryptedKey.Key) == 0 { 162 errDec := pk.encryptedKey.Decrypt(pk.key.PrivateKey, config) 163 if errDec != nil { 164 continue 165 } 166 } 167 // Try to decrypt symmetrically encrypted 168 decrypted, err = edp.Decrypt(pk.encryptedKey.CipherFunc, pk.encryptedKey.Key) 169 if err != nil && err != errors.ErrKeyIncorrect { 170 return nil, err 171 } 172 if decrypted != nil { 173 md.DecryptedWith = pk.key 174 break FindKey 175 } 176 } else { 177 fpr := string(pk.key.PublicKey.Fingerprint[:]) 178 if v := candidateFingerprints[fpr]; v { 179 continue 180 } 181 candidates = append(candidates, pk.key) 182 candidateFingerprints[fpr] = true 183 } 184 } 185 186 if len(candidates) == 0 && len(symKeys) == 0 { 187 return nil, errors.ErrKeyIncorrect 188 } 189 190 if prompt == nil { 191 return nil, errors.ErrKeyIncorrect 192 } 193 194 passphrase, err := prompt(candidates, len(symKeys) != 0) 195 if err != nil { 196 return nil, err 197 } 198 199 // Try the symmetric passphrase first 200 if len(symKeys) != 0 && passphrase != nil { 201 for _, s := range symKeys { 202 key, cipherFunc, err := s.Decrypt(passphrase) 203 // On wrong passphrase, session key decryption is very likely to result in an invalid cipherFunc: 204 // only for < 5% of cases we will proceed to decrypt the data 205 if err == nil { 206 decrypted, err = edp.Decrypt(cipherFunc, key) 207 // TODO: ErrKeyIncorrect is no longer thrown on SEIP decryption, 208 // but it might still be relevant for when we implement AEAD decryption (otherwise, remove?) 209 if err != nil && err != errors.ErrKeyIncorrect { 210 return nil, err 211 } 212 if decrypted != nil { 213 break FindKey 214 } 215 } 216 } 217 } 218 } 219 220 md.decrypted = decrypted 221 if err := packets.Push(decrypted); err != nil { 222 return nil, err 223 } 224 mdFinal, sensitiveParsingErr := readSignedMessage(packets, md, keyring, config) 225 if sensitiveParsingErr != nil { 226 return nil, errors.StructuralError("parsing error") 227 } 228 return mdFinal, nil 229} 230 231// readSignedMessage reads a possibly signed message if mdin is non-zero then 232// that structure is updated and returned. Otherwise a fresh MessageDetails is 233// used. 234func readSignedMessage(packets *packet.Reader, mdin *MessageDetails, keyring KeyRing, config *packet.Config) (md *MessageDetails, err error) { 235 if mdin == nil { 236 mdin = new(MessageDetails) 237 } 238 md = mdin 239 240 var p packet.Packet 241 var h hash.Hash 242 var wrappedHash hash.Hash 243 var prevLast bool 244FindLiteralData: 245 for { 246 p, err = packets.Next() 247 if err != nil { 248 return nil, err 249 } 250 switch p := p.(type) { 251 case *packet.Compressed: 252 if err := packets.Push(p.Body); err != nil { 253 return nil, err 254 } 255 case *packet.OnePassSignature: 256 if prevLast { 257 return nil, errors.UnsupportedError("nested signature packets") 258 } 259 260 if p.IsLast { 261 prevLast = true 262 } 263 264 h, wrappedHash, err = hashForSignature(p.Hash, p.SigType) 265 if err != nil { 266 md.SignatureError = err 267 } 268 269 md.IsSigned = true 270 md.SignedByKeyId = p.KeyId 271 keys := keyring.KeysByIdUsage(p.KeyId, packet.KeyFlagSign) 272 if len(keys) > 0 { 273 md.SignedBy = &keys[0] 274 } 275 case *packet.LiteralData: 276 md.LiteralData = p 277 break FindLiteralData 278 } 279 } 280 281 if md.IsSigned && md.SignatureError == nil { 282 md.UnverifiedBody = &signatureCheckReader{packets, h, wrappedHash, md, config} 283 } else if md.decrypted != nil { 284 md.UnverifiedBody = checkReader{md} 285 } else { 286 md.UnverifiedBody = md.LiteralData.Body 287 } 288 289 return md, nil 290} 291 292// hashForSignature returns a pair of hashes that can be used to verify a 293// signature. The signature may specify that the contents of the signed message 294// should be preprocessed (i.e. to normalize line endings). Thus this function 295// returns two hashes. The second should be used to hash the message itself and 296// performs any needed preprocessing. 297func hashForSignature(hashId crypto.Hash, sigType packet.SignatureType) (hash.Hash, hash.Hash, error) { 298 if hashId == crypto.MD5 { 299 return nil, nil, errors.UnsupportedError("insecure hash algorithm: MD5") 300 } 301 if !hashId.Available() { 302 return nil, nil, errors.UnsupportedError("hash not available: " + strconv.Itoa(int(hashId))) 303 } 304 h := hashId.New() 305 306 switch sigType { 307 case packet.SigTypeBinary: 308 return h, h, nil 309 case packet.SigTypeText: 310 return h, NewCanonicalTextHash(h), nil 311 } 312 313 return nil, nil, errors.UnsupportedError("unsupported signature type: " + strconv.Itoa(int(sigType))) 314} 315 316// checkReader wraps an io.Reader from a LiteralData packet. When it sees EOF 317// it closes the ReadCloser from any SymmetricallyEncrypted packet to trigger 318// MDC checks. 319type checkReader struct { 320 md *MessageDetails 321} 322 323func (cr checkReader) Read(buf []byte) (int, error) { 324 n, sensitiveParsingError := cr.md.LiteralData.Body.Read(buf) 325 if sensitiveParsingError == io.EOF { 326 mdcErr := cr.md.decrypted.Close() 327 if mdcErr != nil { 328 return n, mdcErr 329 } 330 return n, io.EOF 331 } 332 333 if sensitiveParsingError != nil { 334 return n, errors.StructuralError("parsing error") 335 } 336 337 return n, nil 338} 339 340// signatureCheckReader wraps an io.Reader from a LiteralData packet and hashes 341// the data as it is read. When it sees an EOF from the underlying io.Reader 342// it parses and checks a trailing Signature packet and triggers any MDC checks. 343type signatureCheckReader struct { 344 packets *packet.Reader 345 h, wrappedHash hash.Hash 346 md *MessageDetails 347 config *packet.Config 348} 349 350func (scr *signatureCheckReader) Read(buf []byte) (int, error) { 351 n, sensitiveParsingError := scr.md.LiteralData.Body.Read(buf) 352 353 // Hash only if required 354 if scr.md.SignedBy != nil { 355 scr.wrappedHash.Write(buf[:n]) 356 } 357 358 if sensitiveParsingError == io.EOF { 359 var p packet.Packet 360 var readError error 361 var sig *packet.Signature 362 363 p, readError = scr.packets.Next() 364 for readError == nil { 365 var ok bool 366 if sig, ok = p.(*packet.Signature); ok { 367 if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) { 368 sig.Metadata = scr.md.LiteralData 369 } 370 371 // If signature KeyID matches 372 if scr.md.SignedBy != nil && *sig.IssuerKeyId == scr.md.SignedByKeyId { 373 key := scr.md.SignedBy 374 signatureError := key.PublicKey.VerifySignature(scr.h, sig) 375 if signatureError == nil { 376 now := scr.config.Now() 377 if key.Revoked(now) || 378 key.Entity.Revoked(now) || // primary key is revoked (redundant if key is the primary key) 379 key.Entity.PrimaryIdentity().Revoked(now) { 380 signatureError = errors.ErrKeyRevoked 381 } 382 if sig.SigExpired(now) { 383 signatureError = errors.ErrSignatureExpired 384 } 385 if key.PublicKey.KeyExpired(key.SelfSignature, now) || 386 key.SelfSignature.SigExpired(now) { 387 signatureError = errors.ErrKeyExpired 388 } 389 } 390 scr.md.Signature = sig 391 scr.md.SignatureError = signatureError 392 } else { 393 scr.md.UnverifiedSignatures = append(scr.md.UnverifiedSignatures, sig) 394 } 395 } 396 397 p, readError = scr.packets.Next() 398 } 399 400 if scr.md.SignedBy != nil && scr.md.Signature == nil { 401 if scr.md.UnverifiedSignatures == nil { 402 scr.md.SignatureError = errors.StructuralError("LiteralData not followed by signature") 403 } else { 404 scr.md.SignatureError = errors.StructuralError("No matching signature found") 405 } 406 } 407 408 // The SymmetricallyEncrypted packet, if any, might have an 409 // unsigned hash of its own. In order to check this we need to 410 // close that Reader. 411 if scr.md.decrypted != nil { 412 mdcErr := scr.md.decrypted.Close() 413 if mdcErr != nil { 414 return n, mdcErr 415 } 416 } 417 return n, io.EOF 418 } 419 420 if sensitiveParsingError != nil { 421 return n, errors.StructuralError("parsing error") 422 } 423 424 return n, nil 425} 426 427// CheckDetachedSignature takes a signed file and a detached signature and 428// returns the signer if the signature is valid. If the signer isn't known, 429// ErrUnknownIssuer is returned. 430func CheckDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) { 431 var expectedHashes []crypto.Hash 432 return CheckDetachedSignatureAndHash(keyring, signed, signature, expectedHashes, config) 433} 434 435// CheckDetachedSignatureAndHash performs the same actions as 436// CheckDetachedSignature and checks that the expected hash functions were used. 437func CheckDetachedSignatureAndHash(keyring KeyRing, signed, signature io.Reader, expectedHashes []crypto.Hash, config *packet.Config) (signer *Entity, err error) { 438 var issuerKeyId uint64 439 var hashFunc crypto.Hash 440 var sigType packet.SignatureType 441 var keys []Key 442 var p packet.Packet 443 444 expectedHashesLen := len(expectedHashes) 445 packets := packet.NewReader(signature) 446 var sig *packet.Signature 447 for { 448 p, err = packets.Next() 449 if err == io.EOF { 450 return nil, errors.ErrUnknownIssuer 451 } 452 if err != nil { 453 return nil, err 454 } 455 456 var ok bool 457 sig, ok = p.(*packet.Signature) 458 if !ok { 459 return nil, errors.StructuralError("non signature packet found") 460 } 461 if sig.IssuerKeyId == nil { 462 return nil, errors.StructuralError("signature doesn't have an issuer") 463 } 464 issuerKeyId = *sig.IssuerKeyId 465 hashFunc = sig.Hash 466 sigType = sig.SigType 467 468 for i, expectedHash := range expectedHashes { 469 if hashFunc == expectedHash { 470 break 471 } 472 if i+1 == expectedHashesLen { 473 return nil, errors.StructuralError("hash algorithm mismatch with cleartext message headers") 474 } 475 } 476 477 keys = keyring.KeysByIdUsage(issuerKeyId, packet.KeyFlagSign) 478 if len(keys) > 0 { 479 break 480 } 481 } 482 483 if len(keys) == 0 { 484 panic("unreachable") 485 } 486 487 h, wrappedHash, err := hashForSignature(hashFunc, sigType) 488 if err != nil { 489 return nil, err 490 } 491 492 if _, err := io.Copy(wrappedHash, signed); err != nil && err != io.EOF { 493 return nil, err 494 } 495 496 for _, key := range keys { 497 err = key.PublicKey.VerifySignature(h, sig) 498 if err == nil { 499 now := config.Now() 500 if key.Revoked(now) || 501 key.Entity.Revoked(now) || // primary key is revoked (redundant if key is the primary key) 502 key.Entity.PrimaryIdentity().Revoked(now) { 503 return key.Entity, errors.ErrKeyRevoked 504 } 505 if sig.SigExpired(now) { 506 return key.Entity, errors.ErrSignatureExpired 507 } 508 if key.PublicKey.KeyExpired(key.SelfSignature, now) || 509 key.SelfSignature.SigExpired(now) { 510 return key.Entity, errors.ErrKeyExpired 511 } 512 return key.Entity, nil 513 } 514 } 515 516 return nil, err 517} 518 519// CheckArmoredDetachedSignature performs the same actions as 520// CheckDetachedSignature but expects the signature to be armored. 521func CheckArmoredDetachedSignature(keyring KeyRing, signed, signature io.Reader, config *packet.Config) (signer *Entity, err error) { 522 body, err := readArmored(signature, SignatureType) 523 if err != nil { 524 return 525 } 526 527 return CheckDetachedSignature(keyring, signed, body, config) 528} 529