# Class PinSet

java.lang.Object
com.codename1.security.shield.PinSet

public final class PinSet extends Object

An immutable set of certificate pins, keyed by host, as published by the attestation service.

Pins are over the subject public key info, not the whole certificate, so a host can renew its certificate on the same key pair without invalidating the pin. A chain matches if any certificate in it matches any pin for the host, which is what makes it safe to pin an issuing CA as the backup.

##### The never-brick rules

Client-side pinning is the one part of the shield that can take an app offline for reasons the developer cannot fix without an app store release, so the failure behaviour is deliberately asymmetric:

- A host with no pins is never enforced. That covers first run, a cold start with no network, and any host the service has not published pins for.
- A failed pin fetch never fails a request. The last known set is kept.
- Pins carry a soft expiry, after which a refresh is attempted, and a much later hard expiry. Past the hard expiry the set is dropped and enforcement stops. A device that cannot reach the service for weeks loses pinning; it does not lose the app.
- Only an actual mismatch -- a host that has pins presenting a chain that matches none of them -- fails a request, and it fails before any request body is written.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final PinSet`
  `EMPTY`
  A pin set with no hosts.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `PinSet(Hashtable hostToPins, int version, long softExpiry, long hardExpiry)`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `int`
  `getVersion()`
  `int`
  `hostCount()`
  Number of hosts with at least one pin.
  `boolean`
  `isEmpty()`
  True when no host is pinned.
  `boolean`
  `isEnforcedFor(String host)`
  True when this set has at least one pin for the host and has not hard-expired, i.e.
  `boolean`
  `isExpired()`
  True once the set is too old to keep enforcing.
  `boolean`
  `isStale()`
  True once the set should be refreshed.
  `boolean`
  `matches(String host, String[] chainSpkiDigests)`
  True when at least one of the supplied chain digests matches a pin for the host.
  `Vector`
  `pinsFor(String host)`
  The pins registered for a host, honouring a leading `*.` wildcard, or null when the host is not pinned.
  `String`
  `toString()`
  Returns a string representation of the object.

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### EMPTY

    public static final PinSet EMPTY
    A pin set with no hosts. Enforces nothing.

- ## Constructor Details

  - ### PinSet

    public PinSet(Hashtable hostToPins, int version, long softExpiry, long hardExpiry)
    Parameters:
      `hostToPins` - host (lowercase) to a `Vector` of base64 SHA-256 SPKI digests
      `version` - monotonic version from the service, used to detect a newer published set
      `softExpiry` - local millis after which a refresh should be attempted, 0 for never
      `hardExpiry` - local millis after which the set is discarded entirely, 0 for never

- ## Method Details

  - ### getVersion

    public int getVersion()

  - ### isStale

    public boolean isStale()
    True once the set should be refreshed. Does not mean it has stopped being enforced.

  - ### isExpired

    public boolean isExpired()
    True once the set is too old to keep enforcing. At this point pinning disables itself rather than risk locking a long-offline device out of its own app.

  - ### isEnforcedFor

    public boolean isEnforcedFor(String host)
    True when this set has at least one pin for the host and has not hard-expired, i.e. when a chain for this host is actually going to be checked.

  - ### hostCount

    public int hostCount()
    Number of hosts with at least one pin. Used by tests and diagnostics.

  - ### pinsFor

    public Vector pinsFor(String host)
    The pins registered for a host, honouring a leading `*.` wildcard, or null when the host is not pinned.

  - ### matches

    public boolean matches(String host, String[] chainSpkiDigests)

    True when at least one of the supplied chain digests matches a pin for the host.

    Returns true when the host is not pinned at all -- "no opinion" must never be reported as a mismatch, or an unpinned host would start failing.

  - ### isEmpty

    public boolean isEmpty()
    True when no host is pinned.

  - ### toString

    public String toString()
    Description copied from class: `Object`
    Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + '@' + Integer.toHexString(hashCode())
    Overrides:
      `toString` in class `Object`