Class SignatureTrailerInputStream

All Implemented Interfaces:
Closeable, AutoCloseable

public final class SignatureTrailerInputStream extends TailStrippingInputStream
SignatureTrailerInputStream reads an upstream stream that has a trailing signature tag and exposes only the original body while capturing the detached signature.

Overview

This class is a specialized TailStrippingInputStream that wraps a SignatureContext produced stream. The wrapped context emits [body][signature]; this stream transparently strips the trailing signature bytes from the output and optionally delivers a defensive copy of the signature to a user-supplied callback.

The signature length is obtained from TagEngine.tagLength() and the upstream stream is obtained via TagEngine.wrap(java.io.InputStream). Resource ownership is explicit: close() closes both the underlying stream chain and the SignatureContext.

Usage

SignatureContext sc = session.createContext("Ed25519", KeyUsage.SIGN, privateKey, spec);
try (InputStream in = new SignatureTrailerInputStream(
        sc,
        originalContent.getStream(),
        8192,
        sig -> ctx.put(SIG_KEY, sig))) {
    // read 'in' to obtain only the body; signature is delivered to the callback
    in.transferTo(out);
}

Thread-safety

Instances are not thread-safe. Use from a single thread and do not share across readers.
  • Constructor Details

    • SignatureTrailerInputStream

      public SignatureTrailerInputStream(SignatureContext sc, InputStream upstream, int bufferSize, Consumer<byte[]> onSignature) throws IOException
      Creates a new signature-stripping stream that passes through only the body while capturing the trailing signature tag.

      This constructor immediately calls TagEngine.wrap(java.io.InputStream) to obtain the producing stream and configures the tail length to TagEngine.tagLength().

      Parameters:
      sc - the signature context that wraps the upstream stream and provides tag metadata; must not be null
      upstream - the upstream stream that yields [body][signature]; must not be null
      bufferSize - internal buffer size used by the tail stripper; must be positive
      onSignature - optional callback invoked exactly once with a defensive copy of the finalized signature bytes; may be null
      Throws:
      IOException - if initializing the underlying wrapped stream fails
      NullPointerException - if sc or upstream is null
  • Method Details

    • processTail

      protected void processTail(byte[] tail) throws IOException
      Receives the stripped tail bytes and forwards a defensive copy to the registered callback.

      If no callback is set or the tail is null, this method returns without action. Any runtime exception thrown by the callback is caught and ignored so that stream semantics remain unaffected.

      Specified by:
      processTail in class TailStrippingInputStream
      Parameters:
      tail - the stripped signature bytes, or null if no tail was detected
      Throws:
      IOException - never thrown by this implementation, preserved for the template method contract
    • close

      public void close() throws IOException
      Closes the stream and the associated SignatureContext.

      This method first closes the underlying stream chain (draining to EOF if required by the base class), then closes the signature context. If closing the underlying stream throws an IOException, that exception is rethrown after attempting to close the context.

      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Overrides:
      close in class TailStrippingInputStream
      Throws:
      IOException - if closing the underlying stream fails