001package com.quorum.tessera.config.builder;
002
003import com.quorum.tessera.config.ConfigException;
004import com.quorum.tessera.config.EncryptorConfig;
005import com.quorum.tessera.config.EncryptorType;
006import com.quorum.tessera.config.KeyConfiguration;
007import com.quorum.tessera.config.keypairs.ConfigKeyPair;
008import com.quorum.tessera.config.keypairs.FilesystemKeyPair;
009import com.quorum.tessera.config.keys.KeyEncryptor;
010import com.quorum.tessera.config.keys.KeyEncryptorFactory;
011import com.quorum.tessera.config.util.KeyDataUtil;
012
013import java.nio.file.Path;
014import java.nio.file.Paths;
015import java.util.Collections;
016import java.util.List;
017import java.util.Map;
018import java.util.Objects;
019import java.util.stream.Collectors;
020import java.util.stream.IntStream;
021
022import static java.util.stream.Collectors.toList;
023
024public class KeyDataBuilder {
025
026    private KeyDataBuilder() {}
027
028    public static KeyDataBuilder create() {
029        return new KeyDataBuilder();
030    }
031
032    private List<String> publicKeys = Collections.emptyList();
033
034    private List<String> privateKeys = Collections.emptyList();
035
036    private String privateKeyPasswordFile;
037
038    private String workdir;
039
040    public KeyDataBuilder withPublicKeys(final List<String> publicKeys) {
041        this.publicKeys = publicKeys;
042        return this;
043    }
044
045    public KeyDataBuilder withPrivateKeys(final List<String> privateKeys) {
046        this.privateKeys = privateKeys;
047        return this;
048    }
049
050    public KeyDataBuilder withPrivateKeyPasswordFile(final String privateKeyPasswordFile) {
051        this.privateKeyPasswordFile = privateKeyPasswordFile;
052        return this;
053    }
054
055    public KeyDataBuilder withWorkingDirectory(final String workdir) {
056        this.workdir = workdir;
057        return this;
058    }
059
060    public KeyConfiguration build() {
061        if (publicKeys.size() != privateKeys.size()) {
062            throw new ConfigException(new RuntimeException("Different amount of public and private keys supplied"));
063        }
064
065        Map<Path, Path> mappedKeyPairs =
066                IntStream.range(0, publicKeys.size())
067                        .boxed()
068                        .collect(
069                                Collectors.toMap(
070                                        i -> ConfigBuilder.toPath(workdir, publicKeys.get(i)),
071                                        i -> ConfigBuilder.toPath(workdir, privateKeys.get(i))));
072
073        final KeyEncryptor keyEncryptor =
074                KeyEncryptorFactory.newFactory()
075                        .create(
076                                new EncryptorConfig() {
077                                    {
078                                        setType(EncryptorType.NACL);
079                                    }
080                                });
081
082        final List<ConfigKeyPair> keyData =
083                mappedKeyPairs.entrySet().stream()
084                        .map(pair -> new FilesystemKeyPair(pair.getKey(), pair.getValue(), keyEncryptor))
085
086                        .collect(toList());
087
088        final Path privateKeyPasswordFilePath;
089        if (!Objects.isNull(workdir) && !Objects.isNull(privateKeyPasswordFile)) {
090            privateKeyPasswordFilePath = Paths.get(workdir, privateKeyPasswordFile);
091        } else if (!Objects.isNull(privateKeyPasswordFile)) {
092            privateKeyPasswordFilePath = Paths.get(privateKeyPasswordFile);
093        } else {
094            privateKeyPasswordFilePath = null;
095        }
096
097        return new KeyConfiguration(privateKeyPasswordFilePath, null, keyData.stream()
098            .map(KeyDataUtil::marshal).collect(toList()), null, null);
099    }
100}