Class GenericJcaSignatureContext

java.lang.Object
zeroecho.core.alg.common.sig.GenericJcaSignatureContext
All Implemented Interfaces:
Closeable, AutoCloseable, CryptoContext, SignatureContext, TagEngine<Signature>

public final class GenericJcaSignatureContext extends Object implements SignatureContext
Adapts a JCA Signature to the streaming SignatureContext/TagEngine model.

GenericJcaSignatureContext binds a key and a Signature engine to a pull-based pipeline: the wrapped stream forwards bytes unchanged while updating the engine. In SIGN mode a fixed-length trailer containing the signature is appended at end-of-stream; in VERIFY mode the computed signature is compared at end-of-stream to an expected tag supplied by the caller. The trailer length is determined up front so pipelines can append or strip trailers without buffering the whole stream.

Modes and usage

Length resolvers

A fixed tag length is required in both modes. For SIGN, a GenericJcaSignatureContext.SignLengthResolver supplies the produced length (either a constant or by probing a provider). For VERIFY, a GenericJcaSignatureContext.VerifyLengthResolver supplies the expected length derived from key parameters or a known constant.

Examples

Sign with RSA-PSS


GenericJcaSignatureContext ctx = new GenericJcaSignatureContext(
    algorithm,
    privateKey,
    GenericJcaSignatureContext.jcaFactory("RSASSA-PSS", null),
    GenericJcaSignatureContext.SignLengthResolver.probeWith("RSASSA-PSS", null));

try (InputStream in = ctx.wrap(sourceStream)) {
    in.transferTo(out); // body, then trailer of ctx.tagLength() bytes
}

Verify detached RSA signature


GenericJcaSignatureContext vctx = new GenericJcaSignatureContext(
    algorithm,
    publicKey,
    GenericJcaSignatureContext.jcaFactory("SHA256withRSA", null),
    GenericJcaSignatureContext.VerifyLengthResolver.fixed(256)); // 2048-bit modulus

vctx.setVerificationApproach(vctx.getVerificationCore().getThrowOnMismatch());
vctx.setExpectedTag(signatureBytes);

try (InputStream verified = vctx.wrap(bodyWithoutTrailer)) {
    verified.transferTo(java.io.OutputStream.nullOutputStream()); // throws on mismatch at EOF
}

Thread-safety

Instances are stateful, single-use, and not thread-safe. Call wrap(InputStream) at most once per instance.

  • Constructor Details

  • Method Details

    • jcaFactory

      public static GenericJcaSignatureContext.EngineFactory jcaFactory(String jcaAlg, String provider)
      Convenience factory that produces a JCA Signature initialized for sign or verify.

      The returned factory performs Signature.getInstance(String) (optionally with a provider) and then calls Signature.initSign(PrivateKey) or Signature.initVerify(PublicKey).

      
      EngineFactory f = GenericJcaSignatureContext.jcaFactory("SHA256withRSA", null);
      Signature signer = f.create(privateKey, true);
      
      
      Implementation Note:
      In signing mode, the returned factory rejects LMS/XMSS with UnsupportedRoleException before provider lookup or key use.
      Parameters:
      jcaAlg - JCA signature algorithm name; must not be null
      provider - optional provider name; null selects the highest-priority provider
      Returns:
      factory creating initialized Signature engines for the specified algorithm/provider
    • algorithm

      public CryptoAlgorithm algorithm()
      Returns the logical algorithm associated with this context.
      Specified by:
      algorithm in interface CryptoContext
      Returns:
      the algorithm descriptor
    • key

      public Key key()
      Returns the key bound to this context.
      Specified by:
      key in interface CryptoContext
      Returns:
      the signing key in SIGN mode or the verification key in VERIFY mode
    • close

      public void close()
      Closes the active wrapped stream, if any, suppressing IOException.

      Keeping close() non-throwing simplifies pipeline cleanup.

      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Specified by:
      close in interface CryptoContext
    • wrap

      public InputStream wrap(InputStream upstream) throws IOException
      Wraps the supplied upstream stream so the underlying Signature is updated as data flows.

      This method may be called only once per instance. In SIGN mode the returned stream appends a trailer of tagLength() bytes when the upstream finishes. In VERIFY mode the returned stream performs verification at EOF against the expected tag configured via setExpectedTag(byte[]) and surfaces the outcome using the verification approach set via setVerificationApproach(ThrowingBiPredicate.VerificationBiPredicate).

      Specified by:
      wrap in interface TagEngine<Signature>
      Parameters:
      upstream - source stream whose bytes will be fed into the signature; must not be null
      Returns:
      stream that must be fully consumed to trigger signing or verification
      Throws:
      NullPointerException - if upstream is null
      IllegalStateException - if this context has already wrapped a stream
      IOException - if signing or verification fails during processing or finalization
    • tagLength

      public int tagLength()
      Returns the declared tag length in bytes.

      Computed during construction by the configured resolver and constant for the lifetime of this context.

      Specified by:
      tagLength in interface TagEngine<Signature>
      Returns:
      fixed signature trailer length
    • setExpectedTag

      public void setExpectedTag(byte[] expected)
      Sets the expected verification tag to be checked when the wrapped stream finishes.

      Applicable only in VERIFY mode. Passing null clears the tag. The array is defensively copied. If a wrapped stream is already active, its expected tag is updated as well.

      Specified by:
      setExpectedTag in interface TagEngine<Signature>
      Parameters:
      expected - expected signature bytes or null to clear
      Throws:
      UnsupportedOperationException - if called in SIGN mode
    • setVerificationApproach

      public void setVerificationApproach(ThrowingBiPredicate.VerificationBiPredicate<Signature> strategy)
      Sets the verification approach used in VERIFY mode to compare the expected and computed signatures.
      Specified by:
      setVerificationApproach in interface TagEngine<Signature>
      Parameters:
      strategy - verification predicate; may be decorated to throw or to flag into a context; null keeps the default
    • getVerificationCore

      Returns the core verification predicate for signature comparison.
      Specified by:
      getVerificationCore in interface TagEngine<Signature>
      Returns:
      predicate that delegates to Signature.verify(byte[])