All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.java.truevfs.driver.zip.raes.crypto.RaesReadOnlyChannel Maven / Gradle / Ivy

Go to download

Provides a file system driver for accessing the RAES encrypted ZIP file format, alias ZIP.RAES or TZP. 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.

The newest version!
/*
 * Copyright © 2005 - 2021 Schlichtherle IT Services.
 * All rights reserved. Use is subject to license terms.
 */
package net.java.truevfs.driver.zip.raes.crypto;

import edu.umd.cs.findbugs.annotations.CreatesObligation;
import java.io.EOFException;
import java.io.IOException;
import java.nio.channels.SeekableByteChannel;
import javax.annotation.CheckForNull;
import javax.annotation.WillCloseWhenClosed;
import javax.annotation.concurrent.NotThreadSafe;
import net.java.truecommons.io.PowerBuffer;
import net.java.truecommons.io.ReadOnlyChannel;
import net.java.truecommons.io.Source;
import static net.java.truevfs.driver.zip.raes.crypto.Constants.HEADER_MIN_LEN;
import static net.java.truevfs.driver.zip.raes.crypto.Constants.SIGNATURE;
import net.java.truecommons.key.spec.common.AesKeyStrength;

/**
 * This class implements a {@link SeekableByteChannel} for random read-only
 * access to the plain text data of a RAES encrypted file, where RAES means
 * Random Access Encryption Specification.
 * RAES specifies a multistep authentication process:
 * 

* The first step is mandatory and implemented in the constructor of the * concrete implementation of this abstract class. * For this step only the cipher key and the file length is authenticated, * which is fast to process (O(1)). *

* The second step is optional and must be initiated by the client by calling * {@link #authenticate}. * For this step the entire cipher text is authenticated, which is comparably * slow (O(n)). * Please note that this step does not require the cipher text to be * decrypted first, which features comparably fast processing. *

* So it is up to the application which level of security it needs to * provide: * Most applications should always call {@code authenticate()} in * order to guard against integrity attacks. * However, some applications may provide additional (faster) methods for * authentication of the pay load, in which case the authentication * provided by this class may be safely skipped. *

* Note that this channel implements its own virtual file pointer. * * @see RaesOutputStream * @author Christian Schlichtherle */ @NotThreadSafe public abstract class RaesReadOnlyChannel extends ReadOnlyChannel { /** * Creates a new RAES read-only channel. * * @param param the {@link RaesParameters} required to access the RAES * type actually found in the file. * If the class of this parameter does not match the required * parameter interface according to the RAES type found in the * file, but is an instance of the {@link RaesParametersProvider} * interface, then it gets queried to find the required RAES * parameters. * This algorithm gets recursively applied. * @param source the source for reading the RAES file from. * @return A new RAES read-only channel. * @throws RaesParametersException If no RAES parameter can be found which * match the type of RAES file in the given channel. * @throws RaesException If the file is not RAES compatible. * @throws EOFException on unexpected end-of-file. * @throws IOException on any I/O error. */ @CreatesObligation public static RaesReadOnlyChannel create( final RaesParameters param, final Source source) throws RaesParametersException, RaesException, EOFException, IOException { final SeekableByteChannel channel = source.channel(); try { return create(param, channel); } catch (final Throwable ex) { try { channel.close(); } catch (final IOException ex2) { ex.addSuppressed(ex2); } throw ex; } } /** * Creates a new RAES read-only channel. * * @param param the {@link RaesParameters} required to access the RAES * type actually found in the file. * If the class of this parameter does not match the required * parameter interface according to the RAES type found in the * file, but is an instance of the {@link RaesParametersProvider} * interface, then it gets queried to find the required RAES * parameters. * This algorithm gets recursively applied. * @param channel the channel for reading the RAES file from. * @return A new RAES read-only channel. * @throws RaesParametersException If no RAES parameter can be found which * match the type of RAES file in the given channel. * @throws RaesException If the source data is not RAES compatible. * @throws EOFException on unexpected end-of-file. * @throws IOException on any I/O error. */ @CreatesObligation private static RaesReadOnlyChannel create( final RaesParameters param, final @WillCloseWhenClosed SeekableByteChannel channel) throws RaesParametersException, RaesException, EOFException, IOException { final PowerBuffer header = PowerBuffer .allocate(HEADER_MIN_LEN) .littleEndian() .load(channel.position(0)); if (SIGNATURE != header.getUInt()) { throw new RaesException("No RAES signature!"); } final int type = header.getUByte(); if (type != 0) { throw new RaesException("Unknown RAES type: " + type); } return new Type0RaesReadOnlyChannel( parameters(Type0RaesParameters.class, param), channel); } private static

P parameters( final Class

type, @CheckForNull RaesParameters param) throws RaesParametersException { while (null != param) { // Order is important here to support multiple interface implementations! if (type.isInstance(param)) { return type.cast(param); } else if (param instanceof RaesParametersProvider) { param = ((RaesParametersProvider) param).get(type); } else { break; } } throw new RaesParametersException("No suitable RAES parameters available!"); } /** * Returns the key strength which is actually used to decrypt the data * of the RAES file. * * @return The key strength which is actually used to decrypt the data * of the RAES file. */ public abstract AesKeyStrength getKeyStrength(); /** * Authenticates all encrypted data in this read only file. * It is safe to call this method multiple times to detect if the file * has been tampered with meanwhile. *

* This is the second, optional step of authentication. * The first, mandatory step is to compute the cipher key and cipher text * length only and must already have been successfully completed in the * constructor. * * @throws RaesAuthenticationException If the computed MAC does not match * the MAC declared in the RAES file. * @throws IOException On any I/O related issue. */ public abstract void authenticate() throws RaesAuthenticationException, IOException; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy