java.lang.Object
net.i2p.data.PrivateKeyFile
Direct Known Subclasses:
RouterPrivateKeyFile

public class PrivateKeyFileextends Object
This helper class reads and writes files in the same "eepPriv.dat" format used by the client code. The format is:
    - Destination (387 bytes if no certificate, otherwise longer)
       - Public key (256 bytes), random data as of 0.9.57 (except for RouterPrivateKeyFile)
       - Signing Public key (128 bytes)
       - Cert. type (1 byte)
       - Cert. length (2 bytes)
       - Certificate if length != 0
    - Private key (256 bytes for ElGamal, or length specified by key certificate)
       -          All zeros as of 0.9.57 (except for RouterPrivateKeyFile)
    - Signing Private key (20 bytes, or length specified by key certificate)
    - As of 0.9.38, if the Signing Private Key is all zeros,
      the offline signature section (see proposal 123):
       - Expires timestamp (4 bytes, seconds since epoch, rolls over in 2106)
       - Sig type of transient public key (2 bytes)
       - Transient Signing Public key (length as specified by transient sig type)
       - Signature of Signed Public key by offline key (length as specified by destination sig type)
       - Transient Signing Private key (length as specified by transient sig type)

    Total: 663 or more bytes for ElGamal, may be smaller for other enc. types

Destination encryption keys have been unused since 0.6 (2005). As of 0.9.57, new Destination encryption public keys are simply random data, and encryption private keys may be random data or all zeros.

