heavy logging

This commit is contained in:
callebtc
2025-07-20 13:53:58 +02:00
parent d507996da8
commit ec66b41609
4 changed files with 110 additions and 16 deletions
@@ -123,9 +123,17 @@ class NoiseSession(
try {
Log.d(TAG, "Creating HandshakeState with role: ${if (role == HandshakeState.INITIATOR) "INITIATOR" else "RESPONDER"}")
// LOGGING: Track Android handshake initialization (matching iOS)
Log.d(TAG, "=== ANDROID NOISE SESSION - BEFORE HANDSHAKE INIT ===")
Log.d(TAG, "Creating NoiseHandshakeState for peer: $peerID")
Log.d(TAG, "Role: ${if (role == HandshakeState.INITIATOR) "INITIATOR" else "RESPONDER"}")
handshakeState = HandshakeState(PROTOCOL_NAME, role)
Log.d(TAG, "HandshakeState created successfully")
Log.d(TAG, "=== ANDROID NOISE SESSION - AFTER HANDSHAKE INIT ===")
Log.d(TAG, "NoiseHandshakeState created and mixPreMessageKeys() completed")
if (handshakeState?.needsLocalKeyPair() == true) {
Log.d(TAG, "Local static key pair is required for XX pattern")
@@ -181,6 +189,8 @@ class NoiseSession(
*/
@Synchronized
fun startHandshake(): ByteArray {
Log.d(TAG, "Starting noise XX handshake with $peerID as INITIATOR")
if (!isInitiator) {
throw IllegalStateException("Only initiator can start handshake")
}
@@ -189,8 +199,6 @@ class NoiseSession(
throw IllegalStateException("Handshake already started")
}
Log.d(TAG, "Starting real XX handshake with $peerID as initiator")
try {
// Initialize handshake as initiator
initializeNoiseHandshake(HandshakeState.INITIATOR)
@@ -262,7 +270,7 @@ class NoiseSession(
HandshakeState.SPLIT -> {
// Handshake complete, split into transport keys
completeHandshake()
Log.d(TAG, "XX handshake completed with $peerID")
Log.d(TAG, "🔒 XX handshake completed with $peerID")
null
}
@@ -23,6 +23,14 @@ class NoiseSessionManager(
// MARK: - Simple Session Management
/**
* Add new session for a peer
*/
fun addSession(peerID: String, session: NoiseSession) {
sessions[peerID] = session
Log.d(TAG, "Added new session for $peerID")
}
/**
* Get existing session for a peer
*/
@@ -45,6 +53,8 @@ class NoiseSessionManager(
* SIMPLIFIED: Initiate handshake - no tie breaker, just start
*/
fun initiateHandshake(peerID: String): ByteArray {
Log.d(TAG, "initiateHandshake($peerID)")
// Remove any existing session first
removeSession(peerID)
@@ -55,11 +65,12 @@ class NoiseSessionManager(
localStaticPrivateKey = localStaticPrivateKey,
localStaticPublicKey = localStaticPublicKey
)
sessions[peerID] = session
Log.d(TAG, "Storing new INITIATOR session for $peerID")
addSession(peerID, session)
try {
val handshakeData = session.startHandshake()
Log.d(TAG, "Started handshake with $peerID as initiator")
Log.d(TAG, "Started handshake with $peerID as INITIATOR")
return handshakeData
} catch (e: Exception) {
sessions.remove(peerID)
@@ -74,18 +85,18 @@ class NoiseSessionManager(
Log.d(TAG, "handleIncomingHandshake($peerID, ${message.size} bytes)")
try {
var session = sessions[peerID]
var session = getSession(peerID)
// If no session exists, create one as responder
if (session == null) {
Log.d(TAG, "Creating new responder session for $peerID")
Log.d(TAG, "Creating new RESPONDER session for $peerID")
session = NoiseSession(
peerID = peerID,
isInitiator = false,
localStaticPrivateKey = localStaticPrivateKey,
localStaticPublicKey = localStaticPublicKey
)
sessions[peerID] = session
addSession(peerID, session)
}
// Process handshake message
@@ -114,7 +125,7 @@ class NoiseSessionManager(
* SIMPLIFIED: Encrypt data
*/
fun encrypt(data: ByteArray, peerID: String): ByteArray {
val session = sessions[peerID] ?: throw IllegalStateException("No session found for $peerID")
val session = getSession(peerID) ?: throw IllegalStateException("No session found for $peerID")
if (!session.isEstablished()) {
throw IllegalStateException("Session not established with $peerID")
}
@@ -125,7 +136,7 @@ class NoiseSessionManager(
* SIMPLIFIED: Decrypt data
*/
fun decrypt(encryptedData: ByteArray, peerID: String): ByteArray {
val session = sessions[peerID]
val session = getSession(peerID)
if (session == null) {
Log.e(TAG, "No session found for $peerID when trying to decrypt")
throw IllegalStateException("No session found for $peerID")
@@ -141,7 +152,7 @@ class NoiseSessionManager(
* Check if session is established with peer
*/
fun hasEstablishedSession(peerID: String): Boolean {
val hasSession = sessions[peerID]?.isEstablished() ?: false
val hasSession = getSession(peerID)?.isEstablished() ?: false
Log.d(TAG, "hasEstablishedSession($peerID): $hasSession")
return hasSession
}
@@ -150,14 +161,14 @@ class NoiseSessionManager(
* Get remote static public key for a peer (if session established)
*/
fun getRemoteStaticKey(peerID: String): ByteArray? {
return sessions[peerID]?.getRemoteStaticPublicKey()
return getSession(peerID)?.getRemoteStaticPublicKey()
}
/**
* Get handshake hash for channel binding (if session established)
*/
fun getHandshakeHash(peerID: String): ByteArray? {
return sessions[peerID]?.getHandshakeHash()
return getSession(peerID)?.getHandshakeHash()
}
/**
@@ -35,6 +35,8 @@ import javax.crypto.ShortBufferException;
*/
public class HandshakeState implements Destroyable {
private static final String TAG = "AndroidHandshake";
private SymmetricState symmetric;
private boolean isInitiator;
private DHState localKeyPair;
@@ -465,6 +467,17 @@ public class HandshakeState implements Destroyable {
// Empty value for when the prologue is not supplied.
private static final byte[] emptyPrologue = new byte [0];
/**
* Converts a byte array to hex string for logging (matching iOS hex format)
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
/**
* Starts the handshake running.
*
@@ -511,11 +524,19 @@ public class HandshakeState implements Destroyable {
throw new IllegalStateException("Pre-shared key required");
}
// Log the symmetric state BEFORE any mixing operations (matching iOS)
Log.d(TAG, "=== ANDROID HANDSHAKE START - INITIAL STATE ===");
Log.d(TAG, "Protocol: " + symmetric.getProtocolName());
Log.d(TAG, "Role: " + (isInitiator ? "INITIATOR" : "RESPONDER"));
Log.d(TAG, "Initial symmetric hash: " + bytesToHex(symmetric.getHandshakeHash()));
// Hash the prologue value.
Log.d(TAG, "Mixing empty prologue");
if (prologue != null)
symmetric.mixHash(prologue, 0, prologue.length);
else
symmetric.mixHash(emptyPrologue, 0, 0);
Log.d(TAG, "Hash after empty prologue: " + bytesToHex(symmetric.getHandshakeHash()));
// Hash the pre-shared key into the chaining key and handshake hash.
if (preSharedKey != null)
@@ -523,6 +544,7 @@ public class HandshakeState implements Destroyable {
// Mix the pre-supplied public keys into the handshake hash.
if (isInitiator) {
Log.d(TAG, "XX pattern - no pre-message keys to mix");
if ((requirements & LOCAL_PREMSG) != 0)
symmetric.mixPublicKey(localKeyPair);
if ((requirements & FALLBACK_PREMSG) != 0) {
@@ -535,6 +557,7 @@ public class HandshakeState implements Destroyable {
if ((requirements & REMOTE_PREMSG) != 0)
symmetric.mixPublicKey(remotePublicKey);
} else {
Log.d(TAG, "XX pattern - no pre-message keys to mix");
if ((requirements & REMOTE_PREMSG) != 0)
symmetric.mixPublicKey(remotePublicKey);
if ((requirements & FALLBACK_PREMSG) != 0) {
@@ -547,7 +570,11 @@ public class HandshakeState implements Destroyable {
if ((requirements & LOCAL_PREMSG) != 0)
symmetric.mixPublicKey(localKeyPair);
}
// Log the symmetric.hash in hex:
// Log final state after all initialization (matching iOS)
Log.d(TAG, "=== ANDROID HANDSHAKE START - FINAL STATE ===");
Log.d(TAG, "Final symmetric hash after mixPreMessageKeys(): " + bytesToHex(symmetric.getHandshakeHash()));
Log.d(TAG, "===========================================");
// The handshake has officially started - set the first action.
if (isInitiator)
@@ -22,6 +22,8 @@
package com.bitchat.android.noise.southernstorm.protocol;
import android.util.Log;
import java.io.UnsupportedEncodingException;
import java.security.DigestException;
import java.security.MessageDigest;
@@ -36,6 +38,8 @@ import javax.crypto.ShortBufferException;
*/
class SymmetricState implements Destroyable {
private static final String TAG = "AndroidSymmetric";
private String name;
private CipherState cipher;
private MessageDigest hash;
@@ -43,6 +47,17 @@ class SymmetricState implements Destroyable {
private byte[] h;
private byte[] prev_h;
/**
* Converts a byte array to hex string for logging (matching iOS hex format)
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
/**
* Constructs a new symmetric state object.
*
@@ -79,6 +94,14 @@ class SymmetricState implements Destroyable {
}
System.arraycopy(h, 0, ck, 0, hashLength);
// LOGGING: Initial symmetric state after protocol name initialization (matching iOS)
Log.d(TAG, "=== ANDROID SYMMETRIC STATE INITIALIZED ===");
Log.d(TAG, "Protocol: " + protocolName);
Log.d(TAG, "Initial hash (h): " + bytesToHex(h));
Log.d(TAG, "Initial chaining key (ck): " + bytesToHex(ck));
Log.d(TAG, "Hash length: " + h.length);
Log.d(TAG, "=========================================");
}
/**
@@ -111,6 +134,14 @@ class SymmetricState implements Destroyable {
*/
public void mixKey(byte[] data, int offset, int length)
{
// LOGGING: Before mixKey operation (matching iOS)
byte[] inputData = new byte[length];
System.arraycopy(data, offset, inputData, 0, length);
Log.d(TAG, "*** Android mixKey() BEFORE ***");
Log.d(TAG, "Input data (" + length + " bytes): " + bytesToHex(inputData));
Log.d(TAG, "Current CK: " + bytesToHex(ck));
Log.d(TAG, "Current Hash: " + bytesToHex(h));
int keyLength = cipher.getKeyLength();
byte[] tempKey = new byte [keyLength];
try {
@@ -119,6 +150,12 @@ class SymmetricState implements Destroyable {
} finally {
Noise.destroy(tempKey);
}
// LOGGING: After mixKey operation (matching iOS)
Log.d(TAG, "*** Android mixKey() AFTER ***");
Log.d(TAG, "New CK: " + bytesToHex(ck));
Log.d(TAG, "Hash unchanged: " + bytesToHex(h));
Log.d(TAG, "Cipher now has key: " + (cipher.getMACLength() > 0));
}
/**
@@ -130,7 +167,18 @@ class SymmetricState implements Destroyable {
*/
public void mixHash(byte[] data, int offset, int length)
{
// LOGGING: Before mixHash operation (matching iOS)
byte[] inputData = new byte[length];
System.arraycopy(data, offset, inputData, 0, length);
Log.d(TAG, "*** Android mixHash() BEFORE ***");
Log.d(TAG, "Input data (" + length + " bytes): " + bytesToHex(inputData));
Log.d(TAG, "Current Hash: " + bytesToHex(h));
hashTwo(h, 0, h.length, data, offset, length, h, 0, h.length);
// LOGGING: After mixHash operation (matching iOS)
Log.d(TAG, "*** Android mixHash() AFTER ***");
Log.d(TAG, "New Hash: " + bytesToHex(h));
}
/**