tech.pisoft.teagent.FileX509Context
A file-backed, soft-key X509Context: the AM08 channel-bound challenge-response authentication protocol driven from a password-protected PKCS#12 file.
The FileX509Context class is a file-backed, soft-key concrete X509Context for the AM08 X.509 challenge-response authentication protocol. It is the only concrete X509Context since 2026-09-01: its former sibling PKCS11Context took the certificate and private key from a PKCS#11 token through the IAIK wrapper, whose JNI native was never staged, and was deleted. FileX509Context takes them from a PKCS#12 (.p12/.pfx) file protected by a password. No hardware token, no JNI, and no native access are involved — it is pure Java on the JDK's built-in PKCS12 KeyStore and JCA Signature.
Typical use, exactly like the other authentication contexts:
FileX509Context ctx = FileX509Context.getInstance(); ctx.open("/path/to/user.p12", "password"); TEAgentConnection c = TEAgentConnectionFactory.getConnection(TEConnectionType.SECURE_SOCKET); c.open(host, port, ctx); // drives X509Authentication against the KS/RE
The protocol (inherited from X509Context). The client sends its certificate; the server loads the matching principal by certificate digest and returns a random 32-byte challenge; the SDK builds the channel-bound message M = "TE-AM08-CHANNEL-BOUND-v1" || 0x00 || SHA-256("tls-exporter:" || exporter) || challenge from THIS connection's RFC 9266 exporter (TEAgentConnection#getChannelBinding) and the challenge; the client signs M with the certificate's private key and returns the signature; the server verifies it with the certificate's public key against its own exporter. This runs over the ordinary server-auth-only SSL port — it is an application-level challenge-response, not TLS mutual authentication (that is the separate SSLM path) — and it is bound to that TLS connection: a signature made over one connection is refused on every other.
Signature construction. calculateResponse signs M under the key's scheme, which is decided by the key type and never negotiated: an RSA key signs RSASSA-PSS with an explicit PSSParameterSpec (SHA-256, MGF1 with SHA-256, salt length exactly 32, trailer 1); an EC key signs SHA256withECDSA (DER). These are the JCA spellings of the C++ agent's server-verified signing path (EVP_DigestSign with RSA_PKCS1_PSS_PADDING, rsa_pss_saltlen 32, rsa_mgf1_md SHA-256; EVP_DigestSign over SHA-256 for EC), and the Key Service verifies with the salt length set exactly. PSS is randomised, so the check against the C++ reference vector (test/ks-fixture/x509_sigvec) is "verifies under the same public key and parameters", never a byte comparison. The construction this replaced — a raw PKCS#1v1.5 primitive over the bare challenge, no digest, no label — is refused by the Key Service as a wrong signature.
Scope. RSA and EC keys; any other key type is rejected at open with a clear, explicit error rather than a late failure.
Since: 8.0
© Pi Soft, 2018-2026 · Tricryption Engine 8.1
Inheritance
- Inherits tech.pisoft.teagent.X509Context
Public Member Functions
| Member | Description |
|---|---|
FileX509Context() | The default constructor. |
void open(String path, String password) | Loads the certificate and private key from a password-protected PKCS#12 file. |
byte[] getCertificate() | Returns the DER-encoded certificate to present to the server, as the X509Authentication protocol requires. |
byte[] calculateResponse(byte[] message) | Signs the channel-bound message M with the certificate's private key under the key's scheme: RSASSA-PSS with an explicit PSSParameterSpec (SHA-256, MGF1-SHA-256, salt length 32, trailer 1) for RSA; SHA256withECDSA for EC — the construction the Key Service's ChannelBinding::am08Verify accepts (see the class comment). |
Static Public Member Functions
| Member | Description |
|---|---|
FileX509Context getInstance() | Factory method that returns a new FileX509Context, matching the getInstance() idiom of the other authentication contexts. |
Member Function Documentation
FileX509Context()
The default constructor.
Call open before using the context for authentication.
void open(String path, String password)
Loads the certificate and private key from a password-protected PKCS#12 file.
The first key entry in the keystore is used.
Parameters
| Parameter | Description |
|---|---|
path | Path to the PKCS#12 file (.p12/.pfx). |
password | Password protecting both the keystore and the key entry. |
Exceptions
| Exception | Description |
|---|---|
TEAgentException | with a distinct message for each failure mode: the file is missing or unreadable; the password is wrong; the file is not a valid PKCS#12; the keystore holds no key/certificate entry; or the key entry is present but neither RSA nor EC (the scheme covers nothing else). |
byte[] getCertificate()
Returns the DER-encoded certificate to present to the server, as the X509Authentication protocol requires.
open must have been called.
Returns: the DER encoding of the certificate.
byte[] calculateResponse(byte[] message)
Signs the channel-bound message M with the certificate's private key under the key's scheme: RSASSA-PSS with an explicit PSSParameterSpec (SHA-256, MGF1-SHA-256, salt length 32, trailer 1) for RSA; SHA256withECDSA for EC — the construction the Key Service's ChannelBinding::am08Verify accepts (see the class comment).
Parameters
| Parameter | Description |
|---|---|
message | M, 89 bytes, built by X509Context.channelBoundMessage from this connection's channel binding and the server's challenge. |
Exceptions
| Exception | Description |
|---|---|
TEAgentException | if the context is not open, M is not 89 bytes, or signing fails. |
Returns: the signature bytes to return to the server.
FileX509Context getInstance()
Factory method that returns a new FileX509Context, matching the getInstance() idiom of the other authentication contexts.
Returns: a new FileX509Context.