use of com.google.crypto.tink.StreamingAead in project tink by google.
the class InputStreamDecrypter method read.
@Override
@GuardedBy("this")
public synchronized int read(byte[] b, int offset, int len) throws IOException {
if (len == 0) {
return 0;
}
if (matchingStream != null) {
return matchingStream.read(b, offset, len);
} else {
if (attemptedMatching) {
throw new IOException("No matching key found for the ciphertext in the stream.");
}
attemptedMatching = true;
List<PrimitiveSet.Entry<StreamingAead>> entries = primitives.getRawPrimitives();
for (PrimitiveSet.Entry<StreamingAead> entry : entries) {
try {
InputStream attemptedStream = entry.getPrimitive().newDecryptingStream(ciphertextStream, associatedData);
int retValue = attemptedStream.read(b, offset, len);
if (retValue == 0) {
// Read should never return 0 when len > 0.
throw new IOException("Could not read bytes from the ciphertext stream");
}
// Found a matching stream.
// If retValue > 0 then the first ciphertext segment has been decrypted and
// authenticated. If retValue == -1 then plaintext is empty and again this has been
// authenticated.
matchingStream = attemptedStream;
disableRewinding();
return retValue;
} catch (IOException e) {
// Try another key.
// IOException is thrown e.g. when MAC is incorrect, but also in case
// of I/O failures.
// TODO(b/66098906): Use a subclass of IOException.
rewind();
continue;
} catch (GeneralSecurityException e) {
// Try another key.
rewind();
continue;
}
}
throw new IOException("No matching key found for the ciphertext in the stream.");
}
}
Aggregations