@@ -136,6 +136,7 @@ public class NoiseHandshake {
136136
137137 private int currentMessagePattern = 0 ;
138138 private boolean hasSplit = false ;
139+ private boolean hasFallenBack = false ;
139140
140141 private final CipherState cipherState ;
141142 private final NoiseHash noiseHash ;
@@ -478,6 +479,10 @@ public boolean isOneWayHandshake() {
478479 * @see #isDone()
479480 */
480481 public boolean isExpectingRead () {
482+ if (hasFallenBack ) {
483+ return false ;
484+ }
485+
481486 if (currentMessagePattern < handshakePattern .getHandshakeMessagePatterns ().length ) {
482487 return handshakePattern .getHandshakeMessagePatterns ()[currentMessagePattern ].sender () != role ;
483488 }
@@ -497,6 +502,10 @@ public boolean isExpectingRead() {
497502 * @see #isDone()
498503 */
499504 public boolean isExpectingWrite () {
505+ if (hasFallenBack ) {
506+ return false ;
507+ }
508+
500509 if (currentMessagePattern < handshakePattern .getHandshakeMessagePatterns ().length ) {
501510 return handshakePattern .getHandshakeMessagePatterns ()[currentMessagePattern ].sender () == role ;
502511 }
@@ -514,6 +523,10 @@ public boolean isExpectingWrite() {
514523 * @see #isExpectingWrite()
515524 */
516525 public boolean isDone () {
526+ if (hasFallenBack ) {
527+ return false ;
528+ }
529+
517530 return currentMessagePattern == handshakePattern .getHandshakeMessagePatterns ().length ;
518531 }
519532
@@ -1246,7 +1259,6 @@ private void handleMixKeyToken(final HandshakePattern.Token token) {
12461259 * @see HandshakePattern#isFallbackPattern()
12471260 */
12481261 public NoiseHandshake fallbackTo (final String handshakePatternName ) throws NoSuchPatternException {
1249- // TODO Self-destruct after falling back
12501262 return fallbackTo (handshakePatternName , null );
12511263 }
12521264
@@ -1271,6 +1283,10 @@ public NoiseHandshake fallbackTo(final String handshakePatternName) throws NoSuc
12711283 * @see HandshakePattern#isFallbackPattern()
12721284 */
12731285 public NoiseHandshake fallbackTo (final String handshakePatternName , @ Nullable final List <byte []> preSharedKeys ) throws NoSuchPatternException {
1286+ if (hasFallenBack ) {
1287+ throw new IllegalStateException ("Handshake has already fallen back to another pattern" );
1288+ }
1289+
12741290 final HandshakePattern fallbackPattern = HandshakePattern .getInstance (handshakePatternName );
12751291
12761292 if (!fallbackPattern .isFallbackPattern ()) {
@@ -1313,6 +1329,8 @@ public NoiseHandshake fallbackTo(final String handshakePatternName, @Nullable fi
13131329 fallbackRemoteEphemeralPublicKey = null ;
13141330 }
13151331
1332+ hasFallenBack = true ;
1333+
13161334 return new NoiseHandshake (role ,
13171335 fallbackPattern ,
13181336 keyAgreement ,
0 commit comments