Beispiel #1
0
  /**
   * The method generates a DSAPublicKey object from the provided key.
   *
   * @param key - a DSAPublicKey object or DSAPrivateKey object.
   * @return object of the same type as the "key" argument
   * @throws InvalidKeyException if "key" is neither DSAPublicKey nor DSAPrivateKey
   */
  protected Key engineTranslateKey(Key key) throws InvalidKeyException {

    if (key != null) {
      if (key instanceof DSAPrivateKey) {

        DSAPrivateKey privateKey = (DSAPrivateKey) key;
        DSAParams params = privateKey.getParams();

        try {
          return engineGeneratePrivate(
              new DSAPrivateKeySpec(
                  privateKey.getX(), params.getP(), params.getQ(), params.getG()));
        } catch (InvalidKeySpecException e) {
          // Actually this exception shouldn't be thrown
          throw new InvalidKeyException("ATTENTION: InvalidKeySpecException: " + e);
        }
      }

      if (key instanceof DSAPublicKey) {

        DSAPublicKey publicKey = (DSAPublicKey) key;
        DSAParams params = publicKey.getParams();

        try {
          return engineGeneratePublic(
              new DSAPublicKeySpec(publicKey.getY(), params.getP(), params.getQ(), params.getG()));
        } catch (InvalidKeySpecException e) {
          // Actually this exception shouldn't be thrown
          throw new InvalidKeyException("ATTENTION: InvalidKeySpecException: " + e);
        }
      }
    }
    throw new InvalidKeyException("'key' is neither DSAPublicKey nor DSAPrivateKey");
  }
  /**
   * Convert a PrivateKey into a PGPPrivateKey.
   *
   * @param pub the corresponding PGPPublicKey to privKey.
   * @param privKey the private key for the key in pub.
   * @return a PGPPrivateKey
   * @throws PGPException
   */
  public PGPPrivateKey getPGPPrivateKey(PGPPublicKey pub, PrivateKey privKey) throws PGPException {
    BCPGKey privPk;

    switch (pub.getAlgorithm()) {
      case PGPPublicKey.RSA_ENCRYPT:
      case PGPPublicKey.RSA_SIGN:
      case PGPPublicKey.RSA_GENERAL:
        RSAPrivateCrtKey rsK = (RSAPrivateCrtKey) privKey;

        privPk = new RSASecretBCPGKey(rsK.getPrivateExponent(), rsK.getPrimeP(), rsK.getPrimeQ());
        break;
      case PGPPublicKey.DSA:
        DSAPrivateKey dsK = (DSAPrivateKey) privKey;

        privPk = new DSASecretBCPGKey(dsK.getX());
        break;
      case PGPPublicKey.ELGAMAL_ENCRYPT:
      case PGPPublicKey.ELGAMAL_GENERAL:
        ElGamalPrivateKey esK = (ElGamalPrivateKey) privKey;

        privPk = new ElGamalSecretBCPGKey(esK.getX());
        break;
      default:
        throw new PGPException("unknown key class");
    }

    return new PGPPrivateKey(pub.getKeyID(), pub.getPublicKeyPacket(), privPk);
  }
  /**
   * The method generates a DSAPublicKey object from the provided key.
   *
   * @param key - a DSAPublicKey object or DSAPrivateKey object.
   * @return object of the same type as the "key" argument
   * @throws InvalidKeyException if "key" is neither DSAPublicKey nor DSAPrivateKey
   */
  protected Key engineTranslateKey(Key key) throws InvalidKeyException {

    if (key != null) {
      if (key instanceof DSAPrivateKey) {

        DSAPrivateKey privateKey = (DSAPrivateKey) key;
        DSAParams params = privateKey.getParams();

        try {
          return engineGeneratePrivate(
              new DSAPrivateKeySpec(
                  privateKey.getX(), params.getP(), params.getQ(), params.getG()));
        } catch (InvalidKeySpecException e) {
          // Actually this exception shouldn't be thrown
          throw new InvalidKeyException(Messages.getString("security.1A0", e)); // $NON-NLS-1$
        }
      }

      if (key instanceof DSAPublicKey) {

        DSAPublicKey publicKey = (DSAPublicKey) key;
        DSAParams params = publicKey.getParams();

        try {
          return engineGeneratePublic(
              new DSAPublicKeySpec(publicKey.getY(), params.getP(), params.getQ(), params.getG()));
        } catch (InvalidKeySpecException e) {
          // Actually this exception shouldn't be thrown
          throw new InvalidKeyException(Messages.getString("security.1A1", e)); // $NON-NLS-1$
        }
      }
    }
    throw new InvalidKeyException(Messages.getString("security.19F")); // $NON-NLS-1$
  }
