001/*
002 * Copyright 2018 Paul Schaub.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.pgpainless.decryption_verification;
017
018import java.util.Collections;
019import java.util.HashSet;
020import java.util.Set;
021
022import org.bouncycastle.openpgp.PGPPublicKey;
023import org.bouncycastle.openpgp.PGPPublicKeyRing;
024import org.pgpainless.algorithm.CompressionAlgorithm;
025import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
026import org.pgpainless.key.OpenPgpV4Fingerprint;
027
028public class OpenPgpMetadata {
029
030    private final Set<Long> recipientKeyIds;
031    private final OpenPgpV4Fingerprint decryptionFingerprint;
032    private final Set<Long> unverifiedSignatureKeyIds;
033    private final Set<OpenPgpV4Fingerprint> verifiedSignaturesFingerprints;
034
035    private final SymmetricKeyAlgorithm symmetricKeyAlgorithm;
036    private final CompressionAlgorithm compressionAlgorithm;
037    private final boolean integrityProtected;
038
039    public OpenPgpMetadata(Set<Long> recipientKeyIds,
040                           OpenPgpV4Fingerprint decryptionFingerprint,
041                           SymmetricKeyAlgorithm symmetricKeyAlgorithm,
042                           CompressionAlgorithm algorithm,
043                           boolean integrityProtected,
044                           Set<Long> unverifiedSignatureKeyIds,
045                           Set<OpenPgpV4Fingerprint> verifiedSignaturesFingerprints) {
046
047        this.recipientKeyIds = Collections.unmodifiableSet(recipientKeyIds);
048        this.decryptionFingerprint = decryptionFingerprint;
049        this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
050        this.compressionAlgorithm = algorithm;
051        this.integrityProtected = integrityProtected;
052        this.unverifiedSignatureKeyIds = Collections.unmodifiableSet(unverifiedSignatureKeyIds);
053        this.verifiedSignaturesFingerprints = Collections.unmodifiableSet(verifiedSignaturesFingerprints);
054    }
055
056    public Set<Long> getRecipientKeyIds() {
057        return recipientKeyIds;
058    }
059
060    public boolean isEncrypted() {
061        return !getRecipientKeyIds().isEmpty();
062    }
063
064    public OpenPgpV4Fingerprint getDecryptionFingerprint() {
065        return decryptionFingerprint;
066    }
067
068    public SymmetricKeyAlgorithm getSymmetricKeyAlgorithm() {
069        return symmetricKeyAlgorithm;
070    }
071
072    public CompressionAlgorithm getCompressionAlgorithm() {
073        return compressionAlgorithm;
074    }
075
076    public boolean isIntegrityProtected() {
077        return integrityProtected;
078    }
079
080    public Set<Long> getAllSignatureKeyFingerprints() {
081        return unverifiedSignatureKeyIds;
082    }
083
084    public boolean isSigned() {
085        return !unverifiedSignatureKeyIds.isEmpty();
086    }
087
088    public Set<OpenPgpV4Fingerprint> getVerifiedSignaturesFingerprints() {
089        return verifiedSignaturesFingerprints;
090    }
091
092    public boolean isVerified() {
093        return !verifiedSignaturesFingerprints.isEmpty();
094    }
095
096    public boolean containsVerifiedSignatureFrom(PGPPublicKeyRing publicKeys) {
097        for (PGPPublicKey key : publicKeys) {
098            OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(key);
099            if (containsVerifiedSignatureFrom(fingerprint)) {
100                return true;
101            }
102        }
103        return false;
104    }
105
106    public boolean containsVerifiedSignatureFrom(OpenPgpV4Fingerprint fingerprint) {
107        return verifiedSignaturesFingerprints.contains(fingerprint);
108    }
109
110    static Builder getBuilder() {
111        return new Builder();
112    }
113
114    static class Builder {
115
116        private final Set<Long> recipientFingerprints = new HashSet<>();
117        private OpenPgpV4Fingerprint decryptionFingerprint;
118        private final Set<Long> unverifiedSignatureKeyIds = new HashSet<>();
119        private final Set<OpenPgpV4Fingerprint> verifiedSignatureFingerprints = new HashSet<>();
120        private SymmetricKeyAlgorithm symmetricKeyAlgorithm = SymmetricKeyAlgorithm.NULL;
121        private CompressionAlgorithm compressionAlgorithm = CompressionAlgorithm.UNCOMPRESSED;
122        private boolean integrityProtected = false;
123
124        public Builder addRecipientKeyId(Long keyId) {
125            this.recipientFingerprints.add(keyId);
126            return this;
127        }
128
129        public Builder setDecryptionFingerprint(OpenPgpV4Fingerprint fingerprint) {
130            this.decryptionFingerprint = fingerprint;
131            return this;
132        }
133
134        public Builder setCompressionAlgorithm(CompressionAlgorithm algorithm) {
135            this.compressionAlgorithm = algorithm;
136            return this;
137        }
138
139        public Builder addUnverifiedSignatureKeyId(Long keyId) {
140            this.unverifiedSignatureKeyIds.add(keyId);
141            return this;
142        }
143
144        public Builder addVerifiedSignatureFingerprint(OpenPgpV4Fingerprint fingerprint) {
145            this.verifiedSignatureFingerprints.add(fingerprint);
146            return this;
147        }
148
149        public Builder setSymmetricKeyAlgorithm(SymmetricKeyAlgorithm symmetricKeyAlgorithm) {
150            this.symmetricKeyAlgorithm = symmetricKeyAlgorithm;
151            return this;
152        }
153
154        public Builder setIntegrityProtected(boolean integrityProtected) {
155            this.integrityProtected = integrityProtected;
156            return this;
157        }
158
159        public OpenPgpMetadata build() {
160            return new OpenPgpMetadata(recipientFingerprints, decryptionFingerprint, symmetricKeyAlgorithm, compressionAlgorithm, integrityProtected, unverifiedSignatureKeyIds, verifiedSignatureFingerprints);
161        }
162    }
163}