diff --git a/openpgp/forwarding.go b/openpgp/forwarding.go index d4291f8e..ae45c3c2 100644 --- a/openpgp/forwarding.go +++ b/openpgp/forwarding.go @@ -6,6 +6,7 @@ package openpgp import ( goerrors "errors" + "github.com/ProtonMail/go-crypto/openpgp/ecdh" "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/packet" @@ -51,7 +52,7 @@ func (e *Entity) NewForwardingEntity( Subkeys: []Subkey{}, } - err = forwardeeKey.addUserId(name, comment, email, config, now, keyLifetimeSecs) + err = forwardeeKey.addUserId(name, comment, email, config, now, keyLifetimeSecs, true) if err != nil { return nil, nil, err } @@ -91,7 +92,7 @@ func (e *Entity) NewForwardingEntity( return nil, nil, err } - forwardeeSubKey := forwardeeKey.Subkeys[len(forwardeeKey.Subkeys) - 1] + forwardeeSubKey := forwardeeKey.Subkeys[len(forwardeeKey.Subkeys)-1] forwardeeEcdhKey, ok := forwardeeSubKey.PrivateKey.PrivateKey.(*ecdh.PrivateKey) if !ok { @@ -99,7 +100,7 @@ func (e *Entity) NewForwardingEntity( } instance := packet.ForwardingInstance{ - KeyVersion: 4, + KeyVersion: 4, ForwarderFingerprint: forwarderSubKey.PublicKey.Fingerprint, } @@ -109,9 +110,9 @@ func (e *Entity) NewForwardingEntity( } kdf := ecdh.KDF{ - Version: ecdh.KDFVersionForwarding, - Hash: forwarderEcdhKey.KDF.Hash, - Cipher: forwarderEcdhKey.KDF.Cipher, + Version: ecdh.KDFVersionForwarding, + Hash: forwarderEcdhKey.KDF.Hash, + Cipher: forwarderEcdhKey.KDF.Cipher, } // If deriving a forwarding key from a forwarding key diff --git a/openpgp/packet/encrypted_key.go b/openpgp/packet/encrypted_key.go index 069b57af..051d92ab 100644 --- a/openpgp/packet/encrypted_key.go +++ b/openpgp/packet/encrypted_key.go @@ -410,7 +410,7 @@ func SerializeEncryptedKeyAEADwithHiddenOption(w io.Writer, pub *PublicKey, ciph var keyBlock []byte switch pub.PubKeyAlgo { - case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH: + case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal, PubKeyAlgoECDH, ExperimentalPubKeyAlgoAEAD: lenKeyBlock := len(key) + 2 if version < 6 { lenKeyBlock += 1 // cipher type included @@ -439,7 +439,7 @@ func SerializeEncryptedKeyAEADwithHiddenOption(w io.Writer, pub *PublicKey, ciph case PubKeyAlgoX448: return serializeEncryptedKeyX448(w, config.Random(), buf[:lenHeaderWritten], pub.PublicKey.(*x448.PublicKey), keyBlock, byte(cipherFunc), version) case ExperimentalPubKeyAlgoAEAD: - return serializeEncryptedKeyAEAD(w, config.Random(), buf, pub.PublicKey.(*symmetric.AEADPublicKey), keyBlock, config.AEAD()) + return serializeEncryptedKeyAEAD(w, config.Random(), buf[:lenHeaderWritten], pub.PublicKey.(*symmetric.AEADPublicKey), keyBlock, config.AEAD()) case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly, ExperimentalPubKeyAlgoHMAC: return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo))) } @@ -483,8 +483,9 @@ func (e *EncryptedKey) ProxyTransform(instance ForwardingInstance) (transformed copy(copiedWrappedKey, wrappedKey) transformed = &EncryptedKey{ - KeyId: instance.getForwardeeKeyIdOrZero(e.KeyId), - Algo: e.Algo, + Version: e.Version, + KeyId: instance.getForwardeeKeyIdOrZero(e.KeyId), + Algo: e.Algo, encryptedMPI1: encoding.NewMPI(transformedEphemeral), encryptedMPI2: encoding.NewOID(copiedWrappedKey), } @@ -608,7 +609,7 @@ func serializeEncryptedKeyX448(w io.Writer, rand io.Reader, header []byte, pub * return x448.EncodeFields(w, ephemeralPublicX448, ciphertext, cipherFunc, version == 6) } -func serializeEncryptedKeyAEAD(w io.Writer, rand io.Reader, header [10]byte, pub *symmetric.AEADPublicKey, keyBlock []byte, config *AEADConfig) error { +func serializeEncryptedKeyAEAD(w io.Writer, rand io.Reader, header []byte, pub *symmetric.AEADPublicKey, keyBlock []byte, config *AEADConfig) error { mode := algorithm.AEADMode(config.Mode()) iv, ciphertextRaw, err := pub.Encrypt(rand, keyBlock, mode) if err != nil { @@ -620,7 +621,7 @@ func serializeEncryptedKeyAEAD(w io.Writer, rand io.Reader, header [10]byte, pub buffer := append([]byte{byte(mode)}, iv...) buffer = append(buffer, ciphertextShortByteString.EncodedBytes()...) - packetLen := 10 /* header length */ + packetLen := len(header) /* header length */ packetLen += int(len(buffer)) err = serializeHeader(w, packetTypeEncryptedKey, packetLen) @@ -637,60 +638,27 @@ func serializeEncryptedKeyAEAD(w io.Writer, rand io.Reader, header [10]byte, pub return err } -<<<<<<< HEAD func checksumKeyMaterial(key []byte) uint16 { var checksum uint16 for _, v := range key { checksum += uint16(v) -======= -func (e *EncryptedKey) ProxyTransform(instance ForwardingInstance) (transformed *EncryptedKey, err error) { - if e.Algo != PubKeyAlgoECDH { - return nil, errors.InvalidArgumentError("invalid PKESK") ->>>>>>> edf1961 (Use fingerprints instead of KeyIDs) } return checksum } -<<<<<<< HEAD func decodeChecksumKey(msg []byte) (key []byte, err error) { key = msg[:len(msg)-2] expectedChecksum := uint16(msg[len(msg)-2])<<8 | uint16(msg[len(msg)-1]) checksum := checksumKeyMaterial(key) if checksum != expectedChecksum { err = errors.StructuralError("session key checksum is incorrect") -======= - if e.KeyId != 0 && e.KeyId != instance.GetForwarderKeyId() { - return nil, errors.InvalidArgumentError("invalid key id in PKESK") ->>>>>>> edf1961 (Use fingerprints instead of KeyIDs) } return } -<<<<<<< HEAD func encodeChecksumKey(buffer []byte, key []byte) { copy(buffer, key) checksum := checksumKeyMaterial(key) buffer[len(key)] = byte(checksum >> 8) buffer[len(key)+1] = byte(checksum) } -======= - ephemeral := e.encryptedMPI1.Bytes() - transformedEphemeral, err := ecdh.ProxyTransform(ephemeral, instance.ProxyParameter) - if err != nil { - return nil, err - } - - wrappedKey := e.encryptedMPI2.Bytes() - copiedWrappedKey := make([]byte, len(wrappedKey)) - copy(copiedWrappedKey, wrappedKey) - - transformed = &EncryptedKey{ - KeyId: instance.getForwardeeKeyIdOrZero(e.KeyId), - Algo: e.Algo, - encryptedMPI1: encoding.NewMPI(transformedEphemeral), - encryptedMPI2: encoding.NewOID(copiedWrappedKey), - } - - return transformed, nil -} ->>>>>>> edf1961 (Use fingerprints instead of KeyIDs) diff --git a/openpgp/packet/private_key.go b/openpgp/packet/private_key.go index 9dde78ec..406c56e6 100644 --- a/openpgp/packet/private_key.go +++ b/openpgp/packet/private_key.go @@ -28,10 +28,10 @@ import ( "github.com/ProtonMail/go-crypto/openpgp/errors" "github.com/ProtonMail/go-crypto/openpgp/internal/encoding" "github.com/ProtonMail/go-crypto/openpgp/s2k" + "github.com/ProtonMail/go-crypto/openpgp/symmetric" "github.com/ProtonMail/go-crypto/openpgp/x25519" "github.com/ProtonMail/go-crypto/openpgp/x448" "golang.org/x/crypto/hkdf" - "github.com/ProtonMail/go-crypto/openpgp/symmetric" ) // PrivateKey represents a possibly encrypted private key. See RFC 4880, @@ -186,15 +186,12 @@ func NewDecrypterPrivateKey(creationTime time.Time, decrypter interface{}) *Priv pk.PublicKey = *NewElGamalPublicKey(creationTime, &priv.PublicKey) case *ecdh.PrivateKey: pk.PublicKey = *NewECDHPublicKey(creationTime, &priv.PublicKey) -<<<<<<< HEAD case *x25519.PrivateKey: pk.PublicKey = *NewX25519PublicKey(creationTime, &priv.PublicKey) case *x448.PrivateKey: pk.PublicKey = *NewX448PublicKey(creationTime, &priv.PublicKey) -======= case *symmetric.AEADPrivateKey: pk.PublicKey = *NewAEADPublicKey(creationTime, &priv.PublicKey) ->>>>>>> 3731c9c (openpgp: Add support for symmetric subkeys (#74)) default: panic("openpgp: unknown decrypter type in NewDecrypterPrivateKey") }