public abstract class Handshaker extends Object implements Destroyable
Modifier and Type | Field and Description |
---|---|
protected AdvancedPskStore |
advancedPskStore
Used to retrieve identity/pre-shared-key for a given destination
|
protected List<X509Certificate> |
certificateChain
The chain of certificates asserting this handshaker's identity.
|
protected boolean |
certificateIdentityAvailable
true , if the certificate identity request has completed,
false , otherwise. |
protected CertificateProvider |
certificateIdentityProvider
The handshaker's certificate identity provider.
|
protected NewAdvancedCertificateVerifier |
certificateVerifier
The logic in charge of verifying the chain of certificates asserting this
handshaker's identity
|
protected Random |
clientRandom |
protected ConnectionIdGenerator |
connectionIdGenerator
The configured connection id length.
|
protected ExtendedMasterSecretMode |
extendedMasterSecretMode
Send the extended master secret extension.
|
protected int |
flightNumber
The current flight number.
|
protected List<HandshakeMessage> |
handshakeMessages
List of handshake messages
|
protected org.slf4j.Logger |
LOGGER |
protected boolean |
otherPeersCertificateVerified
Indicates, that the verification of the other peer's certificate chain public key has finished.
|
protected PublicKey |
otherPeersPublicKey
The public key of the other peer
May be
null , if other peer sends a empty certificate. |
protected Object |
peerToLog |
protected PrivateKey |
privateKey
The handshaker's private key.
|
protected PublicKey |
publicKey
The handshaker's public key.
|
protected Integer |
recordSizeLimit
Record size limit.
|
protected Random |
serverRandom |
protected boolean |
sniEnabled
Support Server Name Indication TLS extension.
|
protected boolean |
useTruncatedCertificatePathForVerification
Truncate certificate path for validation.
|
Modifier | Constructor and Description |
---|---|
protected |
Handshaker(long initialRecordSequenceNo,
int initialMessageSeq,
RecordLayer recordLayer,
ScheduledExecutorService timer,
Connection connection,
DtlsConnectorConfig config)
Creates a new handshaker for negotiating a DTLS session with a given
peer.
|
Modifier and Type | Method and Description |
---|---|
void |
addApplicationDataForDeferredProcessing(org.eclipse.californium.elements.RawData outgoingMessage)
Add outgoing application data for deferred processing.
|
void |
addRecordsOfNextEpochForDeferredProcessing(Record incomingMessage)
Add incoming records for deferred processing.
|
void |
addSessionListener(SessionListener listener)
Adds a listener to the list of listeners to be notified
about session life cycle events.
|
protected void |
applyMasterSecret(SecretKey masterSecret)
Applying the key expansion on the master secret generates a large key
block to generate the encryption, MAC and IV keys.
|
protected void |
calculateKeys(SecretKey masterSecret)
Calculates the encryption key, MAC key and IV from a given master secret.
|
protected MessageDigest |
cloneMessageDigest(MessageDigest md)
Clone message digest for second FINISHED message.
|
void |
completePendingFlight()
Registers an outbound flight that has not been acknowledged by the peer
yet in order to be able to cancel its re-transmission later once it has
been acknowledged.
|
protected void |
contextEstablished()
Forward session established to registered listeners.
|
protected Finished |
createFinishedMessage(byte[] handshakeHash)
Create the FINISHED message for a pending handshake.
|
DTLSFlight |
createFlight()
Create new flight with the current
getDtlsContext() and the current
flightNumber . |
void |
destroy() |
protected abstract void |
doProcessMessage(HandshakeMessage message)
Does the specific processing of a message received from a peer in
the course of an ongoing handshake.
|
protected void |
ensureUndestroyed()
Check, if this handshaker has been destroyed.
|
protected void |
expectChangeCipherSpecMessage()
Marks this handshaker to expect the peer's CHANGE_CIPHER_SPEC message next.
|
protected void |
expectEcc()
Marks this handshaker to expect the peer to calculate some ECC function.
|
protected void |
expectMessage(DTLSMessage message)
Check, if message is expected.
|
protected byte[] |
generateMasterSecretSeed()
Generate seed for (extended) master secret.
|
Random |
getClientRandom()
Get client random.
|
Connection |
getConnection()
Gets related connection.
|
DTLSContext |
getDtlsContext()
Gets the dtls context this handshaker is used to establish.
|
Throwable |
getFailureCause()
Get cause of failure.
|
protected MessageDigest |
getHandshakeMessageDigest()
Get message digest for FINISH message.
|
InetSocketAddress |
getPeerAddress()
Gets the IP address and port of the peer this handshaker is used to
negotiate a session with.
|
ConnectionId |
getReadConnectionId()
Get read connection ID for inbound records
|
ServerNames |
getServerNames()
Gets the effective server names of
DTLSSession . |
Random |
getServerRandom()
Get server random.
|
DTLSSession |
getSession()
Gets the session this handshaker is used to establish.
|
void |
handshakeAborted(Throwable cause)
Abort handshake.
|
void |
handshakeCompleted()
Forward handshake completed to registered listeners.
|
void |
handshakeFailed(Throwable cause)
Notifies all registered session listeners about a handshake failure.
|
void |
handshakeFlightRetransmitted(int flight)
Notifies all registered session listeners about a handshake
retransmit of a flight.
|
protected void |
handshakeStarted()
Forward handshake start to registered listeners.
|
boolean |
hasContextEstablished()
Checks, if the dtls context is established.
|
boolean |
hasMasterSecret()
Checks, if the master secret is available.
|
protected boolean |
hasPendingApiCall()
Checks, if a internal API call is pending.
|
boolean |
isChangeCipherSpecMessageExpected()
Checks whether the peer's CHANGE_CIPHER_SPEC message is the next message
expected in the ongoing handshake.
|
protected abstract boolean |
isClient() |
boolean |
isDestroyed() |
protected boolean |
isExpectedStates(HandshakeState[] states)
Checks, if the provided states are the currently expected ones.
|
boolean |
isExpired()
Test, if handshake is expired according nano realtime.
|
boolean |
isInboundMessageProcessed()
Check, if inbound messages are all processed.
|
boolean |
isProbing()
Test, if handshake was started in probing mode.
|
boolean |
isPskRequestPending()
Check, if psk request is pending.
|
boolean |
isRemovingConnection()
Check, if the connection must be removed.
|
void |
processAsyncHandshakeResult(HandshakeResult handshakeResult)
Process asynchronous handshake result.
|
protected abstract void |
processCertificateIdentityAvailable()
Do the handshaker specific processing of certificate identity.
|
protected void |
processCertificateIdentityResult(CertificateIdentityResult result)
Process the certificate identity.
|
protected void |
processCertificateVerificationResult(CertificateVerificationResult certificateVerificationResult)
Process certificate verification result.
|
protected abstract void |
processCertificateVerified()
Do the handshaker specific processing of successful verified certificates
|
protected abstract void |
processMasterSecret()
Do the handshaker specific master secret processing
|
void |
processMessage(Record record)
Processes a handshake record received from a peer based on the
handshake's current state.
|
protected void |
processPskSecretResult(PskSecretResult pskSecretResult)
Process PSK secret result.
|
protected GenericHandshakeMessage |
reassembleFragment(FragmentedHandshakeMessage fragment)
Process a received fragmented handshake message.
|
void |
removeSessionListener(SessionListener listener)
Removes a listener from the list of listeners to be notified
about session life cycle events.
|
boolean |
requestCertificateIdentity(List<X500Principal> issuers,
ServerNames serverNames,
List<SignatureAndHashAlgorithm> signatureAndHashAlgorithms,
List<XECDHECryptography.SupportedGroup> curves)
Request the certificate based identity.
|
protected void |
requestPskSecretResult(PskPublicInformation pskIdentity,
SecretKey otherSecret,
byte[] seed)
Request psk secret result for PSK cipher suites.
|
void |
resetProbing()
Reset probing mode, when data is received during.
|
protected void |
resumeMasterSecret()
Resume master secret from established session.
|
void |
sendFlight(DTLSFlight flight)
Send flight.
|
void |
sendLastFlight(DTLSFlight flight)
Send last flight.
|
protected void |
setCurrentReadState() |
protected void |
setCurrentWriteState() |
protected void |
setCustomArgument(HandshakeResult result)
Set custom argument for
ApplicationLevelInfoSupplier . |
protected void |
setExpectedStates(HandshakeState[] states)
Sets expected states.
|
void |
setFailureCause(Throwable cause)
Set the failure cause.
|
void |
setGenerateClusterMacKeys(boolean enable)
Enable to generate keys for cluster MAC.
|
protected boolean |
setOtherPeersSignatureVerified()
Set the signature of the other peer to verified.
|
boolean |
supportsConnectionId()
Check, if this peer supports cid.
|
List<org.eclipse.californium.elements.RawData> |
takeDeferredApplicationData()
Take deferred outgoing application data.
|
void |
takeDeferredApplicationData(Handshaker replacedHandshaker)
Take deferred outgoing application data from provided handshaker.
|
List<Record> |
takeDeferredRecordsOfNextEpoch()
Take deferred incoming records of next epoch.
|
void |
verifyCertificate(CertificateMessage message)
Start validating the X.509 certificate chain provided by the the peer as
part of this message, or the raw public key of the message.
|
protected void |
verifyFinished(Finished finished,
byte[] handshakeHash)
Verify the handshake hash of the FINISHED.
|
protected void |
wrapMessage(DTLSFlight flight,
ChangeCipherSpecMessage ccsMessage)
Add a change cipher specs message to the flight.
|
protected void |
wrapMessage(DTLSFlight flight,
HandshakeMessage handshakeMessage)
Add a handshake message to the flight.
|
protected final org.slf4j.Logger LOGGER
protected Random clientRandom
protected Random serverRandom
protected final NewAdvancedCertificateVerifier certificateVerifier
protected final AdvancedPskStore advancedPskStore
protected final ConnectionIdGenerator connectionIdGenerator
null
, not supported,
0
supported but not used.protected int flightNumber
protected Integer recordSizeLimit
null
, if not used.protected final Object peerToLog
protected final List<HandshakeMessage> handshakeMessages
protected final CertificateProvider certificateIdentityProvider
protected PrivateKey privateKey
null
, if no matching identity is available.protected PublicKey publicKey
null
, if no matching identity is available.protected List<X509Certificate> certificateChain
null
, if no matching identity is available.protected PublicKey otherPeersPublicKey
null
, if other peer sends a empty certificate.protected boolean otherPeersCertificateVerified
protected final boolean sniEnabled
protected final ExtendedMasterSecretMode extendedMasterSecretMode
protected final boolean useTruncatedCertificatePathForVerification
protected boolean certificateIdentityAvailable
true
, if the certificate identity request has completed,
false
, otherwise. Gets true
, even if no matching identity
is available.protected Handshaker(long initialRecordSequenceNo, int initialMessageSeq, RecordLayer recordLayer, ScheduledExecutorService timer, Connection connection, DtlsConnectorConfig config)
initialRecordSequenceNo
- the initial record sequence number (since 3.0).initialMessageSeq
- the initial message sequence number to use and
expect in the exchange of handshake messages with the peer.
This parameter can be used to initialize the
message_seq and receive_next_seq counters to
a value larger than 0, e.g. if one or more cookie exchange
round-trips have been performed with the peer before the
handshake starts.recordLayer
- the object to use for sending flights to the peer.timer
- scheduled executor for flight retransmission (since 2.4).connection
- the connection related to this handshaker.config
- the dtls configurationNullPointerException
- if any of the provided parameter is
null
IllegalArgumentException
- if the initial record or message sequence number
is negativepublic boolean isInboundMessageProcessed()
true
, all inbound messages are processed, false
,
some inbound messages are pending.public final void processMessage(Record record) throws HandshakeException
inboundMessageBuffer
and
delegates processing of the ordered messages to the
doProcessMessage(HandshakeMessage)
method. If
ChangeCipherSpecMessage
is processed, the
nextEpochDeferredRecords
are passed again to the RecordLayer
to
get decrypted and processed.record
- the handshake recordHandshakeException
- if the record's plaintext fragment cannot be
parsed into a handshake message or cannot be processed
properlyIllegalArgumentException
- if the record's epoch differs from the
DTLS context's read epochprotected boolean isExpectedStates(HandshakeState[] states)
states
- state to checktrue
, if the provided states are the currently expected
onessetExpectedStates(HandshakeState[])
protected void setExpectedStates(HandshakeState[] states)
statesIndex
.states
- expected statesisExpectedStates(HandshakeState[])
,
expectMessage(DTLSMessage)
protected void expectMessage(DTLSMessage message) throws HandshakeException
message
- message to checkHandshakeException
- if the message is not expectedprotected abstract void doProcessMessage(HandshakeMessage message) throws HandshakeException
message
- the message received from the peerHandshakeException
- if the handshake message cannot be processed properlypublic void processAsyncHandshakeResult(HandshakeResult handshakeResult) throws HandshakeException
doProcessMessage(HandshakeMessage)
implementations! If handshake expects the cipher change message, then
process the messages from the inbound buffer.handshakeResult
- asynchronous handshake resultHandshakeException
- if an error occursIllegalStateException
- if pskRequestPending
or
certificateVerificationPending
is not pending, or
the handshaker isDestroyed()
.protected void processPskSecretResult(PskSecretResult pskSecretResult) throws HandshakeException
pskSecretResult
- PSK secret result.HandshakeException
- if an error occursIllegalStateException
- if pskRequestPending
is not
pending, or the handshaker isDestroyed()
.protected abstract void processMasterSecret() throws HandshakeException
HandshakeException
- if an error occursprotected void processCertificateVerificationResult(CertificateVerificationResult certificateVerificationResult) throws HandshakeException
certificateVerificationResult
- certificate verification resultHandshakeException
- if an error occurred during processingIllegalStateException
- if certificateVerificationPending
is not pending, or the handshaker isDestroyed()
.protected abstract void processCertificateVerified() throws HandshakeException
HandshakeException
- if an error occursprotected void processCertificateIdentityResult(CertificateIdentityResult result) throws HandshakeException
result
- certificate identityHandshakeException
- if an error occursIllegalStateException
- if no call is pending (see
certificateIdentityPending
), or the handshaker
isDestroyed()
.protected abstract void processCertificateIdentityAvailable() throws HandshakeException
HandshakeException
- if an error occursprotected void setCustomArgument(HandshakeResult result)
ApplicationLevelInfoSupplier
.
A null
custom argument will not overwrite a already set one.result
- handshake result with custom argument.protected boolean hasPendingApiCall()
AdvancedPskStore
or NewAdvancedCertificateVerifier
may result in pending API calls. Such API calls are timed out with the
current flight and so report as INTERNAL_ERROR alert instead of silently
ignore that time out.true
, if call is pending, false
, if not.protected boolean setOtherPeersSignatureVerified()
DTLSSession.setPeerIdentity(Principal)
, if the
certificate chain or public key of the other peer is also already
verified.otherPeersCertificateVerified
protected final MessageDigest getHandshakeMessageDigest()
handshakeMessages
protected final MessageDigest cloneMessageDigest(MessageDigest md) throws HandshakeException
md
- message digestHandshakeException
- if cloning fails.protected void applyMasterSecret(SecretKey masterSecret)
masterSecret
- the master secret.masterSecret
,
calculateKeys(SecretKey)
protected void resumeMasterSecret()
masterSecret
,
calculateKeys(SecretKey)
protected void calculateKeys(SecretKey masterSecret)
masterSecret
- the master secret.protected byte[] generateMasterSecretSeed()
protected void requestPskSecretResult(PskPublicInformation pskIdentity, SecretKey otherSecret, byte[] seed) throws HandshakeException
pskRequestPending
.pskIdentity
- PSK identityotherSecret
- others secret for ECHDE support. Maybe null
.seed
- seed to be used for (extended) master secret.HandshakeException
- if an error occursNullPointerException
- if seed is null
protected final void setCurrentReadState()
protected final void setCurrentWriteState()
protected final Finished createFinishedMessage(byte[] handshakeHash)
handshakeHash
- the hash of the handshake messagesprotected final void verifyFinished(Finished finished, byte[] handshakeHash) throws HandshakeException
finished
- received FINISHED message.handshakeHash
- the hash of the handshake messagesHandshakeException
- if the data can not be verifiedpublic final boolean hasMasterSecret()
true
, if available, false
, otherwise.protected final void wrapMessage(DTLSFlight flight, HandshakeMessage handshakeMessage)
flight
- the flight to add the messageshandshakeMessage
- the handshake messageprotected final void wrapMessage(DTLSFlight flight, ChangeCipherSpecMessage ccsMessage)
flight
- the flight to add change cipher specs wrapped messagesccsMessage
- the change cipher specs messageprotected GenericHandshakeMessage reassembleFragment(FragmentedHandshakeMessage fragment) throws HandshakeException
fragment
- the fragmented handshake message.null
, otherwise.HandshakeException
- if the reassembling failsprotected abstract boolean isClient()
public final ServerNames getServerNames()
DTLSSession
.null
, if disabled or not
available.sniEnabled
public final DTLSSession getSession()
public final DTLSContext getDtlsContext()
public final InetSocketAddress getPeerAddress()
public final Connection getConnection()
public DTLSFlight createFlight()
getDtlsContext()
and the current
flightNumber
.public boolean supportsConnectionId()
true
, if the this peer supports cid, false
, if
not.ConnectionId.supportsConnectionId(ConnectionIdGenerator)
public ConnectionId getReadConnectionId()
null
, if connection ID
is not supported, a empty connection ID, if connection ID is
supported but not used for inbound records.public Random getClientRandom()
null
, if not available.public Random getServerRandom()
null
, if not available.public void addApplicationDataForDeferredProcessing(org.eclipse.californium.elements.RawData outgoingMessage)
outgoingMessage
- outgoing application datapublic void addRecordsOfNextEpochForDeferredProcessing(Record incomingMessage)
incomingMessage
- incoming record.public List<org.eclipse.californium.elements.RawData> takeDeferredApplicationData()
public List<Record> takeDeferredRecordsOfNextEpoch()
public void takeDeferredApplicationData(Handshaker replacedHandshaker)
replacedHandshaker
- replaced handshaker to take deferred outgoing
application datapublic void completePendingFlight()
public void sendLastFlight(DTLSFlight flight)
flight
- last flight to sendsendFlight(DTLSFlight)
public void sendFlight(DTLSFlight flight)
flight
- flight to sendsendFlight(DTLSFlight)
public final void addSessionListener(SessionListener listener)
listener
- The listener to add.public final void removeSessionListener(SessionListener listener)
listener
- The listener to remove.protected final void handshakeStarted() throws HandshakeException
HandshakeException
- if thrown by listenerprotected final void contextEstablished() throws HandshakeException
amendPeerPrincipal()
.HandshakeException
- if thrown by listenerpublic final void handshakeCompleted()
public final void handshakeFailed(Throwable cause)
setFailureCause(Throwable)
was called before, only calls with
the same cause will notify the listeners. If
setFailureCause(Throwable)
wasn't called before, sets the
cause property to the given cause.cause
- The reason for the failure.isRemovingConnection()
,
handshakeAborted(Throwable)
public final void handshakeAborted(Throwable cause)
setFailureCause(Throwable)
was called before, only calls with
the same cause will notify the listeners. If
setFailureCause(Throwable)
wasn't called before, sets the
cause property to the given cause.cause
- The reason for the abort.handshakeFailed(Throwable)
,
isRemovingConnection()
public boolean hasContextEstablished()
true
, if the dtls context is established, false
,
otherwise.public boolean isProbing()
true
, if handshake is in probing mode, false
,
otherwise.ResumingClientHandshaker
,
ClientHandshaker
public void resetProbing()
ResumingClientHandshaker
public boolean isExpired()
true
, if handshake is expired, mainly during deep sleep,
false
, if the handshake is still in time.public boolean isPskRequestPending()
true
, if psk request is pending, false
,
otherwise.public boolean isRemovingConnection()
handshakeFailed(Throwable)
was called, and the connection has no established session.true
, remove the connection, false
, keep it.public Throwable getFailureCause()
null
, if the cause is unknown and not set beforesetFailureCause(Throwable)
,
handshakeFailed(Throwable)
public void setFailureCause(Throwable cause)
handshakeFailed(Throwable)
to
notify listener in that case.cause
- failure causehandshakeFailed(Throwable)
,
getFailureCause()
public void setGenerateClusterMacKeys(boolean enable)
enable
- true
, generate keys for cluster MAC, false
,
otherwise.public final void handshakeFlightRetransmitted(int flight)
flight
- number of retransmitted flight.public final boolean isChangeCipherSpecMessageExpected()
true
if the message is expected next.protected final void expectChangeCipherSpecMessage()
protected void expectEcc()
additionalTimeoutForEcc
will be added for the next flight in
that case.public void verifyCertificate(CertificateMessage message) throws HandshakeException
NewAdvancedCertificateVerifier
. If a asynchronous implementation
of NewAdvancedCertificateVerifier
is used, the result will be not
available after this call, but will be available after the callback of the
asynchronous implementation.message
- the certificate messageHandshakeException
- if any of the checks failspublic boolean requestCertificateIdentity(List<X500Principal> issuers, ServerNames serverNames, List<SignatureAndHashAlgorithm> signatureAndHashAlgorithms, List<XECDHECryptography.SupportedGroup> curves) throws HandshakeException
issuers
- list of trusted issuersserverNames
- indicated server namessignatureAndHashAlgorithms
- list of supported signatures and hash
algorithmscurves
- ec-curves (supported groups). May be null
.true
, if the certificate based identity is available,
false
, if the certificate based identity is requested.HandshakeException
- if any of the checks failspublic void destroy() throws DestroyFailedException
destroy
in interface Destroyable
DestroyFailedException
public boolean isDestroyed()
isDestroyed
in interface Destroyable
protected void ensureUndestroyed()
IllegalStateException
- if the handshake has been destroyed.Copyright © 2021 Eclipse Foundation. All rights reserved.