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 javax.annotation.Nonnull; 019import java.io.IOException; 020import java.io.InputStream; 021import java.util.HashSet; 022import java.util.Iterator; 023import java.util.Set; 024 025import org.bouncycastle.openpgp.PGPException; 026import org.bouncycastle.openpgp.PGPPublicKeyRing; 027import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; 028import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; 029import org.pgpainless.key.OpenPgpV4Fingerprint; 030import org.pgpainless.key.protection.SecretKeyRingProtector; 031 032public class DecryptionBuilder implements DecryptionBuilderInterface { 033 034 private InputStream inputStream; 035 private PGPSecretKeyRingCollection decryptionKeys; 036 private SecretKeyRingProtector decryptionKeyDecryptor; 037 private Set<PGPPublicKeyRing> verificationKeys = new HashSet<>(); 038 private MissingPublicKeyCallback missingPublicKeyCallback = null; 039 040 @Override 041 public DecryptWith onInputStream(InputStream inputStream) { 042 this.inputStream = inputStream; 043 return new DecryptWithImpl(); 044 } 045 046 class DecryptWithImpl implements DecryptWith { 047 048 @Override 049 public VerifyWith decryptWith(@Nonnull SecretKeyRingProtector decryptor, @Nonnull PGPSecretKeyRingCollection secretKeyRings) { 050 DecryptionBuilder.this.decryptionKeys = secretKeyRings; 051 DecryptionBuilder.this.decryptionKeyDecryptor = decryptor; 052 return new VerifyWithImpl(); 053 } 054 055 @Override 056 public VerifyWith doNotDecrypt() { 057 DecryptionBuilder.this.decryptionKeys = null; 058 DecryptionBuilder.this.decryptionKeyDecryptor = null; 059 return new VerifyWithImpl(); 060 } 061 } 062 063 class VerifyWithImpl implements VerifyWith { 064 065 @Override 066 public HandleMissingPublicKeys verifyWith(@Nonnull PGPPublicKeyRingCollection publicKeyRingCollection) { 067 Set<PGPPublicKeyRing> publicKeyRings = new HashSet<>(); 068 for (Iterator<PGPPublicKeyRing> i = publicKeyRingCollection.getKeyRings(); i.hasNext(); ) { 069 publicKeyRings.add(i.next()); 070 } 071 return verifyWith(publicKeyRings); 072 } 073 074 @Override 075 public HandleMissingPublicKeys verifyWith(@Nonnull Set<OpenPgpV4Fingerprint> trustedKeyIds, 076 @Nonnull PGPPublicKeyRingCollection publicKeyRingCollection) { 077 Set<PGPPublicKeyRing> publicKeyRings = new HashSet<>(); 078 for (Iterator<PGPPublicKeyRing> i = publicKeyRingCollection.getKeyRings(); i.hasNext(); ) { 079 PGPPublicKeyRing p = i.next(); 080 OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(p); 081 if (trustedKeyIds.contains(fingerprint)) { 082 publicKeyRings.add(p); 083 } 084 } 085 return verifyWith(publicKeyRings); 086 } 087 088 @Override 089 public HandleMissingPublicKeys verifyWith(@Nonnull Set<PGPPublicKeyRing> publicKeyRings) { 090 DecryptionBuilder.this.verificationKeys = publicKeyRings; 091 return new HandleMissingPublicKeysImpl(); 092 } 093 094 @Override 095 public Build doNotVerify() { 096 DecryptionBuilder.this.verificationKeys = null; 097 return new BuildImpl(); 098 } 099 } 100 101 class HandleMissingPublicKeysImpl implements HandleMissingPublicKeys { 102 103 @Override 104 public Build handleMissingPublicKeysWith(@Nonnull MissingPublicKeyCallback callback) { 105 DecryptionBuilder.this.missingPublicKeyCallback = callback; 106 return new BuildImpl(); 107 } 108 109 @Override 110 public Build ignoreMissingPublicKeys() { 111 DecryptionBuilder.this.missingPublicKeyCallback = null; 112 return new BuildImpl(); 113 } 114 } 115 116 class BuildImpl implements Build { 117 118 @Override 119 public DecryptionStream build() throws IOException, PGPException { 120 return DecryptionStreamFactory.create(inputStream, 121 decryptionKeys, decryptionKeyDecryptor, verificationKeys, missingPublicKeyCallback); 122 } 123 } 124}