java.lang.Object
net.i2p.router.crypto.FamilyKeyCrypto

public class FamilyKeyCryptoextends Object
Utilities for creating, storing, retrieving the signing keys for the netdb family feature.
  • Field Details

    • _context

      private final RouterContext _context
      The router context.
    • _log

      private final Log _log
      Logger for the family certificates.
    • _verified

      private final Map<Hash, FamilyKeyCrypto.Verified> _verified
      The verified family members, by hash.
    • _knownKeys

      private final Map<String, SigningPublicKey> _knownKeys
      The family signing keys, by family name.
    • _negativeCache

      private final Map<Hash, FamilyKeyCrypto.Result> _negativeCache
      The failed verifications, by hash.
    • _ourFamily

      private final Set<Hash> _ourFamily
      The hashes of our own family members.
    • _fname

      private final String _fname
      The family name we serve.
    • _privkey

      private final SigningPrivateKey _privkey
      Our family signing private key.
    • _pubkey

      private final SigningPublicKey _pubkey
      Our family signing public key.
    • _failCount

      private final AtomicInteger _failCount
      Consecutive certificate operation failures.
    • PROP_KEYSTORE_PASSWORD

      public static final String PROP_KEYSTORE_PASSWORD
      Property key for keystore password.
      See Also:
    • PROP_FAMILY_NAME

      public static final String PROP_FAMILY_NAME
      Property key for family name.
      See Also:
    • PROP_KEY_PASSWORD

      public static final String PROP_KEY_PASSWORD
      Property key for key password.
      See Also:
    • CERT_SUFFIX

      public static final String CERT_SUFFIX
      Certificate file suffix.
      See Also:
    • CRL_SUFFIX

      public static final String CRL_SUFFIX
      CRL file suffix.
      See Also:
    • KEYSTORE_PREFIX

      public static final String KEYSTORE_PREFIX
      Keystore file prefix.
      See Also:
    • KEYSTORE_SUFFIX

      public static final String KEYSTORE_SUFFIX
      Keystore file suffix.
      See Also:
    • CN_SUFFIX

      public static final String CN_SUFFIX
      Common name suffix.
      See Also:
    • DEFAULT_KEY_VALID_DAYS

      private static final int DEFAULT_KEY_VALID_DAYS
      Default time a family certificate stays valid.
      See Also:
    • DEFAULT_KEY_ALGORITHM

      private static final String DEFAULT_KEY_ALGORITHM
      Default algorithm for the family keys. RSA is excluded because its signature would exceed the 255 character limit for a family tag, and EdDSA because the keystore cannot encode or decode it.
    • DEFAULT_KEY_SIZE

      private static final int DEFAULT_KEY_SIZE
      Default family key size, in bits.
    • KS_DIR

      private static final String KS_DIR
      Directory holding the key stores.
      See Also:
    • CERT_DIR

      private static final String CERT_DIR
      Directory holding the family certificates.
      See Also:
    • CRL_DIR

      private static final String CRL_DIR
      Directory holding the revocation lists.
      See Also:
    • OPT_NAME

      public static final String OPT_NAME
      Option key for family name.
      See Also:
    • OPT_SIG

      public static final String OPT_SIG
      Option key for family signature.
      See Also:
    • OPT_KEY

      public static final String OPT_KEY
      Option key for family certificate.
      See Also:
    • MAX_VERIFIED

      static final int MAX_VERIFIED
      Bound on the positive verification cache, in entries. One entry per router whose family signature we have checked, each holding two strings, so the map has to be bounded the same way the negative cache is. Clearing it only costs a re-verification on the next lookup, so the bound is enforced by a clear rather than by an eviction policy.
      See Also:
  • Constructor Details

    • FamilyKeyCrypto

      public FamilyKeyCrypto(RouterContext context) throws GeneralSecurityException
      For signing and verification.

      If the context property netdb.family.name is set, this can be used for signing, else only for verification.

      Parameters:
      context - the router context supplying the family name property and certificate directory
      Throws:
      GeneralSecurityException - if the configured family name is illegal or escapes the certificate directory
  • Method Details

    • initialize

      private SigningPrivateKey initialize() throws GeneralSecurityException
      Create (if necessary) and load the key store, then run.
      Returns:
      the family's private key, read from the key store
      Throws:
      GeneralSecurityException - if the key store cannot be opened or the key is missing
    • shutdown

      public void shutdown()
      Clears the caches.
    • cleanupCaches

      static int[] cleanupCaches(Map<?,?> negative, Map<?,?> verified, int max)
      Run the periodic cache maintenance. The negative cache is cleared outright, since a miss simply re-checks the router. The positive cache is only cleared once it passes its bound - dropping live entries costs a re-verification of every family router on the next lookup, so while it is inside the bound the entries are worth keeping, and the bound is enforced by a clear rather than by tracking which entry to evict.
      Parameters:
      negative - the negative cache
      verified - the positive cache
      max - the bound on the positive cache's entry count
      Returns:
      the entries cleared from each cache, negative first
    • cleanup

      private void cleanup()
      Periodic cleanup to prevent unbounded growth of the two caches. Runs every hour via SimpleTimer2.
    • sign

      public Map<String,String> sign(String family, Hash h) throws GeneralSecurityException
      Caller must add family to RI also. throws on all errors.
      Parameters:
      family - non-null, must match that we were initialized with or will throw GSE
      h - non-null
      Returns:
      non-null options to be added to the RI
      Throws:
      GeneralSecurityException - on null hash, null or changed family, or signing error
    • hasFamily

      public boolean hasFamily()
      Do we have a valid family?
      Returns:
      whether family is present
    • getOurFamily

      public Set<Hash> getOurFamily()
      Get verified members of our family. Will not contain ourselves.
      Returns:
      non-null, not a copy, do not modify
    • getOurFamilyName

      public String getOurFamilyName()
      Get our family name.
      Returns:
      name or null
    • verify

      public FamilyKeyCrypto.Result verify(RouterInfo ri)
      Verify the family signature in a RouterInfo. This requires a family key in the RI, or a certificate file for the family in certificates/family.
      Parameters:
      ri - the RouterInfo whose family option names the family and whose signature is checked
      Returns:
      the verification result
    • verifyOurFamily

      public boolean verifyOurFamily(RouterInfo ri)
      Verify the family in a RouterInfo matches ours and the signature is good. Returns false if we don't have a family and sig, or they don't. Returns false for ourselves.
      Parameters:
      ri - the RouterInfo whose family option and signature are checked against our own family
      Returns:
      true if family matches with good sig
    • verify

      private FamilyKeyCrypto.Result verify(RouterInfo ri, String name)
      Verify the family in a RouterInfo, name already retrieved.
      Parameters:
      ri - the router whose family signature is checked
      name - the family name already read from the router, compared with the cached one
      Returns:
      the verification result, NO_SIG when the router has no signature, otherwise the cached or freshly computed result
    • verifyKeyStore

      private void verifyKeyStore(File ks) throws GeneralSecurityException
      Verify the family keystore can be opened and its aliases used. Succeeds if it exists and we have a password, or it was created successfully.
      Parameters:
      ks - the keystore file to check, created when it does not exist
      Throws:
      GeneralSecurityException - on keystore error
    • createKeyStore

      private void createKeyStore(File ks) throws GeneralSecurityException, IOException
      Call out to keytool to create a new keystore with a keypair in it. Trying to do this programatically is a nightmare, requiring either BouncyCastle libs or using proprietary Sun libs, and it's a huge mess. If successful, stores the keystore password and key password in router.config.
      Parameters:
      ks - the keystore file to create, together with its key pair
      Throws:
      GeneralSecurityException - on all errors
      IOException - if keytool cannot be run or the files cannot be written
    • exportCert

      private void exportCert(X509Certificate cert)
      Save the public key certificate so the clients can get to it.
      Parameters:
      cert - the family's certificate to write into the certificate directory
    • exportCRL

      private void exportCRL(File ksdir, X509CRL crl)
      Save the CRL just in case.
      Parameters:
      ksdir - parent of directory to save in
      crl - the certificate revocation list to write out
    • loadCerts

      private void loadCerts()
      Load all the certs.
    • loadCert

      private SigningPublicKey loadCert(File file)
      Load a public key from a cert.
      Parameters:
      file - the certificate file to read
      Returns:
      null on all errors
    • getPrivKey

      private SigningPrivateKey getPrivKey(File ks) throws GeneralSecurityException
      Load the private key for this family from the keystore.
      Parameters:
      ks - the keystore to read the family key from
      Returns:
      non-null, throws on all errors
      Throws:
      GeneralSecurityException - if no key password is set, the family key is missing, or the keystore cannot be read
    • main

      public static void main(String[] args)
      CLI entry point for manual family key operations.
      Parameters:
      args - the keystore file to create, followed by the family name to issue the keys under