Exemple #1
0
 /**
  * Create a keypair and store it in the keystore at ks, creating it if necessary.
  *
  * <p>Warning, may take a long time.
  *
  * @param ks path to the keystore
  * @param ksPW the keystore password
  * @param alias the name of the key
  * @param cname e.g. randomstuff.console.i2p.net
  * @param ou e.g. console
  * @param validDays e.g. 3652 (10 years)
  * @param keyAlg e.g. DSA , RSA, EC
  * @param keySize e.g. 1024
  * @param keyPW the key password, must be at least 6 characters
  * @return success
  * @since 0.8.3, consolidated from RouterConsoleRUnner and SSLClientListenerRunner in 0.9.9
  */
 public static boolean createKeys(
     File ks,
     String ksPW,
     String alias,
     String cname,
     String ou,
     int validDays,
     String keyAlg,
     int keySize,
     String keyPW) {
   if (ks.exists()) {
     try {
       if (getCert(ks, ksPW, alias) != null) {
         error("Not overwriting key " + alias + ", already exists in " + ks, null);
         return false;
       }
     } catch (Exception e) {
       error("Not overwriting key \"" + alias + "\", already exists in " + ks, e);
       return false;
     }
   } else {
     File dir = ks.getParentFile();
     if (dir != null && !dir.exists()) {
       File sdir = new SecureDirectory(dir.getAbsolutePath());
       if (!sdir.mkdir()) {
         error("Can't create directory " + dir, null);
         return false;
       }
     }
   }
   String keytool = (new File(System.getProperty("java.home"), "bin/keytool")).getAbsolutePath();
   String[] args =
       new String[] {
         keytool,
         "-genkey", // -genkeypair preferred in newer keytools, but this works with more
         "-storetype",
         KeyStore.getDefaultType(),
         "-keystore",
         ks.getAbsolutePath(),
         "-storepass",
         ksPW,
         "-alias",
         alias,
         "-dname",
         "CN=" + cname + ",OU=" + ou + ",O=I2P Anonymous Network,L=XX,ST=XX,C=XX",
         "-validity",
         Integer.toString(validDays), // 10 years
         "-keyalg",
         keyAlg,
         "-sigalg",
         getSigAlg(keySize, keyAlg),
         "-keysize",
         Integer.toString(keySize),
         "-keypass",
         keyPW
       };
   // TODO pipe key password to process; requires ShellCommand enhancements
   boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 240);
   if (success) {
     success = ks.exists();
     if (success) {
       try {
         success = getPrivateKey(ks, ksPW, alias, keyPW) != null;
         if (!success) error("Key gen failed to get private key", null);
       } catch (Exception e) {
         error("Key gen failed to get private key", e);
         success = false;
       }
     }
     if (!success) error("Key gen failed for unknown reasons", null);
   }
   if (success) {
     SecureFileOutputStream.setPerms(ks);
     info(
         "Created self-signed certificate for " + cname + " in keystore: " + ks.getAbsolutePath());
   } else {
     StringBuilder buf = new StringBuilder(256);
     for (int i = 0; i < args.length; i++) {
       buf.append('"').append(args[i]).append("\" ");
     }
     error("Failed to generate keys using command line: " + buf, null);
   }
   return success;
 }
  /**
   * 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.
   *
   * @return success
   * @since 0.8.3
   */
  private boolean createKeyStore(File ks) {
    // make a random 48 character password (30 * 8 / 5)
    byte[] rand = new byte[30];
    _context.random().nextBytes(rand);
    String keyPassword = Base32.encode(rand);
    // and one for the cname
    _context.random().nextBytes(rand);
    String cname = Base32.encode(rand) + ".console.i2p.net";

    String keytool = (new File(System.getProperty("java.home"), "bin/keytool")).getAbsolutePath();
    String[] args =
        new String[] {
          keytool,
          "-genkey", // -genkeypair preferred in newer keytools, but this works with more
          "-storetype",
          KeyStore.getDefaultType(),
          "-keystore",
          ks.getAbsolutePath(),
          "-storepass",
          DEFAULT_KEYSTORE_PASSWORD,
          "-alias",
          "console",
          "-dname",
          "CN=" + cname + ",OU=Console,O=I2P Anonymous Network,L=XX,ST=XX,C=XX",
          "-validity",
          "3652", // 10 years
          "-keyalg",
          "DSA",
          "-keysize",
          "1024",
          "-keypass",
          keyPassword
        };
    boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 30); // 30 secs
    if (success) {
      success = ks.exists();
      if (success) {
        SecureFileOutputStream.setPerms(ks);
        try {
          Map<String, String> changes = new HashMap();
          changes.put(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD);
          changes.put(PROP_KEY_PASSWORD, keyPassword);
          _context.router().saveConfig(changes, null);
        } catch (Exception e) {
        } // class cast exception
      }
    }
    if (success) {
      System.err.println(
          "Created self-signed certificate for "
              + cname
              + " in keystore: "
              + ks.getAbsolutePath()
              + "\n"
              + "The certificate name was generated randomly, and is not associated with your "
              + "IP address, host name, router identity, or destination keys.");
    } else {
      System.err.println("Failed to create console SSL keystore using command line:");
      StringBuilder buf = new StringBuilder(256);
      for (int i = 0; i < args.length; i++) {
        buf.append('"').append(args[i]).append("\" ");
      }
      System.err.println(buf.toString());
      System.err.println(
          "This is for the Sun/Oracle keytool, others may be incompatible.\n"
              + "If you create the keystore manually, you must add "
              + PROP_KEYSTORE_PASSWORD
              + " and "
              + PROP_KEY_PASSWORD
              + " to "
              + (new File(_context.getConfigDir(), "router.config")).getAbsolutePath());
    }
    return success;
  }