001// SPDX-FileCopyrightText: 2020 Paul Schaub <vanitasvitae@fsfe.org>
002//
003// SPDX-License-Identifier: Apache-2.0
004
005package org.pgpainless.implementation;
006
007import java.io.InputStream;
008import java.security.KeyPair;
009import java.util.Date;
010
011import org.bouncycastle.openpgp.PGPException;
012import org.bouncycastle.openpgp.PGPKeyPair;
013import org.bouncycastle.openpgp.PGPObjectFactory;
014import org.bouncycastle.openpgp.PGPPrivateKey;
015import org.bouncycastle.openpgp.PGPPublicKey;
016import org.bouncycastle.openpgp.PGPSecretKey;
017import org.bouncycastle.openpgp.PGPSessionKey;
018import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
019import org.bouncycastle.openpgp.operator.PBEDataDecryptorFactory;
020import org.bouncycastle.openpgp.operator.PBEKeyEncryptionMethodGenerator;
021import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
022import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
023import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
024import org.bouncycastle.openpgp.operator.PGPContentVerifierBuilderProvider;
025import org.bouncycastle.openpgp.operator.PGPDataEncryptorBuilder;
026import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
027import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
028import org.bouncycastle.openpgp.operator.PublicKeyDataDecryptorFactory;
029import org.bouncycastle.openpgp.operator.PublicKeyKeyEncryptionMethodGenerator;
030import org.bouncycastle.openpgp.operator.SessionKeyDataDecryptorFactory;
031import org.pgpainless.algorithm.HashAlgorithm;
032import org.pgpainless.algorithm.PublicKeyAlgorithm;
033import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
034import org.pgpainless.util.Passphrase;
035
036public abstract class ImplementationFactory {
037
038    private static ImplementationFactory FACTORY_IMPLEMENTATION;
039
040    public static void setFactoryImplementation(ImplementationFactory implementation) {
041        FACTORY_IMPLEMENTATION = implementation;
042    }
043
044    public static ImplementationFactory getInstance() {
045        if (FACTORY_IMPLEMENTATION == null) {
046            FACTORY_IMPLEMENTATION = new BcImplementationFactory();
047        }
048        return FACTORY_IMPLEMENTATION;
049    }
050
051    public PBESecretKeyEncryptor getPBESecretKeyEncryptor(SymmetricKeyAlgorithm symmetricKeyAlgorithm,
052                                                   Passphrase passphrase)
053            throws PGPException {
054        return getPBESecretKeyEncryptor(symmetricKeyAlgorithm,
055                getPGPDigestCalculator(HashAlgorithm.SHA1), passphrase);
056    }
057
058    public abstract PBESecretKeyEncryptor getPBESecretKeyEncryptor(PGPSecretKey secretKey, Passphrase passphrase) throws PGPException;
059
060    public abstract PBESecretKeyEncryptor getPBESecretKeyEncryptor(SymmetricKeyAlgorithm symmetricKeyAlgorithm,
061                                                          PGPDigestCalculator digestCalculator,
062                                                          Passphrase passphrase);
063
064    public abstract PBESecretKeyDecryptor getPBESecretKeyDecryptor(Passphrase passphrase) throws PGPException;
065
066    public PGPDigestCalculator getV4FingerprintCalculator() throws PGPException {
067        return getPGPDigestCalculator(HashAlgorithm.SHA1);
068    }
069
070    public PGPDigestCalculator getPGPDigestCalculator(HashAlgorithm algorithm) throws PGPException {
071        return getPGPDigestCalculator(algorithm.getAlgorithmId());
072    }
073
074    public PGPDigestCalculator getPGPDigestCalculator(int algorithm) throws PGPException {
075        return getPGPDigestCalculatorProvider().get(algorithm);
076    }
077
078    public abstract PGPDigestCalculatorProvider getPGPDigestCalculatorProvider() throws PGPException;
079
080    public abstract PGPContentVerifierBuilderProvider getPGPContentVerifierBuilderProvider();
081
082    public PGPContentSignerBuilder getPGPContentSignerBuilder(PublicKeyAlgorithm keyAlgorithm, HashAlgorithm hashAlgorithm) {
083        return getPGPContentSignerBuilder(keyAlgorithm.getAlgorithmId(), hashAlgorithm.getAlgorithmId());
084    }
085
086    public abstract PGPContentSignerBuilder getPGPContentSignerBuilder(int keyAlgorithm, int hashAlgorithm);
087
088    public abstract KeyFingerPrintCalculator getKeyFingerprintCalculator();
089
090    public abstract PBEDataDecryptorFactory getPBEDataDecryptorFactory(Passphrase passphrase) throws PGPException;
091
092    public abstract PublicKeyDataDecryptorFactory getPublicKeyDataDecryptorFactory(PGPPrivateKey privateKey);
093
094    public abstract PublicKeyKeyEncryptionMethodGenerator getPublicKeyKeyEncryptionMethodGenerator(PGPPublicKey key);
095
096    public abstract PBEKeyEncryptionMethodGenerator getPBEKeyEncryptionMethodGenerator(Passphrase passphrase);
097
098    public PGPDataEncryptorBuilder getPGPDataEncryptorBuilder(SymmetricKeyAlgorithm symmetricKeyAlgorithm) {
099        return getPGPDataEncryptorBuilder(symmetricKeyAlgorithm.getAlgorithmId());
100    }
101
102    public abstract PGPDataEncryptorBuilder getPGPDataEncryptorBuilder(int symmetricKeyAlgorithm);
103
104    public abstract PGPKeyPair getPGPKeyPair(PublicKeyAlgorithm algorithm, KeyPair keyPair, Date creationDate) throws PGPException;
105
106    public abstract PBESecretKeyEncryptor getPBESecretKeyEncryptor(SymmetricKeyAlgorithm encryptionAlgorithm,
107                                                                   HashAlgorithm hashAlgorithm, int s2kCount,
108                                                                   Passphrase passphrase) throws PGPException;
109
110    public abstract SessionKeyDataDecryptorFactory provideSessionKeyDataDecryptorFactory(PGPSessionKey sessionKey);
111
112    public abstract PGPObjectFactory getPGPObjectFactory(InputStream inputStream);
113
114    public abstract PGPObjectFactory getPGPObjectFactory(byte[] bytes);
115
116    @Override
117    public String toString() {
118        return getClass().getSimpleName();
119    }
120}