Beispiel #4
0
  /**
   * This method returns a specification for the supplied key.
   *
   * <p>The specification will be returned in the form of an object of the type specified by
   * keySpec.
   *
   * @param key - either DSAPrivateKey or DSAPublicKey
   * @param keySpec - either DSAPrivateKeySpec.class or DSAPublicKeySpec.class
   * @return either a DSAPrivateKeySpec or a DSAPublicKeySpec
   * @throws InvalidKeySpecException if "keySpec" is not a specification for DSAPublicKey or
   *     DSAPrivateKey
   */
  protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
      throws InvalidKeySpecException {

    BigInteger p, q, g, x, y;

    if (key != null) {
      if (keySpec == null) {
        throw new NullPointerException("keySpec == null");
      }
      if (key instanceof DSAPrivateKey) {
        DSAPrivateKey privateKey = (DSAPrivateKey) key;

        if (keySpec.equals(DSAPrivateKeySpec.class)) {

          x = privateKey.getX();

          DSAParams params = privateKey.getParams();

          p = params.getP();
          q = params.getQ();
          g = params.getG();

          return (T) (new DSAPrivateKeySpec(x, p, q, g));
        }

        if (keySpec.equals(PKCS8EncodedKeySpec.class)) {
          return (T) (new PKCS8EncodedKeySpec(key.getEncoded()));
        }

        throw new InvalidKeySpecException(
            "'keySpec' is neither DSAPrivateKeySpec nor PKCS8EncodedKeySpec");
      }

      if (key instanceof DSAPublicKey) {
        DSAPublicKey publicKey = (DSAPublicKey) key;

        if (keySpec.equals(DSAPublicKeySpec.class)) {

          y = publicKey.getY();

          DSAParams params = publicKey.getParams();

          p = params.getP();
          q = params.getQ();
          g = params.getG();

          return (T) (new DSAPublicKeySpec(y, p, q, g));
        }

        if (keySpec.equals(X509EncodedKeySpec.class)) {
          return (T) (new X509EncodedKeySpec(key.getEncoded()));
        }

        throw new InvalidKeySpecException(
            "'keySpec' is neither DSAPublicKeySpec nor X509EncodedKeySpec");
      }
    }
    throw new InvalidKeySpecException("'key' is neither DSAPublicKey nor DSAPrivateKey");
  }
