From 499fee8898d82ce40539d7d07c3bd65af19464af Mon Sep 17 00:00:00 2001 From: Dolph Flynn <96876199+DolphFlynn@users.noreply.github.com> Date: Sat, 19 Oct 2024 17:41:10 +0100 Subject: [PATCH] Create KeysRepository interface to narrow KeysModel. --- .../burp/intruder/JWSPayloadProcessor.java | 28 ++++++++++--- .../jwteditor/model/keys/KeysModel.java | 41 +++---------------- .../jwteditor/model/keys/KeysRepository.java | 33 +++++++++++++++ .../jwteditor/presenter/EditorPresenter.java | 24 +++++------ .../jwteditor/view/editor/EditorView.java | 6 +-- .../jwteditor/view/editor/HttpEditorView.java | 6 +-- .../view/editor/HttpRequestEditorView.java | 6 +-- .../view/editor/HttpResponseEditorView.java | 6 +-- .../view/editor/WebSocketEditorView.java | 6 +-- 9 files changed, 89 insertions(+), 67 deletions(-) create mode 100644 src/main/java/com/blackberry/jwteditor/model/keys/KeysRepository.java diff --git a/src/main/java/burp/intruder/JWSPayloadProcessor.java b/src/main/java/burp/intruder/JWSPayloadProcessor.java index 2810732..574bd2f 100644 --- a/src/main/java/burp/intruder/JWSPayloadProcessor.java +++ b/src/main/java/burp/intruder/JWSPayloadProcessor.java @@ -1,3 +1,21 @@ +/* +Author : Dolph Flynn + +Copyright 2024 Dolph Flynn + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package burp.intruder; import burp.api.montoya.core.ByteArray; @@ -10,7 +28,7 @@ import com.blackberry.jwteditor.model.jose.JWS; import com.blackberry.jwteditor.model.jose.JWSFactory; import com.blackberry.jwteditor.model.keys.Key; -import com.blackberry.jwteditor.model.keys.KeysModel; +import com.blackberry.jwteditor.model.keys.KeysRepository; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.util.Base64URL; import org.json.JSONObject; @@ -24,12 +42,12 @@ public class JWSPayloadProcessor implements PayloadProcessor { private final Logging logging; private final IntruderConfig intruderConfig; - private final KeysModel keysModel; + private final KeysRepository keysRepository; - public JWSPayloadProcessor(IntruderConfig intruderConfig, Logging logging, KeysModel keysModel) { + public JWSPayloadProcessor(IntruderConfig intruderConfig, Logging logging, KeysRepository keysRepository) { this.logging = logging; this.intruderConfig = intruderConfig; - this.keysModel = keysModel; + this.keysRepository = keysRepository; } @Override @@ -66,7 +84,7 @@ private Optional loadKey() { return Optional.empty(); } - Key key = keysModel.getKey(intruderConfig.signingKeyId()); + Key key = keysRepository.getKey(intruderConfig.signingKeyId()); if (key == null) { logging.logToError("Key with ID " + intruderConfig.signingKeyId() + " not found."); diff --git a/src/main/java/com/blackberry/jwteditor/model/keys/KeysModel.java b/src/main/java/com/blackberry/jwteditor/model/keys/KeysModel.java index c4df476..0b6dee9 100644 --- a/src/main/java/com/blackberry/jwteditor/model/keys/KeysModel.java +++ b/src/main/java/com/blackberry/jwteditor/model/keys/KeysModel.java @@ -34,7 +34,7 @@ /** * A container class for Key objects */ -public class KeysModel { +public class KeysModel implements KeysRepository { private final Map keys; private final Object lock; @@ -56,13 +56,6 @@ public void addKeyModelListener(KeysModelListener modelListener) { this.modelListeners.add(modelListener); } - /** - * Parse a JSON string to a KeysModel - * - * @param json JSON string containing encoded keys - * @return the KeysModel parsed from the JSON - * @throws ParseException if parsing fails - */ public static KeysModel parse(String json) throws ParseException { KeysModel keysModel = new KeysModel(); @@ -95,35 +88,34 @@ public String serialize() { return jsonArray.toString(); } + @Override public List getSigningKeys() { synchronized (lock) { return keys.values().stream().filter(Key::canSign).toList(); } } + @Override public List getVerificationKeys() { synchronized (lock) { return keys.values().stream().filter(Key::canVerify).toList(); } } + @Override public List getEncryptionKeys() { synchronized (lock) { return keys.values().stream().filter(Key::canEncrypt).toList(); } } + @Override public List getDecryptionKeys() { synchronized (lock) { return keys.values().stream().filter(Key::canDecrypt).toList(); } } - /** - * Add a key to the model - * - * @param key key to add - */ public void addKey(Key key) { Key oldKey; @@ -154,11 +146,6 @@ private int findIndexOfKeyWithId(String id) { return -1; } - /** - * Remove a key from the model by id - * - * @param keyId key id to remove - */ public void deleteKey(String keyId) { int rowIndex; @@ -174,11 +161,6 @@ public void deleteKey(String keyId) { } } - /** - * Remove a set of keys from the model by id - * - * @param indices indices of keys to remove - */ public void deleteKeys(int[] indices) { synchronized (lock) { List idsToDelete = IntStream.of(indices).mapToObj(this::getKey).map(Key::getID).toList(); @@ -189,12 +171,6 @@ public void deleteKeys(int[] indices) { } } - /** - * Get a key from the model by index - * - * @param index index of key to retrieve - * @return retrieved key - */ public Key getKey(int index) { synchronized (lock) { String key = (String) keys.keySet().toArray()[index]; @@ -202,12 +178,7 @@ public Key getKey(int index) { } } - /** - * Get a key from the model by index - * - * @param keyId ID of key to retrieve - * @return retrieved key - */ + @Override public Key getKey(String keyId) { synchronized (lock) { return keys.get(keyId); diff --git a/src/main/java/com/blackberry/jwteditor/model/keys/KeysRepository.java b/src/main/java/com/blackberry/jwteditor/model/keys/KeysRepository.java new file mode 100644 index 0000000..018b7c4 --- /dev/null +++ b/src/main/java/com/blackberry/jwteditor/model/keys/KeysRepository.java @@ -0,0 +1,33 @@ +/* +Author : Dolph Flynn + +Copyright 2024 Dolph Flynn + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package com.blackberry.jwteditor.model.keys; + +import java.util.List; + +public interface KeysRepository { + List getVerificationKeys(); + + List getSigningKeys(); + + List getEncryptionKeys(); + + List getDecryptionKeys(); + + Key getKey(String keyId); +} diff --git a/src/main/java/com/blackberry/jwteditor/presenter/EditorPresenter.java b/src/main/java/com/blackberry/jwteditor/presenter/EditorPresenter.java index f0cf1ee..2a89e80 100644 --- a/src/main/java/com/blackberry/jwteditor/presenter/EditorPresenter.java +++ b/src/main/java/com/blackberry/jwteditor/presenter/EditorPresenter.java @@ -25,7 +25,7 @@ import com.blackberry.jwteditor.model.jose.MutableJOSEObject; import com.blackberry.jwteditor.model.keys.Key; import com.blackberry.jwteditor.model.keys.KeyRing; -import com.blackberry.jwteditor.model.keys.KeysModel; +import com.blackberry.jwteditor.model.keys.KeysRepository; import com.blackberry.jwteditor.utils.Utils; import com.blackberry.jwteditor.view.dialog.MessageDialogFactory; import com.blackberry.jwteditor.view.dialog.operations.*; @@ -52,7 +52,7 @@ */ public class EditorPresenter { - private final KeysModel keysModel; + private final KeysRepository keysRepository; private final EditorView view; private final CollaboratorPayloadGenerator collaboratorPayloadGenerator; private final ErrorLoggingActionListenerFactory actionListenerFactory; @@ -65,11 +65,11 @@ public EditorPresenter( EditorView view, CollaboratorPayloadGenerator collaboratorPayloadGenerator, ErrorLoggingActionListenerFactory actionListenerFactory, - KeysModel keysModel) { + KeysRepository keysRepository) { this.view = view; this.collaboratorPayloadGenerator = collaboratorPayloadGenerator; this.actionListenerFactory = actionListenerFactory; - this.keysModel = keysModel; + this.keysRepository = keysRepository; this.model = new EditorModel(); this.messageDialogFactory = new MessageDialogFactory(view.uiComponent()); } @@ -189,7 +189,7 @@ public void onAttackKeyConfusionClicked() { List attackKeys = new ArrayList<>(); // Get a list of verification capable public keys - List verificationKeys = keysModel.getVerificationKeys(); + List verificationKeys = keysRepository.getVerificationKeys(); for (Key signingKey : verificationKeys) { if (signingKey.isPublic() && signingKey.hasPEM()) { attackKeys.add(signingKey); @@ -284,7 +284,7 @@ public void onSignClicked() { */ private void signingDialog(SignDialog.Mode mode) { // Check there are signing keys in the keystore - if (keysModel.getSigningKeys().isEmpty()) { + if (keysRepository.getSigningKeys().isEmpty()) { messageDialogFactory.showWarningDialog("error_title_no_signing_keys", "error_no_signing_keys"); return; } @@ -292,7 +292,7 @@ private void signingDialog(SignDialog.Mode mode) { SignDialog signDialog = new SignDialog( view.window(), actionListenerFactory, - keysModel.getSigningKeys(), + keysRepository.getSigningKeys(), getJWS(), mode ); @@ -309,7 +309,7 @@ private void signingDialog(SignDialog.Mode mode) { * Handle click events from the Verify button */ public void onVerifyClicked() { - List keys = keysModel.getVerificationKeys(); + List keys = keysRepository.getVerificationKeys(); // Check there are verification keys in the keystore if (keys.isEmpty()) { @@ -328,7 +328,7 @@ public void onVerifyClicked() { public void onEncryptClicked() { // Check there are encryption keys in the keystore - if (keysModel.getEncryptionKeys().isEmpty()) { + if (keysRepository.getEncryptionKeys().isEmpty()) { messageDialogFactory.showWarningDialog("error_title_no_encryption_keys", "error_no_encryption_keys"); return; } @@ -337,7 +337,7 @@ public void onEncryptClicked() { view.window(), actionListenerFactory, getJWS(), - keysModel.getEncryptionKeys() + keysRepository.getEncryptionKeys() ); encryptDialog.display(); @@ -354,14 +354,14 @@ public void onEncryptClicked() { * Handle click events from the Decrypt button */ public void onDecryptClicked() { - if (keysModel.getDecryptionKeys().isEmpty()) { + if (keysRepository.getDecryptionKeys().isEmpty()) { messageDialogFactory.showWarningDialog("error_title_no_decryption_keys", "error_no_decryption_keys"); return; } // Attempt to decrypt the contents of the editor with all available keys try { - List keys = keysModel.getDecryptionKeys(); + List keys = keysRepository.getDecryptionKeys(); Optional jws = new KeyRing(keys).attemptDecryption(getJWE()); // If decryption was successful, set the contents of the editor to the decrypted JWS and set the editor mode to JWS diff --git a/src/main/java/com/blackberry/jwteditor/view/editor/EditorView.java b/src/main/java/com/blackberry/jwteditor/view/editor/EditorView.java index 4c37e9c..fbc90b2 100644 --- a/src/main/java/com/blackberry/jwteditor/view/editor/EditorView.java +++ b/src/main/java/com/blackberry/jwteditor/view/editor/EditorView.java @@ -20,7 +20,7 @@ import burp.api.montoya.collaborator.CollaboratorPayloadGenerator; import burp.api.montoya.ui.Selection; -import com.blackberry.jwteditor.model.keys.KeysModel; +import com.blackberry.jwteditor.model.keys.KeysRepository; import com.blackberry.jwteditor.presenter.EditorPresenter; import com.blackberry.jwteditor.presenter.Information; import com.blackberry.jwteditor.utils.Utils; @@ -100,7 +100,7 @@ public abstract class EditorView { private CodeArea codeAreaTag; EditorView( - KeysModel keysModel, + KeysRepository keysRepository, RstaFactory rstaFactory, HexCodeAreaFactory hexAreaCodeFactory, CollaboratorPayloadGenerator collaboratorPayloadGenerator, @@ -112,7 +112,7 @@ public abstract class EditorView { this.editable = editable; this.hexCodeAreaFactory = hexAreaCodeFactory; this.isProVersion = isProVersion; - this.presenter = new EditorPresenter(this, collaboratorPayloadGenerator, actionListenerFactory, keysModel); + this.presenter = new EditorPresenter(this, collaboratorPayloadGenerator, actionListenerFactory, keysRepository); this.informationPanel = informationPanelFactory.build(); informationScrollPane.setViewportView(informationPanel); diff --git a/src/main/java/com/blackberry/jwteditor/view/editor/HttpEditorView.java b/src/main/java/com/blackberry/jwteditor/view/editor/HttpEditorView.java index cb370aa..f6e6183 100644 --- a/src/main/java/com/blackberry/jwteditor/view/editor/HttpEditorView.java +++ b/src/main/java/com/blackberry/jwteditor/view/editor/HttpEditorView.java @@ -20,7 +20,7 @@ import burp.api.montoya.collaborator.CollaboratorPayloadGenerator; import burp.api.montoya.ui.editor.extension.ExtensionProvidedEditor; -import com.blackberry.jwteditor.model.keys.KeysModel; +import com.blackberry.jwteditor.model.keys.KeysRepository; import com.blackberry.jwteditor.view.hexcodearea.HexCodeAreaFactory; import com.blackberry.jwteditor.view.rsta.RstaFactory; import com.blackberry.jwteditor.view.utils.ErrorLoggingActionListenerFactory; @@ -28,7 +28,7 @@ abstract class HttpEditorView extends EditorView implements ExtensionProvidedEditor { HttpEditorView( - KeysModel keysModel, + KeysRepository keysRepository, RstaFactory rstaFactory, HexCodeAreaFactory hexAreaCodeFactory, CollaboratorPayloadGenerator collaboratorPayloadGenerator, @@ -37,7 +37,7 @@ abstract class HttpEditorView extends EditorView implements ExtensionProvidedEdi boolean editable, boolean isProVersion) { super( - keysModel, + keysRepository, rstaFactory, hexAreaCodeFactory, collaboratorPayloadGenerator, diff --git a/src/main/java/com/blackberry/jwteditor/view/editor/HttpRequestEditorView.java b/src/main/java/com/blackberry/jwteditor/view/editor/HttpRequestEditorView.java index d3b0761..8a17538 100644 --- a/src/main/java/com/blackberry/jwteditor/view/editor/HttpRequestEditorView.java +++ b/src/main/java/com/blackberry/jwteditor/view/editor/HttpRequestEditorView.java @@ -25,7 +25,7 @@ import burp.api.montoya.logging.Logging; import burp.api.montoya.ui.UserInterface; import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpRequestEditor; -import com.blackberry.jwteditor.model.keys.KeysModel; +import com.blackberry.jwteditor.model.keys.KeysRepository; import com.blackberry.jwteditor.view.hexcodearea.HexCodeAreaFactory; import com.blackberry.jwteditor.view.rsta.RstaFactory; import com.blackberry.jwteditor.view.utils.ErrorLoggingActionListenerFactory; @@ -36,7 +36,7 @@ public class HttpRequestEditorView extends HttpEditorView implements ExtensionPr private volatile HttpService httpService; public HttpRequestEditorView( - KeysModel keysModel, + KeysRepository keysRepository, RstaFactory rstaFactory, Logging logging, UserInterface userInterface, @@ -44,7 +44,7 @@ public HttpRequestEditorView( boolean editable, boolean isProVersion) { super( - keysModel, + keysRepository, rstaFactory, new HexCodeAreaFactory(logging, userInterface), collaboratorPayloadGenerator, diff --git a/src/main/java/com/blackberry/jwteditor/view/editor/HttpResponseEditorView.java b/src/main/java/com/blackberry/jwteditor/view/editor/HttpResponseEditorView.java index af68e2d..203bf5d 100644 --- a/src/main/java/com/blackberry/jwteditor/view/editor/HttpResponseEditorView.java +++ b/src/main/java/com/blackberry/jwteditor/view/editor/HttpResponseEditorView.java @@ -24,7 +24,7 @@ import burp.api.montoya.logging.Logging; import burp.api.montoya.ui.UserInterface; import burp.api.montoya.ui.editor.extension.ExtensionProvidedHttpResponseEditor; -import com.blackberry.jwteditor.model.keys.KeysModel; +import com.blackberry.jwteditor.model.keys.KeysRepository; import com.blackberry.jwteditor.view.hexcodearea.HexCodeAreaFactory; import com.blackberry.jwteditor.view.rsta.RstaFactory; import com.blackberry.jwteditor.view.utils.ErrorLoggingActionListenerFactory; @@ -34,7 +34,7 @@ public class HttpResponseEditorView extends HttpEditorView implements ExtensionProvidedHttpResponseEditor { public HttpResponseEditorView( - KeysModel keysModel, + KeysRepository keysRepository, RstaFactory rstaFactory, Logging logging, UserInterface userInterface, @@ -42,7 +42,7 @@ public HttpResponseEditorView( boolean editable, boolean isProVersion) { super( - keysModel, + keysRepository, rstaFactory, new HexCodeAreaFactory(logging, userInterface), collaboratorPayloadGenerator, diff --git a/src/main/java/com/blackberry/jwteditor/view/editor/WebSocketEditorView.java b/src/main/java/com/blackberry/jwteditor/view/editor/WebSocketEditorView.java index 73b0e3a..18f54c3 100644 --- a/src/main/java/com/blackberry/jwteditor/view/editor/WebSocketEditorView.java +++ b/src/main/java/com/blackberry/jwteditor/view/editor/WebSocketEditorView.java @@ -24,14 +24,14 @@ import burp.api.montoya.ui.UserInterface; import burp.api.montoya.ui.contextmenu.WebSocketMessage; import burp.api.montoya.ui.editor.extension.ExtensionProvidedWebSocketMessageEditor; -import com.blackberry.jwteditor.model.keys.KeysModel; +import com.blackberry.jwteditor.model.keys.KeysRepository; import com.blackberry.jwteditor.view.hexcodearea.HexCodeAreaFactory; import com.blackberry.jwteditor.view.rsta.RstaFactory; import com.blackberry.jwteditor.view.utils.ErrorLoggingActionListenerFactory; public class WebSocketEditorView extends EditorView implements ExtensionProvidedWebSocketMessageEditor { - public WebSocketEditorView(KeysModel keysModel, + public WebSocketEditorView(KeysRepository keysRepository, RstaFactory rstaFactory, Logging logging, UserInterface userInterface, @@ -39,7 +39,7 @@ public WebSocketEditorView(KeysModel keysModel, boolean editable, boolean isProVersion) { super( - keysModel, + keysRepository, rstaFactory, new HexCodeAreaFactory(logging, userInterface), collaboratorPayloadGenerator,