This class is extended by net.i2p.data.router.RouterPrivateKeyFile. RouterIdentity encryption keys ARE used and must be valid.

  • Field Details

    • file

      protected final File file
      The key file.
    • client

      private final I2PClient client
      Client format whose version is recorded.
    • dest

      protected Destination dest
      The destination.
    • privKey

      protected PrivateKey privKey
      The private key.
    • signingPrivKey

      protected SigningPrivateKey signingPrivKey
      The signing private key.
    • _offlineExpiration

      private long _offlineExpiration
      When the offline signing part expires, 0 for none.
    • _offlineSignature

      private Signature _offlineSignature
      Signature made by the offline key, if any.
    • _transientSigningPrivKey

      private SigningPrivateKey _transientSigningPrivKey
      The transient private signing key.
    • _transientSigningPubKey

      private SigningPublicKey _transientSigningPubKey
      The transient public signing key.
    • PADDING_ENTROPY

      private static final int PADDING_ENTROPY
      Random bytes stored in the padding section.
      See Also:
  • Constructor Details

    • PrivateKeyFile

      public PrivateKeyFile(String file)
      Create a new PrivateKeyFile from a file name.
      Parameters:
      file - the key file name
    • PrivateKeyFile

      public PrivateKeyFile(File file)
      Create a new PrivateKeyFile from a File.
      Parameters:
      file - the key file
    • PrivateKeyFile

      public PrivateKeyFile(File file, I2PClient client)
      Create a new PrivateKeyFile with a client.
      Parameters:
      file - the key file
      client - the I2P client
    • PrivateKeyFile

      public PrivateKeyFile(File file, I2PSession session)
      Create a new PrivateKeyFile from an I2P session.
      Parameters:
      file - the key file
      session - the I2P session
    • PrivateKeyFile

      public PrivateKeyFile(File file, Destination dest, PrivateKey pk, SigningPrivateKey spk)
      Create a new PrivateKeyFile with a destination and keys.
      Parameters:
      file - the key file
      dest - the destination the keys belong to; its signing key type must match spk
      pk - the private key
      spk - the signing private key
      Throws:
      IllegalArgumentException - on mismatch of spubkey and spk types
    • PrivateKeyFile

      public PrivateKeyFile(File file, PublicKey pubkey, SigningPublicKey spubkey, Certificate cert, PrivateKey pk, SigningPrivateKey spk)
      Create a new PrivateKeyFile from individual key components.
      Parameters:
      file - the key file
      pubkey - the public key
      spubkey - the signing public key
      cert - the certificate to install in the destination
      pk - the private key
      spk - the signing private key
      Throws:
      IllegalArgumentException - on mismatch of spubkey and spk types
    • PrivateKeyFile

      public PrivateKeyFile(File file, PublicKey pubkey, SigningPublicKey spubkey, Certificate cert, PrivateKey pk, SigningPrivateKey spk, byte[] padding)
      Create a new PrivateKeyFile from individual key components with padding.
      Parameters:
      file - the key file
      pubkey - the public key
      spubkey - the signing public key
      cert - the certificate to install in the destination
      pk - the private key
      spk - the signing private key
      padding - null OK, must be non-null if spubkey length < 128
      Throws:
      IllegalArgumentException - on mismatch of spubkey and spk types
    • PrivateKeyFile

      public PrivateKeyFile(InputStream in) throws I2PSessionException
      Read a PrivateKeyFile from an input stream. Can't be used for writing.
      Parameters:
      in - the input stream
      Throws:
      I2PSessionException - if session creation fails
  • Method Details

    • main

      public static void main(String[] args)
      Create a new PrivateKeyFile, or modify an existing one, with various types of Certificates.

      Changing a Certificate does not change the public or private keys. But it does change the Destination Hash, which effectively makes it a new Destination. In other words, don't change the Certificate on a Destination you've already registered in a hosts.txt key add form.

      Copied and expanded from that in Destination.java.

      Parameters:
      args - command line arguments
    • usage

      private static void usage()
      Prints the command-line help.
    • createIfAbsent

      public Destination createIfAbsent() throws I2PException, IOException
      Create with the default signature type if nonexistent.

      Also reads in the file to get the privKey and signingPrivKey, which aren't available from I2PClient.

      Returns:
      the destination for this key file, creating it if the file does not exist
      Throws:
      I2PException - if creation fails
      IOException - if file operations fail
    • createIfAbsent

      public Destination createIfAbsent(SigType type) throws I2PException, IOException
      Create with the specified signature type if nonexistent.

      Also reads in the file to get the privKey and signingPrivKey, which aren't available from I2PClient.

      Parameters:
      type - the signature type to use
      Returns:
      the destination for this key file, creating it if the file does not exist
      Throws:
      I2PException - if creation fails
      IOException - if file operations fail
    • createIfAbsent

      private Destination createIfAbsent(SigType type, EncType ptype) throws I2PException, IOException
      Create with the specified signature and encryption types if nonexistent. Private for now, only for router.keys.dat testing.

      Also reads in the file to get the privKey and signingPrivKey, which aren't available from I2PClient.

      Parameters:
      type - signature type for the new signing keys
      ptype - encryption type; padding-only for destinations, real keypair for routers
      Returns:
      the existing or newly created destination, never null
      Throws:
      I2PException - if the destination cannot be created
      IOException - if the key file cannot be written or read back
    • getDestination

      If the destination is not set, read it in from the file. Also sets the local privKey and signingPrivKey.
      Returns:
      the destination, reading it from the file if it is not already set
      Throws:
      I2PSessionException - if reading fails
      IOException - if file operations fail
      DataFormatException - if data is malformed
    • setDestination

      public void setDestination(Destination d)
      Destination for this key file.
      Parameters:
      d - the destination to associate with this key file
    • setCertType

      public Certificate setCertType(int t)
      Change cert type - caller must also call write(). Side effect - creates new Destination object.
      Parameters:
      t - the certificate type
      Returns:
      the new certificate installed in a replacement destination
    • setKeyCert

      public Certificate setKeyCert(SigType type)
      Change cert type - caller must also call write(). Side effect - creates new Destination object.
      Parameters:
      type - the signature type
      Returns:
      the new key certificate installed in a replacement destination
    • setSignedCert

      public Certificate setSignedCert(PrivateKeyFile pkf2)
      Sign this dest by dest found in pkf2 - caller must also call write().
      Parameters:
      pkf2 - the signing key file
      Returns:
      the new signed certificate, or null if pkf2 has no destination
    • getPrivKey

      public PrivateKey getPrivKey()
      Private key may be random data or all zeros for Destinations as of 0.9.57.
      Returns:
      null on error or if not initialized
    • getSigningPrivKey

      public SigningPrivateKey getSigningPrivKey()
      Signing private key.
      Returns:
      null on error or if not initialized
    • isOffline

      public boolean isOffline()
      Does this session have offline and transient keys?
      Returns:
      true if offline keys are configured
    • setOfflineData

      public void setOfflineData(long expires, SigningPublicKey transientPub, Signature sig, SigningPrivateKey transientPriv)
      Side effect - zeroes out the current signing private key.
      Parameters:
      expires - expiration time in Java ms
      transientPub - the transient signing public key
      sig - the offline signature
      transientPriv - the transient signing private key
    • getOfflineExpiration

      public long getOfflineExpiration()
      Offline key expiration time.
      Returns:
      Java time (ms) or 0 if not initialized or does not have offline keys
    • getOfflineSignature

      public Signature getOfflineSignature()
      Offline signature.
      Returns:
      the signature, or null if not initialized or does not have offline keys
    • getTransientSigningPubKey

      public SigningPublicKey getTransientSigningPubKey()
      Transient signing public key.
      Returns:
      null on error or if not initialized or does not have offline keys
    • getTransientSigningPrivKey

      public SigningPrivateKey getTransientSigningPrivKey()
      Transient signing private key.
      Returns:
      null on error or if not initialized or does not have offline keys
    • open

      Open an I2P session.
      Returns:
      the I2P session
      Throws:
      I2PSessionException - if session creation fails
      IOException - if there is an error reading the key file
    • open

      Open a session with the given options.
      Parameters:
      opts - the options for the session
      Returns:
      the I2P session
      Throws:
      I2PSessionException - if session creation fails
      IOException - if there is an error reading the key file
    • write

      public void write() throws IOException, DataFormatException
      Write the keys to the file. Copied from I2PClientImpl.createDestination(OutputStream).
      Throws:
      IOException - if file operations fail
      DataFormatException - if data encoding fails
    • validateKeyPairs

      public boolean validateKeyPairs()
      Verify that the PublicKey matches the PrivateKey, and the SigningPublicKey matches the SigningPrivateKey.

      NOTE this will fail for Destinations containing random padding for the enc. key.

      Returns:
      true if both key pairs match, false otherwise
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • verifySignature

      public static boolean verifySignature(Destination d)
      Verify the signature on a destination.

      Sample code that goes through all the hosts.txt files and tries everybody. You need to be in the $I2P directory or have a local hosts.txt for this to work. Doubt this is what you want as it is super-slow, and what good is a signing scheme where anybody is allowed to sign? In a real application you would make a list of approved signers, do a naming lookup to get their Destinations, and try those only. Or do a netDb lookup of the Hash in the Certificate, do a reverse naming lookup to see if it is allowed, then verify the Signature.

      Parameters:
      d - the destination to verify
      Returns:
      true if the signature is valid
    • checkSignature

      public static boolean checkSignature(Signature s, byte[] data, SigningPublicKey spk)
      Check a signature against data with a public key.
      Parameters:
      s - the signature to verify
      data - the data that was signed
      spk - the signing public key
      Returns:
      true if the signature is valid