de.schlichtherle.truezip.crypto.raes.RaesOutputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of truezip-driver-tzp Show documentation
Show all versions of truezip-driver-tzp Show documentation
The file system driver family for RAES encrypted ZIP alias
ZIP.RAES alias TZP files.
Add the JAR artifact of this module to the run time class path to
make its file system drivers available for service location in the
client API modules.
/*
* Copyright (C) 2005-2013 Schlichtherle IT Services.
* All rights reserved. Use is subject to license terms.
*/
package de.schlichtherle.truezip.crypto.raes;
import de.schlichtherle.truezip.crypto.CipherOutputStream;
import de.schlichtherle.truezip.crypto.param.KeyStrength;
import edu.umd.cs.findbugs.annotations.CreatesObligation;
import java.io.IOException;
import java.io.OutputStream;
import javax.annotation.CheckForNull;
import javax.annotation.WillCloseWhenClosed;
import javax.annotation.concurrent.NotThreadSafe;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.Mac;
/**
* An {@link OutputStream} to produce a file with data ecnrypted according
* to the Random Access Encryption Specification (RAES).
*
* @see RaesReadOnlyFile
* @author Christian Schlichtherle
*/
@NotThreadSafe
public abstract class RaesOutputStream extends CipherOutputStream {
/**
* Update the given KLAC with the given file {@code length} in
* little endian order and finish it, writing the result to {@code buf}.
* The KLAC must already have been initialized and updated with the
* password bytes as retrieved according to PKCS #12.
* The result is stored in {@code buf}, which must match the given
* KLAC's output size.
*/
static void klac(final Mac klac, long length, final byte[] buf) {
for (int i = 0; i < 8; i++) {
klac.update((byte) length);
length >>= 8;
}
final int bufLength = klac.doFinal(buf, 0);
assert bufLength == buf.length;
}
/**
* Returns a new {@code RaesOutputStream}.
*
* @param out the output stream to decorate for writing the ciphered data.
* @param param The {@link RaesParameters} used to determine and
* configure the type of RAES file created.
* If the run time class of this parameter matches multiple
* parameter interfaces, it is at the discretion of this
* implementation which one is picked and hence which type of
* RAES file is created.
* If you need more control over this, pass in an instance which's
* run time class just implements the
* {@link RaesParametersProvider} interface.
* Instances of this interface are queried to find RAES parameters
* which match a known RAES type.
* This algorithm is recursively applied.
* @return A new {@code RaesOutputStream}.
* @throws RaesParametersException if {@code param} is {@code null} or
* no suitable RAES parameters can be found.
* @throws IOException on any I/O error.
*/
@CreatesObligation
public static RaesOutputStream getInstance(
final @WillCloseWhenClosed OutputStream out, // TODO: Use a source instead!
@CheckForNull RaesParameters param)
throws IOException {
if (null == out)
throw new NullPointerException();
while (null != param) {
// Order is important here to support multiple interface implementations!
if (param instanceof Type0RaesParameters) {
return new Type0RaesOutputStream(out,
(Type0RaesParameters) param);
} else if (param instanceof RaesParametersProvider) {
param = ((RaesParametersProvider) param)
.get(RaesParameters.class);
} else {
break;
}
}
throw new RaesParametersException("No suitable RAES parameters available!");
}
@CreatesObligation
@edu.umd.cs.findbugs.annotations.SuppressWarnings("OBL_UNSATISFIED_OBLIGATION")
RaesOutputStream( @CheckForNull @WillCloseWhenClosed OutputStream out,
@CheckForNull BufferedBlockCipher cipher) {
super(out, cipher);
}
/**
* Returns the key strength which is actually used to encrypt the data of
* the RAES file.
*/
public abstract KeyStrength getKeyStrength();
}