finished config streaming out/in
This commit is contained in:
parent
06da2d026b
commit
27b75062cc
12 changed files with 326 additions and 309 deletions
|
@ -8,14 +8,8 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.async;
|
package ch.ethz.seb.sebserver.gbl.async;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.PipedInputStream;
|
|
||||||
import java.io.PipedOutputStream;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
@ -72,41 +66,4 @@ public class AsyncService {
|
||||||
momoized);
|
momoized);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pipeToOutputStream(
|
|
||||||
final OutputStream output,
|
|
||||||
final Consumer<PipedOutputStream> consumer) {
|
|
||||||
|
|
||||||
this.asyncRunner.runAsync(() -> {
|
|
||||||
|
|
||||||
PipedOutputStream pout = null;
|
|
||||||
PipedInputStream pin = null;
|
|
||||||
try {
|
|
||||||
pout = new PipedOutputStream();
|
|
||||||
pin = new PipedInputStream(pout);
|
|
||||||
|
|
||||||
consumer.accept(pout);
|
|
||||||
|
|
||||||
IOUtils.copyLarge(pin, output);
|
|
||||||
|
|
||||||
pin.close();
|
|
||||||
pout.flush();
|
|
||||||
pout.close();
|
|
||||||
|
|
||||||
} catch (final IOException e) {
|
|
||||||
log.error("Error while pipe stream data: ", e);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
pin.close();
|
|
||||||
} catch (final IOException e1) {
|
|
||||||
log.error("Failed to close PipedInputStream: ", e1);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
pout.close();
|
|
||||||
} catch (final IOException e1) {
|
|
||||||
log.error("Failed to close PipedOutputStream: ", e1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,6 +181,12 @@ public final class Result<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ifPresent(final Consumer<T> consumer) {
|
||||||
|
if (this.value != null) {
|
||||||
|
consumer.accept(this.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Use this to map a given Result of type T to another Result of type U
|
/** Use this to map a given Result of type T to another Result of type U
|
||||||
* within a given mapping function.
|
* within a given mapping function.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,10 +10,8 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy;
|
||||||
|
|
||||||
/** Interface for a SEB Configuration encryption and decryption strategy.
|
/** Interface for a SEB Configuration encryption and decryption strategy.
|
||||||
|
@ -27,32 +25,14 @@ public interface SebConfigCryptor {
|
||||||
* @return Set of strategies a concrete implementation is supporting */
|
* @return Set of strategies a concrete implementation is supporting */
|
||||||
Set<Strategy> strategies();
|
Set<Strategy> strategies();
|
||||||
|
|
||||||
/** Encrypt a given SEB configuration plain text representation within the given SebConfigEncryptionContext
|
|
||||||
*
|
|
||||||
* @param plainTextConfig SEB configuration plain text representation
|
|
||||||
* @param context SebConfigEncryptionContext containing additional data if needed
|
|
||||||
* @return Result of encrypted data within a ByteBuffer or reference to an Exception on error case */
|
|
||||||
Result<ByteBuffer> encrypt(
|
|
||||||
final CharSequence plainTextConfig,
|
|
||||||
final SebConfigEncryptionContext context);
|
|
||||||
|
|
||||||
/** Decrypt a given encrypted SEB configuration that has been encrypted by one of the supported strategies.
|
|
||||||
*
|
|
||||||
* @param cipher the encrypted SEB configuration cipher(text) within a ByteBuffer
|
|
||||||
* @param context SebConfigEncryptionContext containing additional data if needed
|
|
||||||
* @return Result of decrypted SEB configuration within a ByteBuffer or reference to an Exception on error case. */
|
|
||||||
Result<ByteBuffer> decrypt(
|
|
||||||
final ByteBuffer cipher,
|
|
||||||
final SebConfigEncryptionContext context);
|
|
||||||
|
|
||||||
void encrypt(
|
void encrypt(
|
||||||
final OutputStream encryptedOutput,
|
final OutputStream output,
|
||||||
final InputStream plainTextInputStream,
|
final InputStream input,
|
||||||
final SebConfigEncryptionContext context);
|
final SebConfigEncryptionContext context);
|
||||||
|
|
||||||
void decrypt(
|
void decrypt(
|
||||||
final OutputStream plainTextOutput,
|
final OutputStream output,
|
||||||
final InputStream cipherInputStream,
|
final InputStream input,
|
||||||
final SebConfigEncryptionContext context);
|
final SebConfigEncryptionContext context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,9 @@ public interface SebConfigEncryptionContext {
|
||||||
|
|
||||||
/** Get a defined Certificate if supported.
|
/** Get a defined Certificate if supported.
|
||||||
*
|
*
|
||||||
|
* @param key The key of the Certificate to get
|
||||||
* @return a defined Certificate
|
* @return a defined Certificate
|
||||||
* @throws UnsupportedOperationException if not supported */
|
* @throws UnsupportedOperationException if not supported */
|
||||||
Certificate getCertificate();
|
Certificate getCertificate(CharSequence key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,10 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
|
||||||
public interface SebConfigEncryptionService {
|
public interface SebConfigEncryptionService {
|
||||||
|
@ -60,21 +58,18 @@ public interface SebConfigEncryptionService {
|
||||||
* @param plainTextConfig plainTextConfig plain text SEB Configuration as CharSequence
|
* @param plainTextConfig plainTextConfig plain text SEB Configuration as CharSequence
|
||||||
* @return Result of plain text SEB Configuration within a ByteBuffer or a reference to an Exception on error
|
* @return Result of plain text SEB Configuration within a ByteBuffer or a reference to an Exception on error
|
||||||
* case */
|
* case */
|
||||||
Result<ByteBuffer> plainText(CharSequence plainTextConfig);
|
// void streamPlainData(
|
||||||
|
// final OutputStream output,
|
||||||
|
// final InputStream input);
|
||||||
|
|
||||||
void streamEncryption(
|
void streamEncrypted(
|
||||||
final OutputStream output,
|
final OutputStream output,
|
||||||
final InputStream input,
|
final InputStream input,
|
||||||
final Strategy strategy,
|
SebConfigEncryptionContext context);
|
||||||
final CharSequence password);
|
|
||||||
|
|
||||||
Result<ByteBuffer> encryptWithCertificate(
|
void streamDecrypted(
|
||||||
CharSequence plainTextConfig,
|
final OutputStream output,
|
||||||
Strategy strategy,
|
final InputStream input,
|
||||||
Certificate certificate);
|
|
||||||
|
|
||||||
Result<ByteBuffer> decrypt(
|
|
||||||
ByteBuffer cipher,
|
|
||||||
Supplier<CharSequence> passwordSupplier,
|
Supplier<CharSequence> passwordSupplier,
|
||||||
Function<CharSequence, Certificate> certificateStore);
|
Function<CharSequence, Certificate> certificateStore);
|
||||||
|
|
||||||
|
|
|
@ -16,4 +16,5 @@ public interface ZipService {
|
||||||
void write(OutputStream out, InputStream in);
|
void write(OutputStream out, InputStream in);
|
||||||
|
|
||||||
void read(OutputStream out, InputStream in);
|
void read(OutputStream out, InputStream in);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 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.io.OutputStream;
|
||||||
|
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.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.async.AsyncServiceSpringConfig;
|
||||||
|
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 NoneEncryptor implements SebConfigCryptor {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(NoneEncryptor.class);
|
||||||
|
|
||||||
|
private static final Set<Strategy> STRATEGIES = Utils.immutableSetOf(
|
||||||
|
Strategy.PLAIN_TEXT);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Strategy> strategies() {
|
||||||
|
return STRATEGIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
||||||
|
public void encrypt(
|
||||||
|
final OutputStream output,
|
||||||
|
final InputStream input,
|
||||||
|
final SebConfigEncryptionContext context) {
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("No encryption, write plain input data");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
IOUtils.copyLarge(input, output);
|
||||||
|
|
||||||
|
input.close();
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
|
||||||
|
} catch (final IOException e) {
|
||||||
|
log.error("Error while streaming plain data to output: ", e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
input.close();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
log.error("Failed to close InputStream");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Finished with no encryption. Close input stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
||||||
|
public void decrypt(
|
||||||
|
final OutputStream output,
|
||||||
|
final InputStream input,
|
||||||
|
final SebConfigEncryptionContext context) {
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("No decryption, read plain input data");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
IOUtils.copyLarge(input, output);
|
||||||
|
|
||||||
|
input.close();
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
|
||||||
|
} catch (final IOException e) {
|
||||||
|
log.error("Error while streaming plain data to output: ", e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
input.close();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
log.error("Failed to close InputStream");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Finished with no encryption. Close input stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,13 +11,12 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||||
import java.io.IOException;
|
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.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||||
|
import org.cryptonode.jncryptor.AES256JNCryptorInputStream;
|
||||||
import org.cryptonode.jncryptor.AES256JNCryptorOutputStream;
|
import org.cryptonode.jncryptor.AES256JNCryptorOutputStream;
|
||||||
import org.cryptonode.jncryptor.CryptorException;
|
import org.cryptonode.jncryptor.CryptorException;
|
||||||
import org.cryptonode.jncryptor.JNCryptor;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
@ -26,7 +25,6 @@ import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.async.AsyncServiceSpringConfig;
|
import ch.ethz.seb.sebserver.gbl.async.AsyncServiceSpringConfig;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
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.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;
|
||||||
|
@ -43,35 +41,11 @@ public class PasswordEncryptor implements SebConfigCryptor {
|
||||||
Strategy.PASSWORD_PSWD,
|
Strategy.PASSWORD_PSWD,
|
||||||
Strategy.PASSWORD_PWCC);
|
Strategy.PASSWORD_PWCC);
|
||||||
|
|
||||||
private final JNCryptor jnCryptor;
|
|
||||||
|
|
||||||
protected PasswordEncryptor(final JNCryptor jnCryptor) {
|
|
||||||
this.jnCryptor = jnCryptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Strategy> strategies() {
|
public Set<Strategy> strategies() {
|
||||||
return STRATEGIES;
|
return STRATEGIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result<ByteBuffer> encrypt(final CharSequence plainTextConfig, final SebConfigEncryptionContext context) {
|
|
||||||
return Result.tryCatch(() -> {
|
|
||||||
return ByteBuffer.wrap(this.jnCryptor.encryptData(
|
|
||||||
Utils.toByteArray(plainTextConfig),
|
|
||||||
Utils.toCharArray(context.getPassword())));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result<ByteBuffer> decrypt(final ByteBuffer cipher, final SebConfigEncryptionContext context) {
|
|
||||||
return Result.tryCatch(() -> {
|
|
||||||
return ByteBuffer.wrap(this.jnCryptor.decryptData(
|
|
||||||
Utils.toByteArray(cipher),
|
|
||||||
Utils.toCharArray(context.getPassword())));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
||||||
public void encrypt(
|
public void encrypt(
|
||||||
|
@ -80,7 +54,7 @@ public class PasswordEncryptor implements SebConfigCryptor {
|
||||||
final SebConfigEncryptionContext context) {
|
final SebConfigEncryptionContext context) {
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("*** Start streaming asynchronous encryption of SEB exam configuration data");
|
log.debug("*** Start streaming asynchronous encryption");
|
||||||
}
|
}
|
||||||
|
|
||||||
AES256JNCryptorOutputStream encryptOutput = null;
|
AES256JNCryptorOutputStream encryptOutput = null;
|
||||||
|
@ -88,17 +62,17 @@ public class PasswordEncryptor implements SebConfigCryptor {
|
||||||
|
|
||||||
encryptOutput = new AES256JNCryptorOutputStream(
|
encryptOutput = new AES256JNCryptorOutputStream(
|
||||||
output,
|
output,
|
||||||
Utils.toCharArray(context.getPassword()));
|
Utils.toCharArray(context.getPassword()),
|
||||||
|
10000);
|
||||||
|
|
||||||
IOUtils.copyLarge(input, encryptOutput);
|
IOUtils.copyLarge(input, encryptOutput);
|
||||||
|
|
||||||
encryptOutput.close();
|
input.close();
|
||||||
encryptOutput.flush();
|
encryptOutput.flush();
|
||||||
encryptOutput.close();
|
encryptOutput.close();
|
||||||
output.flush();
|
|
||||||
|
|
||||||
} catch (final CryptorException e) {
|
} catch (final CryptorException e) {
|
||||||
log.error("Error while trying to stream and encrypt seb exam configuration data: ", e);
|
log.error("Error while trying to stream and encrypt data: ", e);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
log.error("Error while trying to read/write form/to streams: ", e);
|
log.error("Error while trying to read/write form/to streams: ", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -110,7 +84,7 @@ public class PasswordEncryptor implements SebConfigCryptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("*** Finish streaming asynchronous encryption of SEB exam configuration data");
|
log.debug("*** Finish streaming asynchronous encryption");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,11 +92,42 @@ public class PasswordEncryptor implements SebConfigCryptor {
|
||||||
@Override
|
@Override
|
||||||
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
|
||||||
public void decrypt(
|
public void decrypt(
|
||||||
final OutputStream plainTextOutput,
|
final OutputStream output,
|
||||||
final InputStream cipherInputStream,
|
final InputStream input,
|
||||||
final SebConfigEncryptionContext context) {
|
final SebConfigEncryptionContext context) {
|
||||||
|
|
||||||
// TODO Auto-generated method stub
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("*** Start streaming asynchronous decryption");
|
||||||
|
}
|
||||||
|
|
||||||
|
AES256JNCryptorInputStream encryptInput = null;
|
||||||
|
try {
|
||||||
|
|
||||||
|
encryptInput = new AES256JNCryptorInputStream(
|
||||||
|
input,
|
||||||
|
Utils.toCharArray(context.getPassword()));
|
||||||
|
|
||||||
|
IOUtils.copyLarge(encryptInput, output);
|
||||||
|
|
||||||
|
input.close();
|
||||||
|
encryptInput.close();
|
||||||
|
output.flush();
|
||||||
|
output.close();
|
||||||
|
|
||||||
|
} catch (final IOException e) {
|
||||||
|
log.error("Error while trying to read/write form/to streams: ", e);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (encryptInput != null)
|
||||||
|
encryptInput.close();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
log.error("Failed to close AES256JNCryptorOutputStream: ", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("*** Finish streaming asynchronous decryption");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
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;
|
||||||
import java.io.PipedOutputStream;
|
import java.io.PipedOutputStream;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ -31,7 +29,6 @@ import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentialService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentialService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentials;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentials;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO;
|
||||||
|
@ -40,6 +37,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebClientConfigSe
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ZipService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ZipService;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.SebConfigEncryptionServiceImpl.EncryptionContext;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
|
@ -147,6 +145,7 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
|
||||||
PipedOutputStream pOut = null;
|
PipedOutputStream pOut = null;
|
||||||
PipedInputStream pIn = null;
|
PipedInputStream pIn = null;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// zip the plain text
|
// zip the plain text
|
||||||
final InputStream plainIn = IOUtils.toInputStream(plainTextConfig, "UTF-8");
|
final InputStream plainIn = IOUtils.toInputStream(plainTextConfig, "UTF-8");
|
||||||
pOut = new PipedOutputStream();
|
pOut = new PipedOutputStream();
|
||||||
|
@ -157,7 +156,10 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
|
||||||
if (encryptionPassword != null) {
|
if (encryptionPassword != null) {
|
||||||
passwordEncryption(output, encryptionPassword, pIn);
|
passwordEncryption(output, encryptionPassword, pIn);
|
||||||
} else {
|
} else {
|
||||||
noEncryption(output, plainTextConfig);
|
this.sebConfigEncryptionService.streamEncrypted(
|
||||||
|
output,
|
||||||
|
pIn,
|
||||||
|
EncryptionContext.contextOfPlainText());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
@ -177,21 +179,6 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void noEncryption(
|
|
||||||
final OutputStream output,
|
|
||||||
final String plainTextConfig) throws IOException {
|
|
||||||
|
|
||||||
log.debug("Serve plain text seb configuration with specified header");
|
|
||||||
|
|
||||||
final ByteBuffer encryptedConfig = this.sebConfigEncryptionService.plainText(plainTextConfig)
|
|
||||||
.getOrThrow();
|
|
||||||
|
|
||||||
IOUtils.copyLarge(
|
|
||||||
new ByteArrayInputStream(Utils.toByteArray(encryptedConfig)),
|
|
||||||
output);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void passwordEncryption(
|
private void passwordEncryption(
|
||||||
final OutputStream output,
|
final OutputStream output,
|
||||||
final CharSequence encryptionPassword,
|
final CharSequence encryptionPassword,
|
||||||
|
@ -204,11 +191,12 @@ public class SebClientConfigServiceImpl implements SebClientConfigService {
|
||||||
final CharSequence encryptionPasswordPlaintext = this.clientCredentialService
|
final CharSequence encryptionPasswordPlaintext = this.clientCredentialService
|
||||||
.decrypt(encryptionPassword);
|
.decrypt(encryptionPassword);
|
||||||
|
|
||||||
this.sebConfigEncryptionService.streamEncryption(
|
this.sebConfigEncryptionService.streamEncrypted(
|
||||||
output,
|
output,
|
||||||
input,
|
input,
|
||||||
Strategy.PASSWORD_PSWD,
|
EncryptionContext.contextOf(
|
||||||
encryptionPasswordPlaintext);
|
Strategy.PASSWORD_PSWD,
|
||||||
|
encryptionPasswordPlaintext));
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("*** Finished Seb client configuration with password based encryption");
|
log.debug("*** Finished Seb client configuration with password based encryption");
|
||||||
|
|
|
@ -13,7 +13,6 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PipedInputStream;
|
import java.io.PipedInputStream;
|
||||||
import java.io.PipedOutputStream;
|
import java.io.PipedOutputStream;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -31,7 +30,6 @@ import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
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.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;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService;
|
||||||
|
@ -57,27 +55,24 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public Result<ByteBuffer> plainText(final CharSequence plainTextConfig) {
|
// public void streamPlainData(
|
||||||
|
// final OutputStream output,
|
||||||
if (log.isDebugEnabled()) {
|
// final InputStream input) {
|
||||||
log.debug("No encryption, use plain text with header");
|
//
|
||||||
}
|
//
|
||||||
|
// getEncryptor(strategy)
|
||||||
return Result.tryCatch(() -> {
|
// .getOrThrow()
|
||||||
return addHeader(
|
// .encrypt(pout, input, context);
|
||||||
Utils.toByteBuffer(plainTextConfig),
|
// }
|
||||||
Strategy.PLAIN_TEXT);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void streamEncryption(
|
public void streamEncrypted(
|
||||||
final OutputStream output,
|
final OutputStream output,
|
||||||
final InputStream input,
|
final InputStream input,
|
||||||
final Strategy strategy,
|
final SebConfigEncryptionContext context) {
|
||||||
final CharSequence password) {
|
|
||||||
|
|
||||||
|
final Strategy strategy = context.getStrategy();
|
||||||
PipedOutputStream pout = null;
|
PipedOutputStream pout = null;
|
||||||
PipedInputStream pin = null;
|
PipedInputStream pin = null;
|
||||||
try {
|
try {
|
||||||
|
@ -91,26 +86,27 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
|
||||||
pout.write(strategy.header);
|
pout.write(strategy.header);
|
||||||
getEncryptor(strategy)
|
getEncryptor(strategy)
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.encrypt(pout,
|
.encrypt(pout, input, context);
|
||||||
input,
|
|
||||||
EncryptionContext.contextOf(strategy, password));
|
|
||||||
|
|
||||||
IOUtils.copyLarge(pin, output);
|
IOUtils.copyLarge(pin, output);
|
||||||
|
|
||||||
pin.close();
|
pin.close();
|
||||||
pout.flush();
|
pout.flush();
|
||||||
pout.close();
|
pout.close();
|
||||||
|
output.flush();
|
||||||
|
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
log.error("Error while stream encrypted data: ", e);
|
log.error("Error while stream encrypted data: ", e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
pin.close();
|
if (pin != null)
|
||||||
|
pin.close();
|
||||||
} catch (final IOException e1) {
|
} catch (final IOException e1) {
|
||||||
log.error("Failed to close PipedInputStream: ", e1);
|
log.error("Failed to close PipedInputStream: ", e1);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
pout.close();
|
if (pout != null)
|
||||||
|
pout.close();
|
||||||
} catch (final IOException e1) {
|
} catch (final IOException e1) {
|
||||||
log.error("Failed to close PipedOutputStream: ", e1);
|
log.error("Failed to close PipedOutputStream: ", e1);
|
||||||
}
|
}
|
||||||
|
@ -118,95 +114,72 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<ByteBuffer> encryptWithCertificate(
|
public void streamDecrypted(
|
||||||
final CharSequence plainTextConfig,
|
final OutputStream output,
|
||||||
final Strategy strategy,
|
final InputStream input,
|
||||||
final Certificate certificate) {
|
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Certificate encryption with strategy: {}", strategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getEncryptor(strategy)
|
|
||||||
.flatMap(encryptor -> encryptor.encrypt(
|
|
||||||
plainTextConfig,
|
|
||||||
EncryptionContext.contextOf(strategy, certificate)))
|
|
||||||
.map(bb -> addHeader(bb, strategy));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result<ByteBuffer> decrypt(
|
|
||||||
final ByteBuffer cipher,
|
|
||||||
final Supplier<CharSequence> passwordSupplier,
|
final Supplier<CharSequence> passwordSupplier,
|
||||||
final Function<CharSequence, Certificate> certificateStore) {
|
final Function<CharSequence, Certificate> certificateStore) {
|
||||||
|
|
||||||
return verifyStrategy(cipher)
|
PipedOutputStream pout = null;
|
||||||
.flatMap(strategy -> decrypt(strategy, cipher, passwordSupplier, certificateStore));
|
PipedInputStream pin = null;
|
||||||
}
|
try {
|
||||||
|
pout = new PipedOutputStream();
|
||||||
|
pin = new PipedInputStream(pout);
|
||||||
|
|
||||||
private Result<ByteBuffer> decrypt(
|
final Strategy strategy = verifyStrategy(input);
|
||||||
final Strategy strategy,
|
|
||||||
final ByteBuffer cipher,
|
|
||||||
final Supplier<CharSequence> passwordSupplier,
|
|
||||||
final Function<CharSequence, Certificate> certificateStore) {
|
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Decryption with strategy: {}", strategy);
|
log.debug("Password decryption with strategy: {}", strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strategy == Strategy.PLAIN_TEXT) {
|
final EncryptionContext context = new EncryptionContext(
|
||||||
return Result.of(removeHeader(cipher, strategy));
|
strategy,
|
||||||
}
|
(passwordSupplier != null) ? passwordSupplier.get() : null,
|
||||||
|
certificateStore);
|
||||||
|
|
||||||
return getEncryptor(strategy)
|
getEncryptor(strategy)
|
||||||
.flatMap(encryptor -> encryptor.decrypt(
|
.getOrThrow()
|
||||||
removeHeader(cipher, strategy),
|
.decrypt(pout, input, context);
|
||||||
(strategy.type == Type.PASSWORD)
|
|
||||||
? EncryptionContext.contextOf(strategy, passwordSupplier.get())
|
|
||||||
: EncryptionContext.contextOf(strategy, certificateStore)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ByteBuffer addHeader(final ByteBuffer input, final Strategy strategy) {
|
IOUtils.copyLarge(pin, output);
|
||||||
final ByteBuffer _input = (input == null) ? ByteBuffer.allocate(0) : input;
|
|
||||||
|
|
||||||
_input.rewind();
|
pin.close();
|
||||||
final ByteBuffer buffer = ByteBuffer.allocate(
|
pout.flush();
|
||||||
SebConfigEncryptionServiceImpl.HEADER_SIZE +
|
pout.close();
|
||||||
_input.limit());
|
output.flush();
|
||||||
|
|
||||||
buffer.put(strategy.header);
|
} catch (final IOException e) {
|
||||||
buffer.put(_input);
|
log.error("Error while stream decrypted data: ", e);
|
||||||
return buffer.asReadOnlyBuffer();
|
} finally {
|
||||||
}
|
try {
|
||||||
|
if (pin != null)
|
||||||
private ByteBuffer removeHeader(final ByteBuffer input, final Strategy strategy) {
|
pin.close();
|
||||||
input.rewind();
|
} catch (final IOException e1) {
|
||||||
final byte[] header = new byte[SebConfigEncryptionServiceImpl.HEADER_SIZE];
|
log.error("Failed to close PipedInputStream: ", e1);
|
||||||
input.get(header);
|
}
|
||||||
|
try {
|
||||||
if (Arrays.equals(strategy.header, header)) {
|
if (pout != null)
|
||||||
final byte[] b = new byte[input.remaining()];
|
pout.close();
|
||||||
input.get(b);
|
} catch (final IOException e1) {
|
||||||
return ByteBuffer.wrap(b).asReadOnlyBuffer();
|
log.error("Failed to close PipedOutputStream: ", e1);
|
||||||
} else {
|
|
||||||
input.clear();
|
|
||||||
return input.asReadOnlyBuffer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result<Strategy> verifyStrategy(final ByteBuffer cipher) {
|
|
||||||
cipher.rewind();
|
|
||||||
final byte[] header = new byte[HEADER_SIZE];
|
|
||||||
cipher.get(header);
|
|
||||||
//final String headerString = Utils.toString(header);
|
|
||||||
for (final Strategy s : Strategy.values()) {
|
|
||||||
if (Arrays.equals(s.header, header)) {
|
|
||||||
return Result.of(s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log.error("Failed to verify encryption strategy. Fallback to plain text strategy");
|
private Strategy verifyStrategy(final InputStream input) {
|
||||||
return Result.of(Strategy.PLAIN_TEXT);
|
try {
|
||||||
|
final byte[] header = new byte[HEADER_SIZE];
|
||||||
|
input.read(header);
|
||||||
|
for (final Strategy s : Strategy.values()) {
|
||||||
|
if (Arrays.equals(s.header, header)) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Failed to verify decryption strategy from input stream");
|
||||||
|
} catch (final IOException e) {
|
||||||
|
log.error("Failed to read decryption strategy from input stream");
|
||||||
|
throw new IllegalStateException("Failed to verify decryption strategy from input stream");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<SebConfigCryptor> getEncryptor(final Strategy strategy) {
|
private Result<SebConfigCryptor> getEncryptor(final Strategy strategy) {
|
||||||
|
@ -218,21 +191,20 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
|
||||||
return Result.of(encryptor);
|
return Result.of(encryptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class EncryptionContext implements SebConfigEncryptionContext {
|
static class EncryptionContext implements SebConfigEncryptionContext {
|
||||||
|
|
||||||
public final Strategy strategy;
|
public final Strategy strategy;
|
||||||
public final CharSequence password;
|
public final CharSequence password;
|
||||||
public final Certificate certificate;
|
public final Function<CharSequence, Certificate> certificateStore;
|
||||||
|
|
||||||
private EncryptionContext(
|
private EncryptionContext(
|
||||||
final Strategy strategy,
|
final Strategy strategy,
|
||||||
final CharSequence password,
|
final CharSequence password,
|
||||||
final Certificate certificate,
|
|
||||||
final Function<CharSequence, Certificate> certificateStore) {
|
final Function<CharSequence, Certificate> certificateStore) {
|
||||||
|
|
||||||
this.strategy = strategy;
|
this.strategy = strategy;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.certificate = certificate;
|
this.certificateStore = certificateStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -246,18 +218,16 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Certificate getCertificate() {
|
public Certificate getCertificate(final CharSequence key) {
|
||||||
return this.certificate;
|
if (this.certificateStore == null) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
return this.certificateStore.apply(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SebConfigEncryptionContext contextOf(final Strategy strategy, final CharSequence password) {
|
static SebConfigEncryptionContext contextOf(final Strategy strategy, final CharSequence password) {
|
||||||
checkPasswordbased(strategy);
|
checkPasswordbased(strategy);
|
||||||
return new EncryptionContext(strategy, password, null, null);
|
return new EncryptionContext(strategy, password, null);
|
||||||
}
|
|
||||||
|
|
||||||
static SebConfigEncryptionContext contextOf(final Strategy strategy, final Certificate certificate) {
|
|
||||||
checkCertificateBased(strategy);
|
|
||||||
return new EncryptionContext(strategy, null, certificate, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SebConfigEncryptionContext contextOf(
|
static SebConfigEncryptionContext contextOf(
|
||||||
|
@ -265,7 +235,7 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
|
||||||
final Function<CharSequence, Certificate> certificateStore) {
|
final Function<CharSequence, Certificate> certificateStore) {
|
||||||
|
|
||||||
checkCertificateBased(strategy);
|
checkCertificateBased(strategy);
|
||||||
return new EncryptionContext(strategy, null, null, certificateStore);
|
return new EncryptionContext(strategy, null, certificateStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkPasswordbased(final Strategy strategy) {
|
static void checkPasswordbased(final Strategy strategy) {
|
||||||
|
@ -280,6 +250,10 @@ public final class SebConfigEncryptionServiceImpl implements SebConfigEncryption
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SebConfigEncryptionContext contextOfPlainText() {
|
||||||
|
return new EncryptionContext(Strategy.PLAIN_TEXT, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
@ -22,7 +22,6 @@ import org.cryptonode.jncryptor.AES256JNCryptorOutputStream;
|
||||||
import org.cryptonode.jncryptor.JNCryptor;
|
import org.cryptonode.jncryptor.JNCryptor;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
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.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;
|
||||||
|
@ -45,7 +44,7 @@ public class PasswordEncryptorTest {
|
||||||
public void testUsingPassword() throws Exception {
|
public void testUsingPassword() throws Exception {
|
||||||
|
|
||||||
final String config = "<TestConfig></TestConfig>";
|
final String config = "<TestConfig></TestConfig>";
|
||||||
final byte[] plaintext = Utils.toByteArray(config);//getRandomBytes(127);
|
final byte[] plaintext = Utils.toByteArray(config);
|
||||||
|
|
||||||
final String password = "Testing1234";
|
final String password = "Testing1234";
|
||||||
|
|
||||||
|
@ -63,36 +62,9 @@ public class PasswordEncryptorTest {
|
||||||
assertArrayEquals(plaintext, result);
|
assertArrayEquals(plaintext, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test1() {
|
|
||||||
final JNCryptor jnCryptor = new AES256JNCryptor();
|
|
||||||
jnCryptor.setPBKDFIterations(10000);
|
|
||||||
final PasswordEncryptor encryptor = new PasswordEncryptor(jnCryptor);
|
|
||||||
|
|
||||||
final String config = "<TestConfig></TestConfig>";
|
|
||||||
final String pwd = "password";
|
|
||||||
|
|
||||||
final SebConfigEncryptionContext context = EncryptionContext.contextOf(
|
|
||||||
Strategy.PASSWORD_PWCC,
|
|
||||||
pwd);
|
|
||||||
|
|
||||||
final Result<ByteBuffer> encrypt = encryptor.encrypt(config, context);
|
|
||||||
assertFalse(encrypt.hasError());
|
|
||||||
final ByteBuffer cipher = encrypt.getOrThrow();
|
|
||||||
final byte[] byteArray = Utils.toByteArray(cipher);
|
|
||||||
|
|
||||||
final Result<ByteBuffer> decrypt = encryptor.decrypt(cipher, context);
|
|
||||||
assertFalse(decrypt.hasError());
|
|
||||||
|
|
||||||
final String decryptedConfig = Utils.toString(decrypt.getOrThrow());
|
|
||||||
assertEquals(config, decryptedConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test2() throws IOException {
|
public void test2() throws IOException {
|
||||||
final JNCryptor jnCryptor = new AES256JNCryptor();
|
final PasswordEncryptor encryptor = new PasswordEncryptor();
|
||||||
jnCryptor.setPBKDFIterations(10000);
|
|
||||||
final PasswordEncryptor encryptor = new PasswordEncryptor(jnCryptor);
|
|
||||||
|
|
||||||
final String config = "<TestConfig></TestConfig>";
|
final String config = "<TestConfig></TestConfig>";
|
||||||
final String pwd = "password";
|
final String pwd = "password";
|
||||||
|
@ -109,14 +81,16 @@ public class PasswordEncryptorTest {
|
||||||
|
|
||||||
final byte[] byteArray = out.toByteArray();
|
final byte[] byteArray = out.toByteArray();
|
||||||
|
|
||||||
final Result<ByteBuffer> decrypt = encryptor.decrypt(
|
final ByteArrayOutputStream out2 = new ByteArrayOutputStream(512);
|
||||||
ByteBuffer.wrap(byteArray),
|
encryptor.decrypt(
|
||||||
|
out2,
|
||||||
|
new ByteArrayInputStream(byteArray),
|
||||||
context);
|
context);
|
||||||
assertFalse(decrypt.hasError());
|
|
||||||
|
|
||||||
final ByteBuffer buffer = decrypt.getOrThrow();
|
final byte[] byteArray2 = out2.toByteArray();
|
||||||
buffer.rewind();
|
assertNotNull(byteArray2);
|
||||||
final String decryptedConfig = Utils.toString(buffer);
|
|
||||||
|
final String decryptedConfig = new String(byteArray2, "UTF-8");
|
||||||
assertEquals(config, decryptedConfig);
|
assertEquals(config, decryptedConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
@ -17,31 +18,44 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.cryptonode.jncryptor.AES256JNCryptor;
|
|
||||||
import org.cryptonode.jncryptor.JNCryptor;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
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.sebconfig.SebConfigCryptor;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigCryptor;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.SebConfigEncryptionServiceImpl.EncryptionContext;
|
||||||
|
|
||||||
public class SebConfigEncryptionServiceImplTest {
|
public class SebConfigEncryptionServiceImplTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPlainText() {
|
public void testPlainText() throws IOException {
|
||||||
final SebConfigEncryptionServiceImpl sebConfigEncryptionServiceImpl = sebConfigEncryptionServiceImpl();
|
final SebConfigEncryptionServiceImpl sebConfigEncryptionServiceImpl = sebConfigEncryptionServiceImpl();
|
||||||
|
|
||||||
final String config = "<TestConfig></TestConfig>";
|
final String config = "<TestConfig></TestConfig>";
|
||||||
|
|
||||||
final Result<ByteBuffer> plainText = sebConfigEncryptionServiceImpl.plainText(config);
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
assertFalse(plainText.hasError());
|
sebConfigEncryptionServiceImpl
|
||||||
final ByteBuffer cipher = plainText.get();
|
.streamEncrypted(
|
||||||
assertEquals("plnd<TestConfig></TestConfig>", Utils.toString(cipher));
|
out,
|
||||||
|
IOUtils.toInputStream(config, "UTF-8"),
|
||||||
|
EncryptionContext.contextOfPlainText());
|
||||||
|
|
||||||
final Result<ByteBuffer> decrypt = sebConfigEncryptionServiceImpl.decrypt(cipher, null, null);
|
final byte[] plainWithHeader = out.toByteArray();
|
||||||
assertFalse(decrypt.hasError());
|
assertNotNull(plainWithHeader);
|
||||||
assertEquals("<TestConfig></TestConfig>", Utils.toString(decrypt.get()));
|
assertEquals("plnd<TestConfig></TestConfig>", Utils.toString(plainWithHeader));
|
||||||
|
|
||||||
|
final ByteArrayOutputStream out2 = new ByteArrayOutputStream(512);
|
||||||
|
sebConfigEncryptionServiceImpl.streamDecrypted(
|
||||||
|
out2,
|
||||||
|
new ByteArrayInputStream(plainWithHeader),
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
|
||||||
|
final byte[] byteArray2 = out2.toByteArray();
|
||||||
|
assertNotNull(byteArray2);
|
||||||
|
|
||||||
|
final String decryptedConfig = new String(byteArray2, "UTF-8");
|
||||||
|
assertEquals(config, decryptedConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -53,11 +67,12 @@ public class SebConfigEncryptionServiceImplTest {
|
||||||
|
|
||||||
final ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
|
final ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
|
||||||
|
|
||||||
sebConfigEncryptionServiceImpl.streamEncryption(
|
sebConfigEncryptionServiceImpl.streamEncrypted(
|
||||||
out,
|
out,
|
||||||
IOUtils.toInputStream(config, "UTF-8"),
|
IOUtils.toInputStream(config, "UTF-8"),
|
||||||
Strategy.PASSWORD_PWCC,
|
EncryptionContext.contextOf(
|
||||||
pwd);
|
Strategy.PASSWORD_PWCC,
|
||||||
|
pwd));
|
||||||
|
|
||||||
final byte[] byteArray = out.toByteArray();
|
final byte[] byteArray = out.toByteArray();
|
||||||
|
|
||||||
|
@ -65,17 +80,24 @@ public class SebConfigEncryptionServiceImplTest {
|
||||||
final ByteBuffer cipher = ByteBuffer.wrap(byteArray);
|
final ByteBuffer cipher = ByteBuffer.wrap(byteArray);
|
||||||
assertTrue(Utils.toString(cipher).startsWith(Utils.toString(Strategy.PASSWORD_PWCC.header)));
|
assertTrue(Utils.toString(cipher).startsWith(Utils.toString(Strategy.PASSWORD_PWCC.header)));
|
||||||
|
|
||||||
final Result<ByteBuffer> decrypt = sebConfigEncryptionServiceImpl.decrypt(cipher, () -> pwd, null);
|
final ByteArrayOutputStream out2 = new ByteArrayOutputStream(512);
|
||||||
assertFalse(decrypt.hasError());
|
sebConfigEncryptionServiceImpl.streamDecrypted(
|
||||||
assertEquals("<TestConfig></TestConfig>", Utils.toString(decrypt.get()));
|
out2,
|
||||||
|
new ByteArrayInputStream(byteArray),
|
||||||
|
() -> pwd,
|
||||||
|
null);
|
||||||
|
|
||||||
|
final byte[] byteArray2 = out2.toByteArray();
|
||||||
|
assertNotNull(byteArray2);
|
||||||
|
|
||||||
|
final String decryptedConfig = new String(byteArray2, "UTF-8");
|
||||||
|
assertEquals(config, decryptedConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SebConfigEncryptionServiceImpl sebConfigEncryptionServiceImpl() {
|
private SebConfigEncryptionServiceImpl sebConfigEncryptionServiceImpl() {
|
||||||
final JNCryptor jnCryptor = new AES256JNCryptor();
|
|
||||||
jnCryptor.setPBKDFIterations(10000);
|
|
||||||
|
|
||||||
final List<SebConfigCryptor> encryptors = Arrays.asList(
|
final List<SebConfigCryptor> encryptors = Arrays.asList(
|
||||||
new PasswordEncryptor(jnCryptor));
|
new PasswordEncryptor(),
|
||||||
|
new NoneEncryptor());
|
||||||
return new SebConfigEncryptionServiceImpl(encryptors);
|
return new SebConfigEncryptionServiceImpl(encryptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue