SEBSERV-135 finished implementation
This commit is contained in:
parent
a46e2c0b27
commit
a853c02947
25 changed files with 445 additions and 96 deletions
|
@ -282,4 +282,17 @@ public class APIMessage implements Serializable {
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean checkError(final Exception error, final ErrorMessage errorMessage) {
|
||||||
|
if (!(error instanceof APIMessageException)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final APIMessageException _error = (APIMessageException) error;
|
||||||
|
return _error.getAPIMessages()
|
||||||
|
.stream()
|
||||||
|
.filter(msg -> errorMessage.messageCode.equals(msg.messageCode))
|
||||||
|
.findFirst()
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
||||||
public static final String ATTR_QUIT_PASSWORD_CONFIRM = "hashedQuitPasswordConfirm";
|
public static final String ATTR_QUIT_PASSWORD_CONFIRM = "hashedQuitPasswordConfirm";
|
||||||
public static final String ATTR_ENCRYPT_SECRET_CONFIRM = "confirm_encrypt_secret";
|
public static final String ATTR_ENCRYPT_SECRET_CONFIRM = "confirm_encrypt_secret";
|
||||||
public static final String ATTR_ENCRYPT_CERTIFICATE_ALIAS = "cert_alias";
|
public static final String ATTR_ENCRYPT_CERTIFICATE_ALIAS = "cert_alias";
|
||||||
|
public static final String ATTR_ENCRYPT_CERTIFICATE_ASYM = "cert_encryption_asym";
|
||||||
|
|
||||||
public static final String FILTER_ATTR_CREATION_DATE = "creation_date";
|
public static final String FILTER_ATTR_CREATION_DATE = "creation_date";
|
||||||
|
|
||||||
|
@ -161,6 +162,9 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
||||||
@JsonProperty(ATTR_ENCRYPT_CERTIFICATE_ALIAS)
|
@JsonProperty(ATTR_ENCRYPT_CERTIFICATE_ALIAS)
|
||||||
public final String encryptCertificateAlias;
|
public final String encryptCertificateAlias;
|
||||||
|
|
||||||
|
@JsonProperty(ATTR_ENCRYPT_CERTIFICATE_ASYM)
|
||||||
|
public final Boolean encryptCertificateAsym;
|
||||||
|
|
||||||
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_ACTIVE)
|
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_ACTIVE)
|
||||||
public final Boolean active;
|
public final Boolean active;
|
||||||
|
|
||||||
|
@ -190,6 +194,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
||||||
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET) final CharSequence encryptSecret,
|
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET) final CharSequence encryptSecret,
|
||||||
@JsonProperty(ATTR_ENCRYPT_SECRET_CONFIRM) final CharSequence encryptSecretConfirm,
|
@JsonProperty(ATTR_ENCRYPT_SECRET_CONFIRM) final CharSequence encryptSecretConfirm,
|
||||||
@JsonProperty(ATTR_ENCRYPT_CERTIFICATE_ALIAS) final String encryptCertificateAlias,
|
@JsonProperty(ATTR_ENCRYPT_CERTIFICATE_ALIAS) final String encryptCertificateAlias,
|
||||||
|
@JsonProperty(ATTR_ENCRYPT_CERTIFICATE_ASYM) final Boolean encryptCertificateAsym,
|
||||||
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_ACTIVE) final Boolean active) {
|
@JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_ACTIVE) final Boolean active) {
|
||||||
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -216,6 +221,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
||||||
this.encryptSecret = encryptSecret;
|
this.encryptSecret = encryptSecret;
|
||||||
this.encryptSecretConfirm = encryptSecretConfirm;
|
this.encryptSecretConfirm = encryptSecretConfirm;
|
||||||
this.encryptCertificateAlias = encryptCertificateAlias;
|
this.encryptCertificateAlias = encryptCertificateAlias;
|
||||||
|
this.encryptCertificateAsym = encryptCertificateAsym;
|
||||||
this.active = active;
|
this.active = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +260,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
||||||
this.encryptSecret = postParams.getCharSequence(Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET);
|
this.encryptSecret = postParams.getCharSequence(Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET);
|
||||||
this.encryptSecretConfirm = postParams.getCharSequence(ATTR_ENCRYPT_SECRET_CONFIRM);
|
this.encryptSecretConfirm = postParams.getCharSequence(ATTR_ENCRYPT_SECRET_CONFIRM);
|
||||||
this.encryptCertificateAlias = postParams.getString(ATTR_ENCRYPT_CERTIFICATE_ALIAS);
|
this.encryptCertificateAlias = postParams.getString(ATTR_ENCRYPT_CERTIFICATE_ALIAS);
|
||||||
|
this.encryptCertificateAsym = postParams.getBooleanObject(ATTR_ENCRYPT_CERTIFICATE_ASYM);
|
||||||
this.active = false;
|
this.active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +449,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
||||||
Constants.EMPTY_NOTE,
|
Constants.EMPTY_NOTE,
|
||||||
Constants.EMPTY_NOTE,
|
Constants.EMPTY_NOTE,
|
||||||
Constants.EMPTY_NOTE,
|
Constants.EMPTY_NOTE,
|
||||||
|
this.encryptCertificateAsym,
|
||||||
this.active);
|
this.active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,6 +477,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable {
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
false,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,11 @@ public final class Utils {
|
||||||
: Collections.emptyList();
|
: Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends Collection<V>, V> T addAll(final T target, final T source) {
|
||||||
|
target.addAll(source);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
public static <K, V> Map<K, V> immutableMapOf(final Map<K, V> params) {
|
public static <K, V> Map<K, V> immutableMapOf(final Map<K, V> params) {
|
||||||
return (params != null)
|
return (params != null)
|
||||||
? Collections.unmodifiableMap(params)
|
? Collections.unmodifiableMap(params)
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||||
|
@ -72,6 +73,8 @@ public class CertificateList implements TemplateComposer {
|
||||||
new LocTextKey("sebserver.certificate.message.error.file");
|
new LocTextKey("sebserver.certificate.message.error.file");
|
||||||
static final LocTextKey FORM_IMPORT_CONFIRM_TEXT_KEY =
|
static final LocTextKey FORM_IMPORT_CONFIRM_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.certificate.action.import-config.confirm");
|
new LocTextKey("sebserver.certificate.action.import-config.confirm");
|
||||||
|
static final LocTextKey FORM_ACTION_MESSAGE_IN_USE_TEXT_KEY =
|
||||||
|
new LocTextKey("sebserver.certificate.action.remove.in-use");
|
||||||
|
|
||||||
private final TableFilterAttribute aliasFilter = new TableFilterAttribute(
|
private final TableFilterAttribute aliasFilter = new TableFilterAttribute(
|
||||||
CriteriaType.TEXT,
|
CriteriaType.TEXT,
|
||||||
|
@ -169,7 +172,13 @@ public class CertificateList implements TemplateComposer {
|
||||||
this.restService.getBuilder(RemoveCertificate.class)
|
this.restService.getBuilder(RemoveCertificate.class)
|
||||||
.withFormParam(API.CERTIFICATE_ALIAS, ids)
|
.withFormParam(API.CERTIFICATE_ALIAS, ids)
|
||||||
.call()
|
.call()
|
||||||
.onError(erorr -> action.pageContext().notifyRemoveError(EntityType.CERTIFICATE, erorr));
|
.onError(error -> {
|
||||||
|
if (APIMessage.checkError(error, APIMessage.ErrorMessage.INTEGRITY_VALIDATION)) {
|
||||||
|
action.pageContext().publishInfo(FORM_ACTION_MESSAGE_IN_USE_TEXT_KEY);
|
||||||
|
} else {
|
||||||
|
action.pageContext().notifyRemoveError(EntityType.CERTIFICATE, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,8 @@ public class SEBClientConfigForm implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey FORM_ENCRYPT_CERT_KEY =
|
private static final LocTextKey FORM_ENCRYPT_CERT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.form.certificate");
|
new LocTextKey("sebserver.clientconfig.form.certificate");
|
||||||
|
private static final LocTextKey FORM_ENCRYPT_CERTIFICATE_ASYM =
|
||||||
|
new LocTextKey("sebserver.clientconfig.form.type.async");
|
||||||
private static final LocTextKey FORM_ENCRYPT_SECRET_TEXT_KEY =
|
private static final LocTextKey FORM_ENCRYPT_SECRET_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.form.encryptSecret");
|
new LocTextKey("sebserver.clientconfig.form.encryptSecret");
|
||||||
private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY =
|
private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY =
|
||||||
|
@ -285,15 +287,6 @@ public class SEBClientConfigForm implements TemplateComposer {
|
||||||
.mandatory(!isReadonly))
|
.mandatory(!isReadonly))
|
||||||
.withDefaultSpanEmptyCell(3)
|
.withDefaultSpanEmptyCell(3)
|
||||||
|
|
||||||
.withDefaultSpanInput(3)
|
|
||||||
.addField(FormBuilder.singleSelection(
|
|
||||||
SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ALIAS,
|
|
||||||
FORM_ENCRYPT_CERT_KEY,
|
|
||||||
clientConfig.encryptCertificateAlias,
|
|
||||||
() -> this.pageService.getResourceService().identityCertificatesResources()))
|
|
||||||
.withDefaultSpanEmptyCell(3)
|
|
||||||
|
|
||||||
.withDefaultSpanInput(3)
|
|
||||||
.addField(FormBuilder.password(
|
.addField(FormBuilder.password(
|
||||||
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET,
|
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET,
|
||||||
FORM_ENCRYPT_SECRET_TEXT_KEY,
|
FORM_ENCRYPT_SECRET_TEXT_KEY,
|
||||||
|
@ -307,6 +300,24 @@ public class SEBClientConfigForm implements TemplateComposer {
|
||||||
FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY,
|
FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY,
|
||||||
pwd))
|
pwd))
|
||||||
|
|
||||||
|
.withDefaultSpanInput(2)
|
||||||
|
.addField(FormBuilder.singleSelection(
|
||||||
|
SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ALIAS,
|
||||||
|
FORM_ENCRYPT_CERT_KEY,
|
||||||
|
clientConfig.encryptCertificateAlias,
|
||||||
|
() -> this.pageService.getResourceService().identityCertificatesResources()))
|
||||||
|
.withDefaultSpanInput(3)
|
||||||
|
.withDefaultSpanLabel(1)
|
||||||
|
.addField(FormBuilder.checkbox(
|
||||||
|
SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ASYM,
|
||||||
|
FORM_ENCRYPT_CERTIFICATE_ASYM,
|
||||||
|
(BooleanUtils.isTrue(clientConfig.encryptCertificateAsym))
|
||||||
|
? Constants.TRUE_STRING
|
||||||
|
: Constants.FALSE_STRING)
|
||||||
|
.withRightLabel()
|
||||||
|
.withEmptyCellSeparation(false))
|
||||||
|
.withDefaultSpanEmptyCell(1)
|
||||||
|
.withDefaultSpanLabel(2)
|
||||||
.withDefaultSpanInput(2)
|
.withDefaultSpanInput(2)
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
SEBClientConfig.ATTR_PING_INTERVAL,
|
SEBClientConfig.ATTR_PING_INTERVAL,
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.form;
|
package ch.ethz.seb.sebserver.gui.form;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
@ -17,6 +15,9 @@ import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Control;
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
|
|
||||||
public class CheckboxFieldBuilder extends FieldBuilder<String> {
|
public class CheckboxFieldBuilder extends FieldBuilder<String> {
|
||||||
|
|
||||||
protected CheckboxFieldBuilder(
|
protected CheckboxFieldBuilder(
|
||||||
|
@ -27,15 +28,31 @@ public class CheckboxFieldBuilder extends FieldBuilder<String> {
|
||||||
super(name, label, value);
|
super(name, label, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FieldBuilder<?> withRightLabel() {
|
||||||
|
this.rightLabel = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void build(final FormBuilder builder) {
|
void build(final FormBuilder builder) {
|
||||||
final boolean readonly = builder.readonly || this.readonly;
|
final boolean readonly = builder.readonly || this.readonly;
|
||||||
final Control titleLabel = createTitleLabel(builder.formParent, builder, this);
|
Control titleLabel = null;
|
||||||
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
Composite fieldGrid;
|
||||||
final Button checkbox = builder.widgetFactory.buttonLocalized(
|
Button checkbox;
|
||||||
fieldGrid,
|
if (this.rightLabel) {
|
||||||
SWT.CHECK,
|
fieldGrid = createFieldGrid(builder.formParent, this.spanInput, false);
|
||||||
null, null);
|
checkbox = builder.widgetFactory.buttonLocalized(
|
||||||
|
fieldGrid,
|
||||||
|
SWT.CHECK,
|
||||||
|
this.label, this.tooltip);
|
||||||
|
} else {
|
||||||
|
titleLabel = createTitleLabel(builder.formParent, builder, this);
|
||||||
|
fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
||||||
|
checkbox = builder.widgetFactory.buttonLocalized(
|
||||||
|
fieldGrid,
|
||||||
|
SWT.CHECK,
|
||||||
|
null, null);
|
||||||
|
}
|
||||||
|
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true);
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, true);
|
||||||
checkbox.setLayoutData(gridData);
|
checkbox.setLayoutData(gridData);
|
||||||
|
|
|
@ -39,6 +39,7 @@ public abstract class FieldBuilder<T> {
|
||||||
boolean visible = true;
|
boolean visible = true;
|
||||||
String defaultLabel = null;
|
String defaultLabel = null;
|
||||||
boolean isMandatory = false;
|
boolean isMandatory = false;
|
||||||
|
boolean rightLabel = false;
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
final LocTextKey label;
|
final LocTextKey label;
|
||||||
|
@ -195,8 +196,12 @@ public abstract class FieldBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Composite createFieldGrid(final Composite parent, final int hspan) {
|
public static Composite createFieldGrid(final Composite parent, final int hspan) {
|
||||||
|
return createFieldGrid(parent, hspan, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Composite createFieldGrid(final Composite parent, final int hspan, final boolean rightLabel) {
|
||||||
final Composite fieldGrid = new Composite(parent, SWT.NONE);
|
final Composite fieldGrid = new Composite(parent, SWT.NONE);
|
||||||
final GridLayout gridLayout = new GridLayout();
|
final GridLayout gridLayout = new GridLayout((rightLabel) ? 2 : 1, true);
|
||||||
gridLayout.verticalSpacing = 0;
|
gridLayout.verticalSpacing = 0;
|
||||||
gridLayout.marginHeight = 0;
|
gridLayout.marginHeight = 0;
|
||||||
gridLayout.marginWidth = 0;
|
gridLayout.marginWidth = 0;
|
||||||
|
|
|
@ -222,7 +222,7 @@ public class CertificateDAOImpl implements CertificateDAO {
|
||||||
}
|
}
|
||||||
|
|
||||||
// dataEncipherment
|
// dataEncipherment
|
||||||
if (keyUsage[3]) {
|
if (keyUsage[2] || keyUsage[3]) {
|
||||||
final String alias = certificates.keyStore.engineGetCertificateAlias(cert);
|
final String alias = certificates.keyStore.engineGetCertificateAlias(cert);
|
||||||
if (this.cryptor.getPrivateKey(certificates.keyStore, alias).hasValue()) {
|
if (this.cryptor.getPrivateKey(certificates.keyStore, alias).hasValue()) {
|
||||||
result.add(CertificateType.DATA_ENCIPHERMENT_PRIVATE_KEY);
|
result.add(CertificateType.DATA_ENCIPHERMENT_PRIVATE_KEY);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage;
|
||||||
|
@ -431,6 +432,7 @@ public class SEBClientConfigDAOImpl implements SEBClientConfigDAO {
|
||||||
additionalAttributes.containsKey(SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ALIAS)
|
additionalAttributes.containsKey(SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ALIAS)
|
||||||
? additionalAttributes.get(SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ALIAS).getValue()
|
? additionalAttributes.get(SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ALIAS).getValue()
|
||||||
: null,
|
: null,
|
||||||
|
additionalAttributes.containsKey(SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ASYM),
|
||||||
BooleanUtils.toBooleanObject(record.getActive())));
|
BooleanUtils.toBooleanObject(record.getActive())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -608,6 +610,19 @@ public class SEBClientConfigDAOImpl implements SEBClientConfigDAO {
|
||||||
configId,
|
configId,
|
||||||
SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ALIAS);
|
SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ALIAS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (BooleanUtils.isTrue(sebClientConfig.encryptCertificateAsym)) {
|
||||||
|
this.additionalAttributesDAO.saveAdditionalAttribute(
|
||||||
|
EntityType.SEB_CLIENT_CONFIGURATION,
|
||||||
|
configId,
|
||||||
|
SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ASYM,
|
||||||
|
Constants.TRUE_STRING);
|
||||||
|
} else {
|
||||||
|
this.additionalAttributesDAO.delete(
|
||||||
|
EntityType.SEB_CLIENT_CONFIGURATION,
|
||||||
|
configId,
|
||||||
|
SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ASYM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,9 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigEncrypti
|
||||||
* within a concrete strategy. */
|
* within a concrete strategy. */
|
||||||
public interface SEBConfigEncryptionContext {
|
public interface SEBConfigEncryptionContext {
|
||||||
|
|
||||||
|
/** Get the institution identifier */
|
||||||
|
Long institutionId();
|
||||||
|
|
||||||
/** Get the current encryption/decryption strategy
|
/** Get the current encryption/decryption strategy
|
||||||
*
|
*
|
||||||
* @return the current encryption/decryption strategy */
|
* @return the current encryption/decryption strategy */
|
||||||
|
|
|
@ -40,7 +40,6 @@ public interface SEBConfigEncryptionService {
|
||||||
PASSWORD_PWCC(Type.PASSWORD, "pwcc"),
|
PASSWORD_PWCC(Type.PASSWORD, "pwcc"),
|
||||||
/** Encryption with public/private asymmetric keys and symmetric key */
|
/** Encryption with public/private asymmetric keys and symmetric key */
|
||||||
PUBLIC_KEY_HASH_SYMMETRIC_KEY(Type.CERTIFICATE, "phsk"),
|
PUBLIC_KEY_HASH_SYMMETRIC_KEY(Type.CERTIFICATE, "phsk"),
|
||||||
// NOTE not supported yet but eventually needed for SEB config import.
|
|
||||||
/** Encryption with public/private key */
|
/** Encryption with public/private key */
|
||||||
PUBLIC_KEY_HASH(Type.CERTIFICATE, "pkhs");
|
PUBLIC_KEY_HASH(Type.CERTIFICATE, "pkhs");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
|
||||||
|
public abstract class AbstractCertificateCryptor {
|
||||||
|
|
||||||
|
protected static final int PUBLIC_KEY_HASH_SIZE = 20;
|
||||||
|
protected static final int ENCRYPTION_KEY_BITS = 256;
|
||||||
|
protected static final int KEY_LENGTH_SIZE = 4;
|
||||||
|
|
||||||
|
protected byte[] generatePublicKeyHash(final Certificate cert) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
final org.bouncycastle.asn1.x509.Certificate bcCert =
|
||||||
|
org.bouncycastle.asn1.x509.Certificate.getInstance(cert.getEncoded());
|
||||||
|
final byte[] bytes = bcCert.getSubjectPublicKeyInfo().getPublicKeyData().getBytes();
|
||||||
|
return DigestUtils.sha1(bytes);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new RuntimeException("Failed to generate public key hash:" + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected byte[] encryptWithCert(final Certificate cert, final byte[] data) throws Exception {
|
||||||
|
return encryptWithCert(cert, data, data.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected byte[] encryptWithCert(final Certificate cert, final byte[] data, final int length) throws Exception {
|
||||||
|
final String algorithm = cert.getPublicKey().getAlgorithm();
|
||||||
|
final Cipher encryptCipher = Cipher.getInstance(algorithm);
|
||||||
|
encryptCipher.init(Cipher.ENCRYPT_MODE, cert);
|
||||||
|
return encryptCipher.doFinal(data, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected byte[] decryptWithCert(final Certificate cert, final byte[] encryptedData) throws Exception {
|
||||||
|
final String algorithm = cert.getPublicKey().getAlgorithm();
|
||||||
|
final Cipher encryptCipher = Cipher.getInstance(algorithm);
|
||||||
|
encryptCipher.init(Cipher.DECRYPT_MODE, cert);
|
||||||
|
return encryptCipher.doFinal(encryptedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected byte[] parsePublicKeyHash(final InputStream input) throws IOException {
|
||||||
|
final byte[] publicKeyHash = new byte[PUBLIC_KEY_HASH_SIZE];
|
||||||
|
input.read(publicKeyHash, 0, publicKeyHash.length);
|
||||||
|
return publicKeyHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigCryptor;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigEncryptionContext;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigEncryptionService.Strategy;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component
|
||||||
|
@WebServiceProfile
|
||||||
|
public class CertificateAsymetricKeyCryptor extends AbstractCertificateCryptor implements SEBConfigCryptor {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CertificateAsymetricKeyCryptor.class);
|
||||||
|
|
||||||
|
private static final Set<Strategy> STRATEGIES = Utils.immutableSetOf(
|
||||||
|
Strategy.PUBLIC_KEY_HASH);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Strategy> strategies() {
|
||||||
|
return STRATEGIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encrypt(
|
||||||
|
final OutputStream output,
|
||||||
|
final InputStream input,
|
||||||
|
final SEBConfigEncryptionContext context) {
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("*** Start streaming asynchronous certificate asymmetric-key encryption");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
final Certificate certificate = context.getCertificate();
|
||||||
|
final byte[] publicKeyHash = generatePublicKeyHash(certificate);
|
||||||
|
|
||||||
|
output.write(publicKeyHash, 0, publicKeyHash.length);
|
||||||
|
|
||||||
|
final byte[] buffer = new byte[128];
|
||||||
|
|
||||||
|
int readBytes = input.read(buffer, 0, buffer.length);
|
||||||
|
while (readBytes > 0) {
|
||||||
|
final byte[] encryptedBlock = encryptWithCert(certificate, buffer, readBytes);
|
||||||
|
output.write(encryptedBlock, 0, encryptedBlock.length);
|
||||||
|
readBytes = input.read(buffer, 0, buffer.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Error while trying to stream and encrypt data: ", e);
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(input);
|
||||||
|
try {
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to close output: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decrypt(
|
||||||
|
final OutputStream output,
|
||||||
|
final InputStream input,
|
||||||
|
final SEBConfigEncryptionContext context) {
|
||||||
|
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("*** Start streaming asynchronous certificate asymmetric-key decryption");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,12 +11,14 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
import java.security.Security;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateEncodingException;
|
import java.security.cert.CertificateEncodingException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -25,6 +27,8 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo.CertificateFileType;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo.CertificateFileType;
|
||||||
|
@ -35,6 +39,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.CertificateDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.CertificateDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.SEBClientConfigDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.CertificateService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.CertificateService;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
@ -43,9 +48,15 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.CertificateServic
|
||||||
public class CertificateServiceImpl implements CertificateService {
|
public class CertificateServiceImpl implements CertificateService {
|
||||||
|
|
||||||
private final CertificateDAO certificateDAO;
|
private final CertificateDAO certificateDAO;
|
||||||
|
private final SEBClientConfigDAO sebClientConfigDAO;
|
||||||
|
|
||||||
|
public CertificateServiceImpl(
|
||||||
|
final CertificateDAO certificateDAO,
|
||||||
|
final SEBClientConfigDAO sebClientConfigDAO) {
|
||||||
|
|
||||||
public CertificateServiceImpl(final CertificateDAO certificateDAO) {
|
|
||||||
this.certificateDAO = certificateDAO;
|
this.certificateDAO = certificateDAO;
|
||||||
|
this.sebClientConfigDAO = sebClientConfigDAO;
|
||||||
|
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -103,6 +114,18 @@ public class CertificateServiceImpl implements CertificateService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<EntityKey> removeCertificate(final Long institutionId, final String alias) {
|
public Result<EntityKey> removeCertificate(final Long institutionId, final String alias) {
|
||||||
|
|
||||||
|
// TODO check if certificate is in use
|
||||||
|
if (this.sebClientConfigDAO.all(institutionId, true)
|
||||||
|
.getOr(Collections.emptyList())
|
||||||
|
.stream()
|
||||||
|
.filter(config -> alias.equals(config.encryptCertificateAlias))
|
||||||
|
.findFirst()
|
||||||
|
.isPresent()) {
|
||||||
|
|
||||||
|
throw new APIMessageException(APIMessage.ErrorMessage.INTEGRITY_VALIDATION);
|
||||||
|
}
|
||||||
|
|
||||||
return this.certificateDAO.removeCertificate(institutionId, alias);
|
return this.certificateDAO.removeCertificate(institutionId, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,17 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.security.KeyFactory;
|
import java.nio.ByteOrder;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.KeyGenerator;
|
import javax.crypto.KeyGenerator;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Hex;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
|
||||||
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
|
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -33,8 +30,10 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.CertificateService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigCryptor;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigCryptor;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigEncryptionContext;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigEncryptionContext;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigEncryptionService.Strategy;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigEncryptionService.Strategy;
|
||||||
|
@ -42,26 +41,34 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SEBConfigEncrypti
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@WebServiceProfile
|
@WebServiceProfile
|
||||||
public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
|
/** Uses symetric key for encryption of the data and a certificate asymetric key to encrypt
|
||||||
|
* and decrypt the symetric key. All is put together as described here:
|
||||||
|
* https://www.safeexambrowser.org/developer/seb-file-format.html
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* | “phsk” | public key hash | key length | encrypted key | ... encrypted data ... |
|
||||||
|
* | 0 - 3 | 4 - 23 | 24 - 27 | 28 - (28+kl) | (29+kl) - n |
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public class CertificateSymetricKeyCryptor extends AbstractCertificateCryptor implements SEBConfigCryptor {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(CertificateSymetricKeyCryptor.class);
|
private static final Logger log = LoggerFactory.getLogger(CertificateSymetricKeyCryptor.class);
|
||||||
|
|
||||||
private static final Set<Strategy> STRATEGIES = Utils.immutableSetOf(
|
private static final Set<Strategy> STRATEGIES = Utils.immutableSetOf(
|
||||||
Strategy.PUBLIC_KEY_HASH_SYMMETRIC_KEY);
|
Strategy.PUBLIC_KEY_HASH_SYMMETRIC_KEY);
|
||||||
private static final int PUBLIC_KEY_HASH_SIZE = 20;
|
|
||||||
private static final int ENCRYPTION_KEY_BITS = 256;
|
|
||||||
private static final int ENCRYPTION_KEY_LENGTH = 32;
|
|
||||||
private static final int KEY_LENGTH_SIZE = 4;
|
|
||||||
|
|
||||||
private final PasswordEncryptor passwordEncryptor;
|
private final PasswordEncryptor passwordEncryptor;
|
||||||
private final PasswordDecryptor passwordDecryptor;
|
private final PasswordDecryptor passwordDecryptor;
|
||||||
|
private final CertificateService certificateService;
|
||||||
|
|
||||||
public CertificateSymetricKeyCryptor(
|
public CertificateSymetricKeyCryptor(
|
||||||
final PasswordEncryptor passwordEncryptor,
|
final PasswordEncryptor passwordEncryptor,
|
||||||
final PasswordDecryptor passwordDecryptor) {
|
final PasswordDecryptor passwordDecryptor,
|
||||||
|
final CertificateService certificateService) {
|
||||||
|
|
||||||
this.passwordEncryptor = passwordEncryptor;
|
this.passwordEncryptor = passwordEncryptor;
|
||||||
this.passwordDecryptor = passwordDecryptor;
|
this.passwordDecryptor = passwordDecryptor;
|
||||||
|
this.certificateService = certificateService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,7 +83,7 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
|
||||||
final SEBConfigEncryptionContext context) {
|
final SEBConfigEncryptionContext context) {
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("*** Start streaming asynchronous certificate encryption");
|
log.debug("*** Start streaming asynchronous certificate symmetric-key encryption");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -93,6 +100,14 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.error("Error while trying to stream and encrypt data: ", e);
|
log.error("Error while trying to stream and encrypt data: ", e);
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(input);
|
||||||
|
try {
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to close output: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,31 +117,75 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
|
||||||
final InputStream input,
|
final InputStream input,
|
||||||
final SEBConfigEncryptionContext context) {
|
final SEBConfigEncryptionContext context) {
|
||||||
|
|
||||||
// TODO Auto-generated method stub
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("*** Start streaming asynchronous certificate symmetric-key decryption");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Certificate certificate = context.getCertificate();
|
|
||||||
final byte[] publicKeyHash = parsePublicKeyHash(input);
|
final byte[] publicKeyHash = parsePublicKeyHash(input);
|
||||||
|
final Certificate cert = getCertificateByPublicKeyHash(
|
||||||
|
context.institutionId(),
|
||||||
|
publicKeyHash);
|
||||||
|
final byte[] encryptedKey = getEncryptedKey(input);
|
||||||
|
final byte[] symetricKey = decryptWithCert(cert, encryptedKey);
|
||||||
|
final CharSequence symetricKeyBase64 = Base64.getEncoder().encodeToString(symetricKey);
|
||||||
|
|
||||||
|
this.passwordDecryptor.decrypt(output, input, symetricKeyBase64);
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.error("Error while trying to stream and decrypt data: ", e);
|
log.error("Error while trying to stream and decrypt data: ", e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to close output: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] generatePublicKeyHash(final Certificate cert)
|
private byte[] getEncryptedKey(final InputStream input) throws IOException {
|
||||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
|
||||||
byte[] publicKey = cert.getPublicKey().getEncoded();
|
|
||||||
final PublicKey publicKey2 = cert.getPublicKey();
|
|
||||||
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
||||||
final X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
|
|
||||||
final PublicKey _publicKey = keyFactory.generatePublic(keySpec);
|
|
||||||
publicKey = _publicKey.getEncoded();
|
|
||||||
|
|
||||||
final String algorithm = publicKey2.getAlgorithm();
|
// first get the length of the encrypted key
|
||||||
final String encodeHex = String.valueOf(Hex.encodeHex(publicKey));
|
final byte[] keyLength = new byte[KEY_LENGTH_SIZE];
|
||||||
final String sha1Hex = DigestUtils.sha1Hex(publicKey);
|
input.read(keyLength, 0, keyLength.length);
|
||||||
final String sha256Hex = DigestUtils.sha256Hex(publicKey);
|
final int keyLengthInt = ByteBuffer
|
||||||
return DigestUtils.sha1(publicKey);
|
.wrap(keyLength)
|
||||||
|
.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
.getInt();
|
||||||
|
|
||||||
|
// then get the encrypted symmetric key
|
||||||
|
final byte[] encryptedKey = new byte[keyLengthInt];
|
||||||
|
input.read(encryptedKey, 0, encryptedKey.length);
|
||||||
|
return encryptedKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Certificate getCertificateByPublicKeyHash(final Long institutionId, final byte[] publicKeyHash) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
final Certificates certs = this.certificateService
|
||||||
|
.getCertificates(institutionId)
|
||||||
|
.getOrThrow();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final Iterator<String> asIterator = certs.keyStore
|
||||||
|
.engineAliases()
|
||||||
|
.asIterator();
|
||||||
|
|
||||||
|
while (asIterator.hasNext()) {
|
||||||
|
final Certificate certificate = certs.keyStore.engineGetCertificate(asIterator.next());
|
||||||
|
final byte[] otherPublicKeyHash = generatePublicKeyHash(certificate);
|
||||||
|
if (Objects.equals(otherPublicKeyHash, publicKeyHash)) {
|
||||||
|
return certificate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Unexpected error while trying to get certificate by public key hash: ", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] generateSymetricKey() throws NoSuchAlgorithmException {
|
private byte[] generateSymetricKey() throws NoSuchAlgorithmException {
|
||||||
|
@ -143,9 +202,10 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
|
||||||
final byte[] symetricKey) throws Exception {
|
final byte[] symetricKey) throws Exception {
|
||||||
|
|
||||||
final ByteArrayOutputStream data = new ByteArrayOutputStream();
|
final ByteArrayOutputStream data = new ByteArrayOutputStream();
|
||||||
final byte[] encryptedKey = generateEncryptedKey(cert, symetricKey);
|
final byte[] encryptedKey = encryptWithCert(cert, symetricKey);
|
||||||
final byte[] encryptedKeyLength = ByteBuffer
|
final byte[] encryptedKeyLength = ByteBuffer
|
||||||
.allocate(KEY_LENGTH_SIZE)
|
.allocate(KEY_LENGTH_SIZE)
|
||||||
|
.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
.putInt(encryptedKey.length)
|
.putInt(encryptedKey.length)
|
||||||
.array();
|
.array();
|
||||||
|
|
||||||
|
@ -157,18 +217,4 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
|
||||||
return byteArray;
|
return byteArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] generateEncryptedKey(final Certificate cert, final byte[] symetricKey) throws Exception {
|
|
||||||
final String algorithm = cert.getPublicKey().getAlgorithm();
|
|
||||||
final Cipher encryptCipher = Cipher.getInstance(algorithm);
|
|
||||||
encryptCipher.init(Cipher.ENCRYPT_MODE, cert);
|
|
||||||
final byte[] cipherText = encryptCipher.doFinal(symetricKey);
|
|
||||||
return cipherText;
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] parsePublicKeyHash(final InputStream input) throws IOException {
|
|
||||||
final byte[] publicKeyHash = new byte[PUBLIC_KEY_HASH_SIZE];
|
|
||||||
input.read(publicKeyHash, 0, publicKeyHash.length);
|
|
||||||
return publicKeyHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PipedInputStream;
|
import java.io.PipedInputStream;
|
||||||
|
@ -273,7 +272,7 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
||||||
this.sebConfigEncryptionService.streamEncrypted(
|
this.sebConfigEncryptionService.streamEncrypted(
|
||||||
zipOut,
|
zipOut,
|
||||||
pIn,
|
pIn,
|
||||||
EncryptionContext.contextOfPlainText());
|
EncryptionContext.contextOfPlainText(config.institutionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZIP again to finish up
|
// ZIP again to finish up
|
||||||
|
@ -300,7 +299,10 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
return EncryptionContext.contextOf(
|
return EncryptionContext.contextOf(
|
||||||
SEBConfigEncryptionService.Strategy.PUBLIC_KEY_HASH_SYMMETRIC_KEY,
|
config.institutionId,
|
||||||
|
(config.encryptCertificateAsym)
|
||||||
|
? SEBConfigEncryptionService.Strategy.PUBLIC_KEY_HASH
|
||||||
|
: SEBConfigEncryptionService.Strategy.PUBLIC_KEY_HASH_SYMMETRIC_KEY,
|
||||||
certificate);
|
certificate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,6 +316,7 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
||||||
config.configPurpose)
|
config.configPurpose)
|
||||||
: null;
|
: null;
|
||||||
return EncryptionContext.contextOf(
|
return EncryptionContext.contextOf(
|
||||||
|
config.institutionId,
|
||||||
(config.configPurpose == ConfigPurpose.CONFIGURE_CLIENT)
|
(config.configPurpose == ConfigPurpose.CONFIGURE_CLIENT)
|
||||||
? SEBConfigEncryptionService.Strategy.PASSWORD_PWCC
|
? SEBConfigEncryptionService.Strategy.PASSWORD_PWCC
|
||||||
: SEBConfigEncryptionService.Strategy.PASSWORD_PSWD,
|
: SEBConfigEncryptionService.Strategy.PASSWORD_PSWD,
|
||||||
|
@ -503,7 +506,7 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
||||||
private void certificateEncryption(
|
private void certificateEncryption(
|
||||||
final OutputStream out,
|
final OutputStream out,
|
||||||
final SEBClientConfig config,
|
final SEBClientConfig config,
|
||||||
final InputStream in) throws IOException {
|
final InputStream in) {
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("*** SEB client configuration with certificate based encryption");
|
log.debug("*** SEB client configuration with certificate based encryption");
|
||||||
|
@ -511,20 +514,33 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
||||||
|
|
||||||
final boolean withPasswordEncryption = config.hasEncryptionSecret();
|
final boolean withPasswordEncryption = config.hasEncryptionSecret();
|
||||||
|
|
||||||
PipedOutputStream passEncryptionOut = null;
|
PipedOutputStream streamOut = null;
|
||||||
PipedInputStream passEncryptionIn = null;
|
PipedInputStream streamIn = null;
|
||||||
|
try {
|
||||||
|
streamOut = new PipedOutputStream();
|
||||||
|
streamIn = new PipedInputStream(streamOut);
|
||||||
|
|
||||||
if (withPasswordEncryption) {
|
if (withPasswordEncryption) {
|
||||||
// encrypt with password first
|
// encrypt with password first
|
||||||
passEncryptionOut = new PipedOutputStream();
|
passwordEncryption(streamOut, config, in);
|
||||||
passEncryptionIn = new PipedInputStream(passEncryptionOut);
|
} else {
|
||||||
passwordEncryption(passEncryptionOut, config, in);
|
// just add plaintext header
|
||||||
|
this.sebConfigEncryptionService.streamEncrypted(
|
||||||
|
streamOut,
|
||||||
|
in,
|
||||||
|
EncryptionContext.contextOfPlainText(config.institutionId));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sebConfigEncryptionService.streamEncrypted(
|
||||||
|
out,
|
||||||
|
streamIn,
|
||||||
|
buildCertificateEncryptionContext(config));
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Unexpected error while tying to stream certificate encrypted config: ", e);
|
||||||
|
IOUtils.closeQuietly(streamOut);
|
||||||
|
IOUtils.closeQuietly(streamIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sebConfigEncryptionService.streamEncrypted(
|
|
||||||
out,
|
|
||||||
(withPasswordEncryption) ? passEncryptionIn : in,
|
|
||||||
buildCertificateEncryptionContext(config));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void passwordEncryption(
|
private void passwordEncryption(
|
||||||
|
|
|
@ -225,6 +225,7 @@ public class ExamConfigServiceImpl implements ExamConfigService {
|
||||||
cryptOut,
|
cryptOut,
|
||||||
cryptIn,
|
cryptIn,
|
||||||
EncryptionContext.contextOf(
|
EncryptionContext.contextOf(
|
||||||
|
institutionId,
|
||||||
Strategy.PASSWORD_PSWD,
|
Strategy.PASSWORD_PSWD,
|
||||||
encryptionPasswordPlaintext));
|
encryptionPasswordPlaintext));
|
||||||
|
|
||||||
|
@ -342,7 +343,7 @@ public class ExamConfigServiceImpl implements ExamConfigService {
|
||||||
streamDecrypted = this.sebConfigEncryptionService.streamDecrypted(
|
streamDecrypted = this.sebConfigEncryptionService.streamDecrypted(
|
||||||
cryptOut,
|
cryptOut,
|
||||||
cryptIn,
|
cryptIn,
|
||||||
EncryptionContext.contextOf(password));
|
EncryptionContext.contextOf(config.institutionId, password));
|
||||||
|
|
||||||
// if zipped, unzip attach unzip stream first
|
// if zipped, unzip attach unzip stream first
|
||||||
unzippedIn = this.examConfigIO.unzip(plainIn);
|
unzippedIn = this.examConfigIO.unzip(plainIn);
|
||||||
|
|
|
@ -190,20 +190,28 @@ public final class SEBConfigEncryptionServiceImpl implements SEBConfigEncryption
|
||||||
|
|
||||||
static class EncryptionContext implements SEBConfigEncryptionContext {
|
static class EncryptionContext implements SEBConfigEncryptionContext {
|
||||||
|
|
||||||
|
public final Long institutionId;
|
||||||
public final Strategy strategy;
|
public final Strategy strategy;
|
||||||
public final CharSequence password;
|
public final CharSequence password;
|
||||||
public final Certificate certificate;
|
public final Certificate certificate;
|
||||||
|
|
||||||
private EncryptionContext(
|
private EncryptionContext(
|
||||||
|
final Long institutionId,
|
||||||
final Strategy strategy,
|
final Strategy strategy,
|
||||||
final CharSequence password,
|
final CharSequence password,
|
||||||
final Certificate certificate) {
|
final Certificate certificate) {
|
||||||
|
|
||||||
|
this.institutionId = institutionId;
|
||||||
this.strategy = strategy;
|
this.strategy = strategy;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.certificate = certificate;
|
this.certificate = certificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long institutionId() {
|
||||||
|
return this.institutionId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Strategy getStrategy() {
|
public Strategy getStrategy() {
|
||||||
return this.strategy;
|
return this.strategy;
|
||||||
|
@ -220,19 +228,21 @@ public final class SEBConfigEncryptionServiceImpl implements SEBConfigEncryption
|
||||||
}
|
}
|
||||||
|
|
||||||
static SEBConfigEncryptionContext contextOf(
|
static SEBConfigEncryptionContext contextOf(
|
||||||
|
final Long institutionId,
|
||||||
final Strategy strategy,
|
final Strategy strategy,
|
||||||
final CharSequence password) {
|
final CharSequence password) {
|
||||||
|
|
||||||
checkPasswordBased(strategy);
|
checkPasswordBased(strategy);
|
||||||
return new EncryptionContext(strategy, password, null);
|
return new EncryptionContext(institutionId, strategy, password, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SEBConfigEncryptionContext contextOf(
|
static SEBConfigEncryptionContext contextOf(
|
||||||
|
final Long institutionId,
|
||||||
final Strategy strategy,
|
final Strategy strategy,
|
||||||
final Certificate certificate) {
|
final Certificate certificate) {
|
||||||
|
|
||||||
checkCertificateBased(strategy);
|
checkCertificateBased(strategy);
|
||||||
return new EncryptionContext(strategy, null, certificate);
|
return new EncryptionContext(institutionId, strategy, null, certificate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkPasswordBased(final Strategy strategy) {
|
static void checkPasswordBased(final Strategy strategy) {
|
||||||
|
@ -247,12 +257,16 @@ public final class SEBConfigEncryptionServiceImpl implements SEBConfigEncryption
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SEBConfigEncryptionContext contextOfPlainText() {
|
public static SEBConfigEncryptionContext contextOfPlainText(final Long institutionId) {
|
||||||
return new EncryptionContext(Strategy.PLAIN_TEXT, null, null);
|
|
||||||
|
return new EncryptionContext(institutionId, Strategy.PLAIN_TEXT, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SEBConfigEncryptionContext contextOf(final CharSequence password) {
|
public static SEBConfigEncryptionContext contextOf(
|
||||||
return new EncryptionContext(null, password, null);
|
final Long institutionId,
|
||||||
|
final CharSequence password) {
|
||||||
|
|
||||||
|
return new EncryptionContext(institutionId, null, password, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class ZipServiceImpl implements ZipService {
|
||||||
log.error("Error while streaming data to zipped output: ", e);
|
log.error("Error while streaming data to zipped output: ", e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
in.close();
|
IOUtils.closeQuietly(in);
|
||||||
if (zipOutputStream != null) {
|
if (zipOutputStream != null) {
|
||||||
zipOutputStream.flush();
|
zipOutputStream.flush();
|
||||||
zipOutputStream.close();
|
zipOutputStream.close();
|
||||||
|
|
|
@ -193,7 +193,7 @@ public class CertificateController {
|
||||||
method = RequestMethod.POST,
|
method = RequestMethod.POST,
|
||||||
consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE,
|
consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE,
|
||||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public CertificateInfo loadCertificate(
|
public CertificateInfo importCertificate(
|
||||||
@RequestParam(
|
@RequestParam(
|
||||||
name = API.PARAM_INSTITUTION_ID,
|
name = API.PARAM_INSTITUTION_ID,
|
||||||
required = true,
|
required = true,
|
||||||
|
|
|
@ -731,7 +731,8 @@ sebserver.clientconfig.form.sebConfigPurpose=Configuration Purpose
|
||||||
sebserver.clientconfig.form.sebConfigPurpose.tooltip=This indicates whether this connection configuration shall be used to configure the SEB Client or to start an exam
|
sebserver.clientconfig.form.sebConfigPurpose.tooltip=This indicates whether this connection configuration shall be used to configure the SEB Client or to start an exam
|
||||||
sebserver.clientconfig.form.certificate=Encrypt with Certificate
|
sebserver.clientconfig.form.certificate=Encrypt with Certificate
|
||||||
sebserver.clientconfig.form.certificate.tooltip=Choose identity certificate to be used for encrypting the connection configuration
|
sebserver.clientconfig.form.certificate.tooltip=Choose identity certificate to be used for encrypting the connection configuration
|
||||||
|
sebserver.clientconfig.form.type.async=Use asymmetric-only encryption
|
||||||
|
sebserver.clientconfig.form.type.async.tooltip=Use old asymmetric-only encryption (for SEB < 2.2)
|
||||||
|
|
||||||
sebserver.clientconfig.config.purpose.START_EXAM=Starting an Exam
|
sebserver.clientconfig.config.purpose.START_EXAM=Starting an Exam
|
||||||
sebserver.clientconfig.config.purpose.START_EXAM.tooltip=If the connection configuration is loaded via a SEB-Link, the local configuration will not be overwritten.
|
sebserver.clientconfig.config.purpose.START_EXAM.tooltip=If the connection configuration is loaded via a SEB-Link, the local configuration will not be overwritten.
|
||||||
|
@ -1562,6 +1563,7 @@ sebserver.certificate.action.import.missing-password=The certificate file needs
|
||||||
sebserver.certificate.action.import-config.confirm=Certificate(s) successfully imported
|
sebserver.certificate.action.import-config.confirm=Certificate(s) successfully imported
|
||||||
sebserver.certificate.message.error.file=Unsupported file type
|
sebserver.certificate.message.error.file=Unsupported file type
|
||||||
sebserver.certificate.action.import-file-select.no=Please select a valid file
|
sebserver.certificate.action.import-file-select.no=Please select a valid file
|
||||||
|
sebserver.certificate.action.remove.in-use=This certificate is in use and cannot be removed.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,7 @@ public class ModelObjectJSONGenerator {
|
||||||
"encryptSecret",
|
"encryptSecret",
|
||||||
"encryptSecretConfirm",
|
"encryptSecretConfirm",
|
||||||
"certAlias",
|
"certAlias",
|
||||||
|
false,
|
||||||
true);
|
true);
|
||||||
System.out.println(domainObject.getClass().getSimpleName() + ":");
|
System.out.println(domainObject.getClass().getSimpleName() + ":");
|
||||||
System.out.println(writerWithDefaultPrettyPrinter.writeValueAsString(domainObject));
|
System.out.println(writerWithDefaultPrettyPrinter.writeValueAsString(domainObject));
|
||||||
|
|
|
@ -125,6 +125,7 @@ public class ClientConfigTest extends GuiIntegrationTest {
|
||||||
"password",
|
"password",
|
||||||
null,
|
null,
|
||||||
"certAlias",
|
"certAlias",
|
||||||
|
false,
|
||||||
null))
|
null))
|
||||||
.call();
|
.call();
|
||||||
|
|
||||||
|
@ -155,6 +156,7 @@ public class ClientConfigTest extends GuiIntegrationTest {
|
||||||
"password",
|
"password",
|
||||||
"password",
|
"password",
|
||||||
"certAlias",
|
"certAlias",
|
||||||
|
false,
|
||||||
null))
|
null))
|
||||||
.call()
|
.call()
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
|
@ -74,6 +74,7 @@ public class PasswordEncryptorTest {
|
||||||
final ByteArrayOutputStream out = new ByteArrayOutputStream(512);
|
final ByteArrayOutputStream out = new ByteArrayOutputStream(512);
|
||||||
|
|
||||||
final SEBConfigEncryptionContext context = EncryptionContext.contextOf(
|
final SEBConfigEncryptionContext context = EncryptionContext.contextOf(
|
||||||
|
1L,
|
||||||
Strategy.PASSWORD_PWCC,
|
Strategy.PASSWORD_PWCC,
|
||||||
pwd);
|
pwd);
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class SebConfigEncryptionServiceImplTest {
|
||||||
.streamEncrypted(
|
.streamEncrypted(
|
||||||
out,
|
out,
|
||||||
IOUtils.toInputStream(config, "UTF-8"),
|
IOUtils.toInputStream(config, "UTF-8"),
|
||||||
EncryptionContext.contextOfPlainText());
|
EncryptionContext.contextOfPlainText(1L));
|
||||||
|
|
||||||
final byte[] plainWithHeader = out.toByteArray();
|
final byte[] plainWithHeader = out.toByteArray();
|
||||||
assertNotNull(plainWithHeader);
|
assertNotNull(plainWithHeader);
|
||||||
|
@ -50,7 +50,7 @@ public class SebConfigEncryptionServiceImplTest {
|
||||||
sebConfigEncryptionServiceImpl.streamDecrypted(
|
sebConfigEncryptionServiceImpl.streamDecrypted(
|
||||||
out2,
|
out2,
|
||||||
new ByteArrayInputStream(plainWithHeader),
|
new ByteArrayInputStream(plainWithHeader),
|
||||||
EncryptionContext.contextOf(Strategy.PASSWORD_PSWD, (CharSequence) null));
|
EncryptionContext.contextOf(1L, Strategy.PASSWORD_PSWD, (CharSequence) null));
|
||||||
|
|
||||||
out2.close();
|
out2.close();
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ public class SebConfigEncryptionServiceImplTest {
|
||||||
out,
|
out,
|
||||||
IOUtils.toInputStream(config, "UTF-8"),
|
IOUtils.toInputStream(config, "UTF-8"),
|
||||||
EncryptionContext.contextOf(
|
EncryptionContext.contextOf(
|
||||||
|
1L,
|
||||||
Strategy.PASSWORD_PWCC,
|
Strategy.PASSWORD_PWCC,
|
||||||
pwd));
|
pwd));
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ public class SebConfigEncryptionServiceImplTest {
|
||||||
sebConfigEncryptionServiceImpl.streamDecrypted(
|
sebConfigEncryptionServiceImpl.streamDecrypted(
|
||||||
out2,
|
out2,
|
||||||
new ByteArrayInputStream(byteArray),
|
new ByteArrayInputStream(byteArray),
|
||||||
EncryptionContext.contextOf(Strategy.PASSWORD_PSWD, pwd));
|
EncryptionContext.contextOf(1L, Strategy.PASSWORD_PSWD, pwd));
|
||||||
|
|
||||||
final byte[] byteArray2 = out2.toByteArray();
|
final byte[] byteArray2 = out2.toByteArray();
|
||||||
assertNotNull(byteArray2);
|
assertNotNull(byteArray2);
|
||||||
|
|
Loading…
Reference in a new issue