main
Raw Download raw file
   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
   5package packet
   6
   7import (
   8	"bytes"
   9	"crypto"
  10	"crypto/dsa"
  11	"encoding/asn1"
  12	"encoding/binary"
  13	"hash"
  14	"io"
  15	"math/big"
  16	"strconv"
  17	"time"
  18
  19	"github.com/ProtonMail/go-crypto/openpgp/ecdsa"
  20	"github.com/ProtonMail/go-crypto/openpgp/ed25519"
  21	"github.com/ProtonMail/go-crypto/openpgp/ed448"
  22	"github.com/ProtonMail/go-crypto/openpgp/eddsa"
  23	"github.com/ProtonMail/go-crypto/openpgp/errors"
  24	"github.com/ProtonMail/go-crypto/openpgp/internal/algorithm"
  25	"github.com/ProtonMail/go-crypto/openpgp/internal/encoding"
  26)
  27
  28const (
  29	// First octet of key flags.
  30	// See RFC 9580, section 5.2.3.29 for details.
  31	KeyFlagCertify = 1 << iota
  32	KeyFlagSign
  33	KeyFlagEncryptCommunications
  34	KeyFlagEncryptStorage
  35	KeyFlagSplitKey
  36	KeyFlagAuthenticate
  37	_
  38	KeyFlagGroupKey
  39)
  40
  41const (
  42	// First octet of keyserver preference flags.
  43	// See RFC 9580, section 5.2.3.25 for details.
  44	_ = 1 << iota
  45	_
  46	_
  47	_
  48	_
  49	_
  50	_
  51	KeyserverPrefNoModify
  52)
  53
  54const SaltNotationName = "salt@notations.openpgpjs.org"
  55
  56// Signature represents a signature. See RFC 9580, section 5.2.
  57type Signature struct {
  58	Version    int
  59	SigType    SignatureType
  60	PubKeyAlgo PublicKeyAlgorithm
  61	Hash       crypto.Hash
  62	// salt contains a random salt value for v6 signatures
  63	// See RFC 9580 Section 5.2.4.
  64	salt []byte
  65
  66	// HashSuffix is extra data that is hashed in after the signed data.
  67	HashSuffix []byte
  68	// HashTag contains the first two bytes of the hash for fast rejection
  69	// of bad signed data.
  70	HashTag [2]byte
  71
  72	// Metadata includes format, filename and time, and is protected by v5
  73	// signatures of type 0x00 or 0x01. This metadata is included into the hash
  74	// computation; if nil, six 0x00 bytes are used instead. See section 5.2.4.
  75	Metadata *LiteralData
  76
  77	CreationTime time.Time
  78
  79	RSASignature         encoding.Field
  80	DSASigR, DSASigS     encoding.Field
  81	ECDSASigR, ECDSASigS encoding.Field
  82	EdDSASigR, EdDSASigS encoding.Field
  83	EdSig                []byte
  84
  85	// rawSubpackets contains the unparsed subpackets, in order.
  86	rawSubpackets []outputSubpacket
  87
  88	// The following are optional so are nil when not included in the
  89	// signature.
  90
  91	SigLifetimeSecs, KeyLifetimeSecs                        *uint32
  92	PreferredSymmetric, PreferredHash, PreferredCompression []uint8
  93	PreferredCipherSuites                                   [][2]uint8
  94	IssuerKeyId                                             *uint64
  95	IssuerFingerprint                                       []byte
  96	SignerUserId                                            *string
  97	IsPrimaryId                                             *bool
  98	Notations                                               []*Notation
  99	IntendedRecipients                                      []*Recipient
 100
 101	// TrustLevel and TrustAmount can be set by the signer to assert that
 102	// the key is not only valid but also trustworthy at the specified
 103	// level.
 104	// See RFC 9580, section 5.2.3.21 for details.
 105	TrustLevel  TrustLevel
 106	TrustAmount TrustAmount
 107
 108	// TrustRegularExpression can be used in conjunction with trust Signature
 109	// packets to limit the scope of the trust that is extended.
 110	// See RFC 9580, section 5.2.3.22 for details.
 111	TrustRegularExpression *string
 112
 113	// KeyserverPrefsValid is set if any keyserver preferences were given. See RFC 9580, section
 114	// 5.2.3.25 for details.
 115	KeyserverPrefsValid   bool
 116	KeyserverPrefNoModify bool
 117
 118	// PreferredKeyserver can be set to a URI where the latest version of the
 119	// key that this signature is made over can be found. See RFC 9580, section
 120	// 5.2.3.26 for details.
 121	PreferredKeyserver string
 122
 123	// PolicyURI can be set to the URI of a document that describes the
 124	// policy under which the signature was issued. See RFC 9580, section
 125	// 5.2.3.28 for details.
 126	PolicyURI string
 127
 128	// FlagsValid is set if any flags were given. See RFC 9580, section
 129	// 5.2.3.29 for details.
 130	FlagsValid                                                                                                         bool
 131	FlagCertify, FlagSign, FlagEncryptCommunications, FlagEncryptStorage, FlagSplitKey, FlagAuthenticate, FlagGroupKey bool
 132
 133	// RevocationReason is set if this signature has been revoked.
 134	// See RFC 9580, section 5.2.3.31 for details.
 135	RevocationReason     *ReasonForRevocation
 136	RevocationReasonText string
 137
 138	// In a self-signature, these flags are set there is a features subpacket
 139	// indicating that the issuer implementation supports these features
 140	// see https://datatracker.ietf.org/doc/html/draft-ietf-openpgp-crypto-refresh#features-subpacket
 141	SEIPDv1, SEIPDv2 bool
 142
 143	// EmbeddedSignature, if non-nil, is a signature of the parent key, by
 144	// this key. This prevents an attacker from claiming another's signing
 145	// subkey as their own.
 146	EmbeddedSignature *Signature
 147
 148	outSubpackets []outputSubpacket
 149}
 150
 151// VerifiableSignature internally keeps state if the
 152// the signature has been verified before.
 153type VerifiableSignature struct {
 154	Valid  *bool // nil if it has not been verified yet
 155	Packet *Signature
 156}
 157
 158// NewVerifiableSig returns a struct of type VerifiableSignature referencing the input signature.
 159func NewVerifiableSig(signature *Signature) *VerifiableSignature {
 160	return &VerifiableSignature{
 161		Packet: signature,
 162	}
 163}
 164
 165// Salt returns the signature salt for v6 signatures.
 166func (sig *Signature) Salt() []byte {
 167	if sig == nil {
 168		return nil
 169	}
 170	return sig.salt
 171}
 172
 173func (sig *Signature) parse(r io.Reader) (err error) {
 174	// RFC 9580, section 5.2.3
 175	var buf [7]byte
 176	_, err = readFull(r, buf[:1])
 177	if err != nil {
 178		return
 179	}
 180	sig.Version = int(buf[0])
 181	if sig.Version != 4 && sig.Version != 5 && sig.Version != 6 {
 182		err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0])))
 183		return
 184	}
 185
 186	if V5Disabled && sig.Version == 5 {
 187		return errors.UnsupportedError("support for parsing v5 entities is disabled; build with `-tags v5` if needed")
 188	}
 189
 190	if sig.Version == 6 {
 191		_, err = readFull(r, buf[:7])
 192	} else {
 193		_, err = readFull(r, buf[:5])
 194	}
 195	if err != nil {
 196		return
 197	}
 198	sig.SigType = SignatureType(buf[0])
 199	sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1])
 200	switch sig.PubKeyAlgo {
 201	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA, PubKeyAlgoEdDSA, PubKeyAlgoEd25519, PubKeyAlgoEd448:
 202	default:
 203		err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo)))
 204		return
 205	}
 206
 207	var ok bool
 208
 209	if sig.Version < 5 {
 210		sig.Hash, ok = algorithm.HashIdToHashWithSha1(buf[2])
 211	} else {
 212		sig.Hash, ok = algorithm.HashIdToHash(buf[2])
 213	}
 214
 215	if !ok {
 216		return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2])))
 217	}
 218
 219	var hashedSubpacketsLength int
 220	if sig.Version == 6 {
 221		// For a v6 signature, a four-octet length is used.
 222		hashedSubpacketsLength =
 223			int(buf[3])<<24 |
 224				int(buf[4])<<16 |
 225				int(buf[5])<<8 |
 226				int(buf[6])
 227	} else {
 228		hashedSubpacketsLength = int(buf[3])<<8 | int(buf[4])
 229	}
 230	hashedSubpackets := make([]byte, hashedSubpacketsLength)
 231	_, err = readFull(r, hashedSubpackets)
 232	if err != nil {
 233		return
 234	}
 235	err = sig.buildHashSuffix(hashedSubpackets)
 236	if err != nil {
 237		return
 238	}
 239
 240	err = parseSignatureSubpackets(sig, hashedSubpackets, true)
 241	if err != nil {
 242		return
 243	}
 244
 245	if sig.Version == 6 {
 246		_, err = readFull(r, buf[:4])
 247	} else {
 248		_, err = readFull(r, buf[:2])
 249	}
 250
 251	if err != nil {
 252		return
 253	}
 254	var unhashedSubpacketsLength uint32
 255	if sig.Version == 6 {
 256		unhashedSubpacketsLength = uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2])<<8 | uint32(buf[3])
 257	} else {
 258		unhashedSubpacketsLength = uint32(buf[0])<<8 | uint32(buf[1])
 259	}
 260	unhashedSubpackets := make([]byte, unhashedSubpacketsLength)
 261	_, err = readFull(r, unhashedSubpackets)
 262	if err != nil {
 263		return
 264	}
 265	err = parseSignatureSubpackets(sig, unhashedSubpackets, false)
 266	if err != nil {
 267		return
 268	}
 269
 270	_, err = readFull(r, sig.HashTag[:2])
 271	if err != nil {
 272		return
 273	}
 274
 275	if sig.Version == 6 {
 276		// Only for v6 signatures, a variable-length field containing the salt
 277		_, err = readFull(r, buf[:1])
 278		if err != nil {
 279			return
 280		}
 281		saltLength := int(buf[0])
 282		var expectedSaltLength int
 283		expectedSaltLength, err = SaltLengthForHash(sig.Hash)
 284		if err != nil {
 285			return
 286		}
 287		if saltLength != expectedSaltLength {
 288			err = errors.StructuralError("unexpected salt size for the given hash algorithm")
 289			return
 290		}
 291		salt := make([]byte, expectedSaltLength)
 292		_, err = readFull(r, salt)
 293		if err != nil {
 294			return
 295		}
 296		sig.salt = salt
 297	}
 298
 299	switch sig.PubKeyAlgo {
 300	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
 301		sig.RSASignature = new(encoding.MPI)
 302		_, err = sig.RSASignature.ReadFrom(r)
 303	case PubKeyAlgoDSA:
 304		sig.DSASigR = new(encoding.MPI)
 305		if _, err = sig.DSASigR.ReadFrom(r); err != nil {
 306			return
 307		}
 308
 309		sig.DSASigS = new(encoding.MPI)
 310		_, err = sig.DSASigS.ReadFrom(r)
 311	case PubKeyAlgoECDSA:
 312		sig.ECDSASigR = new(encoding.MPI)
 313		if _, err = sig.ECDSASigR.ReadFrom(r); err != nil {
 314			return
 315		}
 316
 317		sig.ECDSASigS = new(encoding.MPI)
 318		_, err = sig.ECDSASigS.ReadFrom(r)
 319	case PubKeyAlgoEdDSA:
 320		sig.EdDSASigR = new(encoding.MPI)
 321		if _, err = sig.EdDSASigR.ReadFrom(r); err != nil {
 322			return
 323		}
 324
 325		sig.EdDSASigS = new(encoding.MPI)
 326		if _, err = sig.EdDSASigS.ReadFrom(r); err != nil {
 327			return
 328		}
 329	case PubKeyAlgoEd25519:
 330		sig.EdSig, err = ed25519.ReadSignature(r)
 331		if err != nil {
 332			return
 333		}
 334	case PubKeyAlgoEd448:
 335		sig.EdSig, err = ed448.ReadSignature(r)
 336		if err != nil {
 337			return
 338		}
 339	default:
 340		panic("unreachable")
 341	}
 342	return
 343}
 344
 345// parseSignatureSubpackets parses subpackets of the main signature packet. See
 346// RFC 9580, section 5.2.3.1.
 347func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err error) {
 348	for len(subpackets) > 0 {
 349		subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed)
 350		if err != nil {
 351			return
 352		}
 353	}
 354
 355	if sig.CreationTime.IsZero() {
 356		err = errors.StructuralError("no creation time in signature")
 357	}
 358
 359	return
 360}
 361
 362type signatureSubpacketType uint8
 363
 364const (
 365	creationTimeSubpacket        signatureSubpacketType = 2
 366	signatureExpirationSubpacket signatureSubpacketType = 3
 367	exportableCertSubpacket      signatureSubpacketType = 4
 368	trustSubpacket               signatureSubpacketType = 5
 369	regularExpressionSubpacket   signatureSubpacketType = 6
 370	keyExpirationSubpacket       signatureSubpacketType = 9
 371	prefSymmetricAlgosSubpacket  signatureSubpacketType = 11
 372	issuerSubpacket              signatureSubpacketType = 16
 373	notationDataSubpacket        signatureSubpacketType = 20
 374	prefHashAlgosSubpacket       signatureSubpacketType = 21
 375	prefCompressionSubpacket     signatureSubpacketType = 22
 376	keyserverPrefsSubpacket      signatureSubpacketType = 23
 377	prefKeyserverSubpacket       signatureSubpacketType = 24
 378	primaryUserIdSubpacket       signatureSubpacketType = 25
 379	policyUriSubpacket           signatureSubpacketType = 26
 380	keyFlagsSubpacket            signatureSubpacketType = 27
 381	signerUserIdSubpacket        signatureSubpacketType = 28
 382	reasonForRevocationSubpacket signatureSubpacketType = 29
 383	featuresSubpacket            signatureSubpacketType = 30
 384	embeddedSignatureSubpacket   signatureSubpacketType = 32
 385	issuerFingerprintSubpacket   signatureSubpacketType = 33
 386	intendedRecipientSubpacket   signatureSubpacketType = 35
 387	prefCipherSuitesSubpacket    signatureSubpacketType = 39
 388)
 389
 390// parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1.
 391func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err error) {
 392	// RFC 9580, section 5.2.3.7
 393	var (
 394		length     uint32
 395		packetType signatureSubpacketType
 396		isCritical bool
 397	)
 398	if len(subpacket) == 0 {
 399		err = errors.StructuralError("zero length signature subpacket")
 400		return
 401	}
 402	switch {
 403	case subpacket[0] < 192:
 404		length = uint32(subpacket[0])
 405		subpacket = subpacket[1:]
 406	case subpacket[0] < 255:
 407		if len(subpacket) < 2 {
 408			goto Truncated
 409		}
 410		length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192
 411		subpacket = subpacket[2:]
 412	default:
 413		if len(subpacket) < 5 {
 414			goto Truncated
 415		}
 416		length = uint32(subpacket[1])<<24 |
 417			uint32(subpacket[2])<<16 |
 418			uint32(subpacket[3])<<8 |
 419			uint32(subpacket[4])
 420		subpacket = subpacket[5:]
 421	}
 422	if length > uint32(len(subpacket)) {
 423		goto Truncated
 424	}
 425	rest = subpacket[length:]
 426	subpacket = subpacket[:length]
 427	if len(subpacket) == 0 {
 428		err = errors.StructuralError("zero length signature subpacket")
 429		return
 430	}
 431	packetType = signatureSubpacketType(subpacket[0] & 0x7f)
 432	isCritical = subpacket[0]&0x80 == 0x80
 433	subpacket = subpacket[1:]
 434	sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket})
 435	if !isHashed &&
 436		packetType != issuerSubpacket &&
 437		packetType != issuerFingerprintSubpacket &&
 438		packetType != embeddedSignatureSubpacket {
 439		return
 440	}
 441	switch packetType {
 442	case creationTimeSubpacket:
 443		if len(subpacket) != 4 {
 444			err = errors.StructuralError("signature creation time not four bytes")
 445			return
 446		}
 447		t := binary.BigEndian.Uint32(subpacket)
 448		sig.CreationTime = time.Unix(int64(t), 0)
 449	case signatureExpirationSubpacket:
 450		// Signature expiration time, section 5.2.3.18
 451		if len(subpacket) != 4 {
 452			err = errors.StructuralError("expiration subpacket with bad length")
 453			return
 454		}
 455		sig.SigLifetimeSecs = new(uint32)
 456		*sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket)
 457	case exportableCertSubpacket:
 458		if subpacket[0] == 0 {
 459			err = errors.UnsupportedError("signature with non-exportable certification")
 460			return
 461		}
 462	case trustSubpacket:
 463		if len(subpacket) != 2 {
 464			err = errors.StructuralError("trust subpacket with bad length")
 465			return
 466		}
 467		// Trust level and amount, section 5.2.3.21
 468		sig.TrustLevel = TrustLevel(subpacket[0])
 469		sig.TrustAmount = TrustAmount(subpacket[1])
 470	case regularExpressionSubpacket:
 471		if len(subpacket) == 0 {
 472			err = errors.StructuralError("regexp subpacket with bad length")
 473			return
 474		}
 475		// Trust regular expression, section 5.2.3.22
 476		// RFC specifies the string should be null-terminated; remove a null byte from the end
 477		if subpacket[len(subpacket)-1] != 0x00 {
 478			err = errors.StructuralError("expected regular expression to be null-terminated")
 479			return
 480		}
 481		trustRegularExpression := string(subpacket[:len(subpacket)-1])
 482		sig.TrustRegularExpression = &trustRegularExpression
 483	case keyExpirationSubpacket:
 484		// Key expiration time, section 5.2.3.13
 485		if len(subpacket) != 4 {
 486			err = errors.StructuralError("key expiration subpacket with bad length")
 487			return
 488		}
 489		sig.KeyLifetimeSecs = new(uint32)
 490		*sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket)
 491	case prefSymmetricAlgosSubpacket:
 492		// Preferred symmetric algorithms, section 5.2.3.14
 493		sig.PreferredSymmetric = make([]byte, len(subpacket))
 494		copy(sig.PreferredSymmetric, subpacket)
 495	case issuerSubpacket:
 496		// Issuer, section 5.2.3.12
 497		if sig.Version > 4 && isHashed {
 498			err = errors.StructuralError("issuer subpacket found in v6 key")
 499			return
 500		}
 501		if len(subpacket) != 8 {
 502			err = errors.StructuralError("issuer subpacket with bad length")
 503			return
 504		}
 505		if sig.Version <= 4 {
 506			sig.IssuerKeyId = new(uint64)
 507			*sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket)
 508		}
 509	case notationDataSubpacket:
 510		// Notation data, section 5.2.3.24
 511		if len(subpacket) < 8 {
 512			err = errors.StructuralError("notation data subpacket with bad length")
 513			return
 514		}
 515
 516		nameLength := uint32(subpacket[4])<<8 | uint32(subpacket[5])
 517		valueLength := uint32(subpacket[6])<<8 | uint32(subpacket[7])
 518		if len(subpacket) != int(nameLength)+int(valueLength)+8 {
 519			err = errors.StructuralError("notation data subpacket with bad length")
 520			return
 521		}
 522
 523		notation := Notation{
 524			IsHumanReadable: (subpacket[0] & 0x80) == 0x80,
 525			Name:            string(subpacket[8:(nameLength + 8)]),
 526			Value:           subpacket[(nameLength + 8):(valueLength + nameLength + 8)],
 527			IsCritical:      isCritical,
 528		}
 529
 530		sig.Notations = append(sig.Notations, &notation)
 531	case prefHashAlgosSubpacket:
 532		// Preferred hash algorithms, section 5.2.3.16
 533		sig.PreferredHash = make([]byte, len(subpacket))
 534		copy(sig.PreferredHash, subpacket)
 535	case prefCompressionSubpacket:
 536		// Preferred compression algorithms, section 5.2.3.17
 537		sig.PreferredCompression = make([]byte, len(subpacket))
 538		copy(sig.PreferredCompression, subpacket)
 539	case keyserverPrefsSubpacket:
 540		// Keyserver preferences, section 5.2.3.25
 541		sig.KeyserverPrefsValid = true
 542		if len(subpacket) == 0 {
 543			return
 544		}
 545		if subpacket[0]&KeyserverPrefNoModify != 0 {
 546			sig.KeyserverPrefNoModify = true
 547		}
 548	case prefKeyserverSubpacket:
 549		// Preferred keyserver, section 5.2.3.26
 550		sig.PreferredKeyserver = string(subpacket)
 551	case primaryUserIdSubpacket:
 552		// Primary User ID, section 5.2.3.27
 553		if len(subpacket) != 1 {
 554			err = errors.StructuralError("primary user id subpacket with bad length")
 555			return
 556		}
 557		sig.IsPrimaryId = new(bool)
 558		if subpacket[0] > 0 {
 559			*sig.IsPrimaryId = true
 560		}
 561	case keyFlagsSubpacket:
 562		// Key flags, section 5.2.3.29
 563		sig.FlagsValid = true
 564		if len(subpacket) == 0 {
 565			return
 566		}
 567		if subpacket[0]&KeyFlagCertify != 0 {
 568			sig.FlagCertify = true
 569		}
 570		if subpacket[0]&KeyFlagSign != 0 {
 571			sig.FlagSign = true
 572		}
 573		if subpacket[0]&KeyFlagEncryptCommunications != 0 {
 574			sig.FlagEncryptCommunications = true
 575		}
 576		if subpacket[0]&KeyFlagEncryptStorage != 0 {
 577			sig.FlagEncryptStorage = true
 578		}
 579		if subpacket[0]&KeyFlagSplitKey != 0 {
 580			sig.FlagSplitKey = true
 581		}
 582		if subpacket[0]&KeyFlagAuthenticate != 0 {
 583			sig.FlagAuthenticate = true
 584		}
 585		if subpacket[0]&KeyFlagGroupKey != 0 {
 586			sig.FlagGroupKey = true
 587		}
 588	case signerUserIdSubpacket:
 589		userId := string(subpacket)
 590		sig.SignerUserId = &userId
 591	case reasonForRevocationSubpacket:
 592		// Reason For Revocation, section 5.2.3.31
 593		if len(subpacket) == 0 {
 594			err = errors.StructuralError("empty revocation reason subpacket")
 595			return
 596		}
 597		sig.RevocationReason = new(ReasonForRevocation)
 598		*sig.RevocationReason = NewReasonForRevocation(subpacket[0])
 599		sig.RevocationReasonText = string(subpacket[1:])
 600	case featuresSubpacket:
 601		// Features subpacket, section 5.2.3.32 specifies a very general
 602		// mechanism for OpenPGP implementations to signal support for new
 603		// features.
 604		if len(subpacket) > 0 {
 605			if subpacket[0]&0x01 != 0 {
 606				sig.SEIPDv1 = true
 607			}
 608			// 0x02 and 0x04 are reserved
 609			if subpacket[0]&0x08 != 0 {
 610				sig.SEIPDv2 = true
 611			}
 612		}
 613	case embeddedSignatureSubpacket:
 614		// Only usage is in signatures that cross-certify
 615		// signing subkeys. section 5.2.3.34 describes the
 616		// format, with its usage described in section 11.1
 617		if sig.EmbeddedSignature != nil {
 618			err = errors.StructuralError("Cannot have multiple embedded signatures")
 619			return
 620		}
 621		sig.EmbeddedSignature = new(Signature)
 622		if err := sig.EmbeddedSignature.parse(bytes.NewBuffer(subpacket)); err != nil {
 623			return nil, err
 624		}
 625		if sigType := sig.EmbeddedSignature.SigType; sigType != SigTypePrimaryKeyBinding {
 626			return nil, errors.StructuralError("cross-signature has unexpected type " + strconv.Itoa(int(sigType)))
 627		}
 628	case policyUriSubpacket:
 629		// Policy URI, section 5.2.3.28
 630		sig.PolicyURI = string(subpacket)
 631	case issuerFingerprintSubpacket:
 632		if len(subpacket) == 0 {
 633			err = errors.StructuralError("empty issuer fingerprint subpacket")
 634			return
 635		}
 636		v, l := subpacket[0], len(subpacket[1:])
 637		if v >= 5 && l != 32 || v < 5 && l != 20 {
 638			return nil, errors.StructuralError("bad fingerprint length")
 639		}
 640		sig.IssuerFingerprint = make([]byte, l)
 641		copy(sig.IssuerFingerprint, subpacket[1:])
 642		sig.IssuerKeyId = new(uint64)
 643		if v >= 5 {
 644			*sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[1:9])
 645		} else {
 646			*sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket[13:21])
 647		}
 648	case intendedRecipientSubpacket:
 649		// Intended Recipient Fingerprint, section 5.2.3.36
 650		if len(subpacket) < 1 {
 651			return nil, errors.StructuralError("invalid intended recipient fingerpring length")
 652		}
 653		version, length := subpacket[0], len(subpacket[1:])
 654		if version >= 5 && length != 32 || version < 5 && length != 20 {
 655			return nil, errors.StructuralError("invalid fingerprint length")
 656		}
 657		fingerprint := make([]byte, length)
 658		copy(fingerprint, subpacket[1:])
 659		sig.IntendedRecipients = append(sig.IntendedRecipients, &Recipient{int(version), fingerprint})
 660	case prefCipherSuitesSubpacket:
 661		// Preferred AEAD cipher suites, section 5.2.3.15
 662		if len(subpacket)%2 != 0 {
 663			err = errors.StructuralError("invalid aead cipher suite length")
 664			return
 665		}
 666
 667		sig.PreferredCipherSuites = make([][2]byte, len(subpacket)/2)
 668
 669		for i := 0; i < len(subpacket)/2; i++ {
 670			sig.PreferredCipherSuites[i] = [2]uint8{subpacket[2*i], subpacket[2*i+1]}
 671		}
 672	default:
 673		if isCritical {
 674			err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType)))
 675			return
 676		}
 677	}
 678	return
 679
 680Truncated:
 681	err = errors.StructuralError("signature subpacket truncated")
 682	return
 683}
 684
 685// subpacketLengthLength returns the length, in bytes, of an encoded length value.
 686func subpacketLengthLength(length int) int {
 687	if length < 192 {
 688		return 1
 689	}
 690	if length < 16320 {
 691		return 2
 692	}
 693	return 5
 694}
 695
 696func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool {
 697	if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 {
 698		return bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint)
 699	}
 700	return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId
 701}
 702
 703func (sig *Signature) CheckKeyIdOrFingerprintExplicit(fingerprint []byte, keyId uint64) bool {
 704	if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 && fingerprint != nil {
 705		return bytes.Equal(sig.IssuerFingerprint, fingerprint)
 706	}
 707	return sig.IssuerKeyId != nil && *sig.IssuerKeyId == keyId
 708}
 709
 710// serializeSubpacketLength marshals the given length into to.
 711func serializeSubpacketLength(to []byte, length int) int {
 712	// RFC 9580, Section 4.2.1.
 713	if length < 192 {
 714		to[0] = byte(length)
 715		return 1
 716	}
 717	if length < 16320 {
 718		length -= 192
 719		to[0] = byte((length >> 8) + 192)
 720		to[1] = byte(length)
 721		return 2
 722	}
 723	to[0] = 255
 724	to[1] = byte(length >> 24)
 725	to[2] = byte(length >> 16)
 726	to[3] = byte(length >> 8)
 727	to[4] = byte(length)
 728	return 5
 729}
 730
 731// subpacketsLength returns the serialized length, in bytes, of the given
 732// subpackets.
 733func subpacketsLength(subpackets []outputSubpacket, hashed bool) (length int) {
 734	for _, subpacket := range subpackets {
 735		if subpacket.hashed == hashed {
 736			length += subpacketLengthLength(len(subpacket.contents) + 1)
 737			length += 1 // type byte
 738			length += len(subpacket.contents)
 739		}
 740	}
 741	return
 742}
 743
 744// serializeSubpackets marshals the given subpackets into to.
 745func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) {
 746	for _, subpacket := range subpackets {
 747		if subpacket.hashed == hashed {
 748			n := serializeSubpacketLength(to, len(subpacket.contents)+1)
 749			to[n] = byte(subpacket.subpacketType)
 750			if subpacket.isCritical {
 751				to[n] |= 0x80
 752			}
 753			to = to[1+n:]
 754			n = copy(to, subpacket.contents)
 755			to = to[n:]
 756		}
 757	}
 758}
 759
 760// SigExpired returns whether sig is a signature that has expired or is created
 761// in the future.
 762func (sig *Signature) SigExpired(currentTime time.Time) bool {
 763	if sig.CreationTime.Unix() > currentTime.Unix() {
 764		return true
 765	}
 766	if sig.SigLifetimeSecs == nil || *sig.SigLifetimeSecs == 0 {
 767		return false
 768	}
 769	expiry := sig.CreationTime.Add(time.Duration(*sig.SigLifetimeSecs) * time.Second)
 770	return currentTime.Unix() > expiry.Unix()
 771}
 772
 773// buildHashSuffix constructs the HashSuffix member of sig in preparation for signing.
 774func (sig *Signature) buildHashSuffix(hashedSubpackets []byte) (err error) {
 775	var hashId byte
 776	var ok bool
 777
 778	if sig.Version < 5 {
 779		hashId, ok = algorithm.HashToHashIdWithSha1(sig.Hash)
 780	} else {
 781		hashId, ok = algorithm.HashToHashId(sig.Hash)
 782	}
 783
 784	if !ok {
 785		sig.HashSuffix = nil
 786		return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash)))
 787	}
 788
 789	hashedFields := bytes.NewBuffer([]byte{
 790		uint8(sig.Version),
 791		uint8(sig.SigType),
 792		uint8(sig.PubKeyAlgo),
 793		uint8(hashId),
 794	})
 795	hashedSubpacketsLength := len(hashedSubpackets)
 796	if sig.Version == 6 {
 797		// v6 signatures store the length in 4 octets
 798		hashedFields.Write([]byte{
 799			uint8(hashedSubpacketsLength >> 24),
 800			uint8(hashedSubpacketsLength >> 16),
 801			uint8(hashedSubpacketsLength >> 8),
 802			uint8(hashedSubpacketsLength),
 803		})
 804	} else {
 805		hashedFields.Write([]byte{
 806			uint8(hashedSubpacketsLength >> 8),
 807			uint8(hashedSubpacketsLength),
 808		})
 809	}
 810	lenPrefix := hashedFields.Len()
 811	hashedFields.Write(hashedSubpackets)
 812
 813	var l uint64 = uint64(lenPrefix + len(hashedSubpackets))
 814	if sig.Version == 5 {
 815		// v5 case
 816		hashedFields.Write([]byte{0x05, 0xff})
 817		hashedFields.Write([]byte{
 818			uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
 819			uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
 820		})
 821	} else {
 822		// v4 and v6 case
 823		hashedFields.Write([]byte{byte(sig.Version), 0xff})
 824		hashedFields.Write([]byte{
 825			uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
 826		})
 827	}
 828	sig.HashSuffix = make([]byte, hashedFields.Len())
 829	copy(sig.HashSuffix, hashedFields.Bytes())
 830	return
 831}
 832
 833func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) {
 834	hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
 835	hashedSubpackets := make([]byte, hashedSubpacketsLen)
 836	serializeSubpackets(hashedSubpackets, sig.outSubpackets, true)
 837	err = sig.buildHashSuffix(hashedSubpackets)
 838	if err != nil {
 839		return
 840	}
 841	if sig.Version == 5 && (sig.SigType == 0x00 || sig.SigType == 0x01) {
 842		sig.AddMetadataToHashSuffix()
 843	}
 844
 845	h.Write(sig.HashSuffix)
 846	digest = h.Sum(nil)
 847	copy(sig.HashTag[:], digest)
 848	return
 849}
 850
 851// PrepareSign must be called to create a hash object before Sign for v6 signatures.
 852// The created hash object initially hashes a randomly generated salt
 853// as required by v6 signatures. The generated salt is stored in sig. If the signature is not v6,
 854// the method returns an empty hash object.
 855// See RFC 9580 Section 5.2.4.
 856func (sig *Signature) PrepareSign(config *Config) (hash.Hash, error) {
 857	if !sig.Hash.Available() {
 858		return nil, errors.UnsupportedError("hash function")
 859	}
 860	hasher := sig.Hash.New()
 861	if sig.Version == 6 {
 862		if sig.salt == nil {
 863			var err error
 864			sig.salt, err = SignatureSaltForHash(sig.Hash, config.Random())
 865			if err != nil {
 866				return nil, err
 867			}
 868		}
 869		hasher.Write(sig.salt)
 870	}
 871	return hasher, nil
 872}
 873
 874// SetSalt sets the signature salt for v6 signatures.
 875// Assumes salt is generated correctly and checks if length matches.
 876// If the signature is not v6, the method ignores the salt.
 877// Use PrepareSign whenever possible instead of generating and
 878// hashing the salt externally.
 879// See RFC 9580 Section 5.2.4.
 880func (sig *Signature) SetSalt(salt []byte) error {
 881	if sig.Version == 6 {
 882		expectedSaltLength, err := SaltLengthForHash(sig.Hash)
 883		if err != nil {
 884			return err
 885		}
 886		if salt == nil || len(salt) != expectedSaltLength {
 887			return errors.InvalidArgumentError("unexpected salt size for the given hash algorithm")
 888		}
 889		sig.salt = salt
 890	}
 891	return nil
 892}
 893
 894// PrepareVerify must be called to create a hash object before verifying v6 signatures.
 895// The created hash object initially hashes the internally stored salt.
 896// If the signature is not v6, the method returns an empty hash object.
 897// See RFC 9580 Section 5.2.4.
 898func (sig *Signature) PrepareVerify() (hash.Hash, error) {
 899	if !sig.Hash.Available() {
 900		return nil, errors.UnsupportedError("hash function")
 901	}
 902	hasher := sig.Hash.New()
 903	if sig.Version == 6 {
 904		if sig.salt == nil {
 905			return nil, errors.StructuralError("v6 requires a salt for the hash to be signed")
 906		}
 907		hasher.Write(sig.salt)
 908	}
 909	return hasher, nil
 910}
 911
 912// Sign signs a message with a private key. The hash, h, must contain
 913// the hash of the message to be signed and will be mutated by this function.
 914// On success, the signature is stored in sig. Call Serialize to write it out.
 915// If config is nil, sensible defaults will be used.
 916func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) {
 917	if priv.Dummy() {
 918		return errors.ErrDummyPrivateKey("dummy key found")
 919	}
 920	sig.Version = priv.PublicKey.Version
 921	sig.IssuerFingerprint = priv.PublicKey.Fingerprint
 922	if sig.Version < 6 && config.RandomizeSignaturesViaNotation() {
 923		sig.removeNotationsWithName(SaltNotationName)
 924		salt, err := SignatureSaltForHash(sig.Hash, config.Random())
 925		if err != nil {
 926			return err
 927		}
 928		notation := Notation{
 929			Name:            SaltNotationName,
 930			Value:           salt,
 931			IsCritical:      false,
 932			IsHumanReadable: false,
 933		}
 934		sig.Notations = append(sig.Notations, &notation)
 935	}
 936	sig.outSubpackets, err = sig.buildSubpackets(priv.PublicKey)
 937	if err != nil {
 938		return err
 939	}
 940	digest, err := sig.signPrepareHash(h)
 941	if err != nil {
 942		return
 943	}
 944	switch priv.PubKeyAlgo {
 945	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
 946		// supports both *rsa.PrivateKey and crypto.Signer
 947		sigdata, err := priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
 948		if err == nil {
 949			sig.RSASignature = encoding.NewMPI(sigdata)
 950		}
 951	case PubKeyAlgoDSA:
 952		dsaPriv := priv.PrivateKey.(*dsa.PrivateKey)
 953
 954		// Need to truncate hashBytes to match FIPS 186-3 section 4.6.
 955		subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8
 956		if len(digest) > subgroupSize {
 957			digest = digest[:subgroupSize]
 958		}
 959		r, s, err := dsa.Sign(config.Random(), dsaPriv, digest)
 960		if err == nil {
 961			sig.DSASigR = new(encoding.MPI).SetBig(r)
 962			sig.DSASigS = new(encoding.MPI).SetBig(s)
 963		}
 964	case PubKeyAlgoECDSA:
 965		var r, s *big.Int
 966		if sk, ok := priv.PrivateKey.(*ecdsa.PrivateKey); ok {
 967			r, s, err = ecdsa.Sign(config.Random(), sk, digest)
 968		} else {
 969			var b []byte
 970			b, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash)
 971			if err == nil {
 972				r, s, err = unwrapECDSASig(b)
 973			}
 974		}
 975
 976		if err == nil {
 977			sig.ECDSASigR = new(encoding.MPI).SetBig(r)
 978			sig.ECDSASigS = new(encoding.MPI).SetBig(s)
 979		}
 980	case PubKeyAlgoEdDSA:
 981		sk := priv.PrivateKey.(*eddsa.PrivateKey)
 982		r, s, err := eddsa.Sign(sk, digest)
 983		if err == nil {
 984			sig.EdDSASigR = encoding.NewMPI(r)
 985			sig.EdDSASigS = encoding.NewMPI(s)
 986		}
 987	case PubKeyAlgoEd25519:
 988		sk := priv.PrivateKey.(*ed25519.PrivateKey)
 989		signature, err := ed25519.Sign(sk, digest)
 990		if err == nil {
 991			sig.EdSig = signature
 992		}
 993	case PubKeyAlgoEd448:
 994		sk := priv.PrivateKey.(*ed448.PrivateKey)
 995		signature, err := ed448.Sign(sk, digest)
 996		if err == nil {
 997			sig.EdSig = signature
 998		}
 999	default:
1000		err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo)))
1001	}
1002
1003	return
1004}
1005
1006// unwrapECDSASig parses the two integer components of an ASN.1-encoded ECDSA signature.
1007func unwrapECDSASig(b []byte) (r, s *big.Int, err error) {
1008	var ecsdaSig struct {
1009		R, S *big.Int
1010	}
1011	_, err = asn1.Unmarshal(b, &ecsdaSig)
1012	if err != nil {
1013		return
1014	}
1015	return ecsdaSig.R, ecsdaSig.S, nil
1016}
1017
1018// SignUserId computes a signature from priv, asserting that pub is a valid
1019// key for the identity id.  On success, the signature is stored in sig. Call
1020// Serialize to write it out.
1021// If config is nil, sensible defaults will be used.
1022func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error {
1023	if priv.Dummy() {
1024		return errors.ErrDummyPrivateKey("dummy key found")
1025	}
1026	prepareHash, err := sig.PrepareSign(config)
1027	if err != nil {
1028		return err
1029	}
1030	if err := userIdSignatureHash(id, pub, prepareHash); err != nil {
1031		return err
1032	}
1033	return sig.Sign(prepareHash, priv, config)
1034}
1035
1036// SignDirectKeyBinding computes a signature from priv
1037// On success, the signature is stored in sig.
1038// Call Serialize to write it out.
1039// If config is nil, sensible defaults will be used.
1040func (sig *Signature) SignDirectKeyBinding(pub *PublicKey, priv *PrivateKey, config *Config) error {
1041	if priv.Dummy() {
1042		return errors.ErrDummyPrivateKey("dummy key found")
1043	}
1044	prepareHash, err := sig.PrepareSign(config)
1045	if err != nil {
1046		return err
1047	}
1048	if err := directKeySignatureHash(pub, prepareHash); err != nil {
1049		return err
1050	}
1051	return sig.Sign(prepareHash, priv, config)
1052}
1053
1054// CrossSignKey computes a signature from signingKey on pub hashed using hashKey. On success,
1055// the signature is stored in sig. Call Serialize to write it out.
1056// If config is nil, sensible defaults will be used.
1057func (sig *Signature) CrossSignKey(pub *PublicKey, hashKey *PublicKey, signingKey *PrivateKey,
1058	config *Config) error {
1059	prepareHash, err := sig.PrepareSign(config)
1060	if err != nil {
1061		return err
1062	}
1063	h, err := keySignatureHash(hashKey, pub, prepareHash)
1064	if err != nil {
1065		return err
1066	}
1067	return sig.Sign(h, signingKey, config)
1068}
1069
1070// SignKey computes a signature from priv, asserting that pub is a subkey. On
1071// success, the signature is stored in sig. Call Serialize to write it out.
1072// If config is nil, sensible defaults will be used.
1073func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
1074	if priv.Dummy() {
1075		return errors.ErrDummyPrivateKey("dummy key found")
1076	}
1077	prepareHash, err := sig.PrepareSign(config)
1078	if err != nil {
1079		return err
1080	}
1081	h, err := keySignatureHash(&priv.PublicKey, pub, prepareHash)
1082	if err != nil {
1083		return err
1084	}
1085	return sig.Sign(h, priv, config)
1086}
1087
1088// RevokeKey computes a revocation signature of pub using priv. On success, the signature is
1089// stored in sig. Call Serialize to write it out.
1090// If config is nil, sensible defaults will be used.
1091func (sig *Signature) RevokeKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
1092	prepareHash, err := sig.PrepareSign(config)
1093	if err != nil {
1094		return err
1095	}
1096	if err := keyRevocationHash(pub, prepareHash); err != nil {
1097		return err
1098	}
1099	return sig.Sign(prepareHash, priv, config)
1100}
1101
1102// RevokeSubkey computes a subkey revocation signature of pub using priv.
1103// On success, the signature is stored in sig. Call Serialize to write it out.
1104// If config is nil, sensible defaults will be used.
1105func (sig *Signature) RevokeSubkey(pub *PublicKey, priv *PrivateKey, config *Config) error {
1106	// Identical to a subkey binding signature
1107	return sig.SignKey(pub, priv, config)
1108}
1109
1110// Serialize marshals sig to w. Sign, SignUserId or SignKey must have been
1111// called first.
1112func (sig *Signature) Serialize(w io.Writer) (err error) {
1113	if len(sig.outSubpackets) == 0 {
1114		sig.outSubpackets = sig.rawSubpackets
1115	}
1116	if sig.RSASignature == nil && sig.DSASigR == nil && sig.ECDSASigR == nil && sig.EdDSASigR == nil && sig.EdSig == nil {
1117		return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize")
1118	}
1119
1120	sigLength := 0
1121	switch sig.PubKeyAlgo {
1122	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
1123		sigLength = int(sig.RSASignature.EncodedLength())
1124	case PubKeyAlgoDSA:
1125		sigLength = int(sig.DSASigR.EncodedLength())
1126		sigLength += int(sig.DSASigS.EncodedLength())
1127	case PubKeyAlgoECDSA:
1128		sigLength = int(sig.ECDSASigR.EncodedLength())
1129		sigLength += int(sig.ECDSASigS.EncodedLength())
1130	case PubKeyAlgoEdDSA:
1131		sigLength = int(sig.EdDSASigR.EncodedLength())
1132		sigLength += int(sig.EdDSASigS.EncodedLength())
1133	case PubKeyAlgoEd25519:
1134		sigLength = ed25519.SignatureSize
1135	case PubKeyAlgoEd448:
1136		sigLength = ed448.SignatureSize
1137	default:
1138		panic("impossible")
1139	}
1140
1141	hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true)
1142	unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
1143	length := 4 + /* length of version|signature type|public-key algorithm|hash algorithm */
1144		2 /* length of hashed subpackets */ + hashedSubpacketsLen +
1145		2 /* length of unhashed subpackets */ + unhashedSubpacketsLen +
1146		2 /* hash tag */ + sigLength
1147	if sig.Version == 6 {
1148		length += 4 + /* the two length fields are four-octet instead of two */
1149			1 + /* salt length */
1150			len(sig.salt) /* length salt */
1151	}
1152	err = serializeHeader(w, packetTypeSignature, length)
1153	if err != nil {
1154		return
1155	}
1156	err = sig.serializeBody(w)
1157	if err != nil {
1158		return err
1159	}
1160	return
1161}
1162
1163func (sig *Signature) serializeBody(w io.Writer) (err error) {
1164	var fields []byte
1165	if sig.Version == 6 {
1166		// v6 signatures use 4 octets for length
1167		hashedSubpacketsLen :=
1168			uint32(uint32(sig.HashSuffix[4])<<24) |
1169				uint32(uint32(sig.HashSuffix[5])<<16) |
1170				uint32(uint32(sig.HashSuffix[6])<<8) |
1171				uint32(sig.HashSuffix[7])
1172		fields = sig.HashSuffix[:8+hashedSubpacketsLen]
1173	} else {
1174		hashedSubpacketsLen := uint16(uint16(sig.HashSuffix[4])<<8) |
1175			uint16(sig.HashSuffix[5])
1176		fields = sig.HashSuffix[:6+hashedSubpacketsLen]
1177
1178	}
1179	_, err = w.Write(fields)
1180	if err != nil {
1181		return
1182	}
1183
1184	unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false)
1185	var unhashedSubpackets []byte
1186	if sig.Version == 6 {
1187		unhashedSubpackets = make([]byte, 4+unhashedSubpacketsLen)
1188		unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 24)
1189		unhashedSubpackets[1] = byte(unhashedSubpacketsLen >> 16)
1190		unhashedSubpackets[2] = byte(unhashedSubpacketsLen >> 8)
1191		unhashedSubpackets[3] = byte(unhashedSubpacketsLen)
1192		serializeSubpackets(unhashedSubpackets[4:], sig.outSubpackets, false)
1193	} else {
1194		unhashedSubpackets = make([]byte, 2+unhashedSubpacketsLen)
1195		unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8)
1196		unhashedSubpackets[1] = byte(unhashedSubpacketsLen)
1197		serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false)
1198	}
1199
1200	_, err = w.Write(unhashedSubpackets)
1201	if err != nil {
1202		return
1203	}
1204	_, err = w.Write(sig.HashTag[:])
1205	if err != nil {
1206		return
1207	}
1208
1209	if sig.Version == 6 {
1210		// write salt for v6 signatures
1211		_, err = w.Write([]byte{uint8(len(sig.salt))})
1212		if err != nil {
1213			return
1214		}
1215		_, err = w.Write(sig.salt)
1216		if err != nil {
1217			return
1218		}
1219	}
1220
1221	switch sig.PubKeyAlgo {
1222	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
1223		_, err = w.Write(sig.RSASignature.EncodedBytes())
1224	case PubKeyAlgoDSA:
1225		if _, err = w.Write(sig.DSASigR.EncodedBytes()); err != nil {
1226			return
1227		}
1228		_, err = w.Write(sig.DSASigS.EncodedBytes())
1229	case PubKeyAlgoECDSA:
1230		if _, err = w.Write(sig.ECDSASigR.EncodedBytes()); err != nil {
1231			return
1232		}
1233		_, err = w.Write(sig.ECDSASigS.EncodedBytes())
1234	case PubKeyAlgoEdDSA:
1235		if _, err = w.Write(sig.EdDSASigR.EncodedBytes()); err != nil {
1236			return
1237		}
1238		_, err = w.Write(sig.EdDSASigS.EncodedBytes())
1239	case PubKeyAlgoEd25519:
1240		err = ed25519.WriteSignature(w, sig.EdSig)
1241	case PubKeyAlgoEd448:
1242		err = ed448.WriteSignature(w, sig.EdSig)
1243	default:
1244		panic("impossible")
1245	}
1246	return
1247}
1248
1249// outputSubpacket represents a subpacket to be marshaled.
1250type outputSubpacket struct {
1251	hashed        bool // true if this subpacket is in the hashed area.
1252	subpacketType signatureSubpacketType
1253	isCritical    bool
1254	contents      []byte
1255}
1256
1257func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubpacket, err error) {
1258	creationTime := make([]byte, 4)
1259	binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix()))
1260	// Signature Creation Time
1261	subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, true, creationTime})
1262	// Signature Expiration Time
1263	if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 {
1264		sigLifetime := make([]byte, 4)
1265		binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs)
1266		subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime})
1267	}
1268	// Trust Signature
1269	if sig.TrustLevel != 0 {
1270		subpackets = append(subpackets, outputSubpacket{true, trustSubpacket, true, []byte{byte(sig.TrustLevel), byte(sig.TrustAmount)}})
1271	}
1272	// Regular Expression
1273	if sig.TrustRegularExpression != nil {
1274		// RFC specifies the string should be null-terminated; add a null byte to the end
1275		subpackets = append(subpackets, outputSubpacket{true, regularExpressionSubpacket, true, []byte(*sig.TrustRegularExpression + "\000")})
1276	}
1277	// Key Expiration Time
1278	if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 {
1279		keyLifetime := make([]byte, 4)
1280		binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs)
1281		subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime})
1282	}
1283	// Preferred Symmetric Ciphers for v1 SEIPD
1284	if len(sig.PreferredSymmetric) > 0 {
1285		subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric})
1286	}
1287	// Issuer Key ID
1288	if sig.IssuerKeyId != nil && sig.Version == 4 {
1289		keyId := make([]byte, 8)
1290		binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId)
1291		// Note: making this critical breaks RPM <=4.16.
1292		// See: https://github.com/ProtonMail/go-crypto/issues/263
1293		subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId})
1294	}
1295	// Notation Data
1296	for _, notation := range sig.Notations {
1297		subpackets = append(
1298			subpackets,
1299			outputSubpacket{
1300				true,
1301				notationDataSubpacket,
1302				notation.IsCritical,
1303				notation.getData(),
1304			})
1305	}
1306	// Preferred Hash Algorithms
1307	if len(sig.PreferredHash) > 0 {
1308		subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash})
1309	}
1310	// Preferred Compression Algorithms
1311	if len(sig.PreferredCompression) > 0 {
1312		subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression})
1313	}
1314	// Keyserver Preferences
1315	// Keyserver preferences may only appear in self-signatures or certification signatures.
1316	if sig.KeyserverPrefsValid {
1317		var prefs byte
1318		if sig.KeyserverPrefNoModify {
1319			prefs |= KeyserverPrefNoModify
1320		}
1321		subpackets = append(subpackets, outputSubpacket{true, keyserverPrefsSubpacket, false, []byte{prefs}})
1322	}
1323	// Preferred Keyserver
1324	if len(sig.PreferredKeyserver) > 0 {
1325		subpackets = append(subpackets, outputSubpacket{true, prefKeyserverSubpacket, false, []uint8(sig.PreferredKeyserver)})
1326	}
1327	// Primary User ID
1328	if sig.IsPrimaryId != nil && *sig.IsPrimaryId {
1329		subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}})
1330	}
1331	// Policy URI
1332	if len(sig.PolicyURI) > 0 {
1333		subpackets = append(subpackets, outputSubpacket{true, policyUriSubpacket, false, []uint8(sig.PolicyURI)})
1334	}
1335	// Key Flags
1336	// Key flags may only appear in self-signatures or certification signatures.
1337	if sig.FlagsValid {
1338		var flags byte
1339		if sig.FlagCertify {
1340			flags |= KeyFlagCertify
1341		}
1342		if sig.FlagSign {
1343			flags |= KeyFlagSign
1344		}
1345		if sig.FlagEncryptCommunications {
1346			flags |= KeyFlagEncryptCommunications
1347		}
1348		if sig.FlagEncryptStorage {
1349			flags |= KeyFlagEncryptStorage
1350		}
1351		if sig.FlagSplitKey {
1352			flags |= KeyFlagSplitKey
1353		}
1354		if sig.FlagAuthenticate {
1355			flags |= KeyFlagAuthenticate
1356		}
1357		if sig.FlagGroupKey {
1358			flags |= KeyFlagGroupKey
1359		}
1360		subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, true, []byte{flags}})
1361	}
1362	// Signer's User ID
1363	if sig.SignerUserId != nil {
1364		subpackets = append(subpackets, outputSubpacket{true, signerUserIdSubpacket, false, []byte(*sig.SignerUserId)})
1365	}
1366	// Reason for Revocation
1367	// Revocation reason appears only in revocation signatures and is serialized as per section 5.2.3.31.
1368	if sig.RevocationReason != nil {
1369		subpackets = append(subpackets, outputSubpacket{true, reasonForRevocationSubpacket, true,
1370			append([]uint8{uint8(*sig.RevocationReason)}, []uint8(sig.RevocationReasonText)...)})
1371	}
1372	// Features
1373	var features = byte(0x00)
1374	if sig.SEIPDv1 {
1375		features |= 0x01
1376	}
1377	if sig.SEIPDv2 {
1378		features |= 0x08
1379	}
1380	if features != 0x00 {
1381		subpackets = append(subpackets, outputSubpacket{true, featuresSubpacket, false, []byte{features}})
1382	}
1383	// Embedded Signature
1384	// EmbeddedSignature appears only in subkeys capable of signing and is serialized as per section 5.2.3.34.
1385	if sig.EmbeddedSignature != nil {
1386		var buf bytes.Buffer
1387		err = sig.EmbeddedSignature.serializeBody(&buf)
1388		if err != nil {
1389			return
1390		}
1391		subpackets = append(subpackets, outputSubpacket{true, embeddedSignatureSubpacket, true, buf.Bytes()})
1392	}
1393	// Issuer Fingerprint
1394	if sig.IssuerFingerprint != nil {
1395		contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...)
1396		subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version >= 5, contents})
1397	}
1398	// Intended Recipient Fingerprint
1399	for _, recipient := range sig.IntendedRecipients {
1400		subpackets = append(
1401			subpackets,
1402			outputSubpacket{
1403				true,
1404				intendedRecipientSubpacket,
1405				false,
1406				recipient.Serialize(),
1407			})
1408	}
1409	// Preferred AEAD Ciphersuites
1410	if len(sig.PreferredCipherSuites) > 0 {
1411		serialized := make([]byte, len(sig.PreferredCipherSuites)*2)
1412		for i, cipherSuite := range sig.PreferredCipherSuites {
1413			serialized[2*i] = cipherSuite[0]
1414			serialized[2*i+1] = cipherSuite[1]
1415		}
1416		subpackets = append(subpackets, outputSubpacket{true, prefCipherSuitesSubpacket, false, serialized})
1417	}
1418	return
1419}
1420
1421// AddMetadataToHashSuffix modifies the current hash suffix to include metadata
1422// (format, filename, and time). Version 5 keys protect this data including it
1423// in the hash computation. See section 5.2.4.
1424func (sig *Signature) AddMetadataToHashSuffix() {
1425	if sig == nil || sig.Version != 5 {
1426		return
1427	}
1428	if sig.SigType != 0x00 && sig.SigType != 0x01 {
1429		return
1430	}
1431	lit := sig.Metadata
1432	if lit == nil {
1433		// This will translate into six 0x00 bytes.
1434		lit = &LiteralData{}
1435	}
1436
1437	// Extract the current byte count
1438	n := sig.HashSuffix[len(sig.HashSuffix)-8:]
1439	l := uint64(
1440		uint64(n[0])<<56 | uint64(n[1])<<48 | uint64(n[2])<<40 | uint64(n[3])<<32 |
1441			uint64(n[4])<<24 | uint64(n[5])<<16 | uint64(n[6])<<8 | uint64(n[7]))
1442
1443	suffix := bytes.NewBuffer(nil)
1444	suffix.Write(sig.HashSuffix[:l])
1445
1446	// Add the metadata
1447	var buf [4]byte
1448	buf[0] = lit.Format
1449	fileName := lit.FileName
1450	if len(lit.FileName) > 255 {
1451		fileName = fileName[:255]
1452	}
1453	buf[1] = byte(len(fileName))
1454	suffix.Write(buf[:2])
1455	suffix.Write([]byte(lit.FileName))
1456	binary.BigEndian.PutUint32(buf[:], lit.Time)
1457	suffix.Write(buf[:])
1458
1459	suffix.Write([]byte{0x05, 0xff})
1460	suffix.Write([]byte{
1461		uint8(l >> 56), uint8(l >> 48), uint8(l >> 40), uint8(l >> 32),
1462		uint8(l >> 24), uint8(l >> 16), uint8(l >> 8), uint8(l),
1463	})
1464	sig.HashSuffix = suffix.Bytes()
1465}
1466
1467// SaltLengthForHash selects the required salt length for the given hash algorithm,
1468// as per Table 23 (Hash algorithm registry) of the crypto refresh.
1469// See RFC 9580 Section 9.5.
1470func SaltLengthForHash(hash crypto.Hash) (int, error) {
1471	switch hash {
1472	case crypto.SHA256, crypto.SHA224, crypto.SHA3_256:
1473		return 16, nil
1474	case crypto.SHA384:
1475		return 24, nil
1476	case crypto.SHA512, crypto.SHA3_512:
1477		return 32, nil
1478	default:
1479		return 0, errors.UnsupportedError("hash function not supported for V6 signatures")
1480	}
1481}
1482
1483// SignatureSaltForHash generates a random signature salt
1484// with the length for the given hash algorithm.
1485// See RFC 9580 Section 9.5.
1486func SignatureSaltForHash(hash crypto.Hash, randReader io.Reader) ([]byte, error) {
1487	saltLength, err := SaltLengthForHash(hash)
1488	if err != nil {
1489		return nil, err
1490	}
1491	salt := make([]byte, saltLength)
1492	_, err = io.ReadFull(randReader, salt)
1493	if err != nil {
1494		return nil, err
1495	}
1496	return salt, nil
1497}
1498
1499// removeNotationsWithName removes all notations in this signature with the given name.
1500func (sig *Signature) removeNotationsWithName(name string) {
1501	if sig == nil || sig.Notations == nil {
1502		return
1503	}
1504	updatedNotations := make([]*Notation, 0, len(sig.Notations))
1505	for _, notation := range sig.Notations {
1506		if notation.Name != name {
1507			updatedNotations = append(updatedNotations, notation)
1508		}
1509	}
1510	sig.Notations = updatedNotations
1511}