Skip to content

Commit 7c4521c

Browse files
wusslerlubux
authored andcommitted
Use fingerprints instead of KeyIDs
1 parent c38aca0 commit 7c4521c

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
@@ -463,17 +463,17 @@ func SerializeEncryptedKeyWithHiddenOption(w io.Writer, pub *PublicKey, cipherFu
463463
return SerializeEncryptedKeyAEADwithHiddenOption(w, pub, cipherFunc, config.AEAD() != nil, key, hidden, config)
464464
}
465465

466-
func (e *EncryptedKey) ProxyTransform(proxyParam []byte, forwarderKeyId, forwardeeKeyId uint64) (transformed *EncryptedKey, err error) {
466+
func (e *EncryptedKey) ProxyTransform(instance ForwardingInstance) (transformed *EncryptedKey, err error) {
467467
if e.Algo != PubKeyAlgoECDH {
468468
return nil, errors.InvalidArgumentError("invalid PKESK")
469469
}
470470

471-
if e.KeyId != 0 && e.KeyId != forwarderKeyId {
471+
if e.KeyId != 0 && e.KeyId != instance.GetForwarderKeyId() {
472472
return nil, errors.InvalidArgumentError("invalid key id in PKESK")
473473
}
474474

475475
ephemeral := e.encryptedMPI1.Bytes()
476-
transformedEphemeral, err := ecdh.ProxyTransform(ephemeral, proxyParam)
476+
transformedEphemeral, err := ecdh.ProxyTransform(ephemeral, instance.ProxyParameter)
477477
if err != nil {
478478
return nil, err
479479
}
@@ -483,16 +483,12 @@ func (e *EncryptedKey) ProxyTransform(proxyParam []byte, forwarderKeyId, forward
483483
copy(copiedWrappedKey, wrappedKey)
484484

485485
transformed = &EncryptedKey{
486-
KeyId: forwardeeKeyId,
487-
Algo: e.Algo,
486+
KeyId: instance.getForwardeeKeyIdOrZero(e.KeyId),
487+
Algo: e.Algo,
488488
encryptedMPI1: encoding.NewMPI(transformedEphemeral),
489489
encryptedMPI2: encoding.NewOID(copiedWrappedKey),
490490
}
491491

492-
if e.KeyId == 0 {
493-
e.KeyId = 0
494-
}
495-
496492
return transformed, nil
497493
}
498494

@@ -641,27 +637,60 @@ func serializeEncryptedKeyAEAD(w io.Writer, rand io.Reader, header [10]byte, pub
641637
return err
642638
}
643639

640+
<<<<<<< HEAD
644641
func checksumKeyMaterial(key []byte) uint16 {
645642
var checksum uint16
646643
for _, v := range key {
647644
checksum += uint16(v)
645+
=======
646+
func (e *EncryptedKey) ProxyTransform(instance ForwardingInstance) (transformed *EncryptedKey, err error) {
647+
if e.Algo != PubKeyAlgoECDH {
648+
return nil, errors.InvalidArgumentError("invalid PKESK")
649+
>>>>>>> edf1961 (Use fingerprints instead of KeyIDs)
648650
}
649651
return checksum
650652
}
651653

654+
<<<<<<< HEAD
652655
func decodeChecksumKey(msg []byte) (key []byte, err error) {
653656
key = msg[:len(msg)-2]
654657
expectedChecksum := uint16(msg[len(msg)-2])<<8 | uint16(msg[len(msg)-1])
655658
checksum := checksumKeyMaterial(key)
656659
if checksum != expectedChecksum {
657660
err = errors.StructuralError("session key checksum is incorrect")
661+
=======
662+
if e.KeyId != 0 && e.KeyId != instance.GetForwarderKeyId() {
663+
return nil, errors.InvalidArgumentError("invalid key id in PKESK")
664+
>>>>>>> edf1961 (Use fingerprints instead of KeyIDs)
658665
}
659666
return
660667
}
661668

669+
<<<<<<< HEAD
662670
func encodeChecksumKey(buffer []byte, key []byte) {
663671
copy(buffer, key)
664672
checksum := checksumKeyMaterial(key)
665673
buffer[len(key)] = byte(checksum >> 8)
666674
buffer[len(key)+1] = byte(checksum)
667675
}
676+
=======
677+
ephemeral := e.encryptedMPI1.Bytes()
678+
transformedEphemeral, err := ecdh.ProxyTransform(ephemeral, instance.ProxyParameter)
679+
if err != nil {
680+
return nil, err
681+
}
682+
683+
wrappedKey := e.encryptedMPI2.Bytes()
684+
copiedWrappedKey := make([]byte, len(wrappedKey))
685+
copy(copiedWrappedKey, wrappedKey)
686+
687+
transformed = &EncryptedKey{
688+
KeyId: instance.getForwardeeKeyIdOrZero(e.KeyId),
689+
Algo: e.Algo,
690+
encryptedMPI1: encoding.NewMPI(transformedEphemeral),
691+
encryptedMPI2: encoding.NewOID(copiedWrappedKey),
692+
}
693+
694+
return transformed, nil
695+
}
696+
>>>>>>> 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)