Skip to content

Commit

Permalink
v1.4.1: fix for signed messages, able to bolus from x2 again
Browse files Browse the repository at this point in the history
  • Loading branch information
jwoglom committed Dec 10, 2024
1 parent ed78bca commit db7ef33
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 6 deletions.
18 changes: 18 additions & 0 deletions androidLib/src/main/java/com/jwoglom/pumpx2/pump/PumpState.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public class PumpState {
static {
PumpStateSupplier.pumpPairingCode = PumpState::getPairingCodeCached;
PumpStateSupplier.jpakeDerivedSecretHex = PumpState::getJpakeDerivedSecretCached;
PumpStateSupplier.jpakeServerNonceHex = PumpState::getJpakeServerNonceCached;
PumpStateSupplier.pumpTimeSinceReset = PumpState::getPumpTimeSinceReset;
PumpStateSupplier.pumpApiVersion = PumpState::getPumpAPIVersion;
PumpStateSupplier.actionsAffectingInsulinDeliveryEnabled = PumpState::actionsAffectingInsulinDeliveryEnabled;
Expand Down Expand Up @@ -69,6 +70,23 @@ public static String getJpakeDerivedSecretCached() {
return savedJpakeDerivedSecret;
}


private static final String JPAKE_SERVER_NONCE_PREF = "jpakeServerNonce";
public static String savedJpakeServerNonce = null;
public static String getJpakeServerNonce(Context context) {
savedJpakeServerNonce = prefs(context).getString(JPAKE_SERVER_NONCE_PREF, null);
return savedJpakeServerNonce;
}

public static void setJpakeServerNonce(Context context, String hexDerivedSecret) {
prefs(context).edit().putString(JPAKE_SERVER_NONCE_PREF, hexDerivedSecret).commit();
savedJpakeServerNonce = hexDerivedSecret;
}

public static String getJpakeServerNonceCached() {
return savedJpakeServerNonce;
}

// This is used during packet generation for signed messages,
// and is filled by calling TimeSinceResetRequest
public static Long pumpTimeSinceReset = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,8 @@ private synchronized void innerCharacteristicUpdate(@NotNull BluetoothPeripheral
PumpState.setSavedBluetoothMAC(context, peripheral.getAddress());
byte[] derivedSecret = JpakeAuthBuilder.getInstance().getDerivedSecret();
PumpState.setJpakeDerivedSecret(context, Hex.encodeHexString(derivedSecret));
byte[] serverNonce = JpakeAuthBuilder.getInstance().getServerNonce();
PumpState.setJpakeServerNonce(context, Hex.encodeHexString(serverNonce));
tandemPump.onPumpConnected(peripheral);
} else if (JpakeAuthBuilder.getInstance().invalid()) {
Timber.i("JpakeAuth DONE: Invalid");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ public void onPumpConnected(BluetoothPeripheral peripheral) {

// hack: ensure cached in PumpState.
Timber.i("JpakeDerivedSecret=%s", PumpState.getJpakeDerivedSecret(context));
Timber.i("JpakeServerNonce=%s", PumpState.getJpakeServerNonce(context));

sendCommand(peripheral, new ApiVersionRequest());
sendCommand(peripheral, new TimeSinceResetRequest());
Expand Down Expand Up @@ -249,6 +250,7 @@ public void pair(BluetoothPeripheral peripheral, @Nullable AbstractCentralChalle
}
} else if (PumpState.pairingCodeType == PairingCodeType.SHORT_6CHAR) {
String jpakeSecretHex = PumpState.getJpakeDerivedSecret(context);
PumpState.setJpakeServerNonce(context, "");
if (Strings.isNullOrEmpty(jpakeSecretHex)) {
Timber.i("TandemPump: pair(SHORT_6CHAR, pairingCode=" + pairingCode + ", BOOTSTRAP)");
JpakeAuthBuilder.clearInstance();
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugins {
}

group = "com.jwoglom.pumpx2"
version = "1.4.0"
version = "1.4.1"

java {
//withJavadocJar()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.jwoglom.pumpx2.pump.messages.bluetooth;

import com.google.common.base.Strings;
import com.jwoglom.pumpx2.pump.messages.builders.crypto.Hkdf;
import com.jwoglom.pumpx2.pump.messages.models.ApiVersion;
import com.jwoglom.pumpx2.shared.Hex;
import com.jwoglom.pumpx2.shared.L;
Expand All @@ -15,25 +17,32 @@ public class PumpStateSupplier {
public static Supplier<byte[]> authenticationKey = PumpStateSupplier::determinePumpAuthKey;
public static Supplier<String> pumpPairingCode = null;
public static Supplier<String> jpakeDerivedSecretHex = null;
public static Supplier<String> jpakeServerNonceHex = null;
public static Supplier<Long> pumpTimeSinceReset = null;
public static Supplier<ApiVersion> pumpApiVersion = null;
public static Supplier<Boolean> controlIQSupported = () -> false;
public static Supplier<Boolean> actionsAffectingInsulinDeliveryEnabled = () -> false;


private static byte[] determinePumpAuthKey() {
String jpake = jpakeDerivedSecretHex == null ? null : jpakeDerivedSecretHex.get();
String derivedSecret = jpakeDerivedSecretHex == null ? null : jpakeDerivedSecretHex.get();
String serverNonce = jpakeServerNonceHex == null ? null : jpakeServerNonceHex.get();
String code = pumpPairingCode == null ? null : pumpPairingCode.get();

if (jpake == null && code == null) {
if (derivedSecret == null && code == null) {
throw new IllegalStateException("no pump authenticationKey");
}

// stored jpake raw derived secret is decoded from hex for use in hmac
if (jpake != null && !jpake.isEmpty()) {
if (!Strings.isNullOrEmpty(derivedSecret) && !Strings.isNullOrEmpty(serverNonce)) {
try {
L.i(TAG, "PUMP_AUTHENTICATION_KEY=" + jpake);
return Hex.decodeHex(jpake);
L.i(TAG, "PUMP_JPAKE_DERIVED_SECRET=" + derivedSecret + " PUMP_JPAKE_SERVER_NONCE=" + serverNonce);
byte[] jpakeSecret = Hex.decodeHex(derivedSecret);
byte[] jpakeNonce = Hex.decodeHex(serverNonce);
byte[] authKey = Hkdf.build(jpakeNonce, jpakeSecret);
L.i(TAG, "PUMP_AUTHENTICATION_KEY=" + Hex.encodeHexString(authKey) + " PUMP_JPAKE_DERIVED_SECRET=" + derivedSecret + " PUMP_JPAKE_SERVER_NONCE=" + serverNonce);

return authKey;
} catch (DecoderException e) {
L.e(TAG, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,4 +278,8 @@ public boolean invalid() {
public byte[] getDerivedSecret() {
return this.derivedSecret;
}

public byte[] getServerNonce() {
return this.serverNonce3;
}
}

0 comments on commit db7ef33

Please sign in to comment.