diff --git a/go.sum b/go.sum index ef7929aa39..88bb501a33 100644 --- a/go.sum +++ b/go.sum @@ -71,6 +71,7 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/tink v1.3.0 h1:CMg2wQ+VP5QUDwqV89+WpKuxv3I+pBrJ4/ziUS/kIEs= github.com/google/tink v1.4.0-rc2.0.20200525085439-8bdaed4f41ed h1:uR4ckoAt+nUap2lX2rk61vD4Bq7Qlc++xwxnL6i9dto= github.com/google/tink v1.4.0-rc2.0.20200525085439-8bdaed4f41ed/go.mod h1:eu7D8x3z2rMO7fyvHVhMx8yoFH+vH8EZR1uO3hjEIhQ= github.com/google/tink/go v1.4.0-rc2 h1:QU7tW2FbEM4VjagwhxXFYuZXWLyfST2Z0EMLCCrMEmk= diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aead_composite_common.go b/pkg/crypto/tinkcrypto/primitive/composite/composite_common.go similarity index 90% rename from pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aead_composite_common.go rename to pkg/crypto/tinkcrypto/primitive/composite/composite_common.go index e8d9745bfc..cef4b11c96 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aead_composite_common.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/composite_common.go @@ -4,10 +4,10 @@ Copyright SecureKey Technologies Inc. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ -package subtle +package composite -// package subtle provides the core crypto primitives to be used by composite primitives. It is intended for internal -// use only. +// package composite provides the core crypto composite primitives such as ECDH-ES and ECDH-1PU to be used by JWE +// crypto. It is intended for internal use only. // EncryptedData represents the Encryption's output data as a result of ECDHESEncrypt.Encrypt(pt, aad) call // The user of the primitive must unmarshal the result and build their own ECDH-ES compliant message (ie JWE msg) diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu.go new file mode 100644 index 0000000000..45fa04f95e --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu.go @@ -0,0 +1,107 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +// Package ecdh1pu provides implementations of payload encryption using ECDH-1PU KW key wrapping with AEAD primitives. +// +// The functionality of ecdh1pu Encryption is represented as a pair of +// primitives (interfaces): +// +// * ECDH1PUEncrypt for encryption of data and aad for a given list of recipients keys +// +// * ECDH1PUDecrypt for decryption of data for a certain recipient key and returning decrypted plaintext +// +// +// Example: +// +// package main +// +// import ( +// "bytes" +// +// "github.com/google/tink/go/keyset" +// +// "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle" +// "github.com/aries-framework-go/pkg/crypto/tinkcrypto/composite/ecdh1pu" +// ) +// +// func main() { +// // create recipient side keyset handle +// recKH, err := keyset.NewHandle(ecdh1pu.ECDH1PU256KWAES256GCMKeyTemplate()) +// if err != nil { +// //handle error +// } +// +// // extract recipient public keyset handle and key +// recPubKH, err := recKH.Public() +// if err != nil { +// //handle error +// } +// +// buf := new(bytes.Buffer) +// pubKeyWriter := ecdh1pu.NewWriter(buf) +// err = recPubKH.WriteWithNoSecrets(pubKeyWriter) +// if err != nil { +// //handle error +// } +// +// ecPubKey := new(subtle.ECPublicKey) +// err := json.Unmarshal(buf.Bytes(), ecPubKey) +// +// // now create sender keyset handle with recipient public key (ecPubKey) +// sKH, err := keyset.NewHandle(ECDH1PU256KWAES256GCMKeyTemplateWithRecipients( +// []subtle.ECPublicKey{*ecPubKey})) +// if err != nil { +// // handle error +// } +// +// // for more recipient keys pass in a list: []subtle.ECPublicKey{*ecPubKey1, *ecPubKey2, *ecPubKey3, etc.}) +// // at least 1 recipient is required. +// +// // extract sender public keyset handle to encrypt +// senderPubKH, err := sKH.Public() +// if err != nil { +// //handle error +// } +// +// e := ecdh1pu.NewECDH1PUEncrypt(senderPubKH) +// +// ct, err = e.Encrypt([]byte("secret message"), []byte("some aad")) +// if err != nil { +// // handle error +// } +// +// // get a handle on the decryption key material for a recipient +// // this is usually reloading the recipient's keyset handle (ie: `recKH` above) from a kms +// refRecKH , err := keyset.NewHandle( .....reference/rebuild `recKH` here...); +// d := ecdh1pu.NewECDH1PUDecrypt(refRecKH) +// +// pt, err := d.Decrypt(ct) +// if err != nil { +// // handle error +// } +// } +package ecdh1pu + +import ( + "fmt" + + "github.com/google/tink/go/core/registry" +) + +// TODO - find a better way to setup tink than init. +// nolint: gochecknoinits +func init() { + // TODO - avoid the tink registry singleton (if possible). + err := registry.RegisterKeyManager(newECDH1PUPrivateKeyManager()) + if err != nil { + panic(fmt.Sprintf("ecdh1pu.init() failed: %v", err)) + } + + err = registry.RegisterKeyManager(newECDH1PUPublicKeyManager()) + if err != nil { + panic(fmt.Sprintf("ecdh1pu.init() failed: %v", err)) + } +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_private_key_manager.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_private_key_manager.go new file mode 100644 index 0000000000..a00d54c8fb --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_private_key_manager.go @@ -0,0 +1,191 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh1pu + +import ( + "crypto/elliptic" + "fmt" + + "github.com/golang/protobuf/proto" + "github.com/google/tink/go/core/registry" + hybrid "github.com/google/tink/go/hybrid/subtle" + "github.com/google/tink/go/keyset" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" + ecdh1pupb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto" +) + +const ( + ecdh1puAESPrivateKeyVersion = 0 + ecdh1puAESPrivateKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.Ecdh1puAesAeadPrivateKey" +) + +// common errors +var errInvalidECDH1PUAESPrivateKey = fmt.Errorf("ecdh1pu_aes_private_key_manager: invalid key") +var errInvalidECDH1PUAESPrivateKeyFormat = fmt.Errorf("ecdh1pu_aes_private_key_manager: invalid key format") + +// ecdh1puAESPrivateKeyManager is an implementation of PrivateKeyManager interface. +// It generates new ECDHESPrivateKey (AES) keys and produces new instances of ECDH1PUAEADCompositeDecrypt subtle. +type ecdh1puAESPrivateKeyManager struct{} + +// Assert that ecdh1puAESPrivateKeyManager implements the PrivateKeyManager interface. +var _ registry.PrivateKeyManager = (*ecdh1puAESPrivateKeyManager)(nil) + +// newECDH1PUPrivateKeyManager creates a new ecdh1puAESPrivateKeyManager. +func newECDH1PUPrivateKeyManager() *ecdh1puAESPrivateKeyManager { + return new(ecdh1puAESPrivateKeyManager) +} + +// Primitive creates an ECDHESPrivateKey subtle for the given serialized ECDHESPrivateKey proto. +func (km *ecdh1puAESPrivateKeyManager) Primitive(serializedKey []byte) (interface{}, error) { + if len(serializedKey) == 0 { + return nil, errInvalidECDH1PUAESPrivateKey + } + + key := new(ecdh1pupb.Ecdh1PuAeadPrivateKey) + + err := proto.Unmarshal(serializedKey, key) + if err != nil { + return nil, errInvalidECDH1PUAESPrivateKey + } + + curve, err := km.validateKey(key) + if err != nil { + return nil, errInvalidECDH1PUAESPrivateKey + } + + pvt := hybrid.GetECPrivateKey(curve, key.KeyValue) + + rEnc, err := newRegisterECDH1PUAEADEncHelper(key.PublicKey.Params.EncParams.AeadEnc) + if err != nil { + return nil, err + } + + ptFormat := key.PublicKey.Params.EcPointFormat.String() + + return subtle.NewECDH1PUAEADCompositeDecrypt(pvt, ptFormat, rEnc, commonpb.KeyType_EC), nil +} + +// NewKey creates a new key according to the specification of ECDH1PUPrivateKey format. +func (km *ecdh1puAESPrivateKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { + if len(serializedKeyFormat) == 0 { + return nil, errInvalidECDH1PUAESPrivateKeyFormat + } + + keyFormat := new(ecdh1pupb.Ecdh1PuAeadKeyFormat) + + err := proto.Unmarshal(serializedKeyFormat, keyFormat) + if err != nil { + return nil, errInvalidECDH1PUAESPrivateKeyFormat + } + + curve, err := validateKeyFormat(keyFormat.Params) + if err != nil { + return nil, errInvalidECDH1PUAESPrivateKeyFormat + } + + keyFormat.Params.KwParams.KeyType = commonpb.KeyType_EC + + pvt, err := hybrid.GenerateECDHKeyPair(curve) + if err != nil { + return nil, err + } + + return &ecdh1pupb.Ecdh1PuAeadPrivateKey{ + Version: ecdh1puAESPrivateKeyVersion, + KeyValue: pvt.D.Bytes(), + PublicKey: &ecdh1pupb.Ecdh1PuAeadPublicKey{ + Version: ecdh1puAESPrivateKeyVersion, + Params: keyFormat.Params, + X: pvt.PublicKey.Point.X.Bytes(), + Y: pvt.PublicKey.Point.Y.Bytes(), + }, + }, nil +} + +// NewKeyData creates a new KeyData according to the specification of ECDHESPrivateKey Format. +// It should be used solely by the key management API. +func (km *ecdh1puAESPrivateKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { + key, err := km.NewKey(serializedKeyFormat) + if err != nil { + return nil, err + } + + serializedKey, err := proto.Marshal(key) + if err != nil { + return nil, err + } + + return &tinkpb.KeyData{ + TypeUrl: ecdh1puAESPrivateKeyTypeURL, + Value: serializedKey, + KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE, + }, nil +} + +// PublicKeyData returns the enclosed public key data of serializedPrivKey +func (km *ecdh1puAESPrivateKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) { + privKey := new(ecdh1pupb.Ecdh1PuAeadPrivateKey) + + err := proto.Unmarshal(serializedPrivKey, privKey) + if err != nil { + return nil, errInvalidECDH1PUAESPrivateKey + } + + serializedPubKey, err := proto.Marshal(privKey.PublicKey) + if err != nil { + return nil, errInvalidECDH1PUAESPrivateKey + } + + return &tinkpb.KeyData{ + TypeUrl: ecdh1puAESPublicKeyTypeURL, + Value: serializedPubKey, + KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC, + }, nil +} + +// DoesSupport indicates if this key manager supports the given key type. +func (km *ecdh1puAESPrivateKeyManager) DoesSupport(typeURL string) bool { + return typeURL == ecdh1puAESPrivateKeyTypeURL +} + +// TypeURL returns the key type of keys managed by this key manager. +func (km *ecdh1puAESPrivateKeyManager) TypeURL() string { + return ecdh1puAESPrivateKeyTypeURL +} + +// validateKey validates the given ECDH1PUPrivateKey and returns the KW curve. +func (km *ecdh1puAESPrivateKeyManager) validateKey(key *ecdh1pupb.Ecdh1PuAeadPrivateKey) (elliptic.Curve, error) { + err := keyset.ValidateKeyVersion(key.Version, ecdh1puAESPrivateKeyVersion) + if err != nil { + return nil, fmt.Errorf("ecdh1pu_private_key_manager: invalid key: %s", err) + } + + return validateKeyFormat(key.PublicKey.Params) +} + +// validateKeyFormat validates the given ECDHESKeyFormat and returns the KW Curve. +func validateKeyFormat(params *ecdh1pupb.Ecdh1PuAeadParams) (elliptic.Curve, error) { + c, err := hybrid.GetCurve(params.KwParams.CurveType.String()) + if err != nil { + return nil, err + } + + km, err := registry.GetKeyManager(params.EncParams.AeadEnc.TypeUrl) + if err != nil { + return nil, err + } + + _, err = km.NewKeyData(params.EncParams.AeadEnc.Value) + if err != nil { + return nil, err + } + + return c, nil +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_private_key_manager_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_private_key_manager_test.go new file mode 100644 index 0000000000..6384b980ad --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_private_key_manager_test.go @@ -0,0 +1,314 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh1pu + +import ( + "bytes" + "crypto/elliptic" + "crypto/rand" + "strings" + "testing" + + "github.com/golang/protobuf/proto" + "github.com/google/tink/go/aead" + hybrid "github.com/google/tink/go/hybrid/subtle" + gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto" + commonpb "github.com/google/tink/go/proto/common_go_proto" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + "github.com/stretchr/testify/require" + + ecdh1pupb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto" +) + +func TestECDH1PUPrivateKeyManager_Primitive(t *testing.T) { + km := newECDH1PUPrivateKeyManager() + + t.Run("Test private key manager Primitive() with empty serialized key", func(t *testing.T) { + p, err := km.Primitive([]byte("")) + require.EqualError(t, err, errInvalidECDH1PUAESPrivateKey.Error(), + "ECDH1PUPrivate primitive from empty serialized key must fail") + require.Empty(t, p) + }) + + t.Run("Test private key manager Primitive() with bad serialize key", func(t *testing.T) { + p, err := km.Primitive([]byte("bad.data")) + require.EqualError(t, err, errInvalidECDH1PUAESPrivateKey.Error(), + "ECDH1PUPrivate primitive from bad serialized key must fail") + require.Empty(t, p) + }) + + format := &gcmpb.AesGcmKeyFormat{ + KeySize: 32, + } + serializedFormat, err := proto.Marshal(format) + require.NoError(t, err) + + format = &gcmpb.AesGcmKeyFormat{ + KeySize: 99, // bad AES128GCM size + } + + badSerializedFormat, err := proto.Marshal(format) + require.NoError(t, err) + + var flagTests = []struct { + tcName string + version uint32 + curveType commonpb.EllipticCurveType + ecPtFmt commonpb.EcPointFormat + encTmp *tinkpb.KeyTemplate + }{ + { + tcName: "private key manager Primitive() using key with bad version", + version: 9999, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + }, + { + tcName: "private key manager Primitive() using key with bad curve", + version: 0, + curveType: commonpb.EllipticCurveType_UNKNOWN_CURVE, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + }, + { + tcName: "success private key manager Primitive()", + version: 0, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_UNCOMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + }, + { + tcName: "private key manager Primitive() using key with bad key template URL", + version: 0, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: "bad.type/url/value", + Value: serializedFormat, + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + }, + { + tcName: "private key manager Primitive() using key with bad dem key size", + version: 0, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: aesGCMTypeURL, + Value: badSerializedFormat, + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + }, + } + + for _, tc := range flagTests { + tt := tc + t.Run("Test "+tt.tcName, func(t *testing.T) { + c := tt.curveType + encT := tt.encTmp + ptFmt := tt.ecPtFmt + v := tt.version + + // temporarily reset curvType if its unknown type so subtle.GetCurve() below doesn't fail + if tt.curveType.String() == commonpb.EllipticCurveType_UNKNOWN_CURVE.String() { + c = commonpb.EllipticCurveType_NIST_P256 + } + + crv, err := hybrid.GetCurve(c.String()) + require.NoError(t, err) + d, x, y, err := elliptic.GenerateKey(crv, rand.Reader) + require.NoError(t, err) + + // set back curvType if it was unknown to proceed with the test + if tt.curveType.String() == commonpb.EllipticCurveType_UNKNOWN_CURVE.String() { + c = tt.curveType + } + + pubKeyProto := &ecdh1pupb.Ecdh1PuAeadPrivateKey{ + Version: v, + PublicKey: &ecdh1pupb.Ecdh1PuAeadPublicKey{ + Version: v, // if v > 0 to force an error when calling km.Primitive() + Params: &ecdh1pupb.Ecdh1PuAeadParams{ + KwParams: &ecdh1pupb.Ecdh1PuKwParams{ + CurveType: c, // unknown curve type to force an error when calling km.Primitive() + }, + EncParams: &ecdh1pupb.Ecdh1PuAeadEncParams{ + AeadEnc: encT, // invalid data enc key template to get an error when calling km.Primitive() + }, + EcPointFormat: ptFmt, + }, + X: x.Bytes(), + Y: y.Bytes(), + }, + KeyValue: d, + } + + sPubKey, err := proto.Marshal(pubKeyProto) + require.NoError(t, err) + + p, err := km.Primitive(sPubKey) + if bytes.Equal(tt.encTmp.Value, badSerializedFormat) { + require.EqualError(t, err, errInvalidECDH1PUAESPrivateKey.Error(), + "ECDH1PUPrivate primitive from serialized key with invalid serialized key") + require.Empty(t, p) + + return + } + + if strings.Contains(tt.tcName, "success") { + require.NoError(t, err) + require.NotEmpty(t, p) + return + } + + require.Errorf(t, err, tt.tcName) + require.Empty(t, p) + }) + } +} + +func TestEcdh1PuPrivateKeyManager_DoesSupport(t *testing.T) { + km := newECDH1PUPrivateKeyManager() + require.False(t, km.DoesSupport("bad/url")) + require.True(t, km.DoesSupport(ecdh1puAESPrivateKeyTypeURL)) +} + +func TestEcdh1PuPrivateKeyManager_NewKey(t *testing.T) { + km := newECDH1PUPrivateKeyManager() + + t.Run("Test private key manager NewKey() with nil key", func(t *testing.T) { + k, err := km.NewKey(nil) + require.EqualError(t, err, errInvalidECDH1PUAESPrivateKeyFormat.Error()) + require.Empty(t, k) + }) + + t.Run("Test private key manager NewKey() with bad serialize key", func(t *testing.T) { + p, err := km.NewKey([]byte("bad.data")) + require.EqualError(t, err, errInvalidECDH1PUAESPrivateKeyFormat.Error(), + "ECDH1PUPrivate NewKey() from bad serialized key must fail") + require.Empty(t, p) + }) + + format := &gcmpb.AesGcmKeyFormat{ + KeySize: 32, + } + + serializedFormat, err := proto.Marshal(format) + require.NoError(t, err) + + format = &gcmpb.AesGcmKeyFormat{ + KeySize: 99, // bad AES128GCM size + } + + badSerializedFormat, err := proto.Marshal(format) + require.NoError(t, err) + + var flagTests = []struct { + tcName string + curveType commonpb.EllipticCurveType + ecPtFmt commonpb.EcPointFormat + encTmp *tinkpb.KeyTemplate + }{ + { + tcName: "success private key manager NewKey() and NewKeyData()", + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + }, + { + tcName: "private key manager NewKey() and NewKeyData() using key with bad curve", + curveType: commonpb.EllipticCurveType_UNKNOWN_CURVE, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + }, + { + tcName: "private key manager NewKey() and NewKeyData() using key with bad key template URL", + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: "bad.type/url/value", + Value: serializedFormat, + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + }, + { + tcName: "private key manager NewKey() and NewKeyData() using key with bad dem key size", + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: aesGCMTypeURL, + Value: badSerializedFormat, + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + }, + } + + for _, tc := range flagTests { + tt := tc + t.Run("Test "+tt.tcName, func(t *testing.T) { + c := tt.curveType + encT := tt.encTmp + ptFmt := tt.ecPtFmt + + privKeyProto := &ecdh1pupb.Ecdh1PuAeadKeyFormat{ + Params: &ecdh1pupb.Ecdh1PuAeadParams{ + KwParams: &ecdh1pupb.Ecdh1PuKwParams{ + CurveType: c, // unknown curve type to force an error when calling km.Primitive() + }, + EncParams: &ecdh1pupb.Ecdh1PuAeadEncParams{ + AeadEnc: encT, // invalid data enc key template to force an error when calling km.Primitive() + }, + EcPointFormat: ptFmt, // unknown EC Point format type to force an error when calling km.Primitive() + }, + } + + sPrivKey, err := proto.Marshal(privKeyProto) + require.NoError(t, err) + + p, err := km.NewKey(sPrivKey) + if strings.Contains(tt.tcName, "success") { + require.NoError(t, err) + require.NotEmpty(t, p) + + sp, e := proto.Marshal(p) + require.NoError(t, e) + require.NotEmpty(t, sp) + + // try PublicKeyData() with bad serialized private key + pubK, e := km.PublicKeyData([]byte("bad serialized private key")) + require.Error(t, e) + require.Empty(t, pubK) + + // try PublicKeyData() with valid serialized private key + pubK, e = km.PublicKeyData(sp) + require.NoError(t, e) + require.NotEmpty(t, pubK) + } + + kd, err := km.NewKeyData(sPrivKey) + if strings.Contains(tt.tcName, "success") { + require.NoError(t, err) + require.NotEmpty(t, kd) + require.Equal(t, kd.TypeUrl, ecdh1puAESPrivateKeyTypeURL) + require.Equal(t, kd.KeyMaterialType, tinkpb.KeyData_ASYMMETRIC_PRIVATE) + return + } + + if bytes.Equal(tt.encTmp.Value, badSerializedFormat) { + require.EqualError(t, err, errInvalidECDH1PUAESPrivateKeyFormat.Error(), + "ECDH1PUPrivate NewKey from serialized key with invalid serialized key") + require.Empty(t, p) + + return + } + + require.Errorf(t, err, tt.tcName) + require.Empty(t, p) + }) + } +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_public_key_manager.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_public_key_manager.go new file mode 100644 index 0000000000..c51b63c714 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_public_key_manager.go @@ -0,0 +1,140 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh1pu + +import ( + "crypto/elliptic" + "fmt" + + "github.com/golang/protobuf/proto" + "github.com/google/tink/go/core/registry" + hybrid "github.com/google/tink/go/hybrid/subtle" + "github.com/google/tink/go/keyset" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" + ecdh1pupb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto" +) + +const ( + ecdh1puAESPublicKeyVersion = 0 + ecdh1puAESPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.Ecdh1puAesAeadPublicKey" +) + +// common errors +var errInvalidECDH1PUAESPublicKey = fmt.Errorf("ecdh1pu_aes_public_key_manager: invalid key") + +// ecdh1puPublicKeyManager is an implementation of KeyManager interface. +// It generates new ECDH1PUPublicKey (AES) keys and produces new instances of ECDH1PUAEADCompositeEncrypt subtle. +type ecdh1puPublicKeyManager struct{} + +// Assert that ecdh1puPublicKeyManager implements the KeyManager interface. +var _ registry.KeyManager = (*ecdh1puPublicKeyManager)(nil) + +// newECDH1PUPublicKeyManager creates a new ecdh1puPublicKeyManager. +func newECDH1PUPublicKeyManager() *ecdh1puPublicKeyManager { + return new(ecdh1puPublicKeyManager) +} + +// Primitive creates an ECDH1PUPublicKey subtle for the given serialized ECDH1PUPublicKey proto. +func (km *ecdh1puPublicKeyManager) Primitive(serializedKey []byte) (interface{}, error) { + if len(serializedKey) == 0 { + return nil, errInvalidECDH1PUAESPublicKey + } + + ecdh1puPubKey := new(ecdh1pupb.Ecdh1PuAeadPublicKey) + + err := proto.Unmarshal(serializedKey, ecdh1puPubKey) + if err != nil { + return nil, errInvalidECDH1PUAESPublicKey + } + + _, err = km.validateKey(ecdh1puPubKey) + if err != nil { + return nil, errInvalidECDH1PUAESPublicKey + } + + var recipientsKeys []*composite.PublicKey + + for _, recKey := range ecdh1puPubKey.Params.KwParams.Recipients { + e := km.validateRecKey(recKey) + if e != nil { + return nil, errInvalidECDH1PUAESPublicKey + } + + pub := &composite.PublicKey{ + KID: recKey.KID, + Type: recKey.KeyType.String(), + Curve: recKey.CurveType.String(), + X: recKey.X, + Y: recKey.Y, + } + + recipientsKeys = append(recipientsKeys, pub) + } + + rEnc, err := newRegisterECDH1PUAEADEncHelper(ecdh1puPubKey.Params.EncParams.AeadEnc) + if err != nil { + return nil, err + } + + ptFormat := ecdh1puPubKey.Params.EcPointFormat.String() + + return subtle.NewECDH1PUAEADCompositeEncrypt(recipientsKeys, ptFormat, rEnc, commonpb.KeyType_EC), nil +} + +// DoesSupport indicates if this key manager supports the given key type. +func (km *ecdh1puPublicKeyManager) DoesSupport(typeURL string) bool { + return typeURL == ecdh1puAESPublicKeyTypeURL +} + +// TypeURL returns the key type of keys managed by this key manager. +func (km *ecdh1puPublicKeyManager) TypeURL() string { + return ecdh1puAESPublicKeyTypeURL +} + +// NewKey is not implemented for public key manager. +func (km *ecdh1puPublicKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { + return nil, fmt.Errorf("ecdh1pu_public_key_manager: NewKey not implemented") +} + +// NewKeyData is not implemented for public key manager. +func (km *ecdh1puPublicKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { + return nil, fmt.Errorf("ecdh1pu_public_key_manager: NewKeyData not implemented") +} + +// validateKey validates the given ECDHESPublicKey. +func (km *ecdh1puPublicKeyManager) validateKey(key *ecdh1pupb.Ecdh1PuAeadPublicKey) (elliptic.Curve, error) { + err := keyset.ValidateKeyVersion(key.Version, ecdh1puAESPublicKeyVersion) + if err != nil { + return nil, fmt.Errorf("ecdh1pu_publie_key_manager: invalid key: %s", err) + } + + return validateKeyFormat(key.Params) +} + +// validateRecKey validates the given recipient's ECDHESPublicKey. +func (km *ecdh1puPublicKeyManager) validateRecKey(key *ecdh1pupb.Ecdh1PuAeadRecipientPublicKey) error { + err := keyset.ValidateKeyVersion(key.Version, ecdh1puAESPublicKeyVersion) + if err != nil { + return fmt.Errorf("ecdh1pu_public_key_manager: invalid key: %s", err) + } + + _, err = GetKeyType(key.KeyType.String()) + if err != nil { + return err + } + + _, err = hybrid.GetCurve(key.CurveType.String()) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_public_key_manager_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_public_key_manager_test.go new file mode 100644 index 0000000000..e1e7f75dc2 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_aes_aead_public_key_manager_test.go @@ -0,0 +1,262 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh1pu + +import ( + "crypto/elliptic" + "crypto/rand" + "strings" + "testing" + + "github.com/golang/protobuf/proto" + "github.com/google/tink/go/aead" + hybrid "github.com/google/tink/go/hybrid/subtle" + gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto" + commonpb "github.com/google/tink/go/proto/common_go_proto" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + "github.com/stretchr/testify/require" + + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" + ecdh1pupb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto" +) + +func TestECDH1PUPublicKeyManager_Primitive(t *testing.T) { + km := newECDH1PUPublicKeyManager() + + t.Run("Test public key manager Primitive() with empty serialized key", func(t *testing.T) { + p, err := km.Primitive([]byte("")) + require.EqualError(t, err, errInvalidECDH1PUAESPublicKey.Error(), + "ECDH1PUPublic primitive from empty serialized key must fail") + require.Empty(t, p) + }) + + t.Run("Test public key manager Primitive() with bad serialize key", func(t *testing.T) { + p, err := km.Primitive([]byte("bad.data")) + require.EqualError(t, err, errInvalidECDH1PUAESPublicKey.Error(), + "ECDH1PUPublic primitive from bad serialized key must fail") + require.Empty(t, p) + }) + + format := &gcmpb.AesGcmKeyFormat{ + KeySize: 32, + } + serializedFormat, err := proto.Marshal(format) + require.NoError(t, err) + + format = &gcmpb.AesGcmKeyFormat{ + KeySize: 99, // bad AES128GCM size + } + + badSerializedFormat, err := proto.Marshal(format) + require.NoError(t, err) + + recipients := generateRecipients(t) + + badRecipients := generateBadRecipients(t) + + var flagTests = []struct { + tcName string + version uint32 + curveType commonpb.EllipticCurveType + ecPtFmt commonpb.EcPointFormat + encTmp *tinkpb.KeyTemplate + recipients []*ecdh1pupb.Ecdh1PuAeadRecipientPublicKey + }{ + { + tcName: "public key manager Primitive() using key with bad version", + version: 9999, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + recipients: recipients, + }, + { + tcName: "public key manager Primitive() using key with bad curve", + version: 0, + curveType: commonpb.EllipticCurveType_UNKNOWN_CURVE, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + recipients: recipients, + }, + { + tcName: "success public key manager Primitive()", + version: 0, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_UNCOMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + recipients: recipients, + }, + { + tcName: "public key manager Primitive() using key with bad key template URL", + version: 0, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: "bad.type/url/value", + Value: serializedFormat, + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + recipients: recipients, + }, + { + tcName: "public key manager Primitive() using key with bad content encryption key size", + version: 0, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_COMPRESSED, + encTmp: &tinkpb.KeyTemplate{ + TypeUrl: aesGCMTypeURL, + Value: badSerializedFormat, + OutputPrefixType: tinkpb.OutputPrefixType_RAW, + }, + recipients: recipients, + }, + { + tcName: "public key manager Primitive() with bad recipients keys", + version: 0, + curveType: commonpb.EllipticCurveType_NIST_P256, + ecPtFmt: commonpb.EcPointFormat_UNCOMPRESSED, + encTmp: aead.AES128GCMKeyTemplate(), + recipients: badRecipients, + }, + } + + for _, tc := range flagTests { + tt := tc + t.Run("Test "+tt.tcName, func(t *testing.T) { + c := tt.curveType + encT := tt.encTmp + ptFmt := tt.ecPtFmt + v := tt.version + recipientsKeys := tt.recipients + + // temporarily reset curvType if its unknown type so subtle.GetCurve() below doesn't fail + if tt.curveType.String() == commonpb.EllipticCurveType_UNKNOWN_CURVE.String() { + c = commonpb.EllipticCurveType_NIST_P256 + } + + crv, err := hybrid.GetCurve(c.String()) + require.NoError(t, err) + _, x, y, err := elliptic.GenerateKey(crv, rand.Reader) + require.NoError(t, err) + + // set back curvType if it was unknown to proceed with the test + if tt.curveType.String() == commonpb.EllipticCurveType_UNKNOWN_CURVE.String() { + c = tt.curveType + } + + pubKeyProto := &ecdh1pupb.Ecdh1PuAeadPublicKey{ + Version: v, // if v > 0 to force an error when calling km.Primitive() + Params: &ecdh1pupb.Ecdh1PuAeadParams{ + KwParams: &ecdh1pupb.Ecdh1PuKwParams{ + CurveType: c, // unknown curve type to force an error when calling km.Primitive() + Recipients: recipientsKeys, + }, + EncParams: &ecdh1pupb.Ecdh1PuAeadEncParams{ + AeadEnc: encT, // invalid data enc key template to force an error when calling km.Primitive() + }, + EcPointFormat: ptFmt, // unknown EC Pint format type to force an error when calling km.Primitive() + }, + X: x.Bytes(), + Y: y.Bytes(), + } + + sPubKey, err := proto.Marshal(pubKeyProto) + require.NoError(t, err) + + p, err := km.Primitive(sPubKey) + if strings.Contains(tt.tcName, "with bad content encryption key size") { + require.EqualError(t, err, errInvalidECDH1PUAESPublicKey.Error(), + "ECDH1PUPublic primitive from serialized key with invalid serialized key") + require.Empty(t, p) + + return + } + + if strings.Contains(tt.tcName, "success") { + require.NoError(t, err) + require.NotEmpty(t, p) + return + } + + require.Errorf(t, err, tt.tcName) + require.Empty(t, p) + }) + } +} + +func generateBadRecipients(t *testing.T) []*ecdh1pupb.Ecdh1PuAeadRecipientPublicKey { + recipients := generateRecipients(t) + + for _, rec := range recipients { + rec.Version = 999 + } + + return recipients +} + +func generateRecipients(t *testing.T) []*ecdh1pupb.Ecdh1PuAeadRecipientPublicKey { + t.Helper() + + curvProto := commonpb.EllipticCurveType_NIST_P256 + curve, err := hybrid.GetCurve(curvProto.String()) + require.NoError(t, err) + + recipient1Priv, err := hybrid.GenerateECDHKeyPair(curve) + require.NoError(t, err) + + recipient2Priv, err := hybrid.GenerateECDHKeyPair(curve) + require.NoError(t, err) + + recipient3Priv, err := hybrid.GenerateECDHKeyPair(curve) + require.NoError(t, err) + + return []*ecdh1pupb.Ecdh1PuAeadRecipientPublicKey{ + { + Version: 0, + KeyType: compositepb.KeyType_EC, + CurveType: curvProto, + X: recipient1Priv.PublicKey.Point.X.Bytes(), + Y: recipient1Priv.PublicKey.Point.Y.Bytes(), + }, + { + Version: 0, + KeyType: compositepb.KeyType_EC, + CurveType: curvProto, + X: recipient2Priv.PublicKey.Point.X.Bytes(), + Y: recipient2Priv.PublicKey.Point.Y.Bytes(), + }, + { + Version: 0, + KeyType: compositepb.KeyType_EC, + CurveType: curvProto, + X: recipient3Priv.PublicKey.Point.X.Bytes(), + Y: recipient3Priv.PublicKey.Point.Y.Bytes(), + }, + } +} + +func TestEcdh1puPublicKeyManager_DoesSupport(t *testing.T) { + km := newECDH1PUPublicKeyManager() + require.False(t, km.DoesSupport("bad/url")) + require.True(t, km.DoesSupport(ecdh1puAESPublicKeyTypeURL)) +} + +func TestEcdh1puPublicKeyManager_NewKeyAndNewKeyData(t *testing.T) { + km := newECDH1PUPublicKeyManager() + + t.Run("Test public key manager NewKey()", func(t *testing.T) { + k, err := km.NewKey(nil) + require.EqualError(t, err, "ecdh1pu_public_key_manager: NewKey not implemented") + require.Empty(t, k) + }) + + t.Run("Test private key manager NewKeyData()", func(t *testing.T) { + p, err := km.NewKeyData(nil) + require.EqualError(t, err, "ecdh1pu_public_key_manager: NewKeyData not implemented") + require.Empty(t, p) + }) +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_common.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_common.go new file mode 100644 index 0000000000..32d2a083d9 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/ecdh1pu_common.go @@ -0,0 +1,25 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh1pu + +import ( + "fmt" + + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" +) + +// GetKeyType is a utility function that converts a string type value into an proto KeyType +func GetKeyType(keyType string) (commonpb.KeyType, error) { + switch keyType { + case "EC": + return commonpb.KeyType_EC, nil + case "OKP": + return commonpb.KeyType_OKP, nil + default: + return 0, fmt.Errorf("key type %s not supported", keyType) + } +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/register_ecdh1pu_aead_enc_helper.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/register_ecdh1pu_aead_enc_helper.go new file mode 100644 index 0000000000..6e992e51f8 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/register_ecdh1pu_aead_enc_helper.go @@ -0,0 +1,204 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package ecdh1pu + +import ( + "fmt" + + "github.com/golang/protobuf/proto" + aead "github.com/google/tink/go/aead/subtle" + "github.com/google/tink/go/core/registry" + gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto" + chachapb "github.com/google/tink/go/proto/chacha20_poly1305_go_proto" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + xchachapb "github.com/google/tink/go/proto/xchacha20_poly1305_go_proto" + "github.com/google/tink/go/tink" + "golang.org/x/crypto/chacha20poly1305" + "golang.org/x/crypto/poly1305" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" +) + +const ( + aesGCMTypeURL = "type.googleapis.com/google.crypto.tink.AesGcmKey" + chaCha20Poly1305TypeURL = "type.googleapis.com/google.crypto.tink.ChaCha20Poly1305Key" + xChaCha20Poly1305TypeURL = "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key" +) + +// registerECDH1PUAEADEncHelper registers a content encryption helper +type registerECDH1PUAEADEncHelper struct { + encKeyURL string + keyData []byte + symmetricKeySize int + tagSize int + ivSize int +} + +var _ subtle.EncrypterHelper = (*registerECDH1PUAEADEncHelper)(nil) + +// newRegisterECDH1PUAEADEncHelper initializes and returns a registerECDH1PUAEADEncHelper +func newRegisterECDH1PUAEADEncHelper(k *tinkpb.KeyTemplate) (*registerECDH1PUAEADEncHelper, error) { + var ( + keySize, tagSize, ivSize int + skf []byte + err error + ) + + switch k.TypeUrl { + case aesGCMTypeURL: + gcmKeyFormat := new(gcmpb.AesGcmKeyFormat) + + err = proto.Unmarshal(k.Value, gcmKeyFormat) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to unmarshal gcmKeyFormat: %w", err) + } + + keySize = int(gcmKeyFormat.KeySize) + tagSize = aead.AESGCMTagSize + ivSize = aead.AESGCMIVSize + + skf, err = proto.Marshal(gcmKeyFormat) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to serialize key format, error: %w", err) + } + case chaCha20Poly1305TypeURL: + keySize = chacha20poly1305.KeySize + tagSize = poly1305.TagSize + ivSize = chacha20poly1305.NonceSize + case xChaCha20Poly1305TypeURL: + keySize = chacha20poly1305.KeySize + tagSize = poly1305.TagSize + ivSize = chacha20poly1305.NonceSizeX + default: + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: unsupported AEAD content encryption key type: %s", + k.TypeUrl) + } + + km, err := registry.GetKeyManager(k.TypeUrl) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to fetch KeyManager, error: %w", err) + } + + // skf is nil for (X)Chahcha20Poly1305 km + key, err := km.NewKey(skf) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to fetch key, error: %w", err) + } + + sk, err := proto.Marshal(key) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to serialize key, error: %w", err) + } + + return ®isterECDH1PUAEADEncHelper{ + encKeyURL: k.TypeUrl, + keyData: sk, + symmetricKeySize: keySize, + tagSize: tagSize, + ivSize: ivSize, + }, nil +} + +// GetSymmetricKeySize returns the symmetric key size +func (r *registerECDH1PUAEADEncHelper) GetSymmetricKeySize() int { + return r.symmetricKeySize +} + +// GetTagSize returns the primitive tag size +func (r *registerECDH1PUAEADEncHelper) GetTagSize() int { + return r.tagSize +} + +// GetIVSize returns the primitive IV size +func (r *registerECDH1PUAEADEncHelper) GetIVSize() int { + return r.ivSize +} + +// GetAEAD returns the AEAD primitive from the DEM +func (r *registerECDH1PUAEADEncHelper) GetAEAD(symmetricKeyValue []byte) (tink.AEAD, error) { + if len(symmetricKeyValue) != r.GetSymmetricKeySize() { + return nil, fmt.Errorf("symmetric key has incorrect length") + } + + sk, err := r.getSerializedKey(symmetricKeyValue) + if err != nil { + return nil, err + } + + p, err := registry.Primitive(r.encKeyURL, sk) + if err != nil { + return nil, err + } + + g, ok := p.(tink.AEAD) + if !ok { + return nil, fmt.Errorf("invalid primitive") + } + + return g, nil +} + +func (r *registerECDH1PUAEADEncHelper) getSerializedKey(symmetricKeyValue []byte) ([]byte, error) { + var ( + sk []byte + err error + ) + + switch r.encKeyURL { + case aesGCMTypeURL: + sk, err = r.getSerializedAESGCMKey(symmetricKeyValue) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to serialize key, error: %w", err) + } + case chaCha20Poly1305TypeURL: + chachaKey := new(chachapb.ChaCha20Poly1305Key) + + err = proto.Unmarshal(r.keyData, chachaKey) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to unmarshal chacha key: %w", err) + } + + chachaKey.KeyValue = symmetricKeyValue + + sk, err = proto.Marshal(chachaKey) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to serialize key, error: %w", err) + } + case xChaCha20Poly1305TypeURL: + xChachaKey := new(xchachapb.XChaCha20Poly1305Key) + + err = proto.Unmarshal(r.keyData, xChachaKey) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to unmarshal xchacha key: %w", err) + } + + xChachaKey.KeyValue = symmetricKeyValue + + sk, err = proto.Marshal(xChachaKey) + if err != nil { + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: failed to serialize key, error: %w", err) + } + default: + return nil, fmt.Errorf("registerECDH1PUAEADEncHelper: unsupported AEAD content encryption key type: %s", + r.encKeyURL) + } + + return sk, err +} + +func (r *registerECDH1PUAEADEncHelper) getSerializedAESGCMKey(symmetricKeyValue []byte) ([]byte, error) { + gcmKey := new(gcmpb.AesGcmKey) + + err := proto.Unmarshal(r.keyData, gcmKey) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal gcmKeyFormat: %w", err) + } + + gcmKey.KeyValue = symmetricKeyValue + + return proto.Marshal(gcmKey) +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aead_enc_helper.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aead_enc_helper.go new file mode 100644 index 0000000000..12f1c82a7c --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aead_enc_helper.go @@ -0,0 +1,26 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package subtle + +import ( + "github.com/google/tink/go/tink" +) + +// EncrypterHelper is a helper for Content Encryption of composite ECDH-1PU key wrapping + AEAD content encryption +type EncrypterHelper interface { + // GetSymmetricKeySize gives the size of the Encryption key (CEK) in bytes + GetSymmetricKeySize() int + + // GetAEAD returns the newly created AEAD primitive used for the content Encryption + GetAEAD(symmetricKeyValue []byte) (tink.AEAD, error) + + // GetTagSize provides the aead primitive tag size + GetTagSize() int + + // GetIVSize provides the aead primitive nonce size + GetIVSize() int +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_decrypt.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_decrypt.go new file mode 100644 index 0000000000..3a8e2ab532 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_decrypt.go @@ -0,0 +1,98 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package subtle + +import ( + "encoding/json" + "fmt" + + hybrid "github.com/google/tink/go/hybrid/subtle" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" +) + +// package subtle provides the core crypto primitives to be used by ECDH-1PU composite primitives. It is intended for +// internal use only. + +// ECDH1PUAEADCompositeDecrypt is an instance of ECDH-1PU decryption with Concat KDF +// and AEAD content decryption +type ECDH1PUAEADCompositeDecrypt struct { + privateKey *hybrid.ECPrivateKey + pointFormat string + encHelper EncrypterHelper + keyType commonpb.KeyType +} + +// NewECDH1PUAEADCompositeDecrypt returns ECDH-ES composite decryption construct with Concat KDF/ECDH-1PU key unwrapping +// and AEAD payload decryption. +func NewECDH1PUAEADCompositeDecrypt(pvt *hybrid.ECPrivateKey, ptFormat string, encHelper EncrypterHelper, + keyType commonpb.KeyType) *ECDH1PUAEADCompositeDecrypt { + return &ECDH1PUAEADCompositeDecrypt{ + privateKey: pvt, + pointFormat: ptFormat, + encHelper: encHelper, + keyType: keyType, + } +} + +// Decrypt using composite ECDH-ES with a Concat KDF key unwrap and AEAD content decryption +func (d *ECDH1PUAEADCompositeDecrypt) Decrypt(ciphertext, aad []byte) ([]byte, error) { + if d.privateKey == nil { + return nil, fmt.Errorf("ECDH1PUAEADCompositeDecrypt: missing recipient private key for key unwrapping") + } + + keySize := d.encHelper.GetSymmetricKeySize() + + var cek []byte + + encData := new(composite.EncryptedData) + + err := json.Unmarshal(ciphertext, encData) + if err != nil { + return nil, err + } + + // TODO: add support for Chacha content encryption https://github.com/hyperledger/aries-framework-go/issues/1684 + switch d.keyType { + case commonpb.KeyType_EC: + if encData.EncAlg != A256GCM { + return nil, fmt.Errorf("invalid content encryption algorihm '%s' for Decrypt()", encData.EncAlg) + } + default: + return nil, fmt.Errorf("invalid key type '%s' for Decrypt()", d.keyType) + } + + for _, rec := range encData.Recipients { + recipientKW := &ECDH1PUConcatKDFRecipientKW{ + recipientPrivateKey: d.privateKey, + } + + // TODO: add support for 25519 key unwrapping https://github.com/hyperledger/aries-framework-go/issues/1637 + cek, err = recipientKW.unwrapKey(rec, keySize) + if err == nil { + break + } + } + + if cek == nil { + return nil, fmt.Errorf("ecdh-es decrypt: cek unwrap failed for all recipients keys") + } + + aead, err := d.encHelper.GetAEAD(cek) + if err != nil { + return nil, err + } + + iv := encData.IV + tag := encData.Tag + ct := encData.Ciphertext + finalCT := append(iv, ct...) + finalCT = append(finalCT, tag...) + + return aead.Decrypt(finalCT, aad) +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_encrypt.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_encrypt.go new file mode 100644 index 0000000000..8494fb6333 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_encrypt.go @@ -0,0 +1,201 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package subtle + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "encoding/base64" + "encoding/json" + "fmt" + "math/big" + + hybrid "github.com/google/tink/go/hybrid/subtle" + "github.com/google/tink/go/subtle/random" + "github.com/square/go-jose/v3" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/api" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" +) + +// A256GCM is the default content encryption algorithm value as per +// the JWA specification: https://tools.ietf.org/html/rfc7518#section-5.1 +const A256GCM = "A256GCM" + +type marshalFunc func(interface{}) ([]byte, error) + +// ECDH1PUAEADCompositeEncrypt is an instance of ECDH-ES encryption with Concat KDF +// and AEAD content encryption +type ECDH1PUAEADCompositeEncrypt struct { + recPublicKeys []*composite.PublicKey + pointFormat string + encHelper EncrypterHelper + keyType commonpb.KeyType + marshalFunc marshalFunc +} + +var _ api.CompositeEncrypt = (*ECDH1PUAEADCompositeEncrypt)(nil) + +// NewECDH1PUAEADCompositeEncrypt returns ECDH-ES encryption construct with Concat KDF key wrapping +// and AEAD content encryption +func NewECDH1PUAEADCompositeEncrypt(recipientsKeys []*composite.PublicKey, ptFormat string, + encHelper EncrypterHelper, keyType commonpb.KeyType) *ECDH1PUAEADCompositeEncrypt { + return &ECDH1PUAEADCompositeEncrypt{ + recPublicKeys: recipientsKeys, + pointFormat: ptFormat, + encHelper: encHelper, + keyType: keyType, + marshalFunc: json.Marshal, + } +} + +// Encrypt using composite ECDH-1PU with a 1PU KDF key wrap and AEAD content encryption +func (e *ECDH1PUAEADCompositeEncrypt) Encrypt(plaintext, aad []byte) ([]byte, error) { + if len(e.recPublicKeys) == 0 { + return nil, fmt.Errorf("ECDH1PUAEADCompositeEncrypt: missing recipients public keys for key wrapping") + } + + var eAlg, kwAlg string + + // TODO add chacha alg support too, https://github.com/hyperledger/aries-framework-go/issues/1684 + switch e.keyType { + case commonpb.KeyType_EC: + eAlg = A256GCM + kwAlg = A256KWAlg + default: + return nil, fmt.Errorf("ECDH1PUAEADCompositeEncrypt: bad key type: '%s'", e.keyType) + } + + keySize := e.encHelper.GetSymmetricKeySize() + cek := random.GetRandomBytes(uint32(keySize)) + + var recipientsWK []*composite.RecipientWrappedKey + + var singleRecipientAAD []byte + + for _, rec := range e.recPublicKeys { + senderKW := &ECDH1PUConcatKDFSenderKW{ + recipientPublicKey: rec, + cek: cek, + } + + // TODO: add support for 25519 key wrapping https://github.com/hyperledger/aries-framework-go/issues/1637 + kek, err := senderKW.wrapKey(kwAlg, keySize) + if err != nil { + return nil, err + } + + recipientsWK = append(recipientsWK, kek) + + if len(e.recPublicKeys) == 1 { + singleRecipientAAD, err = e.mergeSingleRecipientHeaders(kek, aad) + if err != nil { + return nil, err + } + + aad = singleRecipientAAD + } + } + + aead, err := e.encHelper.GetAEAD(cek) + if err != nil { + return nil, err + } + + ct, err := aead.Encrypt(plaintext, aad) + if err != nil { + return nil, err + } + + return e.buildEncData(eAlg, recipientsWK, ct, singleRecipientAAD) +} + +func (e *ECDH1PUAEADCompositeEncrypt) buildEncData(eAlg string, recipientsWK []*composite.RecipientWrappedKey, + ct, singleRecipientAAD []byte) ([]byte, error) { + tagSize := e.encHelper.GetTagSize() + ivSize := e.encHelper.GetIVSize() + iv := ct[:ivSize] + ctAndTag := ct[ivSize:] + tagOffset := len(ctAndTag) - tagSize + + encData := &composite.EncryptedData{ + EncAlg: eAlg, + Ciphertext: ctAndTag[:tagOffset], + IV: iv, + Tag: ctAndTag[tagOffset:], + Recipients: recipientsWK, + SingleRecipientAAD: singleRecipientAAD, + } + + return e.marshalFunc(encData) +} + +// for single recipient encryption, recipient header info is available in the key, update aad with this info +func (e *ECDH1PUAEADCompositeEncrypt) mergeSingleRecipientHeaders(recipientWK *composite.RecipientWrappedKey, + aad []byte) ([]byte, error) { + newAAD, err := base64.RawURLEncoding.DecodeString(string(aad)) + if err != nil { + return nil, err + } + + rawHeaders := map[string]json.RawMessage{} + + err = json.Unmarshal(newAAD, &rawHeaders) + if err != nil { + return nil, err + } + + kid, err := e.marshalFunc(recipientWK.KID) + if err != nil { + return nil, err + } + + rawHeaders["kid"] = kid + + alg, err := e.marshalFunc(recipientWK.Alg) + if err != nil { + return nil, err + } + + rawHeaders["alg"] = alg + + mEPK, err := convertRecKeyToMarshalledJWK(recipientWK) + if err != nil { + return nil, err + } + + rawHeaders["epk"] = mEPK + + mAAD, err := e.marshalFunc(rawHeaders) + if err != nil { + return nil, err + } + + return []byte(base64.RawURLEncoding.EncodeToString(mAAD)), nil +} + +func convertRecKeyToMarshalledJWK(rec *composite.RecipientWrappedKey) ([]byte, error) { + var c elliptic.Curve + + c, err := hybrid.GetCurve(rec.EPK.Curve) + if err != nil { + return nil, err + } + + recJWK := jose.JSONWebKey{ + KeyID: rec.KID, + Use: "enc", + Key: &ecdsa.PublicKey{ + Curve: c, + X: new(big.Int).SetBytes(rec.EPK.X), + Y: new(big.Int).SetBytes(rec.EPK.Y), + }, + } + + return recJWK.MarshalJSON() +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_test.go new file mode 100644 index 0000000000..57caeb9387 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdh1pu_aes_aead_composite_test.go @@ -0,0 +1,378 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package subtle + +import ( + "crypto/elliptic" + "encoding/base64" + "encoding/json" + "fmt" + "testing" + + "github.com/google/tink/go/aead" + subtleaead "github.com/google/tink/go/aead/subtle" + hybrid "github.com/google/tink/go/hybrid/subtle" + "github.com/google/tink/go/keyset" + commonpb "github.com/google/tink/go/proto/common_go_proto" + tinkpb "github.com/google/tink/go/proto/tink_go_proto" + "github.com/google/tink/go/tink" + "github.com/stretchr/testify/require" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" +) + +func TestEncryptDecrypt(t *testing.T) { + recipientsPrivKeys, recipientsPubKeys := buildRecipientsKeys(t, 10) + aeadPrimitive := getAEADPrimitive(t, aead.AES256GCMKeyTemplate()) + + mEncHelper := &MockEncHelper{ + KeySizeValue: 32, + AEADValue: aeadPrimitive, + TagSizeValue: subtleaead.AESGCMTagSize, + IVSizeValue: subtleaead.AESGCMIVSize, + } + + cEnc := NewECDH1PUAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), + mEncHelper, compositepb.KeyType_EC) + + pt := []byte("secret message") + aad := []byte("aad message") + + ct, err := cEnc.Encrypt(pt, aad) + require.NoError(t, err) + + for _, privKey := range recipientsPrivKeys { + dEnc := NewECDH1PUAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, + compositepb.KeyType_EC) + + dpt, err := dEnc.Decrypt(ct, aad) + require.NoError(t, err) + require.EqualValues(t, pt, dpt) + } +} + +func TestEncryptDecryptNegativeTCs(t *testing.T) { + recipientsPrivKeys, recipientsPubKeys := buildRecipientsKeys(t, 10) + aeadPrimitive := getAEADPrimitive(t, aead.AES256GCMKeyTemplate()) + + mEncHelper := &MockEncHelper{ + KeySizeValue: 32, + AEADValue: aeadPrimitive, + TagSizeValue: subtleaead.AESGCMTagSize, + IVSizeValue: subtleaead.AESGCMIVSize, + } + + pt := []byte("secret message") + aad := []byte("aad message") + + // test with empty recipients public keys + cEnc := NewECDH1PUAEADCompositeEncrypt(nil, commonpb.EcPointFormat_UNCOMPRESSED.String(), + mEncHelper, compositepb.KeyType_EC) + + // Encrypt should fail with empty recipients public keys + _, err := cEnc.Encrypt(pt, aad) + require.EqualError(t, err, "ECDH1PUAEADCompositeEncrypt: missing recipients public keys for key wrapping") + + // test with large key size + mEncHelper.KeySizeValue = 100 + + cEnc = NewECDH1PUAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), + mEncHelper, compositepb.KeyType_EC) + + // Encrypt should fail with large AEAD key size value + _, err = cEnc.Encrypt(pt, aad) + require.EqualError(t, err, "crypto/aes: invalid key size 100") + + mEncHelper.KeySizeValue = 32 + + // Encrypt should fail with bad key type + cEnc.keyType = compositepb.KeyType_UNKNOWN_KEY_TYPE + + _, err = cEnc.Encrypt(pt, aad) + require.EqualError(t, err, fmt.Sprintf("ECDH1PUAEADCompositeEncrypt: bad key type: '%s'", + compositepb.KeyType_UNKNOWN_KEY_TYPE)) + + cEnc.keyType = compositepb.KeyType_EC + + // test with GetAEAD() returning error + mEncHelper.AEADErrValue = fmt.Errorf("error from GetAEAD") + + cEnc = NewECDH1PUAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), + mEncHelper, compositepb.KeyType_EC) + + // Encrypt should fail with large AEAD key size value + _, err = cEnc.Encrypt(pt, aad) + require.EqualError(t, err, "error from GetAEAD") + + mEncHelper.AEADErrValue = nil + + // create a valid ciphertext to test Decrypt for all recipients + cEnc = NewECDH1PUAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), + mEncHelper, compositepb.KeyType_EC) + + // test with empty plaintext + ct, err := cEnc.Encrypt([]byte{}, aad) + require.NoError(t, err) + + encData := new(composite.EncryptedData) + err = json.Unmarshal(ct, encData) + + require.NoError(t, err) + // encrypting empty plaintext should result in empty ciphertext + require.Empty(t, encData.Ciphertext) + require.Len(t, encData.Tag, subtleaead.AESGCMTagSize) + require.Len(t, encData.IV, subtleaead.AESGCMIVSize) + + ct, err = cEnc.Encrypt(pt, aad) + require.NoError(t, err) + + for _, privKey := range recipientsPrivKeys { + // test with nil recipient private key + dEnc := NewECDH1PUAEADCompositeDecrypt(nil, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, + compositepb.KeyType_EC) + + _, err = dEnc.Decrypt(ct, aad) + require.EqualError(t, err, "ECDH1PUAEADCompositeDecrypt: missing recipient private key for key"+ + " unwrapping") + + // test with large key size + mEncHelper.KeySizeValue = 100 + dEnc = NewECDH1PUAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, + compositepb.KeyType_EC) + + _, err = dEnc.Decrypt(ct, aad) + require.EqualError(t, err, "ecdh-es decrypt: cek unwrap failed for all recipients keys") + + mEncHelper.KeySizeValue = 32 + + // test with GetAEAD() returning error + mEncHelper.AEADErrValue = fmt.Errorf("error from GetAEAD") + + dEnc = NewECDH1PUAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, + compositepb.KeyType_EC) + + _, err = dEnc.Decrypt(ct, aad) + require.EqualError(t, err, "error from GetAEAD") + + mEncHelper.AEADErrValue = nil + + // create a valid Decrypt message and test against ct + dEnc = NewECDH1PUAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, + compositepb.KeyType_EC) + + // try decrypting empty ct + _, err = dEnc.Decrypt([]byte{}, aad) + require.EqualError(t, err, "unexpected end of JSON input") + + // try decrypting with empty encAlg + var encData composite.EncryptedData + err = json.Unmarshal(ct, &encData) + require.NoError(t, err) + + encData.EncAlg = "" + + emptyAlgCiphertext, err := json.Marshal(encData) + require.NoError(t, err) + + _, err = dEnc.Decrypt(emptyAlgCiphertext, aad) + require.EqualError(t, err, "invalid content encryption algorihm '' for Decrypt()") + + // finally try successful decrypt + dpt, err := dEnc.Decrypt(ct, aad) + require.NoError(t, err) + require.EqualValues(t, pt, dpt) + } +} + +func TestEncryptDecryptWithSingleRecipient(t *testing.T) { + recipientsPrivKeys, recipientsPubKeys := buildRecipientsKeys(t, 1) + aeadPrimitive := getAEADPrimitive(t, aead.AES256GCMKeyTemplate()) + + mEncHelper := &MockEncHelper{ + KeySizeValue: 32, + AEADValue: aeadPrimitive, + TagSizeValue: subtleaead.AESGCMTagSize, + IVSizeValue: subtleaead.AESGCMIVSize, + } + + pt := []byte("secret message") + aad := []byte("aad message") + + // test with single recipient public key + cEnc := NewECDH1PUAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), + mEncHelper, compositepb.KeyType_EC) + + // Encrypt should fail with aad not base64URL encoded + _, err := cEnc.Encrypt(pt, aad) + require.EqualError(t, err, "illegal base64 data at input byte 3") + + newAAD := base64.RawURLEncoding.EncodeToString(aad) + + // Encrypt should fail with aad not being a marshalled json + _, err = cEnc.Encrypt(pt, []byte(newAAD)) + require.EqualError(t, err, "invalid character 'a' looking for beginning of value") + + newAAD = base64.RawURLEncoding.EncodeToString([]byte("{\"enc\":\"testAlg\"}")) + + // Encrypt should pass with base64Url encoded a valid json marshaled aad + ct, err := cEnc.Encrypt(pt, []byte(newAAD)) + require.NoError(t, err) + + encData := &composite.EncryptedData{} + err = json.Unmarshal(ct, encData) + require.NoError(t, err) + + for _, privKey := range recipientsPrivKeys { + dEnc := NewECDH1PUAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, + compositepb.KeyType_EC) + + dpt, err := dEnc.Decrypt(ct, encData.SingleRecipientAAD) + require.NoError(t, err) + require.EqualValues(t, pt, dpt) + } +} + +func buildRecipientsKeys(t *testing.T, nbOfRecipients int) ([]*hybrid.ECPrivateKey, []*composite.PublicKey) { + t.Helper() + + var ( + recipientsECPrivKeys []*hybrid.ECPrivateKey + recipientsPubKeys []*composite.PublicKey + ) + + curvProto := commonpb.EllipticCurveType_NIST_P256 + curve, err := hybrid.GetCurve(curvProto.String()) + require.NoError(t, err) + + for i := 0; i < nbOfRecipients; i++ { + recipientPriv, err := hybrid.GenerateECDHKeyPair(curve) + require.NoError(t, err) + + recipientPub := &recipientPriv.PublicKey + + recipientsECPrivKeys = append(recipientsECPrivKeys, recipientPriv) + recipientsPubKeys = append(recipientsPubKeys, &composite.PublicKey{ + Type: compositepb.KeyType_EC.String(), + Curve: recipientPub.Curve.Params().Name, + X: recipientPub.Point.X.Bytes(), + Y: recipientPub.Point.Y.Bytes(), + }) + } + + return recipientsECPrivKeys, recipientsPubKeys +} + +func getAEADPrimitive(t *testing.T, kt *tinkpb.KeyTemplate) tink.AEAD { + t.Helper() + + kh, err := keyset.NewHandle(kt) + require.NoError(t, err) + + ps, err := kh.Primitives() + require.NoError(t, err) + + p, ok := (ps.Primary.Primitive).(tink.AEAD) + require.True(t, ok) + + return p +} + +// MockEncHelper an mocked AEAD helper of Composite Encrypt/Decrypt primitives +type MockEncHelper struct { + KeySizeValue int + AEADValue tink.AEAD + AEADErrValue error + TagSizeValue int + IVSizeValue int +} + +// GetSymmetricKeySize gives the size of the Encryption key (CEK) in bytes +func (me *MockEncHelper) GetSymmetricKeySize() int { + return me.KeySizeValue +} + +// GetAEAD returns the newly created AEAD primitive used for the content Encryption +func (me *MockEncHelper) GetAEAD(symmetricKeyValue []byte) (tink.AEAD, error) { + return me.AEADValue, me.AEADErrValue +} + +// GetTagSize provides the aead primitive tag size +func (me *MockEncHelper) GetTagSize() int { + return me.TagSizeValue +} + +// GetIVSize provides the aead primitive nonce size +func (me *MockEncHelper) GetIVSize() int { + return me.IVSizeValue +} + +func TestMergeSingleRecipientsHeadersFailureWithUnsetCurve(t *testing.T) { + aad := map[string]string{"enc": "test"} + + mAAD, err := json.Marshal(aad) + require.NoError(t, err) + + wk := &composite.RecipientWrappedKey{ + EPK: composite.PublicKey{}, + } + + cEnc := NewECDH1PUAEADCompositeEncrypt(nil, "", nil, 0) + + // fail with epk curve not set + _, err = cEnc.mergeSingleRecipientHeaders(wk, []byte(base64.RawURLEncoding.EncodeToString(mAAD))) + require.EqualError(t, err, "unsupported curve") + + // set epk curve for subsequent tests + wk.EPK.Curve = elliptic.P256().Params().Name + + fm := &failingMarshaller{ + numTimesMarshalCalledBeforeReturnErr: 0, + } + + cEnc.marshalFunc = fm.failingMarshal + + // fail KID marshalling + _, err = cEnc.mergeSingleRecipientHeaders(wk, []byte(base64.RawURLEncoding.EncodeToString(mAAD))) + require.EqualError(t, err, errFailingMarshal.Error()) + + fm = &failingMarshaller{ + numTimesMarshalCalledBeforeReturnErr: 1, + } + + cEnc.marshalFunc = fm.failingMarshal + + // fail Alg marshalling + _, err = cEnc.mergeSingleRecipientHeaders(wk, []byte(base64.RawURLEncoding.EncodeToString(mAAD))) + require.EqualError(t, err, errFailingMarshal.Error()) + + fm = &failingMarshaller{ + numTimesMarshalCalledBeforeReturnErr: 2, + } + + cEnc.marshalFunc = fm.failingMarshal + // fail EPK marshalling + _, err = cEnc.mergeSingleRecipientHeaders(wk, []byte(base64.RawURLEncoding.EncodeToString(mAAD))) + require.EqualError(t, err, errFailingMarshal.Error()) +} + +var errFailingMarshal = fmt.Errorf("json marshal error") + +type failingMarshaller struct { + numTimesMarshalCalled int + numTimesMarshalCalledBeforeReturnErr int +} + +func (m *failingMarshaller) failingMarshal(v interface{}) ([]byte, error) { + if m.numTimesMarshalCalled == m.numTimesMarshalCalledBeforeReturnErr { + return nil, errFailingMarshal + } + + m.numTimesMarshalCalled++ + + return nil, nil +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdhes_1pukdf_recipient_kuw.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdhes_1pukdf_recipient_kuw.go new file mode 100644 index 0000000000..498bf836c3 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdhes_1pukdf_recipient_kuw.go @@ -0,0 +1,65 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package subtle + +import ( + "crypto/aes" + "crypto/ecdsa" + "fmt" + "math/big" + + hybrid "github.com/google/tink/go/hybrid/subtle" + josecipher "github.com/square/go-jose/v3/cipher" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" +) + +// ECDH1PUConcatKDFRecipientKW represents concat KDF based ECDH-1PU (One-Pass Unified Model) KW (key wrapping) +// for ECDH-1PU recipient's unwrapping of CEK +type ECDH1PUConcatKDFRecipientKW struct { + recipientPrivateKey *hybrid.ECPrivateKey +} + +// unwrapKey will do ECDH-ES key unwrapping +func (s *ECDH1PUConcatKDFRecipientKW) unwrapKey(recWK *composite.RecipientWrappedKey, keySize int) ([]byte, error) { + if recWK == nil { + return nil, fmt.Errorf("unwrapKey: RecipientWrappedKey is empty") + } + + // TODO: add support for 25519 key wrapping https://github.com/hyperledger/aries-framework-go/issues/1637 + + recPrivKey := &ecdsa.PrivateKey{ + PublicKey: ecdsa.PublicKey{ + Curve: s.recipientPrivateKey.PublicKey.Curve, + X: s.recipientPrivateKey.PublicKey.Point.X, + Y: s.recipientPrivateKey.PublicKey.Point.Y, + }, + D: s.recipientPrivateKey.D, + } + + epkCurve, err := hybrid.GetCurve(recWK.EPK.Curve) + if err != nil { + return nil, err + } + + epkPubKey := &ecdsa.PublicKey{ + Curve: epkCurve, + X: new(big.Int).SetBytes(recWK.EPK.X), + Y: new(big.Int).SetBytes(recWK.EPK.Y), + } + + // TODO replace below calls with new 1PU key derivation algorithm + // DeriveECDHES checks if keys are on the same curve + kek := josecipher.DeriveECDHES(recWK.Alg, []byte{}, []byte{}, recPrivKey, epkPubKey, keySize) + + block, err := aes.NewCipher(kek) + if err != nil { + return nil, err + } + + return josecipher.KeyUnwrap(block, recWK.EncryptedCEK) +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdhes_1pukdf_sender_kw.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdhes_1pukdf_sender_kw.go new file mode 100644 index 0000000000..e059c74fa2 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdh1pu/subtle/ecdhes_1pukdf_sender_kw.go @@ -0,0 +1,77 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package subtle + +import ( + "crypto/aes" + "crypto/ecdsa" + "crypto/rand" + "math/big" + + hybrid "github.com/google/tink/go/hybrid/subtle" + josecipher "github.com/square/go-jose/v3/cipher" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" +) + +// A256KWAlg is the ECDH-1PU key wrapping algorithm +const A256KWAlg = "ECDH-1PU+A256KW" + +// ECDH1PUConcatKDFSenderKW represents concat KDF based ECDH-1PU KW (key wrapping) +// for ECDH-1PU sender +type ECDH1PUConcatKDFSenderKW struct { + recipientPublicKey *composite.PublicKey + cek []byte +} + +// wrapKey will do ECDH-1PU key wrapping +func (s *ECDH1PUConcatKDFSenderKW) wrapKey(kwAlg string, keySize int) (*composite.RecipientWrappedKey, error) { + // TODO: add support for 25519 key wrapping https://github.com/hyperledger/aries-framework-go/issues/1637 + keyType := commonpb.KeyType_EC.String() + + c, err := hybrid.GetCurve(s.recipientPublicKey.Curve) + if err != nil { + return nil, err + } + + recPubKey := &ecdsa.PublicKey{ + Curve: c, + X: new(big.Int).SetBytes(s.recipientPublicKey.X), + Y: new(big.Int).SetBytes(s.recipientPublicKey.Y), + } + + ephemeralPriv, err := ecdsa.GenerateKey(recPubKey.Curve, rand.Reader) + if err != nil { + return nil, err + } + + // TODO replace below key derivation/wrapping with 1PU algorithm + kek := josecipher.DeriveECDHES(kwAlg, []byte{}, []byte{}, ephemeralPriv, recPubKey, keySize) + + block, err := aes.NewCipher(kek) + if err != nil { + return nil, err + } + + wk, err := josecipher.KeyWrap(block, s.cek) + if err != nil { + return nil, err + } + + return &composite.RecipientWrappedKey{ + KID: s.recipientPublicKey.KID, + EncryptedCEK: wk, + EPK: composite.PublicKey{ + X: ephemeralPriv.PublicKey.X.Bytes(), + Y: ephemeralPriv.PublicKey.Y.Bytes(), + Curve: ephemeralPriv.PublicKey.Curve.Params().Name, + Type: keyType, + }, + Alg: kwAlg, + }, nil +} diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_private_key_manager.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_private_key_manager.go index 814c2427f6..20583dcb32 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_private_key_manager.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_private_key_manager.go @@ -17,6 +17,7 @@ import ( tinkpb "github.com/google/tink/go/proto/tink_go_proto" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" ) @@ -68,7 +69,7 @@ func (km *ecdhesAESPrivateKeyManager) Primitive(serializedKey []byte) (interface ptFormat := key.PublicKey.Params.EcPointFormat.String() - return subtle.NewECDHESAEADCompositeDecrypt(pvt, ptFormat, rEnc, ecdhespb.KeyType_EC), nil + return subtle.NewECDHESAEADCompositeDecrypt(pvt, ptFormat, rEnc, commonpb.KeyType_EC), nil } // NewKey creates a new key according to the specification of ECDHESPrivateKey format. @@ -89,7 +90,7 @@ func (km *ecdhesAESPrivateKeyManager) NewKey(serializedKeyFormat []byte) (proto. return nil, errInvalidECDHESAESPrivateKeyFormat } - keyFormat.Params.KwParams.KeyType = ecdhespb.KeyType_EC + keyFormat.Params.KwParams.KeyType = commonpb.KeyType_EC pvt, err := hybrid.GenerateECDHKeyPair(curve) if err != nil { diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_public_key_manager.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_public_key_manager.go index 79dda1d06b..76e65d9974 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_public_key_manager.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_public_key_manager.go @@ -16,7 +16,9 @@ import ( "github.com/google/tink/go/keyset" tinkpb "github.com/google/tink/go/proto/tink_go_proto" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" ) @@ -58,7 +60,7 @@ func (km *ecdhesPublicKeyManager) Primitive(serializedKey []byte) (interface{}, return nil, errInvalidECDHESAESPublicKey } - var recipientsKeys []*subtle.PublicKey + var recipientsKeys []*composite.PublicKey for _, recKey := range ecdhesPubKey.Params.KwParams.Recipients { e := km.validateRecKey(recKey) @@ -66,7 +68,7 @@ func (km *ecdhesPublicKeyManager) Primitive(serializedKey []byte) (interface{}, return nil, errInvalidECDHESAESPublicKey } - pub := &subtle.PublicKey{ + pub := &composite.PublicKey{ KID: recKey.KID, Type: recKey.KeyType.String(), Curve: recKey.CurveType.String(), @@ -84,7 +86,7 @@ func (km *ecdhesPublicKeyManager) Primitive(serializedKey []byte) (interface{}, ptFormat := ecdhesPubKey.Params.EcPointFormat.String() - return subtle.NewECDHESAEADCompositeEncrypt(recipientsKeys, ptFormat, rEnc, ecdhespb.KeyType_EC), nil + return subtle.NewECDHESAEADCompositeEncrypt(recipientsKeys, ptFormat, rEnc, commonpb.KeyType_EC), nil } // DoesSupport indicates if this key manager supports the given key type. diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_public_key_manager_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_public_key_manager_test.go index 173a68b399..595c1950fb 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_public_key_manager_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_aes_aead_public_key_manager_test.go @@ -20,6 +20,7 @@ import ( tinkpb "github.com/google/tink/go/proto/tink_go_proto" "github.com/stretchr/testify/require" + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" ) @@ -216,21 +217,21 @@ func generateRecipients(t *testing.T) []*ecdhespb.EcdhesAeadRecipientPublicKey { return []*ecdhespb.EcdhesAeadRecipientPublicKey{ { Version: 0, - KeyType: ecdhespb.KeyType_EC, + KeyType: compositepb.KeyType_EC, CurveType: curvProto, X: recipient1Priv.PublicKey.Point.X.Bytes(), Y: recipient1Priv.PublicKey.Point.Y.Bytes(), }, { Version: 0, - KeyType: ecdhespb.KeyType_EC, + KeyType: compositepb.KeyType_EC, CurveType: curvProto, X: recipient2Priv.PublicKey.Point.X.Bytes(), Y: recipient2Priv.PublicKey.Point.Y.Bytes(), }, { Version: 0, - KeyType: ecdhespb.KeyType_EC, + KeyType: compositepb.KeyType_EC, CurveType: curvProto, X: recipient3Priv.PublicKey.Point.X.Bytes(), Y: recipient3Priv.PublicKey.Point.Y.Bytes(), diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_common.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_common.go index 6273c10c3b..70ef84ff93 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_common.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_common.go @@ -11,7 +11,7 @@ import ( commonpb "github.com/google/tink/go/proto/common_go_proto" - ecdhesaeadpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ) // GetCurveType is a utility function that converts a string EC curve name into an EC curve proto type @@ -29,12 +29,12 @@ func GetCurveType(curve string) (commonpb.EllipticCurveType, error) { } // GetKeyType is a utility function that converts a string type value into an proto KeyType -func GetKeyType(keyType string) (ecdhesaeadpb.KeyType, error) { +func GetKeyType(keyType string) (compositepb.KeyType, error) { switch keyType { case "EC": - return ecdhesaeadpb.KeyType_EC, nil + return compositepb.KeyType_EC, nil case "OKP": - return ecdhesaeadpb.KeyType_OKP, nil + return compositepb.KeyType_OKP, nil default: return 0, fmt.Errorf("key type %s not supported", keyType) } diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_common_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_common_test.go index 0d5a69d4c6..0a80476cdf 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_common_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_common_test.go @@ -12,7 +12,7 @@ import ( commonpb "github.com/google/tink/go/proto/common_go_proto" "github.com/stretchr/testify/require" - ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ) func TestGetCurveType(t *testing.T) { @@ -124,25 +124,25 @@ func TestGetKeyType(t *testing.T) { tcs := []struct { tcName string keyType string - expectedType ecdhespb.KeyType + expectedType compositepb.KeyType isError bool }{ { "test get EC KeyType", "EC", - ecdhespb.KeyType_EC, + compositepb.KeyType_EC, false, }, { "test get OKP KeyType", "OKP", - ecdhespb.KeyType_OKP, + compositepb.KeyType_OKP, false, }, { "test get bad KeyType", "bad", - ecdhespb.KeyType_UNKNOWN_KEY_TYPE, + compositepb.KeyType_UNKNOWN_KEY_TYPE, true, }, } diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_factory_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_factory_test.go index 389e4f7d0e..d7828bdf4d 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_factory_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_factory_test.go @@ -25,7 +25,8 @@ import ( "github.com/google/tink/go/testutil" "github.com/stretchr/testify/require" - "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" ) @@ -88,7 +89,7 @@ func TestECDHESFactory(t *testing.T) { require.NoError(t, err) // encrypt for single recipient will generate new AAD for recipient, extract it from ct - encData := &subtle.EncryptedData{} + encData := &composite.EncryptedData{} err = json.Unmarshal(ct, encData) require.NoError(t, err) @@ -112,7 +113,7 @@ func ecdhesAEADPublicKey(t *testing.T, c commonpb.EllipticCurveType, ptfmt commo // add recipients for Encryption primitive Recipients: []*ecdhespb.EcdhesAeadRecipientPublicKey{ { - KeyType: ecdhespb.KeyType_EC, + KeyType: compositepb.KeyType_EC, CurveType: c, X: x, Y: y, diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_export.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_export.go index c0335582a4..fb0875c9a1 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_export.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_export.go @@ -15,7 +15,8 @@ import ( hybrid "github.com/google/tink/go/hybrid/subtle" tinkpb "github.com/google/tink/go/proto/tink_go_proto" - ecdhessubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" ) @@ -86,7 +87,7 @@ func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, error) { keyTypeName := pubKeyProto.Params.KwParams.KeyType.String() // validate key type - if pubKeyProto.Params.KwParams.KeyType != ecdhespb.KeyType_EC { + if pubKeyProto.Params.KwParams.KeyType != commonpb.KeyType_EC { return false, fmt.Errorf("undefined key type: '%s'", pubKeyProto.Params.KwParams.KeyType) } @@ -96,7 +97,7 @@ func writePubKey(w io.Writer, key *tinkpb.Keyset_Key) (bool, error) { return false, fmt.Errorf("undefined curve: %w", err) } - pubKey := ecdhessubtle.PublicKey{ + pubKey := composite.PublicKey{ KID: pubKeyProto.KID, Type: keyTypeName, Curve: curveName, diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_pubkey_to_handle.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_pubkey_to_handle.go index 38b382bb70..09d6daef48 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_pubkey_to_handle.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_pubkey_to_handle.go @@ -17,7 +17,7 @@ import ( commonpb "github.com/google/tink/go/proto/common_go_proto" tinkpb "github.com/google/tink/go/proto/tink_go_proto" - ecdhessubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" ) @@ -77,7 +77,7 @@ func getMarshalledProtoKeyAndKeyURL(pubKey []byte) ([]byte, string, error) { } func getMarshalledECDHESKey(pubKey []byte) ([]byte, error) { - ecPubKey := new(ecdhessubtle.PublicKey) + ecPubKey := new(composite.PublicKey) err := json.Unmarshal(pubKey, ecPubKey) if err != nil { @@ -93,7 +93,7 @@ func getMarshalledECDHESKey(pubKey []byte) ([]byte, error) { } } -func getMarshalledECKey(ecPubKey *ecdhessubtle.PublicKey) ([]byte, error) { +func getMarshalledECKey(ecPubKey *composite.PublicKey) ([]byte, error) { keyType, err := GetKeyType(ecPubKey.Type) if err != nil { return nil, fmt.Errorf("error on key type: %w", err) diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_template.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_template.go index 401b31b6b6..eec921dc7d 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_template.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_template.go @@ -12,7 +12,8 @@ import ( commonpb "github.com/google/tink/go/proto/common_go_proto" tinkpb "github.com/google/tink/go/proto/tink_go_proto" - "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" ) @@ -24,23 +25,23 @@ import ( // Keys from this template represent a valid recipient public/private key pairs and can be stored in the KMS func ECDHES256KWAES256GCMKeyTemplate() *tinkpb.KeyTemplate { return createKeyTemplate(commonpb.EllipticCurveType_NIST_P256, commonpb.EcPointFormat_UNCOMPRESSED, - aead.AES256GCMKeyTemplate(), tinkpb.OutputPrefixType_RAW, nil, ecdhespb.KeyType_EC) + aead.AES256GCMKeyTemplate(), tinkpb.OutputPrefixType_RAW, nil, compositepb.KeyType_EC) } // ECDHES256KWAES256GCMKeyTemplateWithRecipients is similar to ECDHES256KWAES256GCMKeyTemplate but adding recipients // keys to execute the CompositeEncrypt primitive for encrypting a message targeted to one ore more recipients. // Keys from this template offer valid CompositeEncrypt primitive execution only and should not be stored in the KMS -func ECDHES256KWAES256GCMKeyTemplateWithRecipients(recPublicKeys []subtle.PublicKey) (*tinkpb.KeyTemplate, error) { +func ECDHES256KWAES256GCMKeyTemplateWithRecipients(recPublicKeys []composite.PublicKey) (*tinkpb.KeyTemplate, error) { ecdhesRecipientKeys, err := createECDHESPublicKeys(recPublicKeys) if err != nil { return nil, err } return createKeyTemplate(commonpb.EllipticCurveType_NIST_P256, commonpb.EcPointFormat_UNCOMPRESSED, - aead.AES256GCMKeyTemplate(), tinkpb.OutputPrefixType_RAW, ecdhesRecipientKeys, ecdhespb.KeyType_EC), nil + aead.AES256GCMKeyTemplate(), tinkpb.OutputPrefixType_RAW, ecdhesRecipientKeys, compositepb.KeyType_EC), nil } -func createECDHESPublicKeys(recRawPublicKeys []subtle.PublicKey) ([]*ecdhespb.EcdhesAeadRecipientPublicKey, error) { +func createECDHESPublicKeys(recRawPublicKeys []composite.PublicKey) ([]*ecdhespb.EcdhesAeadRecipientPublicKey, error) { var recKeys []*ecdhespb.EcdhesAeadRecipientPublicKey for _, key := range recRawPublicKeys { @@ -75,7 +76,7 @@ func createECDHESPublicKeys(recRawPublicKeys []subtle.PublicKey) ([]*ecdhespb.Ec // size in bytes. func createKeyTemplate(c commonpb.EllipticCurveType, epf commonpb.EcPointFormat, contentEncKeyT *tinkpb.KeyTemplate, prefixType tinkpb.OutputPrefixType, recipients []*ecdhespb.EcdhesAeadRecipientPublicKey, - keyType ecdhespb.KeyType) *tinkpb.KeyTemplate { + keyType compositepb.KeyType) *tinkpb.KeyTemplate { format := &ecdhespb.EcdhesAeadKeyFormat{ Params: &ecdhespb.EcdhesAeadParams{ KwParams: &ecdhespb.EcdhesKwParams{ diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_template_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_template_test.go index 2b5100160e..6728a86ae3 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_template_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/ecdhes_key_template_test.go @@ -14,7 +14,7 @@ import ( "github.com/google/tink/go/keyset" "github.com/stretchr/testify/require" - ecdhessubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" ) func TestECDHESKeyTemplateTest(t *testing.T) { @@ -50,17 +50,17 @@ func TestECDHESKeyTemplateTest(t *testing.T) { } // createRecipients and return their public key and keyset.Handle -func createRecipients(t *testing.T, numberOfRecipients int) ([]ecdhessubtle.PublicKey, []*keyset.Handle) { +func createRecipients(t *testing.T, numberOfRecipients int) ([]composite.PublicKey, []*keyset.Handle) { t.Helper() var ( - r []ecdhessubtle.PublicKey + r []composite.PublicKey rKH []*keyset.Handle ) for i := 0; i < numberOfRecipients; i++ { mrKey, kh := createAndMarshalRecipient(t) - ecPubKey := new(ecdhessubtle.PublicKey) + ecPubKey := new(composite.PublicKey) err := json.Unmarshal(mrKey, ecPubKey) require.NoError(t, err) diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_decrypt.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_decrypt.go index 175f1fa073..bf7b80cae9 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_decrypt.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_decrypt.go @@ -12,22 +12,26 @@ import ( hybrid "github.com/google/tink/go/hybrid/subtle" - ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ) +// package subtle provides the core crypto primitives to be used by ECDH-ES composite primitives. It is intended for +// internal use only. + // ECDHESAEADCompositeDecrypt is an instance of ECDH-ES decryption with Concat KDF // and AEAD content decryption type ECDHESAEADCompositeDecrypt struct { privateKey *hybrid.ECPrivateKey pointFormat string encHelper EncrypterHelper - keyType ecdhespb.KeyType + keyType commonpb.KeyType } // NewECDHESAEADCompositeDecrypt returns ECDH-ES composite decryption construct with Concat KDF/ECDH-ES key unwrapping // and AEAD payload decryption. func NewECDHESAEADCompositeDecrypt(pvt *hybrid.ECPrivateKey, ptFormat string, encHelper EncrypterHelper, - keyType ecdhespb.KeyType) *ECDHESAEADCompositeDecrypt { + keyType commonpb.KeyType) *ECDHESAEADCompositeDecrypt { return &ECDHESAEADCompositeDecrypt{ privateKey: pvt, pointFormat: ptFormat, @@ -46,7 +50,7 @@ func (d *ECDHESAEADCompositeDecrypt) Decrypt(ciphertext, aad []byte) ([]byte, er var cek []byte - encData := new(EncryptedData) + encData := new(composite.EncryptedData) err := json.Unmarshal(ciphertext, encData) if err != nil { @@ -55,7 +59,7 @@ func (d *ECDHESAEADCompositeDecrypt) Decrypt(ciphertext, aad []byte) ([]byte, er // TODO: add support for Chacha content encryption https://github.com/hyperledger/aries-framework-go/issues/1684 switch d.keyType { - case ecdhespb.KeyType_EC: + case commonpb.KeyType_EC: if encData.EncAlg != A256GCM { return nil, fmt.Errorf("invalid content encryption algorihm '%s' for Decrypt()", encData.EncAlg) } diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_encrypt.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_encrypt.go index 20763ddef4..67b082b10a 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_encrypt.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_encrypt.go @@ -18,8 +18,9 @@ import ( "github.com/google/tink/go/subtle/random" "github.com/square/go-jose/v3" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/api" - ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ) // A256GCM is the default content encryption algorithm value as per @@ -31,10 +32,10 @@ type marshalFunc func(interface{}) ([]byte, error) // ECDHESAEADCompositeEncrypt is an instance of ECDH-ES encryption with Concat KDF // and AEAD content encryption type ECDHESAEADCompositeEncrypt struct { - recPublicKeys []*PublicKey + recPublicKeys []*composite.PublicKey pointFormat string encHelper EncrypterHelper - keyType ecdhespb.KeyType + keyType commonpb.KeyType marshalFunc marshalFunc } @@ -42,8 +43,8 @@ var _ api.CompositeEncrypt = (*ECDHESAEADCompositeEncrypt)(nil) // NewECDHESAEADCompositeEncrypt returns ECDH-ES encryption construct with Concat KDF key wrapping // and AEAD content encryption -func NewECDHESAEADCompositeEncrypt(recipientsKeys []*PublicKey, ptFormat string, - encHelper EncrypterHelper, keyType ecdhespb.KeyType) *ECDHESAEADCompositeEncrypt { +func NewECDHESAEADCompositeEncrypt(recipientsKeys []*composite.PublicKey, ptFormat string, + encHelper EncrypterHelper, keyType commonpb.KeyType) *ECDHESAEADCompositeEncrypt { return &ECDHESAEADCompositeEncrypt{ recPublicKeys: recipientsKeys, pointFormat: ptFormat, @@ -63,7 +64,7 @@ func (e *ECDHESAEADCompositeEncrypt) Encrypt(plaintext, aad []byte) ([]byte, err // TODO add chacha alg support too, https://github.com/hyperledger/aries-framework-go/issues/1684 switch e.keyType { - case ecdhespb.KeyType_EC: + case commonpb.KeyType_EC: eAlg = A256GCM kwAlg = A256KWAlg default: @@ -73,7 +74,7 @@ func (e *ECDHESAEADCompositeEncrypt) Encrypt(plaintext, aad []byte) ([]byte, err keySize := e.encHelper.GetSymmetricKeySize() cek := random.GetRandomBytes(uint32(keySize)) - var recipientsWK []*RecipientWrappedKey + var recipientsWK []*composite.RecipientWrappedKey var singleRecipientAAD []byte @@ -114,7 +115,7 @@ func (e *ECDHESAEADCompositeEncrypt) Encrypt(plaintext, aad []byte) ([]byte, err return e.buildEncData(eAlg, recipientsWK, ct, singleRecipientAAD) } -func (e *ECDHESAEADCompositeEncrypt) buildEncData(eAlg string, recipientsWK []*RecipientWrappedKey, +func (e *ECDHESAEADCompositeEncrypt) buildEncData(eAlg string, recipientsWK []*composite.RecipientWrappedKey, ct, singleRecipientAAD []byte) ([]byte, error) { tagSize := e.encHelper.GetTagSize() ivSize := e.encHelper.GetIVSize() @@ -122,7 +123,7 @@ func (e *ECDHESAEADCompositeEncrypt) buildEncData(eAlg string, recipientsWK []*R ctAndTag := ct[ivSize:] tagOffset := len(ctAndTag) - tagSize - encData := &EncryptedData{ + encData := &composite.EncryptedData{ EncAlg: eAlg, Ciphertext: ctAndTag[:tagOffset], IV: iv, @@ -135,7 +136,7 @@ func (e *ECDHESAEADCompositeEncrypt) buildEncData(eAlg string, recipientsWK []*R } // for single recipient encryption, recipient header info is available in the key, update aad with this info -func (e *ECDHESAEADCompositeEncrypt) mergeSingleRecipientHeaders(recipientWK *RecipientWrappedKey, +func (e *ECDHESAEADCompositeEncrypt) mergeSingleRecipientHeaders(recipientWK *composite.RecipientWrappedKey, aad []byte) ([]byte, error) { newAAD, err := base64.RawURLEncoding.DecodeString(string(aad)) if err != nil { @@ -178,7 +179,7 @@ func (e *ECDHESAEADCompositeEncrypt) mergeSingleRecipientHeaders(recipientWK *Re return []byte(base64.RawURLEncoding.EncodeToString(mAAD)), nil } -func convertRecKeyToMarshalledJWK(rec *RecipientWrappedKey) ([]byte, error) { +func convertRecKeyToMarshalledJWK(rec *composite.RecipientWrappedKey) ([]byte, error) { var c elliptic.Curve c, err := hybrid.GetCurve(rec.EPK.Curve) diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_test.go index a345174733..d89de9bb91 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_aes_aead_composite_test.go @@ -22,7 +22,8 @@ import ( "github.com/google/tink/go/tink" "github.com/stretchr/testify/require" - ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ) func TestEncryptDecrypt(t *testing.T) { @@ -37,7 +38,7 @@ func TestEncryptDecrypt(t *testing.T) { } cEnc := NewECDHESAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), - mEncHelper, ecdhespb.KeyType_EC) + mEncHelper, compositepb.KeyType_EC) pt := []byte("secret message") aad := []byte("aad message") @@ -47,7 +48,7 @@ func TestEncryptDecrypt(t *testing.T) { for _, privKey := range recipientsPrivKeys { dEnc := NewECDHESAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, - ecdhespb.KeyType_EC) + compositepb.KeyType_EC) dpt, err := dEnc.Decrypt(ct, aad) require.NoError(t, err) @@ -71,7 +72,7 @@ func TestEncryptDecryptNegativeTCs(t *testing.T) { // test with empty recipients public keys cEnc := NewECDHESAEADCompositeEncrypt(nil, commonpb.EcPointFormat_UNCOMPRESSED.String(), - mEncHelper, ecdhespb.KeyType_EC) + mEncHelper, compositepb.KeyType_EC) // Encrypt should fail with empty recipients public keys _, err := cEnc.Encrypt(pt, aad) @@ -81,7 +82,7 @@ func TestEncryptDecryptNegativeTCs(t *testing.T) { mEncHelper.KeySizeValue = 100 cEnc = NewECDHESAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), - mEncHelper, ecdhespb.KeyType_EC) + mEncHelper, compositepb.KeyType_EC) // Encrypt should fail with large AEAD key size value _, err = cEnc.Encrypt(pt, aad) @@ -90,19 +91,19 @@ func TestEncryptDecryptNegativeTCs(t *testing.T) { mEncHelper.KeySizeValue = 32 // Encrypt should fail with bad key type - cEnc.keyType = ecdhespb.KeyType_UNKNOWN_KEY_TYPE + cEnc.keyType = compositepb.KeyType_UNKNOWN_KEY_TYPE _, err = cEnc.Encrypt(pt, aad) require.EqualError(t, err, fmt.Sprintf("ECDHESAEADCompositeEncrypt: bad key type: '%s'", - ecdhespb.KeyType_UNKNOWN_KEY_TYPE)) + compositepb.KeyType_UNKNOWN_KEY_TYPE)) - cEnc.keyType = ecdhespb.KeyType_EC + cEnc.keyType = compositepb.KeyType_EC // test with GetAEAD() returning error mEncHelper.AEADErrValue = fmt.Errorf("error from GetAEAD") cEnc = NewECDHESAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), - mEncHelper, ecdhespb.KeyType_EC) + mEncHelper, compositepb.KeyType_EC) // Encrypt should fail with large AEAD key size value _, err = cEnc.Encrypt(pt, aad) @@ -112,13 +113,13 @@ func TestEncryptDecryptNegativeTCs(t *testing.T) { // create a valid ciphertext to test Decrypt for all recipients cEnc = NewECDHESAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), - mEncHelper, ecdhespb.KeyType_EC) + mEncHelper, compositepb.KeyType_EC) // test with empty plaintext ct, err := cEnc.Encrypt([]byte{}, aad) require.NoError(t, err) - encData := new(EncryptedData) + encData := new(composite.EncryptedData) err = json.Unmarshal(ct, encData) require.NoError(t, err) @@ -133,7 +134,7 @@ func TestEncryptDecryptNegativeTCs(t *testing.T) { for _, privKey := range recipientsPrivKeys { // test with nil recipient private key dEnc := NewECDHESAEADCompositeDecrypt(nil, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, - ecdhespb.KeyType_EC) + compositepb.KeyType_EC) _, err = dEnc.Decrypt(ct, aad) require.EqualError(t, err, "ECDHESAEADCompositeDecrypt: missing recipient private key for key"+ @@ -142,7 +143,7 @@ func TestEncryptDecryptNegativeTCs(t *testing.T) { // test with large key size mEncHelper.KeySizeValue = 100 dEnc = NewECDHESAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, - ecdhespb.KeyType_EC) + compositepb.KeyType_EC) _, err = dEnc.Decrypt(ct, aad) require.EqualError(t, err, "ecdh-es decrypt: cek unwrap failed for all recipients keys") @@ -153,7 +154,7 @@ func TestEncryptDecryptNegativeTCs(t *testing.T) { mEncHelper.AEADErrValue = fmt.Errorf("error from GetAEAD") dEnc = NewECDHESAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, - ecdhespb.KeyType_EC) + compositepb.KeyType_EC) _, err = dEnc.Decrypt(ct, aad) require.EqualError(t, err, "error from GetAEAD") @@ -162,14 +163,14 @@ func TestEncryptDecryptNegativeTCs(t *testing.T) { // create a valid Decrypt message and test against ct dEnc = NewECDHESAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, - ecdhespb.KeyType_EC) + compositepb.KeyType_EC) // try decrypting empty ct _, err = dEnc.Decrypt([]byte{}, aad) require.EqualError(t, err, "unexpected end of JSON input") // try decrypting with empty encAlg - var encData EncryptedData + var encData composite.EncryptedData err = json.Unmarshal(ct, &encData) require.NoError(t, err) @@ -204,7 +205,7 @@ func TestEncryptDecryptWithSingleRecipient(t *testing.T) { // test with single recipient public key cEnc := NewECDHESAEADCompositeEncrypt(recipientsPubKeys, commonpb.EcPointFormat_UNCOMPRESSED.String(), - mEncHelper, ecdhespb.KeyType_EC) + mEncHelper, compositepb.KeyType_EC) // Encrypt should fail with aad not base64URL encoded _, err := cEnc.Encrypt(pt, aad) @@ -222,13 +223,13 @@ func TestEncryptDecryptWithSingleRecipient(t *testing.T) { ct, err := cEnc.Encrypt(pt, []byte(newAAD)) require.NoError(t, err) - encData := &EncryptedData{} + encData := &composite.EncryptedData{} err = json.Unmarshal(ct, encData) require.NoError(t, err) for _, privKey := range recipientsPrivKeys { dEnc := NewECDHESAEADCompositeDecrypt(privKey, commonpb.EcPointFormat_UNCOMPRESSED.String(), mEncHelper, - ecdhespb.KeyType_EC) + compositepb.KeyType_EC) dpt, err := dEnc.Decrypt(ct, encData.SingleRecipientAAD) require.NoError(t, err) @@ -236,12 +237,12 @@ func TestEncryptDecryptWithSingleRecipient(t *testing.T) { } } -func buildRecipientsKeys(t *testing.T, nbOfRecipients int) ([]*hybrid.ECPrivateKey, []*PublicKey) { +func buildRecipientsKeys(t *testing.T, nbOfRecipients int) ([]*hybrid.ECPrivateKey, []*composite.PublicKey) { t.Helper() var ( recipientsECPrivKeys []*hybrid.ECPrivateKey - recipientsPubKeys []*PublicKey + recipientsPubKeys []*composite.PublicKey ) curvProto := commonpb.EllipticCurveType_NIST_P256 @@ -255,8 +256,8 @@ func buildRecipientsKeys(t *testing.T, nbOfRecipients int) ([]*hybrid.ECPrivateK recipientPub := &recipientPriv.PublicKey recipientsECPrivKeys = append(recipientsECPrivKeys, recipientPriv) - recipientsPubKeys = append(recipientsPubKeys, &PublicKey{ - Type: ecdhespb.KeyType_EC.String(), + recipientsPubKeys = append(recipientsPubKeys, &composite.PublicKey{ + Type: compositepb.KeyType_EC.String(), Curve: recipientPub.Curve.Params().Name, X: recipientPub.Point.X.Bytes(), Y: recipientPub.Point.Y.Bytes(), @@ -316,8 +317,8 @@ func TestMergeSingleRecipientsHeadersFailureWithUnsetCurve(t *testing.T) { mAAD, err := json.Marshal(aad) require.NoError(t, err) - wk := &RecipientWrappedKey{ - EPK: PublicKey{}, + wk := &composite.RecipientWrappedKey{ + EPK: composite.PublicKey{}, } cEnc := NewECDHESAEADCompositeEncrypt(nil, "", nil, 0) diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_kw_test.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_kw_test.go index 63e0b3aacb..dda0cd0016 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_kw_test.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_kw_test.go @@ -14,7 +14,8 @@ import ( "github.com/google/tink/go/subtle/random" "github.com/stretchr/testify/require" - ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + compositepb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ) func TestWrap(t *testing.T) { @@ -25,8 +26,8 @@ func TestWrap(t *testing.T) { recPvt, err := hybrid.GenerateECDHKeyPair(curve) require.NoError(t, err) - recPubKey := &PublicKey{ - Type: ecdhespb.KeyType_EC.String(), + recPubKey := &composite.PublicKey{ + Type: compositepb.KeyType_EC.String(), Curve: recPvt.PublicKey.Curve.Params().Name, X: recPvt.PublicKey.Point.X.Bytes(), Y: recPvt.PublicKey.Point.Y.Bytes(), diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_recipient_kuw.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_recipient_kuw.go index 28bf32d706..81539ffa3e 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_recipient_kuw.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_recipient_kuw.go @@ -14,6 +14,8 @@ import ( hybrid "github.com/google/tink/go/hybrid/subtle" josecipher "github.com/square/go-jose/v3/cipher" + + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" ) // ECDHESConcatKDFRecipientKW represents concat KDF based ECDH-ES KW (key wrapping) @@ -23,7 +25,7 @@ type ECDHESConcatKDFRecipientKW struct { } // unwrapKey will do ECDH-ES key unwrapping -func (s *ECDHESConcatKDFRecipientKW) unwrapKey(recWK *RecipientWrappedKey, keySize int) ([]byte, error) { +func (s *ECDHESConcatKDFRecipientKW) unwrapKey(recWK *composite.RecipientWrappedKey, keySize int) ([]byte, error) { if recWK == nil { return nil, fmt.Errorf("unwrapKey: RecipientWrappedKey is empty") } diff --git a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_sender_kw.go b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_sender_kw.go index 1f9ca32525..bbd7d14683 100644 --- a/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_sender_kw.go +++ b/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle/ecdhes_concatkdf_sender_kw.go @@ -15,7 +15,8 @@ import ( hybrid "github.com/google/tink/go/hybrid/subtle" josecipher "github.com/square/go-jose/v3/cipher" - ecdhespb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" + commonpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" ) // A256KWAlg is the ECDH-ES key wrapping algorithm @@ -24,14 +25,14 @@ const A256KWAlg = "ECDH-ES+A256KW" // ECDHESConcatKDFSenderKW represents concat KDF based ECDH-ES KW (key wrapping) // for ECDH-ES sender type ECDHESConcatKDFSenderKW struct { - recipientPublicKey *PublicKey + recipientPublicKey *composite.PublicKey cek []byte } // wrapKey will do ECDH-ES key wrapping -func (s *ECDHESConcatKDFSenderKW) wrapKey(kwAlg string, keySize int) (*RecipientWrappedKey, error) { +func (s *ECDHESConcatKDFSenderKW) wrapKey(kwAlg string, keySize int) (*composite.RecipientWrappedKey, error) { // TODO: add support for 25519 key wrapping https://github.com/hyperledger/aries-framework-go/issues/1637 - keyType := ecdhespb.KeyType_EC.String() + keyType := commonpb.KeyType_EC.String() c, err := hybrid.GetCurve(s.recipientPublicKey.Curve) if err != nil { @@ -61,10 +62,10 @@ func (s *ECDHESConcatKDFSenderKW) wrapKey(kwAlg string, keySize int) (*Recipient return nil, err } - return &RecipientWrappedKey{ + return &composite.RecipientWrappedKey{ KID: s.recipientPublicKey.KID, EncryptedCEK: wk, - EPK: PublicKey{ + EPK: composite.PublicKey{ X: ephemeralPriv.PublicKey.X.Bytes(), Y: ephemeralPriv.PublicKey.Y.Bytes(), Curve: ephemeralPriv.PublicKey.Curve.Params().Name, diff --git a/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto/common_composite.pb.go b/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto/common_composite.pb.go new file mode 100755 index 0000000000..dd9391f08b --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto/common_composite.pb.go @@ -0,0 +1,73 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: proto/common_composite.proto + +package common_composite_proto + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type KeyType int32 + +const ( + KeyType_UNKNOWN_KEY_TYPE KeyType = 0 + KeyType_EC KeyType = 1 + KeyType_OKP KeyType = 2 +) + +var KeyType_name = map[int32]string{ + 0: "UNKNOWN_KEY_TYPE", + 1: "EC", + 2: "OKP", +} + +var KeyType_value = map[string]int32{ + "UNKNOWN_KEY_TYPE": 0, + "EC": 1, + "OKP": 2, +} + +func (x KeyType) String() string { + return proto.EnumName(KeyType_name, int32(x)) +} + +func (KeyType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_3c0933941e418c01, []int{0} +} + +func init() { + proto.RegisterEnum("google.crypto.tink.KeyType", KeyType_name, KeyType_value) +} + +func init() { proto.RegisterFile("proto/common_composite.proto", fileDescriptor_3c0933941e418c01) } + +var fileDescriptor_3c0933941e418c01 = []byte{ + // 213 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x8f, 0x41, 0x4a, 0x03, 0x31, + 0x14, 0x86, 0x9d, 0x11, 0xa6, 0x90, 0x55, 0x08, 0x2e, 0x7b, 0x02, 0xa1, 0x89, 0xe0, 0x0d, 0x2a, + 0xb3, 0x90, 0x40, 0x9a, 0xc5, 0x88, 0xd4, 0x4d, 0xe8, 0xc4, 0x67, 0x1a, 0xda, 0xf4, 0x85, 0xd7, + 0xa8, 0xe4, 0x10, 0x5e, 0xc2, 0x93, 0x8a, 0x33, 0xee, 0xec, 0xee, 0xbd, 0x0f, 0xbe, 0xff, 0xe7, + 0x67, 0xcb, 0x4c, 0x58, 0x50, 0x79, 0x4c, 0x09, 0x4f, 0xce, 0x63, 0xca, 0x78, 0x8e, 0x05, 0xe4, + 0x84, 0x85, 0x08, 0x88, 0xe1, 0x08, 0xd2, 0x53, 0xcd, 0x05, 0x65, 0x89, 0xa7, 0xc3, 0xed, 0x1d, + 0x5b, 0x68, 0xa8, 0x43, 0xcd, 0x20, 0x6e, 0x18, 0x7f, 0x32, 0xda, 0x6c, 0x9e, 0x8d, 0xd3, 0xfd, + 0xd6, 0x0d, 0x5b, 0xdb, 0xf3, 0x2b, 0xd1, 0xb1, 0xb6, 0x7f, 0xe0, 0x8d, 0x58, 0xb0, 0xeb, 0x8d, + 0xb6, 0xbc, 0x5d, 0x7f, 0x35, 0x6c, 0xe9, 0x31, 0xc9, 0xff, 0x61, 0x73, 0x8d, 0x6d, 0x5e, 0xc6, + 0x10, 0xcb, 0xfe, 0x7d, 0x94, 0x1e, 0x93, 0xda, 0xd7, 0x0c, 0x74, 0x84, 0xd7, 0x00, 0xa4, 0x76, + 0x14, 0xe1, 0xbc, 0x7a, 0xa3, 0x5d, 0x82, 0x4f, 0xa4, 0xc3, 0x2a, 0xa0, 0x9a, 0x75, 0xf5, 0xab, + 0xff, 0x9d, 0x99, 0x62, 0x8a, 0x25, 0x7e, 0x80, 0xba, 0x3c, 0xc6, 0x4d, 0xf8, 0xbb, 0xed, 0x86, + 0x47, 0xa3, 0xed, 0x7a, 0xec, 0xa6, 0xff, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0x0a, 0xe5, 0x85, + 0xe6, 0xfc, 0x00, 0x00, 0x00, +} diff --git a/pkg/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto/ecdh1pu_aead.pb.go b/pkg/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto/ecdh1pu_aead.pb.go new file mode 100755 index 0000000000..ac965afa18 --- /dev/null +++ b/pkg/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto/ecdh1pu_aead.pb.go @@ -0,0 +1,472 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: proto/ecdh1pu_aead.proto + +package ecdh1pu_aead_go_proto + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + common_go_proto "github.com/google/tink/go/proto/common_go_proto" + tink_go_proto "github.com/google/tink/go/proto/tink_go_proto" + math "math" + + common_composite_go_proto "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type Ecdh1PuKwParams struct { + CurveType common_go_proto.EllipticCurveType `protobuf:"varint,1,opt,name=curve_type,json=curveType,proto3,enum=google.crypto.tink.EllipticCurveType" json:"curve_type,omitempty"` + KeyType common_composite_go_proto.KeyType `protobuf:"varint,2,opt,name=key_type,json=keyType,proto3,enum=google.crypto.tink.KeyType" json:"key_type,omitempty"` + Recipients []*Ecdh1PuAeadRecipientPublicKey `protobuf:"bytes,3,rep,name=recipients,proto3" json:"recipients,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ecdh1PuKwParams) Reset() { *m = Ecdh1PuKwParams{} } +func (m *Ecdh1PuKwParams) String() string { return proto.CompactTextString(m) } +func (*Ecdh1PuKwParams) ProtoMessage() {} +func (*Ecdh1PuKwParams) Descriptor() ([]byte, []int) { + return fileDescriptor_a77c865180c47e23, []int{0} +} + +func (m *Ecdh1PuKwParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ecdh1PuKwParams.Unmarshal(m, b) +} +func (m *Ecdh1PuKwParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ecdh1PuKwParams.Marshal(b, m, deterministic) +} +func (m *Ecdh1PuKwParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ecdh1PuKwParams.Merge(m, src) +} +func (m *Ecdh1PuKwParams) XXX_Size() int { + return xxx_messageInfo_Ecdh1PuKwParams.Size(m) +} +func (m *Ecdh1PuKwParams) XXX_DiscardUnknown() { + xxx_messageInfo_Ecdh1PuKwParams.DiscardUnknown(m) +} + +var xxx_messageInfo_Ecdh1PuKwParams proto.InternalMessageInfo + +func (m *Ecdh1PuKwParams) GetCurveType() common_go_proto.EllipticCurveType { + if m != nil { + return m.CurveType + } + return common_go_proto.EllipticCurveType_UNKNOWN_CURVE +} + +func (m *Ecdh1PuKwParams) GetKeyType() common_composite_go_proto.KeyType { + if m != nil { + return m.KeyType + } + return common_composite_go_proto.KeyType_UNKNOWN_KEY_TYPE +} + +func (m *Ecdh1PuKwParams) GetRecipients() []*Ecdh1PuAeadRecipientPublicKey { + if m != nil { + return m.Recipients + } + return nil +} + +type Ecdh1PuAeadEncParams struct { + AeadEnc *tink_go_proto.KeyTemplate `protobuf:"bytes,1,opt,name=aead_enc,json=aeadEnc,proto3" json:"aead_enc,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ecdh1PuAeadEncParams) Reset() { *m = Ecdh1PuAeadEncParams{} } +func (m *Ecdh1PuAeadEncParams) String() string { return proto.CompactTextString(m) } +func (*Ecdh1PuAeadEncParams) ProtoMessage() {} +func (*Ecdh1PuAeadEncParams) Descriptor() ([]byte, []int) { + return fileDescriptor_a77c865180c47e23, []int{1} +} + +func (m *Ecdh1PuAeadEncParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ecdh1PuAeadEncParams.Unmarshal(m, b) +} +func (m *Ecdh1PuAeadEncParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ecdh1PuAeadEncParams.Marshal(b, m, deterministic) +} +func (m *Ecdh1PuAeadEncParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ecdh1PuAeadEncParams.Merge(m, src) +} +func (m *Ecdh1PuAeadEncParams) XXX_Size() int { + return xxx_messageInfo_Ecdh1PuAeadEncParams.Size(m) +} +func (m *Ecdh1PuAeadEncParams) XXX_DiscardUnknown() { + xxx_messageInfo_Ecdh1PuAeadEncParams.DiscardUnknown(m) +} + +var xxx_messageInfo_Ecdh1PuAeadEncParams proto.InternalMessageInfo + +func (m *Ecdh1PuAeadEncParams) GetAeadEnc() *tink_go_proto.KeyTemplate { + if m != nil { + return m.AeadEnc + } + return nil +} + +type Ecdh1PuAeadParams struct { + KwParams *Ecdh1PuKwParams `protobuf:"bytes,1,opt,name=kw_params,json=kwParams,proto3" json:"kw_params,omitempty"` + EncParams *Ecdh1PuAeadEncParams `protobuf:"bytes,2,opt,name=enc_params,json=encParams,proto3" json:"enc_params,omitempty"` + EcPointFormat common_go_proto.EcPointFormat `protobuf:"varint,3,opt,name=ec_point_format,json=ecPointFormat,proto3,enum=google.crypto.tink.EcPointFormat" json:"ec_point_format,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ecdh1PuAeadParams) Reset() { *m = Ecdh1PuAeadParams{} } +func (m *Ecdh1PuAeadParams) String() string { return proto.CompactTextString(m) } +func (*Ecdh1PuAeadParams) ProtoMessage() {} +func (*Ecdh1PuAeadParams) Descriptor() ([]byte, []int) { + return fileDescriptor_a77c865180c47e23, []int{2} +} + +func (m *Ecdh1PuAeadParams) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ecdh1PuAeadParams.Unmarshal(m, b) +} +func (m *Ecdh1PuAeadParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ecdh1PuAeadParams.Marshal(b, m, deterministic) +} +func (m *Ecdh1PuAeadParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ecdh1PuAeadParams.Merge(m, src) +} +func (m *Ecdh1PuAeadParams) XXX_Size() int { + return xxx_messageInfo_Ecdh1PuAeadParams.Size(m) +} +func (m *Ecdh1PuAeadParams) XXX_DiscardUnknown() { + xxx_messageInfo_Ecdh1PuAeadParams.DiscardUnknown(m) +} + +var xxx_messageInfo_Ecdh1PuAeadParams proto.InternalMessageInfo + +func (m *Ecdh1PuAeadParams) GetKwParams() *Ecdh1PuKwParams { + if m != nil { + return m.KwParams + } + return nil +} + +func (m *Ecdh1PuAeadParams) GetEncParams() *Ecdh1PuAeadEncParams { + if m != nil { + return m.EncParams + } + return nil +} + +func (m *Ecdh1PuAeadParams) GetEcPointFormat() common_go_proto.EcPointFormat { + if m != nil { + return m.EcPointFormat + } + return common_go_proto.EcPointFormat_UNKNOWN_FORMAT +} + +type Ecdh1PuAeadPublicKey struct { + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + Params *Ecdh1PuAeadParams `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` + KID string `protobuf:"bytes,3,opt,name=KID,proto3" json:"KID,omitempty"` + X []byte `protobuf:"bytes,4,opt,name=x,proto3" json:"x,omitempty"` + Y []byte `protobuf:"bytes,5,opt,name=y,proto3" json:"y,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ecdh1PuAeadPublicKey) Reset() { *m = Ecdh1PuAeadPublicKey{} } +func (m *Ecdh1PuAeadPublicKey) String() string { return proto.CompactTextString(m) } +func (*Ecdh1PuAeadPublicKey) ProtoMessage() {} +func (*Ecdh1PuAeadPublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_a77c865180c47e23, []int{3} +} + +func (m *Ecdh1PuAeadPublicKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ecdh1PuAeadPublicKey.Unmarshal(m, b) +} +func (m *Ecdh1PuAeadPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ecdh1PuAeadPublicKey.Marshal(b, m, deterministic) +} +func (m *Ecdh1PuAeadPublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ecdh1PuAeadPublicKey.Merge(m, src) +} +func (m *Ecdh1PuAeadPublicKey) XXX_Size() int { + return xxx_messageInfo_Ecdh1PuAeadPublicKey.Size(m) +} +func (m *Ecdh1PuAeadPublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_Ecdh1PuAeadPublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_Ecdh1PuAeadPublicKey proto.InternalMessageInfo + +func (m *Ecdh1PuAeadPublicKey) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *Ecdh1PuAeadPublicKey) GetParams() *Ecdh1PuAeadParams { + if m != nil { + return m.Params + } + return nil +} + +func (m *Ecdh1PuAeadPublicKey) GetKID() string { + if m != nil { + return m.KID + } + return "" +} + +func (m *Ecdh1PuAeadPublicKey) GetX() []byte { + if m != nil { + return m.X + } + return nil +} + +func (m *Ecdh1PuAeadPublicKey) GetY() []byte { + if m != nil { + return m.Y + } + return nil +} + +type Ecdh1PuAeadPrivateKey struct { + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + PublicKey *Ecdh1PuAeadPublicKey `protobuf:"bytes,2,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` + KeyValue []byte `protobuf:"bytes,3,opt,name=key_value,json=keyValue,proto3" json:"key_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ecdh1PuAeadPrivateKey) Reset() { *m = Ecdh1PuAeadPrivateKey{} } +func (m *Ecdh1PuAeadPrivateKey) String() string { return proto.CompactTextString(m) } +func (*Ecdh1PuAeadPrivateKey) ProtoMessage() {} +func (*Ecdh1PuAeadPrivateKey) Descriptor() ([]byte, []int) { + return fileDescriptor_a77c865180c47e23, []int{4} +} + +func (m *Ecdh1PuAeadPrivateKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ecdh1PuAeadPrivateKey.Unmarshal(m, b) +} +func (m *Ecdh1PuAeadPrivateKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ecdh1PuAeadPrivateKey.Marshal(b, m, deterministic) +} +func (m *Ecdh1PuAeadPrivateKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ecdh1PuAeadPrivateKey.Merge(m, src) +} +func (m *Ecdh1PuAeadPrivateKey) XXX_Size() int { + return xxx_messageInfo_Ecdh1PuAeadPrivateKey.Size(m) +} +func (m *Ecdh1PuAeadPrivateKey) XXX_DiscardUnknown() { + xxx_messageInfo_Ecdh1PuAeadPrivateKey.DiscardUnknown(m) +} + +var xxx_messageInfo_Ecdh1PuAeadPrivateKey proto.InternalMessageInfo + +func (m *Ecdh1PuAeadPrivateKey) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *Ecdh1PuAeadPrivateKey) GetPublicKey() *Ecdh1PuAeadPublicKey { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *Ecdh1PuAeadPrivateKey) GetKeyValue() []byte { + if m != nil { + return m.KeyValue + } + return nil +} + +type Ecdh1PuAeadRecipientPublicKey struct { + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + CurveType common_go_proto.EllipticCurveType `protobuf:"varint,2,opt,name=curve_type,json=curveType,proto3,enum=google.crypto.tink.EllipticCurveType" json:"curve_type,omitempty"` + KeyType common_composite_go_proto.KeyType `protobuf:"varint,3,opt,name=key_type,json=keyType,proto3,enum=google.crypto.tink.KeyType" json:"key_type,omitempty"` + KID string `protobuf:"bytes,4,opt,name=KID,proto3" json:"KID,omitempty"` + X []byte `protobuf:"bytes,5,opt,name=x,proto3" json:"x,omitempty"` + Y []byte `protobuf:"bytes,6,opt,name=y,proto3" json:"y,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ecdh1PuAeadRecipientPublicKey) Reset() { *m = Ecdh1PuAeadRecipientPublicKey{} } +func (m *Ecdh1PuAeadRecipientPublicKey) String() string { return proto.CompactTextString(m) } +func (*Ecdh1PuAeadRecipientPublicKey) ProtoMessage() {} +func (*Ecdh1PuAeadRecipientPublicKey) Descriptor() ([]byte, []int) { + return fileDescriptor_a77c865180c47e23, []int{5} +} + +func (m *Ecdh1PuAeadRecipientPublicKey) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ecdh1PuAeadRecipientPublicKey.Unmarshal(m, b) +} +func (m *Ecdh1PuAeadRecipientPublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ecdh1PuAeadRecipientPublicKey.Marshal(b, m, deterministic) +} +func (m *Ecdh1PuAeadRecipientPublicKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ecdh1PuAeadRecipientPublicKey.Merge(m, src) +} +func (m *Ecdh1PuAeadRecipientPublicKey) XXX_Size() int { + return xxx_messageInfo_Ecdh1PuAeadRecipientPublicKey.Size(m) +} +func (m *Ecdh1PuAeadRecipientPublicKey) XXX_DiscardUnknown() { + xxx_messageInfo_Ecdh1PuAeadRecipientPublicKey.DiscardUnknown(m) +} + +var xxx_messageInfo_Ecdh1PuAeadRecipientPublicKey proto.InternalMessageInfo + +func (m *Ecdh1PuAeadRecipientPublicKey) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *Ecdh1PuAeadRecipientPublicKey) GetCurveType() common_go_proto.EllipticCurveType { + if m != nil { + return m.CurveType + } + return common_go_proto.EllipticCurveType_UNKNOWN_CURVE +} + +func (m *Ecdh1PuAeadRecipientPublicKey) GetKeyType() common_composite_go_proto.KeyType { + if m != nil { + return m.KeyType + } + return common_composite_go_proto.KeyType_UNKNOWN_KEY_TYPE +} + +func (m *Ecdh1PuAeadRecipientPublicKey) GetKID() string { + if m != nil { + return m.KID + } + return "" +} + +func (m *Ecdh1PuAeadRecipientPublicKey) GetX() []byte { + if m != nil { + return m.X + } + return nil +} + +func (m *Ecdh1PuAeadRecipientPublicKey) GetY() []byte { + if m != nil { + return m.Y + } + return nil +} + +type Ecdh1PuAeadKeyFormat struct { + Params *Ecdh1PuAeadParams `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ecdh1PuAeadKeyFormat) Reset() { *m = Ecdh1PuAeadKeyFormat{} } +func (m *Ecdh1PuAeadKeyFormat) String() string { return proto.CompactTextString(m) } +func (*Ecdh1PuAeadKeyFormat) ProtoMessage() {} +func (*Ecdh1PuAeadKeyFormat) Descriptor() ([]byte, []int) { + return fileDescriptor_a77c865180c47e23, []int{6} +} + +func (m *Ecdh1PuAeadKeyFormat) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ecdh1PuAeadKeyFormat.Unmarshal(m, b) +} +func (m *Ecdh1PuAeadKeyFormat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ecdh1PuAeadKeyFormat.Marshal(b, m, deterministic) +} +func (m *Ecdh1PuAeadKeyFormat) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ecdh1PuAeadKeyFormat.Merge(m, src) +} +func (m *Ecdh1PuAeadKeyFormat) XXX_Size() int { + return xxx_messageInfo_Ecdh1PuAeadKeyFormat.Size(m) +} +func (m *Ecdh1PuAeadKeyFormat) XXX_DiscardUnknown() { + xxx_messageInfo_Ecdh1PuAeadKeyFormat.DiscardUnknown(m) +} + +var xxx_messageInfo_Ecdh1PuAeadKeyFormat proto.InternalMessageInfo + +func (m *Ecdh1PuAeadKeyFormat) GetParams() *Ecdh1PuAeadParams { + if m != nil { + return m.Params + } + return nil +} + +func init() { + proto.RegisterType((*Ecdh1PuKwParams)(nil), "google.crypto.tink.Ecdh1puKwParams") + proto.RegisterType((*Ecdh1PuAeadEncParams)(nil), "google.crypto.tink.Ecdh1puAeadEncParams") + proto.RegisterType((*Ecdh1PuAeadParams)(nil), "google.crypto.tink.Ecdh1puAeadParams") + proto.RegisterType((*Ecdh1PuAeadPublicKey)(nil), "google.crypto.tink.Ecdh1puAeadPublicKey") + proto.RegisterType((*Ecdh1PuAeadPrivateKey)(nil), "google.crypto.tink.Ecdh1puAeadPrivateKey") + proto.RegisterType((*Ecdh1PuAeadRecipientPublicKey)(nil), "google.crypto.tink.Ecdh1puAeadRecipientPublicKey") + proto.RegisterType((*Ecdh1PuAeadKeyFormat)(nil), "google.crypto.tink.Ecdh1puAeadKeyFormat") +} + +func init() { proto.RegisterFile("proto/ecdh1pu_aead.proto", fileDescriptor_a77c865180c47e23) } + +var fileDescriptor_a77c865180c47e23 = []byte{ + // 596 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0xcf, 0x4f, 0x13, 0x41, + 0x14, 0xce, 0xb4, 0x50, 0xe8, 0x03, 0x04, 0x37, 0x9a, 0x6c, 0x00, 0x23, 0xd6, 0x90, 0xf4, 0x42, + 0x1b, 0x30, 0xf1, 0x60, 0x62, 0xa2, 0x08, 0x12, 0xd2, 0xc4, 0xd4, 0x09, 0x7a, 0xf0, 0xb2, 0x19, + 0xa6, 0x8f, 0x65, 0xb2, 0x3f, 0x66, 0x32, 0x9d, 0x16, 0xf6, 0x7f, 0xf0, 0xee, 0xc9, 0x8b, 0x7f, + 0x9a, 0x89, 0x07, 0xff, 0x0b, 0xb3, 0x33, 0xbb, 0x75, 0x2b, 0xb5, 0xa8, 0xf1, 0x36, 0xef, 0xed, + 0x7b, 0xdf, 0x7e, 0xdf, 0x7b, 0xdf, 0x0c, 0xf8, 0x4a, 0x4b, 0x23, 0xbb, 0xc8, 0x07, 0x97, 0xfb, + 0x6a, 0x14, 0x30, 0x64, 0x83, 0x8e, 0x4d, 0x79, 0x5e, 0x28, 0x65, 0x18, 0x63, 0x87, 0xeb, 0x4c, + 0x19, 0xd9, 0x31, 0x22, 0x8d, 0x36, 0x3d, 0x57, 0xcd, 0x65, 0x92, 0xc8, 0xd4, 0xd5, 0x6d, 0x6e, + 0xb8, 0x5c, 0xfe, 0xbd, 0xc8, 0x6c, 0x57, 0xab, 0x02, 0x2e, 0x13, 0x25, 0x87, 0xc2, 0xa0, 0xfb, + 0xda, 0xfa, 0x4a, 0x60, 0xfd, 0xd8, 0xfd, 0xae, 0x77, 0xd5, 0x67, 0x9a, 0x25, 0x43, 0xef, 0x08, + 0x80, 0x8f, 0xf4, 0x18, 0x03, 0x93, 0x29, 0xf4, 0xc9, 0x0e, 0x69, 0xdf, 0x39, 0xd8, 0xed, 0xdc, + 0x24, 0xd0, 0x39, 0x8e, 0x63, 0xa1, 0x8c, 0xe0, 0xaf, 0xf2, 0xea, 0xb3, 0x4c, 0x21, 0x6d, 0xf2, + 0xf2, 0xe8, 0x3d, 0x85, 0xe5, 0x08, 0x33, 0x87, 0x51, 0xb3, 0x18, 0x5b, 0xb3, 0x30, 0x7a, 0x98, + 0xd9, 0xce, 0xa5, 0xc8, 0x1d, 0xbc, 0xb7, 0x00, 0x1a, 0xb9, 0x50, 0x02, 0x53, 0x33, 0xf4, 0xeb, + 0x3b, 0xf5, 0xf6, 0xca, 0xc1, 0xfe, 0xcc, 0xbf, 0x3b, 0xda, 0x2f, 0x91, 0x0d, 0x68, 0xd9, 0xd0, + 0x1f, 0x9d, 0xc7, 0x82, 0xf7, 0x30, 0xa3, 0x15, 0x90, 0x16, 0x85, 0x7b, 0x95, 0xe2, 0xe3, 0x94, + 0x17, 0x42, 0x9f, 0xc1, 0x72, 0x3e, 0xe2, 0x00, 0x53, 0x6e, 0x65, 0xae, 0x1c, 0x3c, 0xfc, 0x1d, + 0x45, 0x4c, 0x54, 0xcc, 0x0c, 0xd2, 0x25, 0xe6, 0x10, 0x5a, 0xdf, 0x09, 0xdc, 0xad, 0x80, 0x16, + 0x88, 0x2f, 0xa0, 0x19, 0x5d, 0x05, 0xca, 0x06, 0x05, 0xe4, 0xe3, 0x39, 0xdc, 0xcb, 0x91, 0xd3, + 0xe5, 0xa8, 0x1c, 0xfe, 0x09, 0x00, 0xa6, 0xbc, 0x84, 0xa8, 0x59, 0x88, 0xf6, 0x2d, 0xf2, 0x27, + 0x8a, 0x68, 0x13, 0x27, 0xe2, 0x4e, 0x61, 0x1d, 0x79, 0xa0, 0xa4, 0x48, 0x4d, 0x70, 0x21, 0x75, + 0xc2, 0x8c, 0x5f, 0xb7, 0x6b, 0x78, 0x34, 0x1b, 0xad, 0x9f, 0x57, 0xbe, 0xb6, 0x85, 0x74, 0x0d, + 0xab, 0x61, 0xeb, 0x33, 0x99, 0x1a, 0xe0, 0x64, 0xc8, 0x9e, 0x0f, 0x4b, 0x63, 0xd4, 0x43, 0x21, + 0x53, 0x2b, 0x76, 0x8d, 0x96, 0xa1, 0xf7, 0x1c, 0x1a, 0x53, 0x12, 0x76, 0x6f, 0x91, 0x50, 0xf0, + 0x2f, 0x9a, 0xbc, 0x0d, 0xa8, 0xf7, 0x4e, 0x8f, 0x2c, 0xe1, 0x26, 0xcd, 0x8f, 0xde, 0x2a, 0x90, + 0x6b, 0x7f, 0x61, 0x87, 0xb4, 0x57, 0x29, 0xb9, 0xce, 0xa3, 0xcc, 0x5f, 0x74, 0x51, 0xd6, 0xfa, + 0x44, 0xe0, 0x7e, 0x15, 0x4b, 0x8b, 0x31, 0x33, 0x38, 0x9f, 0xe0, 0x09, 0x80, 0xb2, 0x3a, 0x82, + 0x08, 0xb3, 0x3f, 0x9c, 0xf3, 0x4f, 0x77, 0x35, 0xd5, 0x64, 0x06, 0x5b, 0xd0, 0xcc, 0x7d, 0x3e, + 0x66, 0xf1, 0x08, 0x2d, 0xe1, 0x55, 0x9a, 0x1b, 0xff, 0x7d, 0x1e, 0xb7, 0xbe, 0x11, 0x78, 0x30, + 0xd7, 0xa7, 0x73, 0x18, 0x4e, 0x5f, 0xc3, 0xda, 0x7f, 0xb8, 0x86, 0xf5, 0xbf, 0xb8, 0x86, 0xc5, + 0x06, 0x16, 0x7e, 0xd9, 0xc0, 0xe2, 0xd4, 0x06, 0x1a, 0xe5, 0x06, 0xde, 0x4d, 0x19, 0xa4, 0x87, + 0x99, 0x73, 0x4e, 0xc5, 0x06, 0xe4, 0x1f, 0x6c, 0x70, 0xf8, 0x91, 0xc0, 0x36, 0x97, 0xc9, 0xac, + 0x26, 0xfb, 0x7c, 0xf5, 0xc9, 0x07, 0x16, 0x0a, 0x73, 0x39, 0x3a, 0xef, 0x70, 0x99, 0x74, 0x2f, + 0x33, 0x85, 0x3a, 0xc6, 0x41, 0x88, 0xba, 0xcb, 0xb4, 0xc0, 0xe1, 0xde, 0x85, 0x66, 0x09, 0x5e, + 0x49, 0x1d, 0xed, 0x85, 0xb2, 0xeb, 0xda, 0xed, 0xdb, 0x58, 0x1c, 0x95, 0x16, 0x89, 0x30, 0x62, + 0x8c, 0xdd, 0x9b, 0x0f, 0x6f, 0x10, 0xca, 0xc0, 0x66, 0xbf, 0xd4, 0x1a, 0x67, 0xa7, 0x6f, 0x7a, + 0xfd, 0xc3, 0xf3, 0x86, 0x8d, 0x9f, 0xfc, 0x08, 0x00, 0x00, 0xff, 0xff, 0x2a, 0x9b, 0xc2, 0x55, + 0xa7, 0x05, 0x00, 0x00, +} diff --git a/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto/ecdhes_aead.pb.go b/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto/ecdhes_aead.pb.go index 22579f3cc8..8bc15ea45d 100755 --- a/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto/ecdhes_aead.pb.go +++ b/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto/ecdhes_aead.pb.go @@ -6,6 +6,7 @@ package ecdhes_aead_go_proto import ( fmt "fmt" proto "github.com/golang/protobuf/proto" + common_composite_go_proto "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto" common_go_proto "github.com/google/tink/go/proto/common_go_proto" tink_go_proto "github.com/google/tink/go/proto/tink_go_proto" math "math" @@ -22,37 +23,9 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package -type KeyType int32 - -const ( - KeyType_UNKNOWN_KEY_TYPE KeyType = 0 - KeyType_EC KeyType = 1 - KeyType_OKP KeyType = 2 -) - -var KeyType_name = map[int32]string{ - 0: "UNKNOWN_KEY_TYPE", - 1: "EC", - 2: "OKP", -} - -var KeyType_value = map[string]int32{ - "UNKNOWN_KEY_TYPE": 0, - "EC": 1, - "OKP": 2, -} - -func (x KeyType) String() string { - return proto.EnumName(KeyType_name, int32(x)) -} - -func (KeyType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_59a984bc83da313d, []int{0} -} - type EcdhesKwParams struct { CurveType common_go_proto.EllipticCurveType `protobuf:"varint,1,opt,name=curve_type,json=curveType,proto3,enum=google.crypto.tink.EllipticCurveType" json:"curve_type,omitempty"` - KeyType KeyType `protobuf:"varint,2,opt,name=key_type,json=keyType,proto3,enum=google.crypto.tink.KeyType" json:"key_type,omitempty"` + KeyType common_composite_go_proto.KeyType `protobuf:"varint,2,opt,name=key_type,json=keyType,proto3,enum=google.crypto.tink.KeyType" json:"key_type,omitempty"` Recipients []*EcdhesAeadRecipientPublicKey `protobuf:"bytes,3,rep,name=recipients,proto3" json:"recipients,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -91,11 +64,11 @@ func (m *EcdhesKwParams) GetCurveType() common_go_proto.EllipticCurveType { return common_go_proto.EllipticCurveType_UNKNOWN_CURVE } -func (m *EcdhesKwParams) GetKeyType() KeyType { +func (m *EcdhesKwParams) GetKeyType() common_composite_go_proto.KeyType { if m != nil { return m.KeyType } - return KeyType_UNKNOWN_KEY_TYPE + return common_composite_go_proto.KeyType_UNKNOWN_KEY_TYPE } func (m *EcdhesKwParams) GetRecipients() []*EcdhesAeadRecipientPublicKey { @@ -328,7 +301,7 @@ func (m *EcdhesAeadPrivateKey) GetKeyValue() []byte { type EcdhesAeadRecipientPublicKey struct { Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` CurveType common_go_proto.EllipticCurveType `protobuf:"varint,2,opt,name=curve_type,json=curveType,proto3,enum=google.crypto.tink.EllipticCurveType" json:"curve_type,omitempty"` - KeyType KeyType `protobuf:"varint,3,opt,name=key_type,json=keyType,proto3,enum=google.crypto.tink.KeyType" json:"key_type,omitempty"` + KeyType common_composite_go_proto.KeyType `protobuf:"varint,3,opt,name=key_type,json=keyType,proto3,enum=google.crypto.tink.KeyType" json:"key_type,omitempty"` KID string `protobuf:"bytes,4,opt,name=KID,proto3" json:"KID,omitempty"` X []byte `protobuf:"bytes,5,opt,name=x,proto3" json:"x,omitempty"` Y []byte `protobuf:"bytes,6,opt,name=y,proto3" json:"y,omitempty"` @@ -376,11 +349,11 @@ func (m *EcdhesAeadRecipientPublicKey) GetCurveType() common_go_proto.EllipticCu return common_go_proto.EllipticCurveType_UNKNOWN_CURVE } -func (m *EcdhesAeadRecipientPublicKey) GetKeyType() KeyType { +func (m *EcdhesAeadRecipientPublicKey) GetKeyType() common_composite_go_proto.KeyType { if m != nil { return m.KeyType } - return KeyType_UNKNOWN_KEY_TYPE + return common_composite_go_proto.KeyType_UNKNOWN_KEY_TYPE } func (m *EcdhesAeadRecipientPublicKey) GetKID() string { @@ -444,7 +417,6 @@ func (m *EcdhesAeadKeyFormat) GetParams() *EcdhesAeadParams { } func init() { - proto.RegisterEnum("google.crypto.tink.KeyType", KeyType_name, KeyType_value) proto.RegisterType((*EcdhesKwParams)(nil), "google.crypto.tink.EcdhesKwParams") proto.RegisterType((*EcdhesAeadEncParams)(nil), "google.crypto.tink.EcdhesAeadEncParams") proto.RegisterType((*EcdhesAeadParams)(nil), "google.crypto.tink.EcdhesAeadParams") @@ -457,44 +429,43 @@ func init() { func init() { proto.RegisterFile("proto/ecdhes_aead.proto", fileDescriptor_59a984bc83da313d) } var fileDescriptor_59a984bc83da313d = []byte{ - // 623 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x5d, 0x6b, 0x13, 0x41, - 0x14, 0x75, 0x92, 0x36, 0x69, 0x6e, 0x3f, 0x5c, 0xc6, 0x82, 0xa1, 0x2d, 0x58, 0x17, 0xc5, 0x22, - 0x34, 0x29, 0x15, 0x7c, 0x10, 0x41, 0x6c, 0x9b, 0x42, 0x59, 0x48, 0xd7, 0xb5, 0x2a, 0xf5, 0x65, - 0xdd, 0x4e, 0x6e, 0xd3, 0x61, 0x3f, 0x66, 0x98, 0x6c, 0xd2, 0xee, 0x6f, 0xf0, 0xd9, 0x27, 0xdf, - 0xfc, 0x65, 0x3e, 0x88, 0xbf, 0x43, 0x76, 0x76, 0x37, 0xdd, 0xd8, 0x34, 0x58, 0xf0, 0x6d, 0xee, - 0xdd, 0x3b, 0x67, 0xce, 0x39, 0x7b, 0x66, 0xe0, 0xa1, 0x54, 0x22, 0x16, 0x6d, 0x64, 0xbd, 0x0b, - 0x1c, 0xb8, 0x1e, 0x7a, 0xbd, 0x96, 0xee, 0x50, 0xda, 0x17, 0xa2, 0x1f, 0x60, 0x8b, 0xa9, 0x44, - 0xc6, 0xa2, 0x15, 0xf3, 0xc8, 0x5f, 0xa3, 0xd9, 0x30, 0x13, 0x61, 0x28, 0xa2, 0x6c, 0x6e, 0xcd, - 0xc8, 0x7a, 0xe9, 0xf7, 0xac, 0x63, 0xfe, 0x24, 0xb0, 0xd2, 0xd1, 0x78, 0xd6, 0xa5, 0xed, 0x29, - 0x2f, 0x1c, 0xd0, 0x03, 0x00, 0x36, 0x54, 0x23, 0x74, 0xe3, 0x44, 0x62, 0x93, 0x6c, 0x92, 0xad, - 0x95, 0xdd, 0xa7, 0xad, 0x9b, 0x27, 0xb4, 0x3a, 0x41, 0xc0, 0x65, 0xcc, 0xd9, 0x7e, 0x3a, 0x7d, - 0x92, 0x48, 0x74, 0x1a, 0xac, 0x58, 0xd2, 0x97, 0xb0, 0xe0, 0x63, 0x92, 0x61, 0x54, 0x34, 0xc6, - 0xfa, 0x34, 0x0c, 0x0b, 0x13, 0xbd, 0xb3, 0xee, 0x67, 0x0b, 0x6a, 0x03, 0x28, 0x64, 0x5c, 0x72, - 0x8c, 0xe2, 0x41, 0xb3, 0xba, 0x59, 0xdd, 0x5a, 0xdc, 0xdd, 0x99, 0x7a, 0xba, 0x66, 0xfd, 0x16, - 0xbd, 0x9e, 0x53, 0xcc, 0xdb, 0xc3, 0xb3, 0x80, 0x33, 0x0b, 0x13, 0xa7, 0x84, 0x61, 0xbe, 0x83, - 0x07, 0xd7, 0xb3, 0x9d, 0x88, 0xe5, 0x32, 0x5f, 0xc1, 0x42, 0xea, 0xa0, 0x8b, 0x11, 0xd3, 0x22, - 0x17, 0x77, 0x1f, 0xdd, 0x46, 0x10, 0x43, 0x19, 0x78, 0x31, 0x3a, 0x75, 0x2f, 0x43, 0x30, 0x7f, - 0x13, 0x30, 0xae, 0x31, 0x73, 0xc0, 0x37, 0xd0, 0xf0, 0x2f, 0x5d, 0xa9, 0x8b, 0x1c, 0xd1, 0xbc, - 0x9d, 0x78, 0x61, 0xb7, 0xb3, 0xe0, 0x17, 0xc6, 0x1f, 0x02, 0x60, 0xc4, 0x0a, 0x84, 0x8a, 0x46, - 0x78, 0x36, 0x5b, 0xfa, 0x58, 0x8e, 0xd3, 0xc0, 0xb1, 0xb2, 0x23, 0xb8, 0x8f, 0xcc, 0x95, 0x82, - 0x47, 0xb1, 0x7b, 0x2e, 0x54, 0xe8, 0xc5, 0xcd, 0xaa, 0xfe, 0x03, 0x8f, 0xa7, 0x83, 0xd9, 0xe9, - 0xe4, 0xa1, 0x1e, 0x74, 0x96, 0xb1, 0x5c, 0x9a, 0xdf, 0x49, 0xd9, 0xbc, 0xb1, 0xbf, 0xb4, 0x09, - 0xf5, 0x11, 0xaa, 0x01, 0x17, 0x91, 0x56, 0xba, 0xec, 0x14, 0x25, 0x7d, 0x0d, 0xb5, 0x09, 0x01, - 0x4f, 0x66, 0x0b, 0xc8, 0xd9, 0xe7, 0x7b, 0xa8, 0x01, 0x55, 0xeb, 0xe8, 0x40, 0xd3, 0x6d, 0x38, - 0xe9, 0x92, 0x2e, 0x01, 0xb9, 0x6a, 0xce, 0x6d, 0x92, 0xad, 0x25, 0x87, 0x5c, 0xa5, 0x55, 0xd2, - 0x9c, 0xcf, 0xaa, 0xc4, 0xfc, 0x46, 0x60, 0xb5, 0x04, 0xa5, 0xf8, 0xc8, 0x8b, 0x71, 0x36, 0xbd, - 0x43, 0x00, 0xa9, 0x55, 0xb8, 0x3e, 0x26, 0xff, 0xe6, 0xf1, 0x75, 0xaa, 0x1a, 0x72, 0x6c, 0xc0, - 0x3a, 0x34, 0xd2, 0x78, 0x8f, 0xbc, 0x60, 0x88, 0x9a, 0xee, 0x92, 0x93, 0xe6, 0xfd, 0x63, 0x5a, - 0x9b, 0xbf, 0x08, 0x6c, 0xcc, 0x8a, 0xe7, 0x0c, 0x7e, 0x93, 0x97, 0xaf, 0xf2, 0x1f, 0x2e, 0x5f, - 0xf5, 0x0e, 0x97, 0x2f, 0xb7, 0x7f, 0xee, 0x2f, 0xfb, 0xe7, 0x27, 0xec, 0xaf, 0x15, 0xf6, 0xbf, - 0x2f, 0x67, 0xc3, 0xc2, 0x24, 0xcb, 0x4c, 0x29, 0x01, 0xe4, 0xee, 0x09, 0x78, 0xbe, 0x03, 0xf5, - 0x9c, 0x16, 0x5d, 0x05, 0xe3, 0x43, 0xd7, 0xea, 0x1e, 0x7f, 0xea, 0xba, 0x56, 0xe7, 0xd4, 0x3d, - 0x39, 0xb5, 0x3b, 0xc6, 0x3d, 0x5a, 0x83, 0x4a, 0x67, 0xdf, 0x20, 0xb4, 0x0e, 0xd5, 0x63, 0xcb, - 0x36, 0x2a, 0x7b, 0x5f, 0x09, 0x6c, 0x30, 0x11, 0x4e, 0x3b, 0x45, 0xbf, 0x71, 0x36, 0xf9, 0xfc, - 0xa5, 0xcf, 0xe3, 0x8b, 0xe1, 0x59, 0x8b, 0x89, 0xb0, 0x7d, 0x91, 0x48, 0x54, 0x01, 0xf6, 0xfa, - 0xa8, 0xda, 0x9e, 0xe2, 0x38, 0xd8, 0x3e, 0x57, 0x5e, 0x88, 0x97, 0x42, 0xf9, 0xdb, 0x7d, 0xd1, - 0xce, 0xb6, 0xeb, 0x27, 0x32, 0x5f, 0x4a, 0xc5, 0x43, 0x1e, 0xf3, 0x11, 0xb6, 0x6f, 0x3c, 0xbf, - 0x6e, 0x5f, 0xb8, 0xba, 0xf9, 0xa3, 0x52, 0x3b, 0x39, 0xea, 0x5a, 0xf6, 0xde, 0x59, 0x4d, 0xd7, - 0x2f, 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0x0e, 0xc4, 0x73, 0x05, 0xac, 0x05, 0x00, 0x00, + // 593 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x54, 0x5d, 0x6b, 0xd4, 0x40, + 0x14, 0x65, 0x76, 0xdb, 0x6d, 0xf7, 0xf6, 0xc3, 0x12, 0x05, 0x43, 0x5b, 0xb0, 0x06, 0xc5, 0xbe, + 0x34, 0x2b, 0x15, 0x7c, 0x10, 0x41, 0xac, 0x6d, 0xa1, 0x04, 0x24, 0xc6, 0xe2, 0x83, 0x2f, 0x71, + 0x3a, 0x7b, 0x9b, 0x0e, 0xf9, 0x98, 0x61, 0x32, 0xbb, 0x6d, 0x7e, 0x83, 0xcf, 0x3e, 0xf9, 0xe6, + 0x2f, 0xf3, 0x41, 0xfc, 0x1d, 0x92, 0x49, 0xb2, 0xcd, 0xda, 0xed, 0x62, 0xc1, 0xb7, 0xb9, 0x93, + 0x7b, 0xcf, 0x9c, 0x73, 0x72, 0x66, 0xe0, 0xa1, 0x54, 0x42, 0x8b, 0x01, 0xb2, 0xe1, 0x05, 0xe6, + 0x21, 0x45, 0x3a, 0x74, 0xcd, 0x8e, 0x65, 0x45, 0x42, 0x44, 0x09, 0xba, 0x4c, 0x15, 0x52, 0x0b, + 0x57, 0xf3, 0x2c, 0xde, 0xb4, 0xaa, 0x66, 0x26, 0xd2, 0x54, 0x64, 0x55, 0xdf, 0xe6, 0x46, 0xb5, + 0x57, 0x7e, 0xaf, 0x77, 0xb6, 0xdb, 0x5d, 0x21, 0x13, 0xa9, 0x14, 0x39, 0xd7, 0x58, 0x7d, 0x75, + 0x7e, 0x12, 0x58, 0x3f, 0x32, 0xa7, 0x79, 0x97, 0x3e, 0x55, 0x34, 0xcd, 0xad, 0x43, 0x00, 0x36, + 0x52, 0x63, 0x0c, 0x75, 0x21, 0xd1, 0x26, 0x3b, 0x64, 0x77, 0x7d, 0xff, 0xa9, 0x7b, 0xf3, 0x7c, + 0xf7, 0x28, 0x49, 0xb8, 0xd4, 0x9c, 0xbd, 0x2b, 0xbb, 0x4f, 0x0b, 0x89, 0x41, 0x9f, 0x35, 0x4b, + 0xeb, 0x25, 0x2c, 0xc7, 0x58, 0x54, 0x18, 0x1d, 0x83, 0xb1, 0x35, 0x0b, 0xc3, 0xc3, 0xc2, 0x4c, + 0x2e, 0xc5, 0xd5, 0xc2, 0xf2, 0x01, 0x14, 0x32, 0x2e, 0x39, 0x66, 0x3a, 0xb7, 0xbb, 0x3b, 0xdd, + 0xdd, 0x95, 0xfd, 0xe7, 0x33, 0x4f, 0x37, 0xac, 0xdf, 0x22, 0x1d, 0x06, 0x4d, 0xbf, 0x3f, 0x3a, + 0x4b, 0x38, 0xf3, 0xb0, 0x08, 0x5a, 0x18, 0xce, 0x07, 0xb8, 0x7f, 0xdd, 0x7b, 0x94, 0xb1, 0x5a, + 0xe6, 0x2b, 0x58, 0x2e, 0xfd, 0x0d, 0x31, 0x63, 0x46, 0xe4, 0xca, 0xfe, 0xa3, 0xdb, 0x08, 0x62, + 0x2a, 0x13, 0xaa, 0x31, 0x58, 0xa2, 0x15, 0x82, 0xf3, 0x9b, 0xc0, 0xc6, 0x35, 0x66, 0x0d, 0xf8, + 0x06, 0xfa, 0xf1, 0x65, 0x28, 0x4d, 0x51, 0x23, 0x3a, 0xb7, 0x13, 0x6f, 0xec, 0x0e, 0x96, 0xe3, + 0xc6, 0xf8, 0x63, 0x00, 0xcc, 0x58, 0x83, 0xd0, 0x31, 0x08, 0xcf, 0xe6, 0x4b, 0x9f, 0xc8, 0x09, + 0xfa, 0x38, 0x51, 0x76, 0x02, 0xf7, 0x90, 0x85, 0x52, 0xf0, 0x4c, 0x87, 0xe7, 0x42, 0xa5, 0x54, + 0xdb, 0x5d, 0xf3, 0x07, 0x1e, 0xcf, 0x06, 0xf3, 0xcb, 0xce, 0x63, 0xd3, 0x18, 0xac, 0x61, 0xbb, + 0x74, 0xbe, 0x93, 0xb6, 0x79, 0x13, 0x7f, 0x2d, 0x1b, 0x96, 0xc6, 0xa8, 0x72, 0x2e, 0x32, 0xa3, + 0x74, 0x2d, 0x68, 0x4a, 0xeb, 0x35, 0xf4, 0xa6, 0x04, 0x3c, 0x99, 0x2f, 0xa0, 0x66, 0x5f, 0xcf, + 0x58, 0x1b, 0xd0, 0xf5, 0x4e, 0x0e, 0x0d, 0xdd, 0x7e, 0x50, 0x2e, 0xad, 0x55, 0x20, 0x57, 0xf6, + 0xc2, 0x0e, 0xd9, 0x5d, 0x0d, 0xc8, 0x55, 0x59, 0x15, 0xf6, 0x62, 0x55, 0x15, 0xce, 0x37, 0x02, + 0x0f, 0x5a, 0x50, 0x8a, 0x8f, 0xa9, 0xc6, 0xf9, 0xf4, 0x8e, 0x01, 0xa4, 0x51, 0x11, 0xc6, 0x58, + 0xfc, 0x9b, 0xc7, 0xd7, 0xa9, 0xea, 0xcb, 0x89, 0x01, 0x5b, 0xd0, 0x2f, 0xe3, 0x3d, 0xa6, 0xc9, + 0x08, 0x0d, 0xdd, 0xd5, 0xa0, 0xcc, 0xfb, 0xa7, 0xb2, 0x76, 0x7e, 0x11, 0xd8, 0x9e, 0x17, 0xcf, + 0x39, 0xfc, 0xa6, 0x2f, 0x5f, 0xe7, 0x3f, 0x5c, 0xbe, 0xee, 0x1d, 0x2e, 0x5f, 0x6d, 0xff, 0xc2, + 0x5f, 0xf6, 0x2f, 0x4e, 0xd9, 0xdf, 0x6b, 0xec, 0xff, 0xd8, 0xce, 0x86, 0x87, 0x45, 0x95, 0x99, + 0x56, 0x02, 0xc8, 0xdd, 0x13, 0x70, 0xf0, 0x95, 0xc0, 0x36, 0x13, 0xe9, 0xac, 0x19, 0xf3, 0x62, + 0xf9, 0xe4, 0xf3, 0x97, 0x88, 0xeb, 0x8b, 0xd1, 0x99, 0xcb, 0x44, 0x3a, 0xb8, 0x28, 0x24, 0xaa, + 0x04, 0x87, 0x11, 0xaa, 0x01, 0x55, 0x1c, 0xf3, 0xbd, 0x73, 0x45, 0x53, 0xbc, 0x14, 0x2a, 0xde, + 0x8b, 0xc4, 0xa0, 0x1a, 0x37, 0xcf, 0x61, 0xbd, 0x94, 0x8a, 0xa7, 0x5c, 0xf3, 0x31, 0x0e, 0x6e, + 0x3c, 0xb5, 0x61, 0x24, 0x42, 0xb3, 0xf9, 0xa3, 0xd3, 0x3b, 0x3d, 0x79, 0xef, 0xf9, 0x07, 0x67, + 0x3d, 0x53, 0xbf, 0xf8, 0x13, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x85, 0x4d, 0xce, 0x98, 0x05, 0x00, + 0x00, } diff --git a/pkg/didcomm/packer/anoncrypt/pack.go b/pkg/didcomm/packer/anoncrypt/pack.go index b474eb25ab..c63133cda9 100644 --- a/pkg/didcomm/packer/anoncrypt/pack.go +++ b/pkg/didcomm/packer/anoncrypt/pack.go @@ -15,8 +15,8 @@ import ( "github.com/google/tink/go/keyset" "github.com/hyperledger/aries-framework-go/pkg/common/log" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes" - "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/transport" "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer" "github.com/hyperledger/aries-framework-go/pkg/doc/jose" @@ -87,11 +87,11 @@ func (p *Packer) Pack(payload, _ []byte, recipientsPubKeys [][]byte) ([]byte, er return []byte(s), nil } -func unmarshalRecipientKeys(keys [][]byte) ([]subtle.PublicKey, error) { - var pubKeys []subtle.PublicKey +func unmarshalRecipientKeys(keys [][]byte) ([]composite.PublicKey, error) { + var pubKeys []composite.PublicKey for _, key := range keys { - var ecKey subtle.PublicKey + var ecKey composite.PublicKey err := json.Unmarshal(key, &ecKey) if err != nil { diff --git a/pkg/didcomm/packer/anoncrypt/pack_test.go b/pkg/didcomm/packer/anoncrypt/pack_test.go index c98ed87679..1cdabfd257 100644 --- a/pkg/didcomm/packer/anoncrypt/pack_test.go +++ b/pkg/didcomm/packer/anoncrypt/pack_test.go @@ -14,7 +14,7 @@ import ( "github.com/google/tink/go/keyset" "github.com/stretchr/testify/require" - ecdhessubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/transport" "github.com/hyperledger/aries-framework-go/pkg/doc/jose" "github.com/hyperledger/aries-framework-go/pkg/kms" @@ -160,7 +160,7 @@ func createAndMarshalRecipient(t *testing.T, k *localkms.LocalKMS) (string, []by pubKeyBytes, err := exportPubKeyBytes(kh) require.NoError(t, err) - key := &ecdhessubtle.PublicKey{} + key := &composite.PublicKey{} err = json.Unmarshal(pubKeyBytes, key) require.NoError(t, err) diff --git a/pkg/doc/jose/decrypter.go b/pkg/doc/jose/decrypter.go index 2bfad0db06..ed0c75df26 100644 --- a/pkg/doc/jose/decrypter.go +++ b/pkg/doc/jose/decrypter.go @@ -13,9 +13,9 @@ import ( "github.com/google/tink/go/keyset" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/api" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes" - "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" ) // Decrypter interface to Decrypt JWE messages @@ -87,7 +87,7 @@ func (jd *JWEDecrypt) Decrypt(jwe *JSONWebEncryption) ([]byte, error) { } func buildEncryptedData(encAlg string, jwe *JSONWebEncryption) ([]byte, error) { - var recipients []*subtle.RecipientWrappedKey + var recipients []*composite.RecipientWrappedKey if len(jwe.Recipients) == 1 { // compact serialization: it has only 1 recipient with no headers rHeaders, err := extractRecipientHeaders(jwe.ProtectedHeaders) @@ -104,7 +104,7 @@ func buildEncryptedData(encAlg string, jwe *JSONWebEncryption) ([]byte, error) { rec.Alg = rHeaders.Alg rec.EncryptedCEK = []byte(jwe.Recipients[0].EncryptedKey) - recipients = []*subtle.RecipientWrappedKey{ + recipients = []*composite.RecipientWrappedKey{ rec, } } else { // full serialization @@ -122,7 +122,7 @@ func buildEncryptedData(encAlg string, jwe *JSONWebEncryption) ([]byte, error) { } } - encData := new(subtle.EncryptedData) + encData := new(composite.EncryptedData) encData.Recipients = recipients encData.Tag = []byte(jwe.Tag) encData.IV = []byte(jwe.IV) @@ -178,7 +178,7 @@ func extractRecipientHeaders(headers map[string]interface{}) (*RecipientHeaders, return recHeaders, nil } -func convertMarshalledJWKToRecKey(marshalledJWK []byte) (*subtle.RecipientWrappedKey, error) { +func convertMarshalledJWKToRecKey(marshalledJWK []byte) (*composite.RecipientWrappedKey, error) { jwk := &JWK{} err := jwk.UnmarshalJSON(marshalledJWK) @@ -186,7 +186,7 @@ func convertMarshalledJWKToRecKey(marshalledJWK []byte) (*subtle.RecipientWrappe return nil, err } - epk := subtle.PublicKey{ + epk := composite.PublicKey{ Curve: jwk.Crv, Type: jwk.Kty, } @@ -199,7 +199,7 @@ func convertMarshalledJWKToRecKey(marshalledJWK []byte) (*subtle.RecipientWrappe return nil, fmt.Errorf("unsupported recipient key type") } - return &subtle.RecipientWrappedKey{ + return &composite.RecipientWrappedKey{ KID: jwk.KeyID, EPK: epk, }, nil diff --git a/pkg/doc/jose/encrypter.go b/pkg/doc/jose/encrypter.go index f14dbe61d9..53a87601b8 100644 --- a/pkg/doc/jose/encrypter.go +++ b/pkg/doc/jose/encrypter.go @@ -19,6 +19,7 @@ import ( tinkpb "github.com/google/tink/go/proto/tink_go_proto" "github.com/square/go-jose/v3" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/api" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" @@ -46,14 +47,14 @@ type encPrimitiveFunc func(*keyset.Handle) (api.CompositeEncrypt, error) // JWEEncrypt is responsible for encrypting a plaintext and its AAD into a protected JWE and decrypting it type JWEEncrypt struct { - recipients []subtle.PublicKey + recipients []composite.PublicKey senderKH *keyset.Handle getPrimitive encPrimitiveFunc encAlg EncAlg } // NewJWEEncrypt creates a new JWEEncrypt instance to build JWE with recipientsPubKeys -func NewJWEEncrypt(encAlg EncAlg, recipientsPubKeys []subtle.PublicKey) (*JWEEncrypt, error) { +func NewJWEEncrypt(encAlg EncAlg, recipientsPubKeys []composite.PublicKey) (*JWEEncrypt, error) { if len(recipientsPubKeys) == 0 { return nil, fmt.Errorf("empty recipientsPubKeys list") } @@ -122,7 +123,7 @@ func (je *JWEEncrypt) EncryptWithAuthData(plaintext, aad []byte) (*JSONWebEncryp return nil, fmt.Errorf("jweencrypt: failed to Encrypt: %w", err) } - encData := new(subtle.EncryptedData) + encData := new(composite.EncryptedData) err = json.Unmarshal(serializedEncData, encData) if err != nil { @@ -158,7 +159,7 @@ func mergeRecipientHeaders(headers map[string]interface{}, recHeaders *Recipient headers[HeaderEPK] = recHeaders.EPK } -func (je *JWEEncrypt) buildRecipients(encData *subtle.EncryptedData) ([]*Recipient, *RecipientHeaders, error) { +func (je *JWEEncrypt) buildRecipients(encData *composite.EncryptedData) ([]*Recipient, *RecipientHeaders, error) { var ( recipients []*Recipient singleRecipientHeaders *RecipientHeaders @@ -191,7 +192,7 @@ func (je *JWEEncrypt) buildRecipients(encData *subtle.EncryptedData) ([]*Recipie return recipients, singleRecipientHeaders, nil } -func buildRecipientHeaders(rec *subtle.RecipientWrappedKey) (*RecipientHeaders, error) { +func buildRecipientHeaders(rec *composite.RecipientWrappedKey) (*RecipientHeaders, error) { mRecJWK, err := convertRecKeyToMarshalledJWK(rec) if err != nil { return nil, fmt.Errorf("failed to convert recipient key to marshalled JWK: %w", err) @@ -204,7 +205,7 @@ func buildRecipientHeaders(rec *subtle.RecipientWrappedKey) (*RecipientHeaders, }, nil } -func convertRecKeyToMarshalledJWK(rec *subtle.RecipientWrappedKey) ([]byte, error) { +func convertRecKeyToMarshalledJWK(rec *composite.RecipientWrappedKey) ([]byte, error) { var c elliptic.Curve c, err := hybrid.GetCurve(rec.EPK.Curve) diff --git a/pkg/doc/jose/encrypter_decrypter_test.go b/pkg/doc/jose/encrypter_decrypter_test.go index e7248af199..6e4610001d 100644 --- a/pkg/doc/jose/encrypter_decrypter_test.go +++ b/pkg/doc/jose/encrypter_decrypter_test.go @@ -22,9 +22,9 @@ import ( "github.com/square/go-jose/v3" "github.com/stretchr/testify/require" + "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/api" "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes" - ecdhessubtle "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/composite/ecdhes/subtle" ) func TestJWEEncryptRoundTrip(t *testing.T) { @@ -282,7 +282,7 @@ func TestInteropWithLocalJoseEncryptAndGoJoseDecrypt(t *testing.T) { require.NoError(t, err) // add third key to recECKeys - recECKeys = append(recECKeys, ecdhessubtle.PublicKey{ + recECKeys = append(recECKeys, composite.PublicKey{ X: rec3PrivKey.PublicKey.X.Bytes(), Y: rec3PrivKey.PublicKey.Y.Bytes(), Curve: rec3PrivKey.PublicKey.Curve.Params().Name, @@ -315,13 +315,13 @@ func TestInteropWithLocalJoseEncryptAndGoJoseDecrypt(t *testing.T) { } func TestInteropWithLocalJoseEncryptAndGoJoseDecryptUsingCompactSerialization(t *testing.T) { - var recECKeys []ecdhessubtle.PublicKey + var recECKeys []composite.PublicKey // create a normal recipient key (not using Tink) recPrivKey, err := ecdsa.GenerateKey(subtle.GetCurve("NIST_P256"), rand.Reader) require.NoError(t, err) // add third key to recECKeys - recECKeys = append(recECKeys, ecdhessubtle.PublicKey{ + recECKeys = append(recECKeys, composite.PublicKey{ X: recPrivKey.PublicKey.X.Bytes(), Y: recPrivKey.PublicKey.Y.Bytes(), Curve: recPrivKey.PublicKey.Curve.Params().Name, @@ -350,7 +350,7 @@ func TestInteropWithLocalJoseEncryptAndGoJoseDecryptUsingCompactSerialization(t require.EqualValues(t, pt, msg) } -func convertToGoJoseRecipients(t *testing.T, keys []ecdhessubtle.PublicKey) []jose.Recipient { +func convertToGoJoseRecipients(t *testing.T, keys []composite.PublicKey) []jose.Recipient { t.Helper() var joseRecipients []jose.Recipient @@ -373,17 +373,17 @@ func convertToGoJoseRecipients(t *testing.T, keys []ecdhessubtle.PublicKey) []jo } // createRecipients and return their public key and keyset.Handle -func createRecipients(t *testing.T, numberOfRecipients int) ([]ecdhessubtle.PublicKey, []*keyset.Handle) { +func createRecipients(t *testing.T, numberOfRecipients int) ([]composite.PublicKey, []*keyset.Handle) { t.Helper() var ( - r []ecdhessubtle.PublicKey + r []composite.PublicKey rKH []*keyset.Handle ) for i := 0; i < numberOfRecipients; i++ { mrKey, kh := createAndMarshalRecipient(t) - ecPubKey := new(ecdhessubtle.PublicKey) + ecPubKey := new(composite.PublicKey) err := json.Unmarshal(mrKey, ecPubKey) require.NoError(t, err) @@ -416,8 +416,8 @@ func createAndMarshalRecipient(t *testing.T) ([]byte, *keyset.Handle) { } func TestFailConvertRecKeyToMarshalledJWK(t *testing.T) { - recKey := &ecdhessubtle.RecipientWrappedKey{ - EPK: ecdhessubtle.PublicKey{ + recKey := &composite.RecipientWrappedKey{ + EPK: composite.PublicKey{ Curve: "badCurveName", }, } diff --git a/protos/tink/README.md b/protos/tink/README.md index bb0c0fbcfa..f4734cc55e 100644 --- a/protos/tink/README.md +++ b/protos/tink/README.md @@ -1,13 +1,24 @@ -# How to generate ecdhes_aead protobuf +# How to generate common_composite, ecdhes_aead and ecdh1pu_aead protobufs -To execute the proto generation of `ecdhes_aead.proto`, copy this file into -`tink/proto` folder then cd to Tink's Go proto folder `/tink/go/proto`. Copying the proto to Tink is required because of +To execute the proto generation of `protos/tink/common_composite.proto`, `protos/tink/ecdhes_aead.proto` and `protos/tink/ecdh1pu_aead.proto`, +copy these files into `tink/proto` folder then cd to Tink's Go proto folder `/tink/go/proto`. Copying the protos to Tink is required because of the dependencies needed to generate the Go protobuf. -The following steps will generate the protobuf in Tink: -1. Edit Tink's proto file `proto/BUILD.bazel` to add a proto library definition by adding the following to the file: +The following steps will generate the protobuf files in Tink: +1. Edit Tink's proto file `proto/BUILD.bazel` to add proto library definitions by adding the following to the file: ``` +# ----------------------------------------------- +# common_composite +# ----------------------------------------------- +proto_library( + visibility = ["//visibility:public"], + name = "common_composite_proto", + srcs = [ + "common_composite.proto", + ], +) + # ----------------------------------------------- # ecdhes_aead # ----------------------------------------------- @@ -18,6 +29,23 @@ proto_library( "ecdhes_aead.proto", ], deps = [ + ":common_composite_proto", + ":common_proto", + ":tink_proto", + ], +) + +# ----------------------------------------------- +# ecdh1pu_aead +# ----------------------------------------------- +proto_library( + visibility = ["//visibility:public"], + name = "ecdh1pu_aead_proto", + srcs = [ + "ecdh1pu_aead.proto", + ], + deps = [ + ":common_composite_proto", ":common_proto", ":tink_proto", ], @@ -27,14 +55,32 @@ proto_library( Note: if you don't have Bazlisk installed, Tink's build tool, please do so before proceeding. Hint, use an alias to call `bazel` commands: `alias bazel='bazelisk'` -2. Add the bazel Go proto build target by adding the following to `go/proto/BUILD.bazel`: +2. Add the bazel Go proto build targets by adding the following to `go/proto/BUILD.bazel`: + ``` +go_proto_library( + name = "common_composite_go_proto", + importpath = "github.com/google/tink/go/proto/common_composite_go_proto", + proto = "@tink_base//proto:common_composite_proto", +) go_proto_library( name = "ecdhes_aead_go_proto", importpath = "github.com/google/tink/go/proto/ecdhes_aead_go_proto", proto = "@tink_base//proto:ecdhes_aead_proto", deps = [ + ":common_composite_go_proto", + ":common_go_proto", + ":tink_go_proto", + ], +) + +go_proto_library( + name = "ecdh1pu_aead_go_proto", + importpath = "github.com/google/tink/go/proto/ecdh1pu_aead_go_proto", + proto = "@tink_base//proto:ecdh1pu_aead_proto", + deps = [ + ":common_composite_go_proto", ":common_go_proto", ":tink_go_proto", ], @@ -47,15 +93,27 @@ go_proto_library( bazel clean ``` -4. Run the bazel build for the added target above as follows: +4. Run the bazel builds for the added targets above as follows: ```shell script +bazel build common_composite_go_proto bazel build ecdhes_aead_go_proto +bazel build ecdh1pu_aead_go_proto ``` -This will generate a new Go protobuf file in Bazel's output path, for example on a Mac it would be under: +This will generate new Go protobuf files in Bazel's output path, for example on a Mac it would be under: +`tink/go/bazel-bin/proto/darwin_amd64_stripped/common_composite_go_proto%/github.com/google/tink/go/proto/common_composite_go_proto/common_composite.pb.go` `tink/go/bazel-bin/proto/darwin_amd64_stripped/ecdhes_aead_go_proto%/github.com/google/tink/go/proto/ecdhes_aead_go_proto/ecdhes_aead.pb.go` +`tink/go/bazel-bin/proto/darwin_amd64_stripped/ecdh1pu_aead_go_proto%/github.com/google/tink/go/proto/ecdh1pu_aead_go_proto/ecdh1pu_aead.pb.go` + +5. Copy these generated files in Aries's proto paths below in their respective location: +* common composite proto: `aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto/common_composite.pb.go` +* ecdh-es proto: `aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto/ecdhes_aead.pb.go` +* ecdh-1pu proto: `aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto/ecdh1pu_aead.pb.go` -5. Copy this generated file in Aries's proto path below: -`aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto/ecdhes_aead.pb.go` +6. Manually update the common composite import in ecdh-es and ecdh-1pu pb.go files above to match the patch of the local common_composite.pb.go dependency. +This is required since common composite proto is created above and not found in the Tink repository. Replace: +`common_composite_go_proto "github.com/google/tink/go/proto/common_composite_go_proto"` +with +`common_composite_go_proto "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/common_composite_go_proto"` You're done! diff --git a/protos/tink/common_composite.proto b/protos/tink/common_composite.proto new file mode 100644 index 0000000000..c2609b245d --- /dev/null +++ b/protos/tink/common_composite.proto @@ -0,0 +1,21 @@ +/* +Copyright Google Inc., SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +// Definitions for common Elliptic Curve Diffie-Hellman (ECDH) primitives. +syntax = "proto3"; + +package google.crypto.tink; + +option java_package = "com.google.crypto.tink.proto"; +option java_multiple_files = true; +option objc_class_prefix = "TINKPB"; +option go_package = "github.com/hyperledger/aries-framework-go/crypto/tinkcrypto/primitive/proto/common_composite_proto"; + +enum KeyType { + UNKNOWN_KEY_TYPE = 0; + EC = 1; + OKP = 2; +} \ No newline at end of file diff --git a/protos/tink/ecdh1pu_aead.proto b/protos/tink/ecdh1pu_aead.proto new file mode 100644 index 0000000000..bcf654758d --- /dev/null +++ b/protos/tink/ecdh1pu_aead.proto @@ -0,0 +1,113 @@ +/* +Copyright Google Inc., SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +// Definitions for Elliptic Curve Diffie-Hellman - One-Pass Unified Model (ECDH-1PU). +syntax = "proto3"; + +package google.crypto.tink; +import "proto/common.proto"; +import "proto/tink.proto"; +import "proto/common_composite.proto"; + +option java_package = "com.google.crypto.tink.proto"; +option java_multiple_files = true; +option objc_class_prefix = "TINKPB"; +option go_package = "github.com/hyperledger/aries-framework-go/crypto/tinkcrypto/primitive/proto/ecdh1pu_aead_go_proto"; + +// Protos for keys for ECDH-1PU with One-Step KDF key wrapping and AEAD encryption. +// +// +// ECDH-1PU-keys represent 1PUEncryption and 1PUDecryption primitives. + +// Parameters of KW (Key Wrapping) +message Ecdh1puKwParams { + // Required. + EllipticCurveType curve_type = 1; + + // Required. + KeyType key_type = 2; + + // Not needed for key storage but required for primitive execution + repeated Ecdh1puAeadRecipientPublicKey recipients = 3; +} + +// Parameters of AEAD Content encryption. +message Ecdh1puAeadEncParams { + // Required. + KeyTemplate aead_enc = 1; // Contains e.g. AesGcmKeyFormat. +} + +message Ecdh1puAeadParams { + // Key Wrapping. + // Required. + Ecdh1puKwParams kw_params = 1; + + // Content Encryption. + // Required. + Ecdh1puAeadEncParams enc_params = 2; + + // EC point format. + // Required. + EcPointFormat ec_point_format = 3; +} + +// Ecdh1puAeadPublicKey represents ECDH1PUEncrypt primitive. +// key_type: type.hyperledger.org/hyperledger.aries.crypto.tink.Ecdh1puAeadPublicKey +message Ecdh1puAeadPublicKey { + // Required. + uint32 version = 1; + + // Required. + Ecdh1puAeadParams params = 2; + + // Required. + string KID = 3; + + // Affine coordinates of the public key in bigendian representation. + // The public key is a point (x, y) on the curve defined by params.kw_params.curve. + // Required. + bytes x = 4; + + // Required. + bytes y = 5; +} + +// Ecdh1puAeadPrivateKey represents ECDH1PUDecrypt primitive. +// key_type: type.hyperledger.org/hyperledger.aries.crypto.tink.Ecdh1puAeadPrivateKey +message Ecdh1puAeadPrivateKey { + // Required. + uint32 version = 1; + + // Required. + Ecdh1puAeadPublicKey public_key = 2; + + // Required. + bytes key_value = 3; // Big integer in bigendian representation. +} + +message Ecdh1puAeadRecipientPublicKey { + // Required. + uint32 version = 1; + // Required. + EllipticCurveType curve_type = 2; + // Required. + KeyType key_type = 3; + + // Required. + string KID = 4; + + // Affine coordinates of the public key in bigendian representation. + // The public key is a point (x, y) on the curve defined by params.kw_params.curve. + // Required. + bytes x = 5; + // Required. + bytes y = 6; +} + +message Ecdh1puAeadKeyFormat { + // Required. + Ecdh1puAeadParams params = 1; +} \ No newline at end of file diff --git a/protos/tink/ecdhes_aead.proto b/protos/tink/ecdhes_aead.proto index 2022ac1a52..4ff203713a 100644 --- a/protos/tink/ecdhes_aead.proto +++ b/protos/tink/ecdhes_aead.proto @@ -10,13 +10,14 @@ syntax = "proto3"; package google.crypto.tink; import "proto/common.proto"; import "proto/tink.proto"; +import "proto/common_composite.proto"; option java_package = "com.google.crypto.tink.proto"; option java_multiple_files = true; option objc_class_prefix = "TINKPB"; option go_package = "github.com/hyperledger/aries-framework-go/crypto/tinkcrypto/primitive/proto/ecdhes_aead_go_proto"; -// Protos for keys for ECIES with Concat KDF key wrapping and AEAD encryption. +// Protos for keys for ECDH-ES with Concat KDF key wrapping and AEAD encryption. // // // ECDH-ES-keys represent ESEncryption and ESDecryption primitives. @@ -109,10 +110,4 @@ message EcdhesAeadRecipientPublicKey { message EcdhesAeadKeyFormat { // Required. EcdhesAeadParams params = 1; -} - -enum KeyType { - UNKNOWN_KEY_TYPE = 0; - EC = 1; - OKP = 2; } \ No newline at end of file