-
Notifications
You must be signed in to change notification settings - Fork 960
Update Handshakers to use NodeKey #666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: Trent Mohay <trent.mohay@consensys.net>
@@ -53,7 +54,8 @@ public HandshakeHandlerOutbound( | |||
connectionFuture, | |||
connectionEventDispatcher, | |||
metricsSystem); | |||
handshaker.prepareInitiator(kp, SECP256K1.PublicKey.create(peer.getId())); | |||
handshaker.prepareInitiator( |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about ephKeyPair
?
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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' ?
There was a problem hiding this comment.
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.
There was a problem hiding this 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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
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)); |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
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>
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