read masterkey from JWE

This commit is contained in:
Sebastian Stenzel
2021-12-09 14:03:39 +01:00
parent 0110e5bedd
commit fb580ff79d
5 changed files with 16 additions and 38 deletions

View File

@@ -1,14 +0,0 @@
package org.cryptomator.ui.keyloading.hub;
/**
* ECIES parameters required to decrypt the masterkey:
* <ul>
* <li><code>m</code> Encrypted Masterkey (base64url-encoded ciphertext)</li>
* <li><code>epk</code> Ephemeral Public Key (base64url-encoded SPKI format)</li>
* </ul>
* <p>
* No separate tag required, since we use GCM for encryption.
*/
record EciesParams(String m, String epk) {
}

View File

@@ -1,5 +1,6 @@
package org.cryptomator.ui.keyloading.hub;
import com.nimbusds.jose.JWEObject;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@@ -55,7 +56,7 @@ public abstract class HubKeyLoadingModule {
@Provides
@KeyLoadingScoped
static AtomicReference<EciesParams> provideEciesParamsRef() {
static AtomicReference<JWEObject> provideJweRef() {
return new AtomicReference<>();
}

View File

@@ -1,13 +1,11 @@
package org.cryptomator.ui.keyloading.hub;
import com.google.common.base.Preconditions;
import com.nimbusds.jose.JWEObject;
import dagger.Lazy;
import org.cryptomator.common.settings.DeviceKey;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.cryptolib.api.Masterkey;
import org.cryptomator.cryptolib.api.MasterkeyLoadingFailedException;
import org.cryptomator.cryptolib.common.Destroyables;
import org.cryptomator.cryptolib.common.MasterkeyHubAccess;
import org.cryptomator.ui.common.FxmlFile;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.UserInteractionLock;
@@ -21,7 +19,6 @@ import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.Window;
import java.net.URI;
import java.security.KeyPair;
import java.util.concurrent.atomic.AtomicReference;
@KeyLoading
@@ -35,24 +32,23 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy {
private final Lazy<Scene> authFlowScene;
private final UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> userInteraction;
private final DeviceKey deviceKey;
private final AtomicReference<EciesParams> eciesParams;
private final AtomicReference<JWEObject> jweRef;
@Inject
public HubKeyLoadingStrategy(@KeyLoading Stage window, @FxmlScene(FxmlFile.HUB_AUTH_FLOW) Lazy<Scene> authFlowScene, UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> userInteraction, DeviceKey deviceKey, AtomicReference<EciesParams> eciesParams) {
public HubKeyLoadingStrategy(@KeyLoading Stage window, @FxmlScene(FxmlFile.HUB_AUTH_FLOW) Lazy<Scene> authFlowScene, UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> userInteraction, DeviceKey deviceKey, AtomicReference<JWEObject> jweRef) {
this.window = window;
this.authFlowScene = authFlowScene;
this.userInteraction = userInteraction;
this.deviceKey = deviceKey;
this.eciesParams = eciesParams;
this.jweRef = jweRef;
}
@Override
public Masterkey loadKey(URI keyId) throws MasterkeyLoadingFailedException {
Preconditions.checkArgument(keyId.getScheme().startsWith(SCHEME_PREFIX));
try {
var keyPair = deviceKey.get();
return switch (auth()) {
case SUCCESS -> MasterkeyHubAccess.decryptMasterkey(keyPair.getPrivate(), eciesParams.get().m(), eciesParams.get().epk());
case SUCCESS -> JWEHelper.decrypt(jweRef.get(), deviceKey.get().getPrivate());
case FAILED -> throw new MasterkeyLoadingFailedException("failed to load keypair");
case CANCELLED -> throw new UnlockCancelledException("User cancelled auth workflow");
};

View File

@@ -1,7 +1,7 @@
package org.cryptomator.ui.keyloading.hub;
import com.google.common.base.Preconditions;
import com.google.common.io.BaseEncoding;
import com.nimbusds.jose.JWEObject;
import dagger.Lazy;
import org.cryptomator.common.settings.DeviceKey;
import org.cryptomator.common.vaults.Vault;
@@ -32,6 +32,7 @@ import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.text.ParseException;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicReference;
@@ -45,7 +46,7 @@ public class ReceiveKeyController implements FxController {
private final Stage window;
private final P384KeyPair keyPair;
private final String bearerToken;
private final AtomicReference<EciesParams> eciesParamsRef;
private final AtomicReference<JWEObject> jweRef;
private final UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result;
private final Lazy<Scene> registerDeviceScene;
private final Lazy<Scene> unauthorizedScene;
@@ -53,13 +54,12 @@ public class ReceiveKeyController implements FxController {
private final URI vaultBaseUri;
private final HttpClient httpClient;
@Inject
public ReceiveKeyController(@KeyLoading Vault vault, ExecutorService executor, @KeyLoading Stage window, DeviceKey deviceKey, @Named("bearerToken") AtomicReference<String> tokenRef, AtomicReference<EciesParams> eciesParamsRef, UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result, @FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene, @FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy<Scene> unauthorizedScene, ErrorComponent.Builder errorComponent) {
public ReceiveKeyController(@KeyLoading Vault vault, ExecutorService executor, @KeyLoading Stage window, DeviceKey deviceKey, @Named("bearerToken") AtomicReference<String> tokenRef, AtomicReference<JWEObject> jweRef, UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result, @FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene, @FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy<Scene> unauthorizedScene, ErrorComponent.Builder errorComponent) {
this.window = window;
this.keyPair = Objects.requireNonNull(deviceKey.get());
this.bearerToken = Objects.requireNonNull(tokenRef.get());
this.eciesParamsRef = eciesParamsRef;
this.jweRef = jweRef;
this.result = result;
this.registerDeviceScene = registerDeviceScene;
this.unauthorizedScene = unauthorizedScene;
@@ -98,16 +98,11 @@ public class ReceiveKeyController implements FxController {
private void retrievalSucceeded(HttpResponse<InputStream> response) {
try {
var json = HttpHelper.parseBody(response);
Preconditions.checkArgument(json.isJsonObject());
Preconditions.checkArgument(json.getAsJsonObject().has("device_specific_masterkey"));
Preconditions.checkArgument(json.getAsJsonObject().has("ephemeral_public_key"));
var m = json.getAsJsonObject().get("device_specific_masterkey").getAsString();
var epk = json.getAsJsonObject().get("ephemeral_public_key").getAsString();
eciesParamsRef.set(new EciesParams(m, epk));
var string = HttpHelper.readBody(response);
jweRef.set(JWEObject.parse(string));
result.interacted(HubKeyLoadingModule.HubLoadingResult.SUCCESS);
window.close();
} catch (IOException | IllegalArgumentException e) {
} catch (ParseException | IOException e) {
retrievalFailed(e);
}
}

View File

@@ -50,7 +50,7 @@ public class RegisterDeviceController implements FxController {
var hashedKey = MessageDigestSupplier.SHA256.get().digest(deviceKey);
var deviceId = BaseEncoding.base16().encode(hashedKey);
var hash = computeVerificationHash(deviceId + encodedKey + verificationCode);
var url = hubConfig.deviceRegistrationUrl + "?device_key=" + encodedKey + "&device_id=" + deviceId + "&verification_hash=" + hash;
var url = hubConfig.deviceRegistrationUrl + "&device_key=" + encodedKey + "&device_id=" + deviceId + "&verification_hash=" + hash;
application.getHostServices().showDocument(url);
}