Beispiel #5
0
 @JRubyMethod(name = "priv_key")
 public synchronized IRubyObject get_priv_key() {
   DSAPrivateKey key;
   BigInteger param;
   if ((key = this.privKey) != null) {
     return BN.newBN(getRuntime(), key.getX());
   }
   return getRuntime().getNil();
 }
  /**
   * This method returns a specification for the supplied key.
   *
   * <p>The specification will be returned in the form of an object of the type specified by
   * keySpec.
   *
   * @param key - either DSAPrivateKey or DSAPublicKey
   * @param keySpec - either DSAPrivateKeySpec.class or DSAPublicKeySpec.class
   * @return either a DSAPrivateKeySpec or a DSAPublicKeySpec
   * @throws InvalidKeySpecException if "keySpec" is not a specification for DSAPublicKey or
   *     DSAPrivateKey
   */
  protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec)
      throws InvalidKeySpecException {

    BigInteger p, q, g, x, y;

    if (key != null) {
      if (keySpec == null) {
        throw new NullPointerException(Messages.getString("security.19E")); // $NON-NLS-1$
      }
      if (key instanceof DSAPrivateKey) {
        DSAPrivateKey privateKey = (DSAPrivateKey) key;

        if (keySpec.equals(DSAPrivateKeySpec.class)) {

          x = privateKey.getX();

          DSAParams params = privateKey.getParams();

          p = params.getP();
          q = params.getQ();
          g = params.getG();

          return (T) (new DSAPrivateKeySpec(x, p, q, g));
        }

        if (keySpec.equals(PKCS8EncodedKeySpec.class)) {
          return (T) (new PKCS8EncodedKeySpec(key.getEncoded()));
        }

        throw new InvalidKeySpecException(Messages.getString("security.19C")); // $NON-NLS-1$
      }

      if (key instanceof DSAPublicKey) {
        DSAPublicKey publicKey = (DSAPublicKey) key;

        if (keySpec.equals(DSAPublicKeySpec.class)) {

          y = publicKey.getY();

          DSAParams params = publicKey.getParams();

          p = params.getP();
          q = params.getQ();
          g = params.getG();

          return (T) (new DSAPublicKeySpec(y, p, q, g));
        }

        if (keySpec.equals(X509EncodedKeySpec.class)) {
          return (T) (new X509EncodedKeySpec(key.getEncoded()));
        }

        throw new InvalidKeySpecException(Messages.getString("security.19D")); // $NON-NLS-1$
      }
    }
    throw new InvalidKeySpecException(Messages.getString("security.19F")); // $NON-NLS-1$
  }
  public boolean equals(Object o) {
    if (!(o instanceof DSAPrivateKey)) {
      return false;
    }

    DSAPrivateKey other = (DSAPrivateKey) o;

    return this.getX().equals(other.getX())
        && this.getParams().getG().equals(other.getParams().getG())
        && this.getParams().getP().equals(other.getParams().getP())
        && this.getParams().getQ().equals(other.getParams().getQ());
  }
  /** {@inheritDoc} */
  public void initSign() {
    if (signKey == null) {
      throw new IllegalStateException("Sign key must be set prior to initialization.");
    }

    final DSAPrivateKey privKey = (DSAPrivateKey) signKey;
    final DSAParams params = privKey.getParams();
    final DSAPrivateKeyParameters bcParams =
        new DSAPrivateKeyParameters(
            privKey.getX(), new DSAParameters(params.getP(), params.getQ(), params.getG()));
    init(true, bcParams);
  }
  public static void writeDSAPrivateKey(
      Writer _out, DSAPrivateKey obj, CipherSpec cipher, char[] passwd) throws IOException {
    BufferedWriter out = makeBuffered(_out);
    PrivateKeyInfo info =
        new PrivateKeyInfo((ASN1Sequence) new ASN1InputStream(getEncoded(obj)).readObject());
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    ASN1OutputStream aOut = new ASN1OutputStream(bOut);

    DSAParameter p = DSAParameter.getInstance(info.getAlgorithmId().getParameters());
    ASN1EncodableVector v = new ASN1EncodableVector();
    v.add(new DERInteger(0));
    v.add(new DERInteger(p.getP()));
    v.add(new DERInteger(p.getQ()));
    v.add(new DERInteger(p.getG()));

    BigInteger x = obj.getX();
    BigInteger y = p.getG().modPow(x, p.getP());

    v.add(new DERInteger(y));
    v.add(new DERInteger(x));

    aOut.writeObject(new DERSequence(v));
    byte[] encoding = bOut.toByteArray();

    if (cipher != null && passwd != null) {
      writePemEncrypted(out, PEM_STRING_DSA, encoding, cipher, passwd);
    } else {
      writePemPlain(out, PEM_STRING_DSA, encoding);
    }
  }
  public void regenerateLocalPublicKey(
      KeyFactory factory, String fullUserId, DSAPrivateKey privKey) {

    String userId = Address.stripResource(fullUserId);

    BigInteger x = privKey.getX();
    DSAParams params = privKey.getParams();
    BigInteger y = params.getG().modPow(x, params.getP());
    DSAPublicKeySpec keySpec = new DSAPublicKeySpec(y, params.getP(), params.getQ(), params.getG());
    PublicKey pubKey;
    try {
      pubKey = factory.generatePublic(keySpec);
    } catch (InvalidKeySpecException e) {
      throw new RuntimeException(e);
    }
    storeLocalPublicKey(userId, pubKey);
  }
