Skip to content

Commit

Permalink
refactor: rename ECDHES Tink Key to distinguish NIST vs Chacha crypto
Browse files Browse the repository at this point in the history
This change renames current ECDHES Tink key to prepare for adding support
for (X)Chacha/X25519 type as ECDHES Tink key type.

The following was changed:
* Files names renamed to include `AES` keyword
* new `KeyType` added in the proto, PublicKey and current logic to seperate EC keys from Chacha keys

Closes hyperledger-archives#1804
Closes hyperledger-archives#1805

Signed-off-by: Baha Shaaban <[email protected]>
  • Loading branch information
Baha Shaaban committed May 13, 2020
1 parent 3bee279 commit fd32913
Show file tree
Hide file tree
Showing 25 changed files with 430 additions and 221 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,42 +21,42 @@ import (
)

const (
ecdhesPrivateKeyVersion = 0
ecdhesPrivateKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhesAeadPrivateKey"
ecdhesAESPrivateKeyVersion = 0
ecdhesAESPrivateKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhesAesAeadPrivateKey"
)

// common errors
var errInvalidECDHESPrivateKey = fmt.Errorf("ecdhes_private_key_manager: invalid key")
var errInvalidECDHESPrivateKeyFormat = fmt.Errorf("ecdhes_private_key_manager: invalid key format")
var errInvalidECDHESAESPrivateKey = fmt.Errorf("ecdhes_aes_private_key_manager: invalid key")
var errInvalidECDHESAESPrivateKeyFormat = fmt.Errorf("ecdhes_aes_private_key_manager: invalid key format")

// ecdhesPrivateKeyManager is an implementation of PrivateKeyManager interface.
// It generates new ECDHESPrivateKey keys and produces new instances of ECDHESAEADCompositeDecrypt subtle.
type ecdhesPrivateKeyManager struct{}
// ecdhesAESPrivateKeyManager is an implementation of PrivateKeyManager interface.
// It generates new ECDHESPrivateKey (NIST AES EC) keys and produces new instances of ECDHESAEADCompositeDecrypt subtle.
type ecdhesAESPrivateKeyManager struct{}

// Assert that ecdhesPrivateKeyManager implements the PrivateKeyManager interface.
var _ registry.PrivateKeyManager = (*ecdhesPrivateKeyManager)(nil)
// Assert that ecdhesAESPrivateKeyManager implements the PrivateKeyManager interface.
var _ registry.PrivateKeyManager = (*ecdhesAESPrivateKeyManager)(nil)

