SEBSERV-135 try to encrypt config but still fails

This commit is contained in:
anhefti 2021-05-06 17:10:42 +02:00
parent 6bf1551028
commit c222f4216e
11 changed files with 190 additions and 106 deletions

View file

@ -29,6 +29,7 @@ public class CertificateInfo implements Entity {
UNKNOWN, UNKNOWN,
DIGITAL_SIGNATURE, DIGITAL_SIGNATURE,
DATA_ENCIPHERMENT, DATA_ENCIPHERMENT,
DATA_ENCIPHERMENT_PRIVATE_KEY,
KEY_CERT_SIGN KEY_CERT_SIGN
} }

View file

@ -104,6 +104,8 @@ public class SEBClientConfigForm implements TemplateComposer {
private static final LocTextKey QUIT_PASSWORD_CONFIRM_TEXT_KEY = private static final LocTextKey QUIT_PASSWORD_CONFIRM_TEXT_KEY =
new LocTextKey("sebserver.clientconfig.form.hashedQuitPassword.confirm"); new LocTextKey("sebserver.clientconfig.form.hashedQuitPassword.confirm");
private static final LocTextKey FORM_ENCRYPT_CERT_KEY =
new LocTextKey("sebserver.clientconfig.form.certificate");
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 =
@ -283,6 +285,14 @@ 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) .withDefaultSpanInput(3)
.addField(FormBuilder.password( .addField(FormBuilder.password(
Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET, Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET,

View file

@ -138,11 +138,14 @@ public final class SelectionFieldBuilder extends FieldBuilder<String> {
gridData.horizontalIndent = 0; gridData.horizontalIndent = 0;
label.setLayoutData(gridData); label.setLayoutData(gridData);
final Supplier<String> valueSupplier = () -> this.itemsSupplier.get().stream() final Supplier<String> valueSupplier = () -> (StringUtils.isBlank(valueKey))
.filter(tuple -> valueKey.equals(tuple._1)) ? Constants.EMPTY_NOTE
.findFirst() : this.itemsSupplier.get()
.map(tuple -> tuple._2) .stream()
.orElse(Constants.EMPTY_NOTE); .filter(tuple -> valueKey.equals(tuple._1))
.findFirst()
.map(tuple -> tuple._2)
.orElse(Constants.EMPTY_NOTE);
final Consumer<Text> updateFunction = t -> t.setText(valueSupplier.get()); final Consumer<Text> updateFunction = t -> t.setText(valueSupplier.get());
label.setText(valueSupplier.get()); label.setText(valueSupplier.get());

View file

@ -20,9 +20,12 @@ import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -43,6 +46,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSEBRestriction.WhiteListPath;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType; import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType; import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationStatus;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType;
@ -72,6 +76,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamNames
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExams; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExams;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutionNames; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutionNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetupNames; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetupNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.cert.GetCertificateNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodeNames; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodeNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodes; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNodes;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetViews; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetViews;
@ -85,6 +90,8 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
* combo-box content. */ * combo-box content. */
public class ResourceService { public class ResourceService {
private static final Logger log = LoggerFactory.getLogger(ResourceService.class);
private static final String MISSING_CLIENT_PING_NAME_KEY = "MISSING"; private static final String MISSING_CLIENT_PING_NAME_KEY = "MISSING";
public static final Comparator<Tuple<String>> RESOURCE_COMPARATOR = Comparator.comparing(t -> t._2); public static final Comparator<Tuple<String>> RESOURCE_COMPARATOR = Comparator.comparing(t -> t._2);
@ -732,4 +739,19 @@ public class ResourceService {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
public List<Tuple<String>> identityCertificatesResources() {
return Stream.concat(
Stream.of(new EntityName("", EntityType.CERTIFICATE, "")),
this.restService.getBuilder(GetCertificateNames.class)
.withQueryParam(
CertificateInfo.FILTER_ATTR_TYPE,
String.valueOf(CertificateInfo.CertificateType.DATA_ENCIPHERMENT_PRIVATE_KEY))
.call()
.onError(error -> log.warn("Failed to get identity certificate names: {}", error.getMessage()))
.getOr(Collections.emptyList())
.stream())
.map(entityName -> new Tuple<>(entityName.modelId, entityName.name))
.collect(Collectors.toList());
}
} }

View file

@ -10,23 +10,11 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.Collection; import java.util.Collection;
import java.util.EnumSet;
import java.util.NoSuchElementException;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.style.IETFUtils;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.joda.time.DateTime;
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.CertificateType;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates; import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates;
import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gbl.util.Result;
@ -52,79 +40,10 @@ public interface CertificateDAO {
Result<Collection<String>> getAllIdentityAlias(Long institutionId); Result<Collection<String>> getAllIdentityAlias(Long institutionId);
static Result<CertificateInfo> getDataFromCertificate(final Certificates certificates, final String alias) { Result<CertificateInfo> getDataFromCertificate(Certificates certificates, String alias);
return Result.tryCatch(() -> {
final X509Certificate certificate = (X509Certificate) certificates.keyStore.engineGetCertificate(alias);
if (certificate != null) {
final X509Certificate cert = certificate; Result<Collection<String>> getIdentityAlias(Long institutionId);
return new CertificateInfo(
extractAlias(cert, alias),
new DateTime(cert.getNotBefore()),
new DateTime(cert.getNotAfter()),
getTypes(cert));
} else { String extractAlias(X509Certificate a, String alias);
throw new NoSuchElementException("X509Certificate with alias: " + alias);
}
});
}
static String extractAlias(final X509Certificate certificate, final String alias) {
if (StringUtils.isNotBlank(alias)) {
return alias;
}
try {
final X500Name x500name = new JcaX509CertificateHolder(certificate).getSubject();
final RDN cn = x500name.getRDNs(BCStyle.CN)[0];
final String dn = IETFUtils.valueToString(cn.getFirst().getValue());
if (StringUtils.isBlank(dn)) {
return String.valueOf(certificate.getSerialNumber());
} else {
return dn.replace(" ", "_").toLowerCase();
}
} catch (final CertificateEncodingException e) {
return String.valueOf(certificate.getSerialNumber());
}
}
static EnumSet<CertificateType> getTypes(final X509Certificate cert) {
// KeyUsage ::= BIT STRING {
// digitalSignature (0),
// nonRepudiation (1),
// keyEncipherment (2),
// dataEncipherment (3),
// keyAgreement (4),
// keyCertSign (5),
// cRLSign (6),
// encipherOnly (7),
// decipherOnly (8) }
final boolean[] keyUsage = cert.getKeyUsage();
final EnumSet<CertificateType> result = EnumSet.noneOf(CertificateType.class);
// digitalSignature
if (keyUsage[0]) {
result.add(CertificateType.DIGITAL_SIGNATURE);
}
// dataEncipherment
if (keyUsage[3]) {
result.add(CertificateType.DATA_ENCIPHERMENT);
}
// keyCertSign
if (keyUsage[5]) {
result.add(CertificateType.KEY_CERT_SIGN);
}
if (result.isEmpty()) {
result.add(CertificateType.UNKNOWN);
}
return result;
}
} }

View file

@ -12,17 +12,27 @@ import java.io.ByteArrayInputStream;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream; import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.style.IETFUtils;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi; import org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi;
import org.joda.time.DateTime;
import org.mybatis.dynamic.sql.SqlBuilder; import org.mybatis.dynamic.sql.SqlBuilder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -35,6 +45,7 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
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;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo.CertificateType;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates; 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.Cryptor; import ch.ethz.seb.sebserver.gbl.util.Cryptor;
@ -109,7 +120,7 @@ public class CertificateDAOImpl implements CertificateDAO {
return getCertificatesFromPersistent(institutionId) return getCertificatesFromPersistent(institutionId)
.flatMap(record -> addCertificate(record, alias, certificate, privateKey)) .flatMap(record -> addCertificate(record, alias, certificate, privateKey))
.flatMap(this::storeUpdate) .flatMap(this::storeUpdate)
.flatMap(certs -> CertificateDAO.getDataFromCertificate(certs, alias)) .flatMap(certs -> getDataFromCertificate(certs, alias))
.onError(TransactionHandler::rollback); .onError(TransactionHandler::rollback);
} }
@ -136,6 +147,102 @@ public class CertificateDAOImpl implements CertificateDAO {
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
@Override
public Result<CertificateInfo> getDataFromCertificate(final Certificates certificates, final String alias) {
return Result.tryCatch(() -> {
final X509Certificate certificate = (X509Certificate) certificates.keyStore.engineGetCertificate(alias);
if (certificate != null) {
final X509Certificate cert = certificate;
return new CertificateInfo(
extractAlias(cert, alias),
new DateTime(cert.getNotBefore()),
new DateTime(cert.getNotAfter()),
getTypes(certificates, cert));
} else {
throw new NoSuchElementException("X509Certificate with alias: " + alias);
}
});
}
@Override
@Transactional(readOnly = true)
public Result<Collection<String>> getIdentityAlias(final Long institutionId) {
return getCertificates(institutionId)
.map(certs -> certs.aliases
.stream()
.filter(alias -> this.cryptor.getPrivateKey(certs.keyStore, alias).hasValue())
.collect(Collectors.toList()));
}
@Override
public String extractAlias(final X509Certificate certificate, final String alias) {
if (StringUtils.isNotBlank(alias)) {
return alias;
}
try {
final X500Name x500name = new JcaX509CertificateHolder(certificate).getSubject();
final RDN cn = x500name.getRDNs(BCStyle.CN)[0];
final String dn = IETFUtils.valueToString(cn.getFirst().getValue());
if (StringUtils.isBlank(dn)) {
return String.valueOf(certificate.getSerialNumber());
} else {
return dn.replace(" ", "_").toLowerCase();
}
} catch (final CertificateEncodingException e) {
log.warn("Error while trying to get alias form certificate subject name. Use serial number as alias");
return String.valueOf(certificate.getSerialNumber());
}
}
private EnumSet<CertificateType> getTypes(
final Certificates certificates,
final X509Certificate cert) {
// KeyUsage ::= BIT STRING {
// digitalSignature (0),
// nonRepudiation (1),
// keyEncipherment (2),
// dataEncipherment (3),
// keyAgreement (4),
// keyCertSign (5),
// cRLSign (6),
// encipherOnly (7),
// decipherOnly (8) }
final boolean[] keyUsage = cert.getKeyUsage();
final EnumSet<CertificateType> result = EnumSet.noneOf(CertificateType.class);
// digitalSignature
if (keyUsage[0]) {
result.add(CertificateType.DIGITAL_SIGNATURE);
}
// dataEncipherment
if (keyUsage[3]) {
final String alias = certificates.keyStore.engineGetCertificateAlias(cert);
if (this.cryptor.getPrivateKey(certificates.keyStore, alias).hasValue()) {
result.add(CertificateType.DATA_ENCIPHERMENT_PRIVATE_KEY);
} else {
result.add(CertificateType.DATA_ENCIPHERMENT);
}
}
// keyCertSign
if (keyUsage[5]) {
result.add(CertificateType.KEY_CERT_SIGN);
}
if (result.isEmpty()) {
result.add(CertificateType.UNKNOWN);
}
return result;
}
private Certificates createNewCertificateStore(final Long institutionId) { private Certificates createNewCertificateStore(final Long institutionId) {
return this.cryptor.createNewEmptyKeyStore() return this.cryptor.createNewEmptyKeyStore()
.map(store -> new CertificateRecord( .map(store -> new CertificateRecord(

View file

@ -53,7 +53,7 @@ public class CertificateServiceImpl implements CertificateService {
return this.certificateDAO return this.certificateDAO
.getCertificates(institutionId) .getCertificates(institutionId)
.flatMap(certs -> CertificateDAO.getDataFromCertificate(certs, alias)); .flatMap(certs -> this.certificateDAO.getDataFromCertificate(certs, alias));
} }
@Override @Override
@ -86,14 +86,14 @@ public class CertificateServiceImpl implements CertificateService {
return loadCertFromPEM(in) return loadCertFromPEM(in)
.flatMap(cert -> this.certificateDAO.addCertificate( .flatMap(cert -> this.certificateDAO.addCertificate(
institutionId, institutionId,
CertificateDAO.extractAlias(cert, alias), this.certificateDAO.extractAlias(cert, alias),
cert)); cert));
case PKCS12: case PKCS12:
return loadCertFromPKC(in, password) return loadCertFromPKC(in, password)
.flatMap(pair -> this.certificateDAO.addCertificate( .flatMap(pair -> this.certificateDAO.addCertificate(
institutionId, institutionId,
CertificateDAO.extractAlias(pair.a, alias), this.certificateDAO.extractAlias(pair.a, alias),
pair.a, pair.a,
pair.b)); pair.b));
default: default:
@ -133,7 +133,7 @@ public class CertificateServiceImpl implements CertificateService {
return certificates.aliases return certificates.aliases
.stream() .stream()
.map(alias -> CertificateDAO.getDataFromCertificate(certificates, alias)) .map(alias -> this.certificateDAO.getDataFromCertificate(certificates, alias))
.flatMap(Result::onErrorLogAndSkip) .flatMap(Result::onErrorLogAndSkip)
.filter(predicate) .filter(predicate)
.collect(Collectors.toList()); .collect(Collectors.toList());

View file

@ -12,15 +12,20 @@ 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.MessageDigest; import java.security.KeyFactory;
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.Set; import java.util.Set;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
import org.apache.commons.codec.binary.Hex;
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;
@ -44,6 +49,7 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
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 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 ENCRYPTION_KEY_LENGTH = 32;
private static final int KEY_LENGTH_SIZE = 4; private static final int KEY_LENGTH_SIZE = 4;
@ -82,6 +88,7 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
final byte[] generateParameter = generateParameter(certificate, publicKeyHash, symetricKey); final byte[] generateParameter = generateParameter(certificate, publicKeyHash, symetricKey);
output.write(generateParameter, 0, generateParameter.length); output.write(generateParameter, 0, generateParameter.length);
this.passwordEncryptor.encrypt(output, input, symetricKeyBase64); this.passwordEncryptor.encrypt(output, input, symetricKeyBase64);
} catch (final Exception e) { } catch (final Exception e) {
@ -106,17 +113,27 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
} }
private byte[] generatePublicKeyHash(final Certificate cert) throws NoSuchAlgorithmException { private byte[] generatePublicKeyHash(final Certificate cert)
final byte[] publicKey = cert.getPublicKey().getEncoded(); throws NoSuchAlgorithmException, InvalidKeySpecException {
final MessageDigest md = MessageDigest.getInstance(Constants.SHA_1); byte[] publicKey = cert.getPublicKey().getEncoded();
final byte[] hash = md.digest(publicKey); final PublicKey publicKey2 = cert.getPublicKey();
return hash; 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();
final String encodeHex = String.valueOf(Hex.encodeHex(publicKey));
final String sha1Hex = DigestUtils.sha1Hex(publicKey);
final String sha256Hex = DigestUtils.sha256Hex(publicKey);
return DigestUtils.sha1(publicKey);
} }
private byte[] generateSymetricKey() throws NoSuchAlgorithmException { private byte[] generateSymetricKey() throws NoSuchAlgorithmException {
final KeyGenerator keyGenerator = KeyGenerator.getInstance(Constants.AES); final KeyGenerator keyGenerator = KeyGenerator.getInstance(Constants.AES);
keyGenerator.init(ENCRYPTION_KEY_LENGTH); keyGenerator.init(ENCRYPTION_KEY_BITS);
return keyGenerator.generateKey().getEncoded(); final byte[] encoded = keyGenerator.generateKey().getEncoded();
return encoded;
} }
@SuppressWarnings("resource") @SuppressWarnings("resource")
@ -135,8 +152,9 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor {
data.write(publicKeyHash, 0, publicKeyHash.length); data.write(publicKeyHash, 0, publicKeyHash.length);
data.write(encryptedKeyLength, 0, encryptedKeyLength.length); data.write(encryptedKeyLength, 0, encryptedKeyLength.length);
data.write(encryptedKey, 0, encryptedKey.length); data.write(encryptedKey, 0, encryptedKey.length);
final byte[] byteArray = data.toByteArray();
return data.toByteArray(); return byteArray;
} }
private byte[] generateEncryptedKey(final Certificate cert, final byte[] symetricKey) throws Exception { private byte[] generateEncryptedKey(final Certificate cert, final byte[] symetricKey) throws Exception {

View file

@ -523,7 +523,7 @@ public class ClientConfigServiceImpl implements ClientConfigService {
this.sebConfigEncryptionService.streamEncrypted( this.sebConfigEncryptionService.streamEncrypted(
out, out,
(withPasswordEncryption) ? in : passEncryptionIn, (withPasswordEncryption) ? passEncryptionIn : in,
buildCertificateEncryptionContext(config)); buildCertificateEncryptionContext(config));
} }

View file

@ -63,7 +63,7 @@ public class PasswordEncryptor {
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 {
try { try {
input.close(); IOUtils.closeQuietly(input);
if (encryptOutput != null) { if (encryptOutput != null) {
encryptOutput.flush(); encryptOutput.flush();
encryptOutput.close(); encryptOutput.close();

View file

@ -729,6 +729,9 @@ sebserver.clientconfig.form.encryptSecret.confirm=Confirm Password
sebserver.clientconfig.form.encryptSecret.confirm.tooltip=Please retype the given password for confirmation sebserver.clientconfig.form.encryptSecret.confirm.tooltip=Please retype the given password for confirmation
sebserver.clientconfig.form.sebConfigPurpose=Configuration Purpose 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.tooltip=Choose identity certificate to be used for encrypting the connection configuration
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.
@ -1547,7 +1550,8 @@ sebserver.certificate.list.column.validTo=Valid To
sebserver.certificate.list.column.type=Types sebserver.certificate.list.column.type=Types
sebserver.certificate.list.column.type.UNKNOWN=Unknown sebserver.certificate.list.column.type.UNKNOWN=Unknown
sebserver.certificate.list.column.type.DIGITAL_SIGNATURE=TLS/SSL sebserver.certificate.list.column.type.DIGITAL_SIGNATURE=TLS/SSL
sebserver.certificate.list.column.type.DATA_ENCIPHERMENT=Identity sebserver.certificate.list.column.type.DATA_ENCIPHERMENT=Encipherment
sebserver.certificate.list.column.type.DATA_ENCIPHERMENT_PRIVATE_KEY=Identity
sebserver.certificate.list.column.type.KEY_CERT_SIGN=CA sebserver.certificate.list.column.type.KEY_CERT_SIGN=CA
sebserver.certificate.form.alias=Alias sebserver.certificate.form.alias=Alias