Skip to content

Conversation

rain-on
Copy link
Contributor

@rain-on rain-on commented Apr 7, 2020

PR description

Update the Handhshaking classes to use an injected NodeKey object for ECIES encryption.
This has necessitated an update of NodeKey to support the creation of Key and ECIES agreement creation.

Fixed Issue(s)

N/A

Signed-off-by: Trent Mohay <trent.mohay@consensys.net>
@rain-on rain-on requested review from usmansaleem and jframe April 7, 2020 06:47
@@ -53,7 +54,8 @@ public HandshakeHandlerOutbound(
connectionFuture,
connectionEventDispatcher,
metricsSystem);
handshaker.prepareInitiator(kp, SECP256K1.PublicKey.create(peer.getId()));
handshaker.prepareInitiator(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to move the second parameter SECP256K1.PublicKey.create(peer.getId()) as potentially a static method in NodeKey as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking not - NodeKey is all about protecting this node's identity/private key - the Peer in this question is someone remote.
I.e. only operations for our node key need to go via the NodeKey interface

checkState(
status.compareAndSet(
Handshaker.HandshakeStatus.UNINITIALIZED, Handshaker.HandshakeStatus.IN_PROGRESS),
"handshake was already prepared");

this.initiator = false;
this.identityKeyPair = ourKeypair;
this.nodeKey = nodeKey;
this.ephKeyPair = SECP256K1.KeyPair.generate();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about ephKeyPair?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the ephemeral key used for inter-node communications and is rolling - so no need to protect it alongside our nodekey

* @return The plaintext.
* @throws InvalidCipherTextException Thrown if decryption failed.
*/
public static Bytes decryptMsgEIP8(final Bytes msgBytes, final SECP256K1.PrivateKey ourKey)
public static Bytes decryptMsgEIP8(final Bytes msgBytes, final NodeKey nodeKey)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wondering, should we name argument as 'ourNodeKey' ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer not to. For 2 reasons:
Thinking "nodeKey" is explicit enough to indicate ownership (on some levels).
Secondly, I'd hate for this class to imply the owner of the key which is doing the decryption - i.e. it simply needs a key to do the decryption - ownership of the key makes no difference as to the operation being conducted.

Copy link
Member

@usmansaleem usmansaleem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

* @param theirPubKey The public key of the node we're handshaking with.
* @throws IllegalStateException Indicates that preparation had already occured.
*/
void prepareInitiator(SECP256K1.KeyPair ourKeypair, SECP256K1.PublicKey theirPubKey);
void prepareInitiator(final NodeKey nodeKey, SECP256K1.PublicKey theirPubKey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final isn't needed on the interface fields

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* @throws IllegalStateException Indicates that preparation had already occured.
*/
void prepareResponder(SECP256K1.KeyPair ourKeypair);
void prepareResponder(final NodeKey nodeKey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final isn't needed on the interface fields

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -95,11 +95,10 @@ public static InitiatorHandshakeMessageV1 create(
* Decodes this message.
*
* @param bytes The raw bytes.
* @param keyPair Our keypair to calculat ECDH key agreements.
* @param nodeKey Our keypair to calculat ECDH key agreements.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also update the javadoc since this is no longer a keypair

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

import org.apache.tuweni.bytes.Bytes32;

public interface NodeKey {

Signature sign(Bytes32 dataHash);

PublicKey getPublicKey();

Bytes32 calculateKeyAgreement(final PublicKey partyKey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to be more explicit here and call out that is the ECDH key agreement? I thinking we should.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

import org.apache.tuweni.bytes.Bytes32;

public interface NodeKey {

Signature sign(Bytes32 dataHash);

PublicKey getPublicKey();

Bytes32 calculateKeyAgreement(final PublicKey partyKey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this just be publicKey instead of partyKey? I don't know enough ECDH key agreements to say it should be, but elsewhere it seems to be just referred to as publicKey

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

@Override
public Bytes calculateECIESAgreement(final SECP256K1.PublicKey ephPubKey) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking this should be calculateECIESKeyAgreement

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

final CipherParameters privParam,
final SECP256K1.PublicKey ephPubKey,
final byte[] iv) {
final Bytes Z, final SECP256K1.PublicKey ephPubKey, final byte[] iv) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be lower z

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed - but I wonder what it REALLY is .... changed to agreedSecret

Comment on lines 62 to 71
final ECDomainParameters dp = SECP256K1.CURVE;

final CipherParameters pubParam = new ECPublicKeyParameters(ephPubKey.asEcPoint(), dp);
final CipherParameters privParam =
new ECPrivateKeyParameters(nodeKeys.getPrivateKey().getD(), dp);

final BasicAgreement agree = new ECDHBasicAgreement();
agree.init(privParam);
final BigInteger z = agree.calculateAgreement(pubParam);
return Bytes.wrap(BigIntegers.asUnsignedByteArray(agree.getFieldSize(), z));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nicer if both of the key agreement functions were in SECP256k1 class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Trent Mohay and others added 3 commits April 8, 2020 11:55
Signed-off-by: Trent Mohay <trent.mohay@consensys.net>
Signed-off-by: Trent Mohay <trent.mohay@consensys.net>
Signed-off-by: Trent Mohay <trent.mohay@consensys.net>
Signed-off-by: Trent Mohay <trent.mohay@consensys.net>
@rain-on rain-on merged commit d757af8 into hyperledger:master Apr 8, 2020
@rain-on rain-on deleted the handshaker branch April 8, 2020 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants