forked from hyperledger-archives/aries-framework-go
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add XChacha key to ECDH AEAD Tink key
part of hyperledger-archives#1637, hyperledger-archives#1806, hyperledger-archives#1684, hyperledger-archives#815, hyperledger-archives#817 Signed-off-by: Baha Shaaban <[email protected]>
- Loading branch information
Baha Shaaban
committed
Jan 8, 2021
1 parent
b423cb5
commit 48ebe02
Showing
16 changed files
with
987 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 0 additions & 9 deletions
9
pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_x25519_private_key_manager.go
This file was deleted.
Oops, something went wrong.
200 changes: 200 additions & 0 deletions
200
pkg/crypto/tinkcrypto/primitive/composite/ecdh/ecdh_xchacha_aead_private_key_manager.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
/* | ||
Copyright SecureKey Technologies Inc. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package ecdh | ||
|
||
import ( | ||
"crypto/ed25519" | ||
"crypto/rand" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/google/tink/go/core/registry" | ||
"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/ecdh/subtle" | ||
ecdhpb "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto/primitive/proto/ecdh_aead_go_proto" | ||
"github.com/hyperledger/aries-framework-go/pkg/internal/cryptoutil" | ||
) | ||
|
||
const ( | ||
ecdhXChachaPrivateKeyVersion = 0 | ||
ecdhXChachaPrivateKeyTypeURL = "type.hyperledger.org/hyperledger.aries.crypto.tink.EcdhXChachaAeadPrivateKey" | ||
) | ||
|
||
// common errors. | ||
var ( | ||
errInvalidECDHXChachaPrivateKey = errors.New("ecdh_xchacha_private_key_manager: invalid key") | ||
errInvalidECDHXChachaPrivateKeyFormat = errors.New("ecdh_xchacha_private_key_manager: invalid key format") | ||
) | ||
|
||
// ecdhXChachaPrivateKeyManager is an implementation of PrivateKeyManager interface. | ||
// It generates new ECDHPrivateKey (XChacha) keys and produces new instances of ECDHAEADCompositeDecrypt subtle. | ||
type ecdhXChachaPrivateKeyManager struct{} | ||
|
||
// Assert that ecdhXChachaPrivateKeyManager implements the PrivateKeyManager interface. | ||
var _ registry.PrivateKeyManager = (*ecdhXChachaPrivateKeyManager)(nil) | ||
|
||
// newECDHXChachaPrivateKeyManager creates a new ecdhXChachaPrivateKeyManager. | ||
func newECDHXChachaPrivateKeyManager() *ecdhXChachaPrivateKeyManager { | ||
return new(ecdhXChachaPrivateKeyManager) | ||
} | ||
|
||
// Primitive creates an ECDHESPrivateKey subtle for the given serialized ECDHESPrivateKey proto. | ||
func (km *ecdhXChachaPrivateKeyManager) Primitive(serializedKey []byte) (interface{}, error) { | ||
if len(serializedKey) == 0 { | ||
return nil, errInvalidECDHXChachaPrivateKey | ||
} | ||
|
||
key := new(ecdhpb.EcdhAeadPrivateKey) | ||
|
||
err := proto.Unmarshal(serializedKey, key) | ||
if err != nil { | ||
return nil, errInvalidECDHXChachaPrivateKey | ||
} | ||
|
||
err = km.validateKey(key) | ||
if err != nil { | ||
return nil, errInvalidECDHXChachaPrivateKey | ||
} | ||
|
||
rEnc, err := composite.NewRegisterCompositeAEADEncHelper(key.PublicKey.Params.EncParams.AeadEnc) | ||
if err != nil { | ||
return nil, fmt.Errorf("ecdh_xchacha_private_key_manager: NewRegisterCompositeAEADEncHelper "+ | ||
"failed: %w", err) | ||
} | ||
|
||
return subtle.NewECDHAEADCompositeDecrypt(rEnc, key.PublicKey.Params.EncParams.CEK), nil | ||
} | ||
|
||
// NewKey creates a new key according to the specification of ECDHESPrivateKey format. | ||
func (km *ecdhXChachaPrivateKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { | ||
if len(serializedKeyFormat) == 0 { | ||
return nil, errInvalidECDHXChachaPrivateKeyFormat | ||
} | ||
|
||
keyFormat := new(ecdhpb.EcdhAeadKeyFormat) | ||
|
||
err := proto.Unmarshal(serializedKeyFormat, keyFormat) | ||
if err != nil { | ||
return nil, errInvalidECDHXChachaPrivateKeyFormat | ||
} | ||
|
||
err = validateKeyXChachaFormat(keyFormat.Params) | ||
if err != nil { | ||
return nil, errInvalidECDHXChachaPrivateKeyFormat | ||
} | ||
|
||
pub, pvt, err := ed25519.GenerateKey(rand.Reader) | ||
if err != nil { | ||
return nil, fmt.Errorf("ecdh_xchacha_private_key_manager: GenerateECDHKeyPair failed: %w", err) | ||
} | ||
|
||
x25519Pub, err := cryptoutil.PublicEd25519toCurve25519(pub) | ||
if err != nil { | ||
return nil, fmt.Errorf("ecdh_xchacha_private_key_manager: Convert to X25519 pub key failed: %w", err) | ||
} | ||
|
||
x25519Pvt, err := cryptoutil.SecretEd25519toCurve25519(pvt) | ||
if err != nil { | ||
return nil, fmt.Errorf("ecdh_xchacha_private_key_manager: Convert to X25519 priv key failed: %w", err) | ||
} | ||
|
||
return &ecdhpb.EcdhXChachaAeadPrivateKey{ | ||
Version: ecdhXChachaPrivateKeyVersion, | ||
KeyValue: x25519Pvt, | ||
PublicKey: &ecdhpb.EcdhXChachaAeadPublicKey{ | ||
Version: ecdhXChachaPrivateKeyVersion, | ||
Params: keyFormat.Params, | ||
KeyValue: x25519Pub, | ||
}, | ||
}, 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 *ecdhXChachaPrivateKeyManager) 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, fmt.Errorf("ecdhes_xchacha_private_key_manager: Proto.Marshal failed: %w", err) | ||
} | ||
|
||
return &tinkpb.KeyData{ | ||
TypeUrl: ecdhXChachaPrivateKeyTypeURL, | ||
Value: serializedKey, | ||
KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE, | ||
}, nil | ||
} | ||
|
||
// PublicKeyData returns the enclosed public key data of serializedPrivKey. | ||
func (km *ecdhXChachaPrivateKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) { | ||
privKey := new(ecdhpb.EcdhAeadPrivateKey) | ||
|
||
err := proto.Unmarshal(serializedPrivKey, privKey) | ||
if err != nil { | ||
return nil, errInvalidECDHXChachaPrivateKey | ||
} | ||
|
||
serializedPubKey, err := proto.Marshal(privKey.PublicKey) | ||
if err != nil { | ||
return nil, errInvalidECDHXChachaPrivateKey | ||
} | ||
|
||
return &tinkpb.KeyData{ | ||
TypeUrl: ecdhXChachaPublicKeyTypeURL, | ||
Value: serializedPubKey, | ||
KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC, | ||
}, nil | ||
} | ||
|
||
// DoesSupport indicates if this key manager supports the given key type. | ||
func (km *ecdhXChachaPrivateKeyManager) DoesSupport(typeURL string) bool { | ||
return typeURL == ecdhXChachaPrivateKeyTypeURL | ||
} | ||
|
||
// TypeURL returns the key type of keys managed by this key manager. | ||
func (km *ecdhXChachaPrivateKeyManager) TypeURL() string { | ||
return ecdhXChachaPrivateKeyTypeURL | ||
} | ||
|
||
// validateKey validates the given ECDHPrivateKey and returns the KW curve. | ||
func (km *ecdhXChachaPrivateKeyManager) validateKey(key *ecdhpb.EcdhAeadPrivateKey) error { | ||
err := keyset.ValidateKeyVersion(key.Version, ecdhXChachaPrivateKeyVersion) | ||
if err != nil { | ||
return fmt.Errorf("ecdhes_xchacha_private_key_manager: invalid key: %w", err) | ||
} | ||
|
||
return validateKeyXChachaFormat(key.PublicKey.Params) | ||
} | ||
|
||
// validateKeyFormat validates the given ECDHESKeyFormat and returns the KW Curve. | ||
func validateKeyXChachaFormat(params *ecdhpb.EcdhAeadParams) error { | ||
var err error | ||
|
||
km, err := registry.GetKeyManager(params.EncParams.AeadEnc.TypeUrl) | ||
if err != nil { | ||
return fmt.Errorf("ecdhes_aes_private_key_manager: GetKeyManager error: %w", err) | ||
} | ||
|
||
_, err = km.NewKeyData(params.EncParams.AeadEnc.Value) | ||
if err != nil { | ||
return fmt.Errorf("ecdhes_aes_private_key_manager: NewKeyData error: %w", err) | ||
} | ||
|
||
if params.KwParams.KeyType.String() != ecdhpb.KeyType_OKP.String() { | ||
return fmt.Errorf("ecdhes_aes_private_key_manager: invalid key type %v", params.KwParams.KeyType) | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.