001// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org> 002// 003// SPDX-License-Identifier: Apache-2.0 004 005package org.pgpainless.decryption_verification.cleartext_signatures; 006 007import java.io.ByteArrayOutputStream; 008import java.io.File; 009import java.io.IOException; 010import java.io.InputStream; 011import java.io.OutputStream; 012 013/** 014 * Since the {@link CleartextSignatureProcessor} needs to read the whole data twice in order to verify signatures, 015 * a strategy for how to cache the read data is required. 016 * Otherwise, large data kept in memory could cause {@link OutOfMemoryError OutOfMemoryErrors} or other issues. 017 * 018 * This is an Interface that describes a strategy to deal with the fact that detached signatures require multiple passes 019 * to do verification. 020 * 021 * This interface can be used to write the signed data stream out via {@link #getMessageOutputStream()} and later 022 * get access to the data again via {@link #getMessageInputStream()}. 023 * Thereby the detail where the data is being stored (memory, file, etc.) can be abstracted away. 024 */ 025public interface MultiPassStrategy { 026 027 /** 028 * Provide an {@link OutputStream} into which the signed data can be read into. 029 * 030 * @return output stream 031 * @throws IOException io error 032 */ 033 OutputStream getMessageOutputStream() throws IOException; 034 035 /** 036 * Provide an {@link InputStream} which contains the data that was previously written away in 037 * {@link #getMessageOutputStream()}. 038 * 039 * As there may be multiple signatures that need to be processed, each call of this method MUST return 040 * a new {@link InputStream}. 041 * 042 * @return input stream 043 * @throws IOException io error 044 */ 045 InputStream getMessageInputStream() throws IOException; 046 047 /** 048 * Write the message content out to a file and re-read it to verify signatures. 049 * This strategy is best suited for larger messages (e.g. plaintext signed files) which might not fit into memory. 050 * After the message has been processed completely, the messages content are available at the provided file. 051 * 052 * @param file target file 053 * @return strategy 054 */ 055 static MultiPassStrategy writeMessageToFile(File file) { 056 return new WriteToFileMultiPassStrategy(file); 057 } 058 059 /** 060 * Read the message content into memory. 061 * This strategy is best suited for small messages which fit into memory. 062 * After the message has been processed completely, the message content can be accessed by calling 063 * {@link ByteArrayOutputStream#toByteArray()} on {@link #getMessageOutputStream()}. 064 * 065 * @return strategy 066 */ 067 static InMemoryMultiPassStrategy keepMessageInMemory() { 068 return new InMemoryMultiPassStrategy(); 069 } 070}