Class AbstractExternalPublicKeyDataDecryptorFactory

java.lang.Object
org.bouncycastle.openpgp.operator.AbstractPublicKeyDataDecryptorFactory
org.bouncycastle.openpgp.api.operator.AbstractExternalPublicKeyDataDecryptorFactory
All Implemented Interfaces:
PGPDataDecryptorFactory, PublicKeyDataDecryptorFactory

public abstract class AbstractExternalPublicKeyDataDecryptorFactory extends AbstractPublicKeyDataDecryptorFactory
Base class for a PublicKeyDataDecryptorFactory whose private key material is held outside the OpenPGP key - typically on a hardware token - as described by OpenPGP External Secret Keys and signalled by SecretKeyPacket.USAGE_EXTERNAL.

The session-key recovery flow - packet parsing, length checking, the RFC 6637 KDF and the RFC 9580 HKDF/key-unwrap sequencing - lives here, expressed entirely over byte arrays, so it is tied to no crypto stack. A subclass binds the primitive operations: the raw private-key operation (an RSA or ElGamal decryption, or an ECDH / X25519 / X448 agreement, routed to wherever the key is held) and the two symmetric primitives (HKDF and key unwrap), plus the PGPDataDecryptor creation the PublicKeyDataDecryptorFactory interface requires.

The JCA/JCE binding is built by org.bouncycastle.openpgp.api.operator.jcajce.JceExternalPublicKeyDataDecryptorFactoryBuilder. On the lightweight side org.bouncycastle.openpgp.api.operator.bc.BcExternalPublicKeyDataDecryptorFactory predates this class and inherits the equivalent flow from org.bouncycastle.openpgp.operator.bc.BcPublicKeyDataDecryptorFactory instead; the packet parsing is shared with both through AbstractPublicKeyDataDecryptorFactory's parse methods.

  • Constructor Details

    • AbstractExternalPublicKeyDataDecryptorFactory

      protected AbstractExternalPublicKeyDataDecryptorFactory(PGPPublicKey pubKey, KeyFingerPrintCalculator fingerPrintCalculator, PGPDigestCalculatorProvider digestCalculatorProvider)
      Base constructor.
      Parameters:
      pubKey - the public half of the key being decrypted for
      fingerPrintCalculator - calculator for the key fingerprint carried in the RFC 6637 user keying material
      digestCalculatorProvider - source of the digest the RFC 6637 KDF runs on
  • Method Details

    • getPublicKey

      protected PGPPublicKey getPublicKey()
      Return the public half of the key this factory decrypts for.
      Returns:
      public key
    • recoverSessionData

      public byte[] recoverSessionData(int keyAlgorithm, byte[][] secKeyData, int pkeskVersion) throws PGPException
      Description copied from interface: PublicKeyDataDecryptorFactory
      Recover the plain session info by decrypting the encrypted session key. This method returns the decrypted session info as-is (without prefixing missing cipher algorithm), so the return value is:
      [sym-alg]?[session-key][checksum]?
      Parameters:
      keyAlgorithm - public key algorithm
      secKeyData - encrypted session key data
      pkeskVersion - version of the PKESK packet
      Returns:
      decrypted session info
      Throws:
      PGPException
    • decryptRSA

      protected abstract byte[] decryptRSA(int keyAlgorithm, byte[] sessionKey) throws PGPException
      Perform RSA decryption of an encrypted session key.
      Parameters:
      keyAlgorithm - public key algorithm
      sessionKey - encrypted session key, with the MPI length octets already removed
      Returns:
      decrypted session key
      Throws:
      PGPException - if the session key cannot be decrypted
    • decryptElGamal

      protected abstract byte[] decryptElGamal(int keyAlgorithm, byte[][] secKeyData) throws PGPException
      Perform ElGamal decryption of an encrypted session key.
      Parameters:
      keyAlgorithm - public key algorithm
      secKeyData - encrypted session key data
      Returns:
      decrypted session key
      Throws:
      PGPException - if the session key cannot be decrypted
    • agreeECDH

      protected abstract byte[] agreeECDH(ECDHPublicBCPGKey pubKey, byte[] ephemeralKeyBytes) throws PGPException
      Perform an ECDH agreement against the sender's ephemeral point and return the shared secret.
      Parameters:
      pubKey - our ECDH public key
      ephemeralKeyBytes - the sender's encoded ephemeral point
      Returns:
      shared secret
      Throws:
      PGPException - if the agreement cannot be performed
    • agreeX25519

      protected abstract byte[] agreeX25519(byte[] ephemeralKey) throws PGPException
      Perform an X25519 agreement against the sender's ephemeral key and return the shared secret.
      Parameters:
      ephemeralKey - the sender's ephemeral X25519 public key (32 octets, no header byte)
      Returns:
      shared secret
      Throws:
      PGPException - if the agreement cannot be performed
    • agreeX448

      protected abstract byte[] agreeX448(byte[] ephemeralKey) throws PGPException
      Perform an X448 agreement against the sender's ephemeral key and return the shared secret.
      Parameters:
      ephemeralKey - the sender's ephemeral X448 public key (56 octets, no header byte)
      Returns:
      shared secret
      Throws:
      PGPException - if the agreement cannot be performed
    • generateHKDFBytes

      protected abstract byte[] generateHKDFBytes(int hashAlgorithm, byte[] ikm, String info, int keyLen) throws PGPException
      Derive key material with HKDF as RFC 9580 sections 5.1.6 and 5.1.7 prescribe for the X25519 and X448 encrypted session keys: no salt, the given info string, output truncated to keyLen.
      Parameters:
      hashAlgorithm - the hash algorithm underlying the HKDF (SHA256 or SHA512)
      ikm - input keying material
      info - the HKDF info string ("OpenPGP X25519" / "OpenPGP X448")
      keyLen - number of octets of output keying material
      Returns:
      derived key material
      Throws:
      PGPException - if the derivation cannot be performed
    • unwrapSessionData

      protected abstract byte[] unwrapSessionData(byte[] keyEnc, int symmetricKeyAlgorithm, byte[] key) throws PGPException
      Unwrap a wrapped (RFC 3394) session key.
      Parameters:
      keyEnc - the wrapped session key
      symmetricKeyAlgorithm - the wrapping algorithm
      key - the key-encryption key
      Returns:
      the unwrapped session key
      Throws:
      PGPException - if the session key cannot be unwrapped