Beispiel #11
0
  private void checkPrivateKey(DSAPrivateKey k2, PrivateKey sKey) {
    if (!k2.getX().equals(((DSAPrivateKey) sKey).getX())) {
      fail("private number not decoded properly");
    }

    if (!k2.getParams().getG().equals(((DSAPrivateKey) sKey).getParams().getG())) {
      fail("private generator not decoded properly");
    }

    if (!k2.getParams().getP().equals(((DSAPrivateKey) sKey).getParams().getP())) {
      fail("private p value not decoded properly");
    }

    if (!k2.getParams().getQ().equals(((DSAPrivateKey) sKey).getParams().getQ())) {
      fail("private q value not decoded properly");
    }
  }
Beispiel #12
0
 @JRubyMethod
 public IRubyObject to_text() {
   StringBuilder result = new StringBuilder();
   if (privKey != null) {
     int len = privKey.getParams().getP().bitLength();
     result.append("Private-Key: (").append(len).append(" bit)").append("\n");
     result.append("priv:");
     addSplittedAndFormatted(result, privKey.getX());
   }
   result.append("pub:");
   addSplittedAndFormatted(result, pubKey.getY());
   result.append("P:");
   addSplittedAndFormatted(result, pubKey.getParams().getP());
   result.append("Q:");
   addSplittedAndFormatted(result, pubKey.getParams().getQ());
   result.append("G:");
   addSplittedAndFormatted(result, pubKey.getParams().getG());
   return getRuntime().newString(result.toString());
 }
  /** Given a DSA key pair, return the BIND9-style text encoding */
  private String generatePrivateDSA(DSAPrivateKey key, DSAPublicKey pub, int algorithm) {
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);
    DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();

    DSAParams p = key.getParams();

    out.println("Private-key-format: v1.2");
    out.println("Algorithm: " + algorithm + " (" + algs.algToString(algorithm) + ")");
    out.print("Prime(p): ");
    out.println(b64BigInt(p.getP()));
    out.print("Subprime(q): ");
    out.println(b64BigInt(p.getQ()));
    out.print("Base(g): ");
    out.println(b64BigInt(p.getG()));
    out.print("Private_value(x): ");
    out.println(b64BigInt(key.getX()));
    out.print("Public_value(y): ");
    out.println(b64BigInt(pub.getY()));

    return sw.toString();
  }
 BCDSAPrivateKey(DSAPrivateKey key) {
   this.x = key.getX();
   this.dsaSpec = key.getParams();
 }
