Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create KeysRepository interface to narrow KeysModel. #68

Merged
merged 1 commit into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions src/main/java/burp/intruder/JWSPayloadProcessor.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -66,7 +84,7 @@ private Optional<Key> 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.");
Expand Down
41 changes: 6 additions & 35 deletions src/main/java/com/blackberry/jwteditor/model/keys/KeysModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
/**
* A container class for Key objects
*/
public class KeysModel {
public class KeysModel implements KeysRepository {
private final Map<String, Key> keys;
private final Object lock;

Expand All @@ -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();

Expand Down Expand Up @@ -95,35 +88,34 @@ public String serialize() {
return jsonArray.toString();
}

@Override
public List<Key> getSigningKeys() {
synchronized (lock) {
return keys.values().stream().filter(Key::canSign).toList();
}
}

@Override
public List<Key> getVerificationKeys() {
synchronized (lock) {
return keys.values().stream().filter(Key::canVerify).toList();
}
}

@Override
public List<Key> getEncryptionKeys() {
synchronized (lock) {
return keys.values().stream().filter(Key::canEncrypt).toList();
}
}

@Override
public List<Key> 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;

Expand Down Expand Up @@ -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;

Expand All @@ -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<String> idsToDelete = IntStream.of(indices).mapToObj(this::getKey).map(Key::getID).toList();
Expand All @@ -189,25 +171,14 @@ 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];
return keys.get(key);
}
}

/**
* 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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Key> getVerificationKeys();

List<Key> getSigningKeys();

List<Key> getEncryptionKeys();

List<Key> getDecryptionKeys();

Key getKey(String keyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;
Expand All @@ -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;
Expand All @@ -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());
}
Expand Down Expand Up @@ -189,7 +189,7 @@ public void onAttackKeyConfusionClicked() {
List<Key> attackKeys = new ArrayList<>();

// Get a list of verification capable public keys
List<Key> verificationKeys = keysModel.getVerificationKeys();
List<Key> verificationKeys = keysRepository.getVerificationKeys();
for (Key signingKey : verificationKeys) {
if (signingKey.isPublic() && signingKey.hasPEM()) {
attackKeys.add(signingKey);
Expand Down Expand Up @@ -284,15 +284,15 @@ 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;
}

SignDialog signDialog = new SignDialog(
view.window(),
actionListenerFactory,
keysModel.getSigningKeys(),
keysRepository.getSigningKeys(),
getJWS(),
mode
);
Expand All @@ -309,7 +309,7 @@ private void signingDialog(SignDialog.Mode mode) {
* Handle click events from the Verify button
*/
public void onVerifyClicked() {
List<Key> keys = keysModel.getVerificationKeys();
List<Key> keys = keysRepository.getVerificationKeys();

// Check there are verification keys in the keystore
if (keys.isEmpty()) {
Expand All @@ -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;
}
Expand All @@ -337,7 +337,7 @@ public void onEncryptClicked() {
view.window(),
actionListenerFactory,
getJWS(),
keysModel.getEncryptionKeys()
keysRepository.getEncryptionKeys()
);
encryptDialog.display();

Expand All @@ -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<Key> keys = keysModel.getDecryptionKeys();
List<Key> keys = keysRepository.getDecryptionKeys();
Optional<JWS> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -100,7 +100,7 @@ public abstract class EditorView {
private CodeArea codeAreaTag;

EditorView(
KeysModel keysModel,
KeysRepository keysRepository,
RstaFactory rstaFactory,
HexCodeAreaFactory hexAreaCodeFactory,
CollaboratorPayloadGenerator collaboratorPayloadGenerator,
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@

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;

abstract class HttpEditorView extends EditorView implements ExtensionProvidedEditor {

HttpEditorView(
KeysModel keysModel,
KeysRepository keysRepository,
RstaFactory rstaFactory,
HexCodeAreaFactory hexAreaCodeFactory,
CollaboratorPayloadGenerator collaboratorPayloadGenerator,
Expand All @@ -37,7 +37,7 @@ abstract class HttpEditorView extends EditorView implements ExtensionProvidedEdi
boolean editable,
boolean isProVersion) {
super(
keysModel,
keysRepository,
rstaFactory,
hexAreaCodeFactory,
collaboratorPayloadGenerator,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -36,15 +36,15 @@ public class HttpRequestEditorView extends HttpEditorView implements ExtensionPr
private volatile HttpService httpService;

public HttpRequestEditorView(
KeysModel keysModel,
KeysRepository keysRepository,
RstaFactory rstaFactory,
Logging logging,
UserInterface userInterface,
CollaboratorPayloadGenerator collaboratorPayloadGenerator,
boolean editable,
boolean isProVersion) {
super(
keysModel,
keysRepository,
rstaFactory,
new HexCodeAreaFactory(logging, userInterface),
collaboratorPayloadGenerator,
Expand Down
Loading
Loading