diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/CertificateInfo.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/CertificateInfo.java index a629fef6..99e96a32 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/CertificateInfo.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/CertificateInfo.java @@ -29,6 +29,7 @@ public class CertificateInfo implements Entity { UNKNOWN, DIGITAL_SIGNATURE, DATA_ENCIPHERMENT, + DATA_ENCIPHERMENT_PRIVATE_KEY, KEY_CERT_SIGN } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SEBClientConfigForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SEBClientConfigForm.java index d5106c80..7cc703b8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SEBClientConfigForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SEBClientConfigForm.java @@ -104,6 +104,8 @@ public class SEBClientConfigForm implements TemplateComposer { private static final LocTextKey QUIT_PASSWORD_CONFIRM_TEXT_KEY = 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 = new LocTextKey("sebserver.clientconfig.form.encryptSecret"); private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY = @@ -283,6 +285,14 @@ public class SEBClientConfigForm implements TemplateComposer { .mandatory(!isReadonly)) .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( Domain.SEB_CLIENT_CONFIGURATION.ATTR_ENCRYPT_SECRET, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java index 7d624aa2..9b4c8684 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java @@ -138,11 +138,14 @@ public final class SelectionFieldBuilder extends FieldBuilder { gridData.horizontalIndent = 0; label.setLayoutData(gridData); - final Supplier valueSupplier = () -> this.itemsSupplier.get().stream() - .filter(tuple -> valueKey.equals(tuple._1)) - .findFirst() - .map(tuple -> tuple._2) - .orElse(Constants.EMPTY_NOTE); + final Supplier valueSupplier = () -> (StringUtils.isBlank(valueKey)) + ? Constants.EMPTY_NOTE + : this.itemsSupplier.get() + .stream() + .filter(tuple -> valueKey.equals(tuple._1)) + .findFirst() + .map(tuple -> tuple._2) + .orElse(Constants.EMPTY_NOTE); final Consumer updateFunction = t -> t.setText(valueSupplier.get()); label.setText(valueSupplier.get()); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/ResourceService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/ResourceService.java index cf2f2697..24a47943 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/ResourceService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/ResourceService.java @@ -20,9 +20,12 @@ import java.util.Map; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTimeZone; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.core.env.Environment; 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.institution.LmsSetup.LmsType; 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.ConfigurationStatus; 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.institution.GetInstitutionNames; 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.GetExamConfigNodes; 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. */ public class ResourceService { + private static final Logger log = LoggerFactory.getLogger(ResourceService.class); + private static final String MISSING_CLIENT_PING_NAME_KEY = "MISSING"; public static final Comparator> RESOURCE_COMPARATOR = Comparator.comparing(t -> t._2); @@ -732,4 +739,19 @@ public class ResourceService { .collect(Collectors.toList()); } + public List> 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()); + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/CertificateDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/CertificateDAO.java index bdaf1edb..d6cde6b2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/CertificateDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/CertificateDAO.java @@ -10,23 +10,11 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao; import java.security.PrivateKey; import java.security.cert.Certificate; -import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; 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.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.util.Result; @@ -52,79 +40,10 @@ public interface CertificateDAO { Result> getAllIdentityAlias(Long institutionId); - static Result getDataFromCertificate(final Certificates certificates, final String alias) { - return Result.tryCatch(() -> { - final X509Certificate certificate = (X509Certificate) certificates.keyStore.engineGetCertificate(alias); - if (certificate != null) { + Result getDataFromCertificate(Certificates certificates, String alias); - final X509Certificate cert = certificate; - return new CertificateInfo( - extractAlias(cert, alias), - new DateTime(cert.getNotBefore()), - new DateTime(cert.getNotAfter()), - getTypes(cert)); + Result> getIdentityAlias(Long institutionId); - } else { - 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 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 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; - } + String extractAlias(X509Certificate a, String alias); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/CertificateDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/CertificateDAOImpl.java index 30b84b7c..f79072e5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/CertificateDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/CertificateDAOImpl.java @@ -12,17 +12,27 @@ import java.io.ByteArrayInputStream; import java.security.KeyStoreException; import java.security.PrivateKey; import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; import java.util.List; +import java.util.NoSuchElementException; import java.util.stream.Collectors; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; 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.joda.time.DateTime; import org.mybatis.dynamic.sql.SqlBuilder; import org.slf4j.Logger; 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.model.EntityKey; 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.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Cryptor; @@ -109,7 +120,7 @@ public class CertificateDAOImpl implements CertificateDAO { return getCertificatesFromPersistent(institutionId) .flatMap(record -> addCertificate(record, alias, certificate, privateKey)) .flatMap(this::storeUpdate) - .flatMap(certs -> CertificateDAO.getDataFromCertificate(certs, alias)) + .flatMap(certs -> getDataFromCertificate(certs, alias)) .onError(TransactionHandler::rollback); } @@ -136,6 +147,102 @@ public class CertificateDAOImpl implements CertificateDAO { .collect(Collectors.toList())); } + @Override + public Result 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> 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 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 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) { return this.cryptor.createNewEmptyKeyStore() .map(store -> new CertificateRecord( diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/CertificateServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/CertificateServiceImpl.java index 591a0bea..f87c2638 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/CertificateServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/CertificateServiceImpl.java @@ -53,7 +53,7 @@ public class CertificateServiceImpl implements CertificateService { return this.certificateDAO .getCertificates(institutionId) - .flatMap(certs -> CertificateDAO.getDataFromCertificate(certs, alias)); + .flatMap(certs -> this.certificateDAO.getDataFromCertificate(certs, alias)); } @Override @@ -86,14 +86,14 @@ public class CertificateServiceImpl implements CertificateService { return loadCertFromPEM(in) .flatMap(cert -> this.certificateDAO.addCertificate( institutionId, - CertificateDAO.extractAlias(cert, alias), + this.certificateDAO.extractAlias(cert, alias), cert)); case PKCS12: return loadCertFromPKC(in, password) .flatMap(pair -> this.certificateDAO.addCertificate( institutionId, - CertificateDAO.extractAlias(pair.a, alias), + this.certificateDAO.extractAlias(pair.a, alias), pair.a, pair.b)); default: @@ -133,7 +133,7 @@ public class CertificateServiceImpl implements CertificateService { return certificates.aliases .stream() - .map(alias -> CertificateDAO.getDataFromCertificate(certificates, alias)) + .map(alias -> this.certificateDAO.getDataFromCertificate(certificates, alias)) .flatMap(Result::onErrorLogAndSkip) .filter(predicate) .collect(Collectors.toList()); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/CertificateSymetricKeyCryptor.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/CertificateSymetricKeyCryptor.java index 7d456449..293f2ff1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/CertificateSymetricKeyCryptor.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/CertificateSymetricKeyCryptor.java @@ -12,15 +12,20 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; -import java.security.MessageDigest; +import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; import java.security.cert.Certificate; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import java.util.Set; import javax.crypto.Cipher; 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.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,6 +49,7 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor { private static final Set STRATEGIES = Utils.immutableSetOf( 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; @@ -82,6 +88,7 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor { final byte[] generateParameter = generateParameter(certificate, publicKeyHash, symetricKey); output.write(generateParameter, 0, generateParameter.length); + this.passwordEncryptor.encrypt(output, input, symetricKeyBase64); } catch (final Exception e) { @@ -106,17 +113,27 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor { } - private byte[] generatePublicKeyHash(final Certificate cert) throws NoSuchAlgorithmException { - final byte[] publicKey = cert.getPublicKey().getEncoded(); - final MessageDigest md = MessageDigest.getInstance(Constants.SHA_1); - final byte[] hash = md.digest(publicKey); - return hash; + private byte[] generatePublicKeyHash(final Certificate cert) + 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(); + 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 { final KeyGenerator keyGenerator = KeyGenerator.getInstance(Constants.AES); - keyGenerator.init(ENCRYPTION_KEY_LENGTH); - return keyGenerator.generateKey().getEncoded(); + keyGenerator.init(ENCRYPTION_KEY_BITS); + final byte[] encoded = keyGenerator.generateKey().getEncoded(); + return encoded; } @SuppressWarnings("resource") @@ -135,8 +152,9 @@ public class CertificateSymetricKeyCryptor implements SEBConfigCryptor { data.write(publicKeyHash, 0, publicKeyHash.length); data.write(encryptedKeyLength, 0, encryptedKeyLength.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 { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java index b9f88158..b7a98409 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java @@ -523,7 +523,7 @@ public class ClientConfigServiceImpl implements ClientConfigService { this.sebConfigEncryptionService.streamEncrypted( out, - (withPasswordEncryption) ? in : passEncryptionIn, + (withPasswordEncryption) ? passEncryptionIn : in, buildCertificateEncryptionContext(config)); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/PasswordEncryptor.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/PasswordEncryptor.java index 42ba67be..07ae4974 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/PasswordEncryptor.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/PasswordEncryptor.java @@ -63,7 +63,7 @@ public class PasswordEncryptor { log.error("Error while trying to read/write form/to streams: ", e); } finally { try { - input.close(); + IOUtils.closeQuietly(input); if (encryptOutput != null) { encryptOutput.flush(); encryptOutput.close(); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 776c30bd..6558b158 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -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.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.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.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.UNKNOWN=Unknown 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.form.alias=Alias