Skip to content

Commit

Permalink
update uat
Browse files Browse the repository at this point in the history
  • Loading branch information
izouxv committed Sep 3, 2024
1 parent 50c23b2 commit b8cdb17
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 86 deletions.
18 changes: 9 additions & 9 deletions openpgp/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Entity struct {
Subkeys []Subkey
SelfSignature *packet.Signature // Direct-key self signature of the PrimaryKey (contains primary key properties in v6)
Signatures []*packet.Signature // all (potentially unverified) self-signatures, revocations, and third-party signatures
Attribute []*Attribute
Attributes []*Attribute
}

// An Identity represents an identity claimed by an Entity and zero or more
Expand Down Expand Up @@ -738,29 +738,29 @@ func (e *Entity) serializePrivate(w io.Writer, config *packet.Config, reSign boo
}
}
}
for _, uat := range e.Attribute {
for _, attr := range e.Attributes {
if reSign {
UserAttribute := uat.UserAttribute
userAttribute := attr.UserAttribute

err = UserAttribute.Serialize(w)
err = userAttribute.Serialize(w)
if err != nil {
return
}

if uat.SelfSignature == nil {
if attr.SelfSignature == nil {
return goerrors.New("openpgp: can't re-sign identity without valid self-signature")
}
err = uat.SelfSignature.SignUserAttribute(UserAttribute, e.PrimaryKey, e.PrivateKey, config)
err = attr.SelfSignature.SignUserAttribute(userAttribute, e.PrimaryKey, e.PrivateKey, config)
if err != nil {
return
}
} else {
err = uat.UserAttribute.Serialize(w)
err = attr.UserAttribute.Serialize(w)
if err != nil {
return
}
}
for _, sig := range uat.Signatures {
for _, sig := range attr.Signatures {
err = sig.Serialize(w)
if err != nil {
return err
Expand Down Expand Up @@ -831,7 +831,7 @@ func (e *Entity) Serialize(w io.Writer) error {
}
}

for _, uat := range e.Attribute {
for _, uat := range e.Attributes {
err = uat.UserAttribute.Serialize(w)
if err != nil {
return err
Expand Down
59 changes: 31 additions & 28 deletions openpgp/packet/public_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -992,33 +992,6 @@ func (pk *PublicKey) VerifyUserIdHashTag(id string, sig *Signature) (err error)
return VerifyHashTag(preparedHash, sig)
}

// userAttributeSignatureHash returns a Hash of the message that needs to be signed
// to assert that pk is a valid key for id.
func userAttributeSignatureHash(uat *UserAttribute, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {

if !hashFunc.Available() {
return nil, errors.UnsupportedError("hash function")
}
h = hashFunc.New()

// RFC 4880, section 5.2.4
pk.SerializeSignaturePrefix(h)
pk.serializeWithoutHeaders(h)

data := uat.Data()

var buf [5]byte
buf[0] = 0xd1
buf[1] = byte(len(data) >> 24)
buf[2] = byte(len(data) >> 16)
buf[3] = byte(len(data) >> 8)
buf[4] = byte(len(data))
h.Write(buf[:])
h.Write(data)

return
}

// VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
// public key, that id is the identity of pub.
func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
Expand Down Expand Up @@ -1046,7 +1019,7 @@ func (pk *PublicKey) VerifyDirectKeySignature(sig *Signature) (err error) {
}

// VerifyUserAttributeSignature returns nil iff sig is a valid signature, made by this
// public key, that id is the identity of pub.
// public key, that uat is an attribute of pub.
func (pk *PublicKey) VerifyUserAttributeSignature(pkt *UserAttribute, pub *PublicKey, sig *Signature) (err error) {
h, err := userAttributeSignatureHash(pkt, pub, sig.Hash)
if err != nil {
Expand All @@ -1055,6 +1028,36 @@ func (pk *PublicKey) VerifyUserAttributeSignature(pkt *UserAttribute, pub *Publi
return pk.VerifySignature(h, sig)
}

// userAttributeSignatureHash returns a Hash of the message that needs to be signed
// to assert that pk is a valid key for uat.
func userAttributeSignatureHash(uat *UserAttribute, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
if !hashFunc.Available() {
return nil, errors.UnsupportedError("hash function")
}
h = hashFunc.New()

// RFC 4880, section 5.2.4
if err := pk.SerializeSignaturePrefix(h); err != nil {
return nil, err
}
if err := pk.serializeWithoutHeaders(h); err != nil {
return nil, err
}

data := uat.data()

var buf [5]byte
buf[0] = 0xd1
buf[1] = byte(len(data) >> 24)
buf[2] = byte(len(data) >> 16)
buf[3] = byte(len(data) >> 8)
buf[4] = byte(len(data))
h.Write(buf[:])
h.Write(data)

return
}

// KeyIdString returns the public key's fingerprint in capital hex
// (e.g. "6C7EE1B8621CC013").
func (pk *PublicKey) KeyIdString() string {
Expand Down
4 changes: 2 additions & 2 deletions openpgp/packet/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -996,8 +996,8 @@ func (sig *Signature) SignDirectKeyBinding(pub *PublicKey, priv *PrivateKey, con
return sig.Sign(prepareHash, priv, config)
}

// SignUserAttribute computes a signature from priv, asserting that pub is a valid
// key for the identity id. On success, the signature is stored in sig. Call
// SignUserAttribute computes a signature from priv, asserting that pub has
// user attribute uat. On success, the signature is stored in sig. Call
// Serialize to write it out.
// If config is nil, sensible defaults will be used.
func (sig *Signature) SignUserAttribute(uat *UserAttribute, pub *PublicKey, priv *PrivateKey, config *Config) error {
Expand Down
4 changes: 1 addition & 3 deletions openpgp/packet/userattribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ func NewUserAttributePhotoBytes(photos [][]byte) (uat *UserAttribute, err error)
func newUserAttributePhotoBytes(photos [][]byte) (uat *UserAttribute, err error) {
uat = new(UserAttribute)
for _, photo := range photos {

var buf bytes.Buffer
// RFC 4880, Section 5.12.1.
data := []byte{
Expand Down Expand Up @@ -83,7 +82,7 @@ func newUserAttributePhotoBytes(photos [][]byte) (uat *UserAttribute, err error)
func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute {
return &UserAttribute{Contents: contents}
}
func (uat *UserAttribute) Data() []byte {
func (uat *UserAttribute) data() []byte {
buf := bytes.NewBuffer(nil)
for _, osp := range uat.Contents {
osp.Serialize(buf)
Expand All @@ -103,7 +102,6 @@ func (uat *UserAttribute) parse(r io.Reader) (err error) {
// Serialize marshals the user attribute to w in the form of an OpenPGP packet, including
// header.
func (uat *UserAttribute) Serialize(w io.Writer) (err error) {

var buf bytes.Buffer
for _, sp := range uat.Contents {
err = sp.Serialize(&buf)
Expand Down
46 changes: 7 additions & 39 deletions openpgp/uat.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package openpgp

import (
"crypto"
"io"

"github.com/ProtonMail/go-crypto/openpgp/errors"
Expand All @@ -14,7 +9,6 @@ import (

func (t *Entity) AddPhoto(jpegBytes []byte, config *packet.Config) error {
creationTime := config.Now()
keyLifetimeSecs := config.KeyLifetime()

uat, err := packet.NewUserAttributePhotoBytes([][]byte{jpegBytes})
if err != nil {
Expand All @@ -23,46 +17,20 @@ func (t *Entity) AddPhoto(jpegBytes []byte, config *packet.Config) error {

primary := t.PrivateKey

isPrimaryId := len(t.Identities) == 0
isPrimaryId := len(t.Attributes) == 0

selfSignature := &packet.Signature{
Version: primary.PublicKey.Version,
SigType: packet.SigTypePositiveCert,
PubKeyAlgo: primary.PublicKey.PubKeyAlgo,
Hash: config.Hash(),
CreationTime: creationTime,
KeyLifetimeSecs: &keyLifetimeSecs,
IssuerKeyId: &primary.PublicKey.KeyId,
IssuerFingerprint: primary.PublicKey.Fingerprint,
IsPrimaryId: &isPrimaryId,
FlagsValid: true,
FlagSign: true,
FlagCertify: true,
}

// Set the PreferredHash for the SelfSignature from the packet.Config.
// If it is not the must-implement algorithm from rfc4880bis, append that.
selfSignature.PreferredHash = []uint8{hashToHashId(config.Hash())}
if config.Hash() != crypto.SHA256 {
selfSignature.PreferredHash = append(selfSignature.PreferredHash, hashToHashId(crypto.SHA256))
}

// Likewise for DefaultCipher.
selfSignature.PreferredSymmetric = []uint8{uint8(config.Cipher())}
if config.Cipher() != packet.CipherAES128 {
selfSignature.PreferredSymmetric = append(selfSignature.PreferredSymmetric, uint8(packet.CipherAES128))
}

// We set CompressionNone as the preferred compression algorithm because
// of compression side channel attacks, then append the configured
// DefaultCompressionAlgo if any is set (to signal support for cases
// where the application knows that using compression is safe).
selfSignature.PreferredCompression = []uint8{uint8(packet.CompressionNone)}
if config.Compression() != packet.CompressionNone {
selfSignature.PreferredCompression = append(selfSignature.PreferredCompression, uint8(config.Compression()))
}

// User ID binding signature
// User Attribute binding signature
err = selfSignature.SignUserAttribute(uat, &primary.PublicKey, primary, config)
if err != nil {
return err
Expand All @@ -72,17 +40,17 @@ func (t *Entity) AddPhoto(jpegBytes []byte, config *packet.Config) error {
SelfSignature: selfSignature,
Signatures: []*packet.Signature{selfSignature},
}
t.Attribute = append(t.Attribute, userAttribute)
t.Attributes = append(t.Attributes, userAttribute)
return nil
}

func addUserAttribute(e *Entity, packets *packet.Reader, pkt *packet.UserAttribute) error {
// Make a new Identity object, that we might wind up throwing away.
// Make a new Attribute object, that we might wind up throwing away.
// We'll only add it if we get a valid self-signature over this
// userID.
// user attribute.
uat := new(Attribute)
uat.UserAttribute = pkt
e.Attribute = append(e.Attribute, uat)
e.Attributes = append(e.Attributes, uat)

for {
p, err := packets.Next()
Expand All @@ -103,7 +71,7 @@ func addUserAttribute(e *Entity, packets *packet.Reader, pkt *packet.UserAttribu
sig.SigType != packet.SigTypeCasualCert &&
sig.SigType != packet.SigTypePositiveCert &&
sig.SigType != packet.SigTypeCertificationRevocation {
return errors.StructuralError("user ID signature with wrong type")
return errors.StructuralError("user attribute signature with wrong type")
}

if sig.CheckKeyIdOrFingerprint(e.PrimaryKey) {
Expand Down
7 changes: 2 additions & 5 deletions openpgp/uat_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package openpgp

import (
Expand Down Expand Up @@ -43,11 +40,11 @@ func TestAddPhoto(t *testing.T) {
t.Fatal(err)
}

if len(entity2.Attribute) != 1 {
if len(entity2.Attributes) != 1 {
t.Fatal("data err, entity have no uat")
}

imgBytes := entity2.Attribute[0].UserAttribute.ImageData()
imgBytes := entity2.Attributes[0].UserAttribute.ImageData()
if !bytes.Equal(imgBytes[0], jpegBytes) {
t.Fatal("image data not equal")
}
Expand Down

0 comments on commit b8cdb17

Please sign in to comment.