Beispiel #15
0
  public void writeObject(Object var1, String var2, char[] var3, SecureRandom var4)
      throws IOException {
    if (var1 instanceof KeyPair) {
      PrivateKey var5 = ((KeyPair) var1).getPrivate();
      this.writeObject(var5);
    } else {
      String var8 = null;
      byte[] var9 = null;
      if (var1 instanceof RSAPrivateCrtKey) {
        var8 = "RSA PRIVATE KEY";
        RSAPrivateCrtKey var10 = (RSAPrivateCrtKey) var1;
        BigInteger var11 = var10.getModulus();
        BigInteger var12 = var10.getPublicExponent();
        BigInteger var13 = var10.getPrivateExponent();
        BigInteger var14 = var10.getPrimeP();
        BigInteger var15 = var10.getPrimeQ();
        BigInteger var16 = var10.getPrimeExponentP();
        BigInteger var17 = var10.getPrimeExponentQ();
        BigInteger var18 = var10.getCrtCoefficient();
        var9 =
            (new RSAPrivateKeyStructure(var11, var12, var13, var14, var15, var16, var17, var18))
                .getEncoded();
      } else if (var1 instanceof DSAPrivateKey) {
        var8 = "DSA PRIVATE KEY";
        DSAPrivateKey var22 = (DSAPrivateKey) var1;
        DSAParams var23 = var22.getParams();
        ASN1EncodableVector var24 = new ASN1EncodableVector();
        DERInteger var25 = new DERInteger(0);
        var24.add(var25);
        BigInteger var28 = var23.getP();
        DERInteger var29 = new DERInteger(var28);
        var24.add(var29);
        BigInteger var32 = var23.getQ();
        DERInteger var33 = new DERInteger(var32);
        var24.add(var33);
        BigInteger var36 = var23.getG();
        DERInteger var37 = new DERInteger(var36);
        var24.add(var37);
        BigInteger var40 = var22.getX();
        BigInteger var41 = var23.getG();
        BigInteger var42 = var23.getP();
        BigInteger var46 = var41.modPow(var40, var42);
        DERInteger var47 = new DERInteger(var46);
        var24.add(var47);
        DERInteger var52 = new DERInteger(var40);
        var24.add(var52);
        DERSequence var57 = new DERSequence(var24);
        var9 = var57.getEncoded();
      } else if (var1 instanceof PrivateKey) {
        String var60 = ((PrivateKey) var1).getAlgorithm();
        if ("ECDSA".equals(var60)) {
          var8 = "EC PRIVATE KEY";
          var9 =
              PrivateKeyInfo.getInstance(ASN1Object.fromByteArray(((PrivateKey) var1).getEncoded()))
                  .getPrivateKey()
                  .getEncoded();
        }
      }

      if (var8 != null && var9 != null) {
        String var61 = Strings.toUpperCase(var2);
        if (var61.equals("DESEDE")) {
          var61 = "DES-EDE3-CBC";
        }

        byte var62;
        if (var61.startsWith("AES-")) {
          var62 = 16;
        } else {
          var62 = 8;
        }

        byte[] var63 = new byte[var62];
        var4.nextBytes(var63);
        String var66 = this.provider;
        byte[] var68 = PEMUtilities.crypt((boolean) 1, var66, var9, var3, var61, var63);
        this.writeHeader(var8);
        String var72 = "Proc-Type: 4,ENCRYPTED";
        this.write(var72);
        this.newLine();
        String var73 = "DEK-Info: " + var61 + ",";
        this.write(var73);
        this.writeHexEncoded(var63);
        this.newLine();
        this.newLine();
        this.writeEncoded(var68);
        this.writeFooter(var8);
      } else {
        StringBuilder var19 = (new StringBuilder()).append("Object type not supported: ");
        String var20 = var1.getClass().getName();
        String var21 = var19.append(var20).toString();
        throw new IllegalArgumentException(var21);
      }
    }
  }
