Skip to content

Commit a425074

Browse files
wusslerlubux
authored andcommitted
Use fingerprints instead of KeyIDs
1 parent b55bb97 commit a425074

File tree

4 files changed

+87
-32
lines changed

4 files changed

+87
-32
lines changed

openpgp/forwarding.go

+7-13
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,13 @@ import (
1111
"github.com/ProtonMail/go-crypto/openpgp/packet"
1212
)
1313

14-
// ForwardingInstance represents a single forwarding instance (mapping IDs to a Proxy Param)
15-
type ForwardingInstance struct {
16-
ForwarderKeyId uint64
17-
ForwardeeKeyId uint64
18-
ProxyParameter []byte
19-
}
20-
2114
// NewForwardingEntity generates a new forwardee key and derives the proxy parameters from the entity e.
2215
// If strict, it will return an error if encryption-capable non-revoked subkeys with a wrong algorithm are found,
2316
// instead of ignoring them
2417
func (e *Entity) NewForwardingEntity(
2518
name, comment, email string, config *packet.Config, strict bool,
2619
) (
27-
forwardeeKey *Entity, instances []ForwardingInstance, err error,
20+
forwardeeKey *Entity, instances []packet.ForwardingInstance, err error,
2821
) {
2922
if e.PrimaryKey.Version != 4 {
3023
return nil, nil, errors.InvalidArgumentError("unsupported key version")
@@ -64,7 +57,7 @@ func (e *Entity) NewForwardingEntity(
6457
}
6558

6659
// Init empty instances
67-
instances = []ForwardingInstance{}
60+
instances = []packet.ForwardingInstance{}
6861

6962
// Handle all forwarder subkeys
7063
for _, forwarderSubKey := range e.Subkeys {
@@ -105,8 +98,9 @@ func (e *Entity) NewForwardingEntity(
10598
return nil, nil, goerrors.New("wrong forwarding sub key generation")
10699
}
107100

108-
instance := ForwardingInstance{
109-
ForwarderKeyId: forwarderSubKey.PublicKey.KeyId,
101+
instance := packet.ForwardingInstance{
102+
KeyVersion: 4,
103+
ForwarderFingerprint: forwarderSubKey.PublicKey.Fingerprint,
110104
}
111105

112106
instance.ProxyParameter, err = ecdh.DeriveProxyParam(forwarderEcdhKey, forwardeeEcdhKey)
@@ -135,8 +129,8 @@ func (e *Entity) NewForwardingEntity(
135129
return nil, nil, err
136130
}
137131

138-
// Set ID after changing the KDF
139-
instance.ForwardeeKeyId = forwardeeSubKey.PublicKey.KeyId
132+
// Extract fingerprint after changing the KDF
133+
instance.ForwardeeFingerprint = forwardeeSubKey.PublicKey.Fingerprint
140134

141135
// 0x04 - This key may be used to encrypt communications.
142136
forwardeeSubKey.Sig.FlagEncryptCommunications = false

openpgp/forwarding_test.go

+6-10
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,12 @@ func TestForwardingFull(t *testing.T) {
8989
t.Fatalf("invalid number of instances, expected 1 got %d", len(instances))
9090
}
9191

92-
if instances[0].ForwarderKeyId != bobEntity.Subkeys[0].PublicKey.KeyId {
93-
t.Fatalf("invalid forwarder key ID, expected: %x, got: %x", bobEntity.Subkeys[0].PublicKey.KeyId, instances[0].ForwarderKeyId)
92+
if bytes.Compare(instances[0].ForwarderFingerprint, bobEntity.Subkeys[0].PublicKey.Fingerprint) != 0 {
93+
t.Fatalf("invalid forwarder key ID, expected: %x, got: %x", bobEntity.Subkeys[0].PublicKey.Fingerprint, instances[0].ForwarderFingerprint)
9494
}
9595

96-
if instances[0].ForwardeeKeyId != charlesEntity.Subkeys[0].PublicKey.KeyId {
97-
t.Fatalf("invalid forwardee key ID, expected: %x, got: %x", charlesEntity.Subkeys[0].PublicKey.KeyId, instances[0].ForwardeeKeyId)
96+
if bytes.Compare(instances[0].ForwardeeFingerprint, charlesEntity.Subkeys[0].PublicKey.Fingerprint) != 0 {
97+
t.Fatalf("invalid forwardee key ID, expected: %x, got: %x", charlesEntity.Subkeys[0].PublicKey.Fingerprint, instances[0].ForwardeeFingerprint)
9898
}
9999

100100
// Encrypt message
@@ -166,7 +166,7 @@ func TestForwardingFull(t *testing.T) {
166166
}
167167
}
168168

169-
func transformTestMessage(t *testing.T, encrypted []byte, instance ForwardingInstance) []byte {
169+
func transformTestMessage(t *testing.T, encrypted []byte, instance packet.ForwardingInstance) []byte {
170170
bytesReader := bytes.NewReader(encrypted)
171171
packets := packet.NewReader(bytesReader)
172172
splitPoint := int64(0)
@@ -183,11 +183,7 @@ Loop:
183183
}
184184
switch p := p.(type) {
185185
case *packet.EncryptedKey:
186-
tp, err := p.ProxyTransform(
187-
instance.ProxyParameter,
188-
instance.ForwarderKeyId,
189-
instance.ForwardeeKeyId,
190-
)
186+
tp, err := p.ProxyTransform(instance)
191187
if err != nil {
192188
t.Fatalf("error transforming PKESK: %s", err)
193189
}

openpgp/packet/encrypted_key.go

+38-9
Original file line numberDiff line numberDiff line change
@@ -458,17 +458,17 @@ func SerializeEncryptedKeyWithHiddenOption(w io.Writer, pub *PublicKey, cipherFu
458458
return SerializeEncryptedKeyAEADwithHiddenOption(w, pub, cipherFunc, config.AEAD() != nil, key, hidden, config)
459459
}
460460

461-
func (e *EncryptedKey) ProxyTransform(proxyParam []byte, forwarderKeyId, forwardeeKeyId uint64) (transformed *EncryptedKey, err error) {
461+
func (e *EncryptedKey) ProxyTransform(instance ForwardingInstance) (transformed *EncryptedKey, err error) {
462462
if e.Algo != PubKeyAlgoECDH {
463463
return nil, errors.InvalidArgumentError("invalid PKESK")
464464
}
465465

466-
if e.KeyId != 0 && e.KeyId != forwarderKeyId {
466+
if e.KeyId != 0 && e.KeyId != instance.GetForwarderKeyId() {
467467
return nil, errors.InvalidArgumentError("invalid key id in PKESK")
468468
}
469469

470470
ephemeral := e.encryptedMPI1.Bytes()
471-
transformedEphemeral, err := ecdh.ProxyTransform(ephemeral, proxyParam)
471+
transformedEphemeral, err := ecdh.ProxyTransform(ephemeral, instance.ProxyParameter)
472472
if err != nil {
473473
return nil, err
474474
}
@@ -478,16 +478,12 @@ func (e *EncryptedKey) ProxyTransform(proxyParam []byte, forwarderKeyId, forward
478478
copy(copiedWrappedKey, wrappedKey)
479479

480480
transformed = &EncryptedKey{
481-
KeyId: forwardeeKeyId,
482-
Algo: e.Algo,
481+
KeyId: instance.getForwardeeKeyIdOrZero(e.KeyId),
482+
Algo: e.Algo,
483483
encryptedMPI1: encoding.NewMPI(transformedEphemeral),
484484
encryptedMPI2: encoding.NewOID(copiedWrappedKey),
485485
}
486486

487-
if e.KeyId == 0 {
488-
e.KeyId = 0
489-
}
490-
491487
return transformed, nil
492488
}
493489

@@ -636,27 +632,60 @@ func serializeEncryptedKeyAEAD(w io.Writer, rand io.Reader, header [10]byte, pub
636632
return err
637633
}
638634

635+
<<<<<<< HEAD
639636
func checksumKeyMaterial(key []byte) uint16 {
640637
var checksum uint16
641638
for _, v := range key {
642639
checksum += uint16(v)
640+
=======
641+
func (e *EncryptedKey) ProxyTransform(instance ForwardingInstance) (transformed *EncryptedKey, err error) {
642+
if e.Algo != PubKeyAlgoECDH {
643+
return nil, errors.InvalidArgumentError("invalid PKESK")
644+
>>>>>>> edf1961 (Use fingerprints instead of KeyIDs)
643645
}
644646
return checksum
645647
}
646648

649+
<<<<<<< HEAD
647650
func decodeChecksumKey(msg []byte) (key []byte, err error) {
648651
key = msg[:len(msg)-2]
649652
expectedChecksum := uint16(msg[len(msg)-2])<<8 | uint16(msg[len(msg)-1])
650653
checksum := checksumKeyMaterial(key)
651654
if checksum != expectedChecksum {
652655
err = errors.StructuralError("session key checksum is incorrect")
656+
=======
657+
if e.KeyId != 0 && e.KeyId != instance.GetForwarderKeyId() {
658+
return nil, errors.InvalidArgumentError("invalid key id in PKESK")
659+
>>>>>>> edf1961 (Use fingerprints instead of KeyIDs)
653660
}
654661
return
655662
}
656663

664+
<<<<<<< HEAD
657665
func encodeChecksumKey(buffer []byte, key []byte) {
658666
copy(buffer, key)
659667
checksum := checksumKeyMaterial(key)
660668
buffer[len(key)] = byte(checksum >> 8)
661669
buffer[len(key)+1] = byte(checksum)
662670
}
671+
=======
672+
ephemeral := e.encryptedMPI1.Bytes()
673+
transformedEphemeral, err := ecdh.ProxyTransform(ephemeral, instance.ProxyParameter)
674+
if err != nil {
675+
return nil, err
676+
}
677+
678+
wrappedKey := e.encryptedMPI2.Bytes()
679+
copiedWrappedKey := make([]byte, len(wrappedKey))
680+
copy(copiedWrappedKey, wrappedKey)
681+
682+
transformed = &EncryptedKey{
683+
KeyId: instance.getForwardeeKeyIdOrZero(e.KeyId),
684+
Algo: e.Algo,
685+
encryptedMPI1: encoding.NewMPI(transformedEphemeral),
686+
encryptedMPI2: encoding.NewOID(copiedWrappedKey),
687+
}
688+
689+
return transformed, nil
690+
}
691+
>>>>>>> edf1961 (Use fingerprints instead of KeyIDs)

openpgp/packet/forwarding.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package packet
2+
3+
import "encoding/binary"
4+
5+
// ForwardingInstance represents a single forwarding instance (mapping IDs to a Proxy Param)
6+
type ForwardingInstance struct {
7+
KeyVersion int
8+
ForwarderFingerprint []byte
9+
ForwardeeFingerprint []byte
10+
ProxyParameter []byte
11+
}
12+
13+
func (f *ForwardingInstance) GetForwarderKeyId() uint64 {
14+
return computeForwardingKeyId(f.ForwarderFingerprint, f.KeyVersion)
15+
}
16+
17+
func (f *ForwardingInstance) GetForwardeeKeyId() uint64 {
18+
return computeForwardingKeyId(f.ForwardeeFingerprint, f.KeyVersion)
19+
}
20+
21+
func (f *ForwardingInstance) getForwardeeKeyIdOrZero(originalKeyId uint64) uint64 {
22+
if originalKeyId == 0 {
23+
return 0
24+
}
25+
26+
return f.GetForwardeeKeyId()
27+
}
28+
29+
func computeForwardingKeyId(fingerprint []byte, version int) uint64 {
30+
switch version {
31+
case 4:
32+
return binary.BigEndian.Uint64(fingerprint[12:20])
33+
default:
34+
panic("invalid pgp key version")
35+
}
36+
}

0 commit comments

Comments
 (0)