// newECDHESPrivateKeyManager creates a new ecdhesPrivateKeyManager.
func newECDHESPrivateKeyManager() *ecdhesPrivateKeyManager {
return new(ecdhesPrivateKeyManager)
// newECDHESPrivateKeyManager creates a new ecdhesAESPrivateKeyManager.
func newECDHESPrivateKeyManager() *ecdhesAESPrivateKeyManager {
return new(ecdhesAESPrivateKeyManager)
}

// Primitive creates an ECDHESPrivateKey subtle for the given serialized ECDHESPrivateKey proto.
func (km *ecdhesPrivateKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
func (km *ecdhesAESPrivateKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
if len(serializedKey) == 0 {
return nil, errInvalidECDHESPrivateKey
return nil, errInvalidECDHESAESPrivateKey
}

key := new(ecdhespb.EcdhesAeadPrivateKey)

err := proto.Unmarshal(serializedKey, key)
if err != nil {
return nil, errInvalidECDHESPrivateKey
return nil, errInvalidECDHESAESPrivateKey
}

curve, err := km.validateKey(key)
if err != nil {
return nil, errInvalidECDHESPrivateKey
return nil, errInvalidECDHESAESPrivateKey
}

pvt := hybrid.GetECPrivateKey(curve, key.KeyValue)
Expand All @@ -68,37 +68,39 @@ func (km *ecdhesPrivateKeyManager) Primitive(serializedKey []byte) (interface{},

ptFormat := key.PublicKey.Params.EcPointFormat.String()

return subtle.NewECDHESAEADCompositeDecrypt(pvt, ptFormat, rEnc)
return subtle.NewECDHESAEADCompositeDecrypt(pvt, ptFormat, rEnc, ecdhespb.KeyType_EC), nil
}

// NewKey creates a new key according to the specification of ECDHESPrivateKey format.
func (km *ecdhesPrivateKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
func (km *ecdhesAESPrivateKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
if len(serializedKeyFormat) == 0 {
return nil, errInvalidECDHESPrivateKeyFormat
return nil, errInvalidECDHESAESPrivateKeyFormat
}

keyFormat := new(ecdhespb.EcdhesAeadKeyFormat)

err := proto.Unmarshal(serializedKeyFormat, keyFormat)
if err != nil {
return nil, errInvalidECDHESPrivateKeyFormat
return nil, errInvalidECDHESAESPrivateKeyFormat
}

curve, err := validateKeyFormat(keyFormat.Params)
if err != nil {
return nil, errInvalidECDHESPrivateKeyFormat
return nil, errInvalidECDHESAESPrivateKeyFormat
}

keyFormat.Params.KwParams.KeyType = ecdhespb.KeyType_EC

pvt, err := hybrid.GenerateECDHKeyPair(curve)
if err != nil {
return nil, err
}

return &ecdhespb.EcdhesAeadPrivateKey{
Version: ecdhesPrivateKeyVersion,
Version: ecdhesAESPrivateKeyVersion,
KeyValue: pvt.D.Bytes(),
PublicKey: &ecdhespb.EcdhesAeadPublicKey{
Version: ecdhesPrivateKeyVersion,
Version: ecdhesAESPrivateKeyVersion,
Params: keyFormat.Params,
X: pvt.PublicKey.Point.X.Bytes(),
Y: pvt.PublicKey.Point.Y.Bytes(),
Expand All @@ -108,7 +110,7 @@ func (km *ecdhesPrivateKeyManager) NewKey(serializedKeyFormat []byte) (proto.Mes

// NewKeyData creates a new KeyData according to the specification of ECDHESPrivateKey Format.
// It should be used solely by the key management API.
func (km *ecdhesPrivateKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
func (km *ecdhesAESPrivateKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
key, err := km.NewKey(serializedKeyFormat)
if err != nil {
return nil, err
Expand All @@ -120,46 +122,46 @@ func (km *ecdhesPrivateKeyManager) NewKeyData(serializedKeyFormat []byte) (*tink
}

return &tinkpb.KeyData{
TypeUrl: ecdhesPrivateKeyTypeURL,
TypeUrl: ecdhesAESPrivateKeyTypeURL,
Value: serializedKey,
KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE,
}, nil
}

// PublicKeyData returns the enclosed public key data of serializedPrivKey
func (km *ecdhesPrivateKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) {
func (km *ecdhesAESPrivateKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) {
privKey := new(ecdhespb.EcdhesAeadPrivateKey)

err := proto.Unmarshal(serializedPrivKey, privKey)
if err != nil {
return nil, errInvalidECDHESPrivateKey
return nil, errInvalidECDHESAESPrivateKey
}

serializedPubKey, err := proto.Marshal(privKey.PublicKey)
if err != nil {
return nil, errInvalidECDHESPrivateKey
return nil, errInvalidECDHESAESPrivateKey
}

return &tinkpb.KeyData{
TypeUrl: ecdhesPublicKeyTypeURL,
TypeUrl: ecdhesAESPublicKeyTypeURL,
Value: serializedPubKey,
KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC,
}, nil
}

// DoesSupport indicates if this key manager supports the given key type.
func (km *ecdhesPrivateKeyManager) DoesSupport(typeURL string) bool {
return typeURL == ecdhesPrivateKeyTypeURL
func (km *ecdhesAESPrivateKeyManager) DoesSupport(typeURL string) bool {
return typeURL == ecdhesAESPrivateKeyTypeURL
}

// TypeURL returns the key type of keys managed by this key manager.
func (km *ecdhesPrivateKeyManager) TypeURL() string {
return ecdhesPrivateKeyTypeURL
func (km *ecdhesAESPrivateKeyManager) TypeURL() string {
return ecdhesAESPrivateKeyTypeURL
}

// validateKey validates the given ECDHESPrivateKey and erturns the KW curve.
func (km *ecdhesPrivateKeyManager) validateKey(key *ecdhespb.EcdhesAeadPrivateKey) (elliptic.Curve, error) {
err := keyset.ValidateKeyVersion(key.Version, ecdhesPrivateKeyVersion)
func (km *ecdhesAESPrivateKeyManager) validateKey(key *ecdhespb.EcdhesAeadPrivateKey) (elliptic.Curve, error) {
err := keyset.ValidateKeyVersion(key.Version, ecdhesAESPrivateKeyVersion)
if err != nil {
return nil, fmt.Errorf("ecdhes_private_key_manager: invalid key: %s", err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ func TestECDHESPrivateKeyManager_Primitive(t *testing.T) {

t.Run("Test private key manager Primitive() with empty serialized key", func(t *testing.T) {
p, err := km.Primitive([]byte(""))
require.EqualError(t, err, errInvalidECDHESPrivateKey.Error(),
require.EqualError(t, err, errInvalidECDHESAESPrivateKey.Error(),
"ECDHESPrivate 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, errInvalidECDHESPrivateKey.Error(),
require.EqualError(t, err, errInvalidECDHESAESPrivateKey.Error(),
"ECDHESPrivate primitive from bad serialized key must fail")
require.Empty(t, p)
})
Expand Down Expand Up @@ -153,7 +153,7 @@ func TestECDHESPrivateKeyManager_Primitive(t *testing.T) {

p, err := km.Primitive(sPubKey)
if bytes.Equal(tt.encTmp.Value, badSerializedFormat) {
require.EqualError(t, err, errInvalidECDHESPrivateKey.Error(),
require.EqualError(t, err, errInvalidECDHESAESPrivateKey.Error(),
"ECDHESPrivate primitive from serialized key with invalid serialized key")
require.Empty(t, p)

Expand All @@ -175,21 +175,21 @@ func TestECDHESPrivateKeyManager_Primitive(t *testing.T) {
func TestEcdhesPrivateKeyManager_DoesSupport(t *testing.T) {
km := newECDHESPrivateKeyManager()
require.False(t, km.DoesSupport("bad/url"))
require.True(t, km.DoesSupport(ecdhesPrivateKeyTypeURL))
require.True(t, km.DoesSupport(ecdhesAESPrivateKeyTypeURL))
}

func TestEcdhesPrivateKeyManager_NewKey(t *testing.T) {
km := newECDHESPrivateKeyManager()

t.Run("Test private key manager NewKey() with nil key", func(t *testing.T) {
k, err := km.NewKey(nil)
require.EqualError(t, err, errInvalidECDHESPrivateKeyFormat.Error())
require.EqualError(t, err, errInvalidECDHESAESPrivateKeyFormat.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, errInvalidECDHESPrivateKeyFormat.Error(),
require.EqualError(t, err, errInvalidECDHESAESPrivateKeyFormat.Error(),
"ECDHESPrivate NewKey() from bad serialized key must fail")
require.Empty(t, p)
})
Expand Down Expand Up @@ -294,13 +294,13 @@ func TestEcdhesPrivateKeyManager_NewKey(t *testing.T) {
if strings.Contains(tt.tcName, "success") {
require.NoError(t, err)
require.NotEmpty(t, kd)
require.Equal(t, kd.TypeUrl, ecdhesPrivateKeyTypeURL)
require.Equal(t, kd.TypeUrl, ecdhesAESPrivateKeyTypeURL)
require.Equal(t, kd.KeyMaterialType, tinkpb.KeyData_ASYMMETRIC_PRIVATE)
return
}

if bytes.Equal(tt.encTmp.Value, badSerializedFormat) {
require.EqualError(t, err, errInvalidECDHESPrivateKeyFormat.Error(),
require.EqualError(t, err, errInvalidECDHESAESPrivateKeyFormat.Error(),
"ECDHESPrivate NewKey from serialized key with invalid serialized key")
require.Empty(t, p)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package ecdhes
import (
"crypto/elliptic"
"fmt"
"math/big"

"github.com/golang/protobuf/proto"
"github.com/google/tink/go/core/registry"
Expand All @@ -22,12 +21,12 @@ import (
)

const (
ecdhesPublicKeyVersion = 0
ecdhesPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhesAeadPublicKey"
ecdhesAESPublicKeyVersion = 0
ecdhesAESPublicKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhesAesAeadPublicKey"
)

// common errors
var errInvalidECDHESPublicKey = fmt.Errorf("ecdhes_public_key_manager: invalid key")
var errInvalidECDHESAESPublicKey = fmt.Errorf("ecdhes_aes_public_key_manager: invalid key")

// ecdhesPublicKeyManager is an implementation of KeyManager interface.
// It generates new ECDHESPublicKey keys and produces new instances of ECDHESAEADCompositeEncrypt subtle.
Expand All @@ -44,35 +43,34 @@ func newECDHESPublicKeyManager() *ecdhesPublicKeyManager {
// Primitive creates an ECDHESPublicKey subtle for the given serialized ECDHESPublicKey proto.
func (km *ecdhesPublicKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
if len(serializedKey) == 0 {
return nil, errInvalidECDHESPublicKey
return nil, errInvalidECDHESAESPublicKey
}

ecdhesPubKey := new(ecdhespb.EcdhesAeadPublicKey)

err := proto.Unmarshal(serializedKey, ecdhesPubKey)
if err != nil {
return nil, errInvalidECDHESPublicKey
return nil, errInvalidECDHESAESPublicKey
}

_, err = km.validateKey(ecdhesPubKey)
if err != nil {
return nil, errInvalidECDHESPublicKey
return nil, errInvalidECDHESAESPublicKey
}

var recipientsKeys []*hybrid.ECPublicKey
var recipientsKeys []*subtle.PublicKey

for _, recKey := range ecdhesPubKey.Params.KwParams.Recipients {
recCurve, e := km.validateRecKey(recKey)
e := km.validateRecKey(recKey)
if e != nil {
return nil, errInvalidECDHESPublicKey
return nil, errInvalidECDHESAESPublicKey
}

pub := &hybrid.ECPublicKey{
Curve: recCurve,
Point: hybrid.ECPoint{
X: new(big.Int).SetBytes(recKey.X),
Y: new(big.Int).SetBytes(recKey.Y),
},
pub := &subtle.PublicKey{
Type: recKey.KeyType.String(),
Curve: recKey.CurveType.String(),
X: recKey.X,
Y: recKey.Y,
}

recipientsKeys = append(recipientsKeys, pub)
Expand All @@ -85,17 +83,17 @@ func (km *ecdhesPublicKeyManager) Primitive(serializedKey []byte) (interface{},

ptFormat := ecdhesPubKey.Params.EcPointFormat.String()

return subtle.NewECDHESAEADCompositeEncrypt(recipientsKeys, ptFormat, rEnc)
return subtle.NewECDHESAEADCompositeEncrypt(recipientsKeys, ptFormat, rEnc, ecdhespb.KeyType_EC), nil
}

// DoesSupport indicates if this key manager supports the given key type.
func (km *ecdhesPublicKeyManager) DoesSupport(typeURL string) bool {
return typeURL == ecdhesPublicKeyTypeURL
return typeURL == ecdhesAESPublicKeyTypeURL
}

// TypeURL returns the key type of keys managed by this key manager.
func (km *ecdhesPublicKeyManager) TypeURL() string {
return ecdhesPublicKeyTypeURL
return ecdhesAESPublicKeyTypeURL
}

// NewKey is not implemented for public key manager.
Expand All @@ -110,7 +108,7 @@ func (km *ecdhesPublicKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkp

// validateKey validates the given ECDHESPublicKey.
func (km *ecdhesPublicKeyManager) validateKey(key *ecdhespb.EcdhesAeadPublicKey) (elliptic.Curve, error) {
err := keyset.ValidateKeyVersion(key.Version, ecdhesPublicKeyVersion)
err := keyset.ValidateKeyVersion(key.Version, ecdhesAESPublicKeyVersion)
if err != nil {
return nil, fmt.Errorf("ecdhes_publie_key_manager: invalid key: %s", err)
}
Expand All @@ -119,16 +117,21 @@ func (km *ecdhesPublicKeyManager) validateKey(key *ecdhespb.EcdhesAeadPublicKey)
}

// validateRecKey validates the given recipient's ECDHESPublicKey.
func (km *ecdhesPublicKeyManager) validateRecKey(key *ecdhespb.EcdhesAeadRecipientPublicKey) (elliptic.Curve, error) {
err := keyset.ValidateKeyVersion(key.Version, ecdhesPublicKeyVersion)
func (km *ecdhesPublicKeyManager) validateRecKey(key *ecdhespb.EcdhesAeadRecipientPublicKey) error {
err := keyset.ValidateKeyVersion(key.Version, ecdhesAESPublicKeyVersion)
if err != nil {
return nil, fmt.Errorf("ecdhes_public_key_manager: invalid key: %s", err)
return fmt.Errorf("ecdhes_public_key_manager: invalid key: %s", err)
}

c, err := hybrid.GetCurve(key.CurveType.String())
_, err = GetKeyType(key.KeyType.String())
if err != nil {
return nil, err
return err
}

_, err = hybrid.GetCurve(key.CurveType.String())
if err != nil {
return err
}

return c, nil
return nil
}
Loading

0 comments on commit fd32913

Please sign in to comment.