public interface ShieldEngine

The service-provider seam between the public shield API and the attestation engine that implements it.

Codename One ships an inert default that reports itself unavailable, so an app written against AppShield compiles and runs everywhere. A build entitled to the enterprise engine has a real implementation registered by the build server before Display.init, via ShieldEngineRegistry.setEngine(ShieldEngine).

What must never move into the framework

The split is only worth anything if the engine keeps the parts an attacker would want to reach. An implementation must own, and must never delegate to open framework code:

  • challenge and nonce generation – predictable nonces make replay possible;
  • any key material, and any code that touches it;
  • the pin comparison and the decision to fail a request. The framework may hold a PinSet; patching the framework’s copy must not be enough to disable pinning;
  • the detection heuristics themselves. Published heuristics are bypassed heuristics, so the framework only ever sees finished ShieldSignal results – and only the ones the engine chooses to publish;
  • interpretation of the raw platform attestation. Those responses go to the verifying service, which the attacker does not control, rather than being judged on the device.

The security property this preserves is not “the app refuses to make the call” – an attacker who controls the device can always strip a header. It is that the customer’s backend refuses to serve a request without a valid, unexpired, service-signed token, which a substituted engine cannot mint.

Methods

public abstract String getName()A stable name for diagnostics, for example unprotected, simulator or the enterprise engine’s own identifier.
public abstract boolean isAvailable()True when this engine can actually attest.
public abstract void initialize(EngineContext ctx, ShieldConfig config)Called once from AppShield.init(ShieldConfig).
public abstract ShieldToken fetchToken(String bindingData) throws ShieldExceptionObtains a token, blocking until it has one or fails.
public abstract ShieldToken getCachedToken()The cached token, without contacting the service.
public abstract boolean verifyPins(String host, String[] spkiDigests, String[] certDigests)Decides whether a certificate chain is acceptable for a host.
public abstract PinSet getPinSet()The pin set currently in force, never null.
public abstract ShieldSignal[] collectSignals()The runtime self-protection observations this engine wants reported.
public abstract void invalidate()Discards any cached token, forcing the next fetch to go to the service.
public abstract void shutdown()Releases resources.

Method details

getName

public abstract String getName()
A stable name for diagnostics, for example unprotected, simulator or the enterprise engine’s own identifier.

isAvailable

public abstract boolean isAvailable()
True when this engine can actually attest. False for the inert default, which is how AppShield.isProtected() is answered.

initialize

public abstract void initialize(EngineContext ctx, ShieldConfig config)
Called once from AppShield.init(ShieldConfig). Must not block on the network; do warm-up work on a background thread.

fetchToken

public abstract ShieldToken fetchToken(String bindingData) throws ShieldException
Obtains a token, blocking until it has one or fails. Called on a network thread, never the EDT.

Parameters

bindingData String
request data to bind the token to, or null for a plain time-limited token. A bound token is only valid for the request whose data was supplied.

Throws

ShieldException
carrying the ShieldStatus that explains whether the failure was about reaching the service or about this device

getCachedToken

public abstract ShieldToken getCachedToken()

The cached token, without contacting the service. Returns null when nothing is cached.

Must never block: callers are typically on the EDT, deciding whether they can decorate a request right now.

verifyPins

public abstract boolean verifyPins(String host, String[] spkiDigests, String[] certDigests)

Decides whether a certificate chain is acceptable for a host.

Must be purely local and non-blocking: on iOS this is invoked synchronously from the TLS delegate thread while the handshake is held open, so any network call or blocking wait here deadlocks the connection.

Returns true when the host is not pinned – “no opinion” must never read as a mismatch.

Parameters

host String
Not documented.
spkiDigests String[]
base64 SHA-256 digests of each chain certificate’s public key info
certDigests String[]
whole-certificate digests, for engines that pin those instead

getPinSet

public abstract PinSet getPinSet()
The pin set currently in force, never null. May be PinSet.EMPTY.

collectSignals

public abstract ShieldSignal[] collectSignals()
The runtime self-protection observations this engine wants reported. May legitimately be a subset of what it detected.

invalidate

public abstract void invalidate()
Discards any cached token, forcing the next fetch to go to the service. Called when a backend rejects a token, which usually means the device’s attestation state is stale.

shutdown

public abstract void shutdown()
Releases resources. Called when the app is shutting down.