Beispiel #16
0
  public void testCompat() throws Exception {
    if (Security.getProvider("SUN") == null) {
      return;
    }

    Signature s = Signature.getInstance("DSA", "SUN");
    KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "SUN");
    byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};

    g.initialize(512, new SecureRandom());

    KeyPair p = g.generateKeyPair();

    PrivateKey sKey = p.getPrivate();
    PublicKey vKey = p.getPublic();

    //
    // sign SUN - verify with BC
    //
    s.initSign(sKey);

    s.update(data);

    byte[] sigBytes = s.sign();

    s = Signature.getInstance("DSA", "BC");

    s.initVerify(vKey);

    s.update(data);

    if (!s.verify(sigBytes)) {
      fail("SUN -> BC verification failed");
    }

    //
    // sign BC - verify with SUN
    //

    s.initSign(sKey);

    s.update(data);

    sigBytes = s.sign();

    s = Signature.getInstance("DSA", "SUN");

    s.initVerify(vKey);

    s.update(data);

    if (!s.verify(sigBytes)) {
      fail("BC -> SUN verification failed");
    }

    //
    // key encoding test - BC decoding Sun keys
    //
    KeyFactory f = KeyFactory.getInstance("DSA", "BC");
    X509EncodedKeySpec x509s = new X509EncodedKeySpec(vKey.getEncoded());

    DSAPublicKey k1 = (DSAPublicKey) f.generatePublic(x509s);

    checkPublic(k1, vKey);

    PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(sKey.getEncoded());

    DSAPrivateKey k2 = (DSAPrivateKey) f.generatePrivate(pkcs8);

    checkPrivateKey(k2, sKey);

    //
    // key decoding test - SUN decoding BC keys
    //
    f = KeyFactory.getInstance("DSA", "SUN");
    x509s = new X509EncodedKeySpec(k1.getEncoded());

    vKey = (DSAPublicKey) f.generatePublic(x509s);

    checkPublic(k1, vKey);

    pkcs8 = new PKCS8EncodedKeySpec(k2.getEncoded());
    sKey = f.generatePrivate(pkcs8);

    checkPrivateKey(k2, sKey);
  }
  /** java.security.KeyStore#setEntry(String, KeyStore.Entry, KeyStore.ProtectionParameter) */
  public void test_setEntry() throws Exception {
    String type = "DSA";

    KeyStore keyTest = KeyStore.getInstance(KeyStore.getDefaultType());
    keyTest.load(null, pssWord);

    Certificate[] chain = {
      new MyCertificate(type, testEncoding), new MyCertificate(type, testEncoding)
    };
    DSAPrivateKey privateKey1 =
        (DSAPrivateKey)
            KeyFactory.getInstance(type)
                .generatePrivate(
                    new DSAPrivateKeySpec(
                        new BigInteger("1"),
                        new BigInteger("2"),
                        new BigInteger("3"),
                        new BigInteger("4")));

    KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(pssWord);
    KeyStore.PrivateKeyEntry pke = new KeyStore.PrivateKeyEntry(getPrivateKey(), chain);
    KeyStore.PrivateKeyEntry pke1 = new KeyStore.PrivateKeyEntry(privateKey1, chain);

    try {
      keyTest.setEntry("alias", pke, null);
      assertFalse(StandardNames.IS_RI); // BKS KeyStore does not require a password
    } catch (KeyStoreException e) {
      assertTrue(StandardNames.IS_RI); // JKS KeyStore requires a password
    }

    keyTest.setEntry("alias", pke, pp);

    KeyStore.PrivateKeyEntry pkeActual = (KeyStore.PrivateKeyEntry) keyTest.getEntry("alias", pp);

    assertTrue(Arrays.equals(chain, pkeActual.getCertificateChain()));
    assertEquals(getPrivateKey(), pkeActual.getPrivateKey());
    assertEquals(new MyCertificate(type, testEncoding), pkeActual.getCertificate());
    assertTrue(keyTest.entryInstanceOf("alias", KeyStore.PrivateKeyEntry.class));

    keyTest.setEntry("alias", pke1, pp);
    pkeActual = (KeyStore.PrivateKeyEntry) keyTest.getEntry("alias", pp);

    assertTrue(Arrays.equals(chain, pkeActual.getCertificateChain()));
    DSAPrivateKey actualPrivateKey = (DSAPrivateKey) pkeActual.getPrivateKey();
    assertEquals(privateKey1.getX(), actualPrivateKey.getX());
    assertEquals(privateKey1.getParams().getG(), actualPrivateKey.getParams().getG());
    assertEquals(privateKey1.getParams().getP(), actualPrivateKey.getParams().getP());
    assertEquals(privateKey1.getParams().getQ(), actualPrivateKey.getParams().getQ());
    assertEquals(new MyCertificate(type, testEncoding), pkeActual.getCertificate());
    assertTrue(keyTest.entryInstanceOf("alias", KeyStore.PrivateKeyEntry.class));

    keyTest.setEntry("alias2", pke1, pp);
    pkeActual = (KeyStore.PrivateKeyEntry) keyTest.getEntry("alias2", pp);

    assertTrue(Arrays.equals(chain, pkeActual.getCertificateChain()));
    actualPrivateKey = (DSAPrivateKey) pkeActual.getPrivateKey();
    assertEquals(privateKey1.getX(), actualPrivateKey.getX());
    assertEquals(privateKey1.getParams().getG(), actualPrivateKey.getParams().getG());
    assertEquals(privateKey1.getParams().getP(), actualPrivateKey.getParams().getP());
    assertEquals(privateKey1.getParams().getQ(), actualPrivateKey.getParams().getQ());
    assertEquals(new MyCertificate(type, testEncoding), pkeActual.getCertificate());
    assertTrue(keyTest.entryInstanceOf("alias2", KeyStore.PrivateKeyEntry.class));

    try {
      keyTest.setEntry(null, null, null);
      fail();
    } catch (NullPointerException expected) {
    }
  }
  /** java.security.KeyStore#getEntry(String, KeyStore.ProtectionParameter) */
  public void test_getEntry() throws Exception {
    String type = "DSA";

    KeyStore keyTest = KeyStore.getInstance(KeyStore.getDefaultType());

    try {
      keyTest.getEntry("anAlias", new KeyStore.PasswordProtection(new char[] {}));
      fail();
    } catch (KeyStoreException expected) {
    }

    keyTest.load(null, pssWord);

    try {
      keyTest.getEntry(null, new KeyStore.PasswordProtection(new char[] {}));
      fail();
    } catch (NullPointerException expected) {
    }

    keyTest.getEntry("anAlias", null);

    try {
      keyTest.getEntry(null, null);
      fail();
    } catch (NullPointerException expected) {
    }

    assertNull(keyTest.getEntry("alias", null));

    Certificate[] chain = {
      new MyCertificate(type, testEncoding), new MyCertificate(type, testEncoding)
    };

    DSAPrivateKey privateKey1 =
        (DSAPrivateKey)
            KeyFactory.getInstance(type)
                .generatePrivate(
                    new DSAPrivateKeySpec(
                        new BigInteger("1"),
                        new BigInteger("2"),
                        new BigInteger("3"),
                        new BigInteger("4")));

    KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(pssWord);
    assertNull(keyTest.getEntry("alias", pp));

    KeyStore.PrivateKeyEntry pke1 = new KeyStore.PrivateKeyEntry(getPrivateKey(), chain);
    KeyStore.PrivateKeyEntry pke2 = new KeyStore.PrivateKeyEntry(privateKey1, chain);

    keyTest.setEntry("alias1", pke1, pp);
    keyTest.setEntry("alias2", pke2, pp);

    assertNull(keyTest.getEntry("alias", pp));
    KeyStore.PrivateKeyEntry pkeActual1 = (KeyStore.PrivateKeyEntry) keyTest.getEntry("alias1", pp);
    KeyStore.PrivateKeyEntry pkeActual2 = (KeyStore.PrivateKeyEntry) keyTest.getEntry("alias2", pp);

    assertTrue(Arrays.equals(chain, pkeActual1.getCertificateChain()));
    assertEquals(getPrivateKey(), pkeActual1.getPrivateKey());
    assertEquals(new MyCertificate(type, testEncoding), pkeActual1.getCertificate());
    assertTrue(keyTest.entryInstanceOf("alias1", KeyStore.PrivateKeyEntry.class));

    assertTrue(Arrays.equals(chain, pkeActual2.getCertificateChain()));
    DSAPrivateKey entryPrivateKey = (DSAPrivateKey) pkeActual2.getPrivateKey();
    assertEquals(privateKey1.getX(), entryPrivateKey.getX());
    assertEquals(privateKey1.getParams().getG(), entryPrivateKey.getParams().getG());
    assertEquals(privateKey1.getParams().getP(), entryPrivateKey.getParams().getP());
    assertEquals(privateKey1.getParams().getQ(), entryPrivateKey.getParams().getQ());

    assertEquals(new MyCertificate(type, testEncoding), pkeActual2.getCertificate());
    assertTrue(keyTest.entryInstanceOf("alias2", KeyStore.PrivateKeyEntry.class));
  }
  private PemObject createPemObject(
      Object obj, String algorithm, char[] password, SecureRandom random) throws IOException {
    if (obj instanceof KeyPair) {
      return createPemObject(((KeyPair) obj).getPrivate(), algorithm, password, random);
    }

    String type = null;
    byte[] keyData = null;

    if (obj instanceof RSAPrivateCrtKey) {
      type = "RSA PRIVATE KEY";

      RSAPrivateCrtKey k = (RSAPrivateCrtKey) obj;

      org.bouncycastle.asn1.pkcs.RSAPrivateKey keyStruct =
          new org.bouncycastle.asn1.pkcs.RSAPrivateKey(
              k.getModulus(),
              k.getPublicExponent(),
              k.getPrivateExponent(),
              k.getPrimeP(),
              k.getPrimeQ(),
              k.getPrimeExponentP(),
              k.getPrimeExponentQ(),
              k.getCrtCoefficient());

      // convert to bytearray
      keyData = keyStruct.getEncoded();
    } else if (obj instanceof DSAPrivateKey) {
      type = "DSA PRIVATE KEY";

      DSAPrivateKey k = (DSAPrivateKey) obj;
      DSAParams p = k.getParams();
      ASN1EncodableVector v = new ASN1EncodableVector();

      v.add(new DERInteger(0));
      v.add(new DERInteger(p.getP()));
      v.add(new DERInteger(p.getQ()));
      v.add(new DERInteger(p.getG()));

      BigInteger x = k.getX();
      BigInteger y = p.getG().modPow(x, p.getP());

      v.add(new DERInteger(y));
      v.add(new DERInteger(x));

      keyData = new DERSequence(v).getEncoded();
    } else if (obj instanceof PrivateKey && "ECDSA".equals(((PrivateKey) obj).getAlgorithm())) {
      type = "EC PRIVATE KEY";

      PrivateKeyInfo privInfo =
          PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(((PrivateKey) obj).getEncoded()));

      keyData = privInfo.parsePrivateKey().toASN1Primitive().getEncoded();
    }

    if (type == null || keyData == null) {
      // TODO Support other types?
      throw new IllegalArgumentException("Object type not supported: " + obj.getClass().getName());
    }

    String dekAlgName = Strings.toUpperCase(algorithm);

    // Note: For backward compatibility
    if (dekAlgName.equals("DESEDE")) {
      dekAlgName = "DES-EDE3-CBC";
    }

    int ivLength = dekAlgName.startsWith("AES-") ? 16 : 8;

    byte[] iv = new byte[ivLength];
    random.nextBytes(iv);

    byte[] encData = PEMUtilities.crypt(true, provider, keyData, password, dekAlgName, iv);

    List headers = new ArrayList(2);

    headers.add(new PemHeader("Proc-Type", "4,ENCRYPTED"));
    headers.add(new PemHeader("DEK-Info", dekAlgName + "," + getHexEncoded(iv)));

    return new PemObject(type, headers, encData);
  }