public Object parseObject(PemObject obj) throws IOException {
   try {
     return PrivateKeyInfo.getInstance(obj.getContent());
   } catch (Exception e) {
     throw new PEMException("problem parsing PRIVATE KEY: " + e.toString(), e);
   }
 }
  public PrivateKeyInfo decryptPrivateKeyInfo(InputDecryptorProvider inputDecryptorProvider)
      throws PKCSException {
    try {
      InputDecryptor decrytor =
          inputDecryptorProvider.get(encryptedPrivateKeyInfo.getEncryptionAlgorithm());

      ByteArrayInputStream encIn =
          new ByteArrayInputStream(encryptedPrivateKeyInfo.getEncryptedData());

      return PrivateKeyInfo.getInstance(Streams.readAll(decrytor.getInputStream(encIn)));
    } catch (Exception e) {
      throw new PKCSException("unable to read encrypted data: " + e.getMessage(), e);
    }
  }
Beispiel #3
0
  public void performTest() throws Exception {
    KeyFactory fact;
    byte[] input =
        new byte[] {
          (byte) 0x54,
          (byte) 0x85,
          (byte) 0x9b,
          (byte) 0x34,
          (byte) 0x2c,
          (byte) 0x49,
          (byte) 0xea,
          (byte) 0x2a
        };
    byte[][] output =
        new byte[][] {
          Hex.decode(
              "8b427f781a2e59dd9def386f1956b996ee07f48c96880e65a368055ed8c0a8831669ef7250b40918b2b1d488547e72c84540e42bd07b03f14e226f04fbc2d929"),
          Hex.decode(
              "2ec6e1a1711b6c7b8cd3f6a25db21ab8bb0a5f1d6df2ef375fa708a43997730ffc7c98856dbbe36edddcdd1b2d2a53867d8355af94fea3aeec128da908e08f4c"),
          Hex.decode(
              "0850ac4e5a8118323200c8ed1e5aaa3d5e635172553ccac66a8e4153d35c79305c4440f11034ab147fccce21f18a50cf1c0099c08a577eb68237a91042278965"),
          Hex.decode(
              "1c9649bdccb51056751fe43837f4eb43bada472accf26f65231666d5de7d11950d8379b3596dfdf75c6234274896fa8d18ad0865d3be2ac4d6687151abdf01e93941dcef18fa63186c9351d1506c89d09733c5ff4304208c812bdd21a50f56fde115e629e0e973721c9fcc87e89295a79853dee613962a0b2f2fc57163fd99057a3c776f13c20c26407eb8863998d7e53b543ba8d0a295a9a68d1a149833078c9809ad6a6dad7fc22a95ad615a73138c54c018f40d99bf8eeecd45f5be526f2d6b01aeb56381991c1ab31a2e756f15e052b9cd5638b2eff799795c5bae493307d5eb9f8c21d438de131fe505a4e7432547ab19224094f9e4be1968bd0793b79d"),
          Hex.decode(
              "4c4afc0c24dddaedd4f9a3b23be30d35d8e005ffd36b3defc5d18acc830c3ed388ce20f43a00e614fd087c814197bc9fc2eff9ad4cc474a7a2ef3ed9c0f0a55eb23371e41ee8f2e2ed93ea3a06ca482589ab87e0d61dcffda5eea1241408e43ea1108726cdb87cc3aa5e9eaaa9f72507ca1352ac54a53920c94dccc768147933d8c50aefd9d1da10522a40133cd33dbc0524669e70f771a88d65c4716d471cd22b08b9f01f24e4e9fc7ffbcfa0e0a7aed47b345826399b26a73be112eb9c5e06fc6742fc3d0ef53d43896403c5105109cfc12e6deeaf4a48ba308e039774b9bdb31a9b9e133c81c321630cf0b4b2d1f90717b24c3268e1fea681ea9cdc709342"),
          Hex.decode(
              "06b5b26bd13515f799e5e37ca43cace15cd82fd4bf36b25d285a6f0998d97c8cb0755a28f0ae66618b1cd03e27ac95eaaa4882bc6dc0078cd457d4f7de4154173a9c7a838cfc2ac2f74875df462aae0cfd341645dc51d9a01da9bdb01507f140fa8a016534379d838cc3b2a53ac33150af1b242fc88013cb8d914e66c8182864ee6de88ce2879d4c05dd125409620a96797c55c832fb2fb31d4310c190b8ed2c95fdfda2ed87f785002faaec3f35ec05cf70a3774ce185e4882df35719d582dd55ac31257344a9cba95189dcbea16e8c6cb7a235a0384bc83b6183ca8547e670fe33b1b91725ae0c250c9eca7b5ba78bd77145b70270bf8ac31653006c02ca9c"),
          Hex.decode(
              "135f1be3d045526235bf9d5e43499d4ee1bfdf93370769ae56e85dbc339bc5b7ea3bee49717497ee8ac3f7cd6adb6fc0f17812390dcd65ac7b87fef7970d9ff9"),
          Hex.decode(
              "03c05add1e030178c352face07cafc9447c8f369b8f95125c0d311c16b6da48ca2067104cce6cd21ae7b163cd18ffc13001aecebdc2eb02b9e92681f84033a98"),
          Hex.decode(
              "00319bb9becb49f3ed1bca26d0fcf09b0b0a508e4d0bd43b350f959b72cd25b3af47d608fdcd248eada74fbe19990dbeb9bf0da4b4e1200243a14e5cab3f7e610c")
        };
    SecureRandom rand = new FixedSecureRandom();

    fact = KeyFactory.getInstance("RSA", "BC");

    PrivateKey privKey = fact.generatePrivate(privKeySpec);
    PublicKey pubKey = fact.generatePublic(pubKeySpec);

    PrivateKey priv2048Key = fact.generatePrivate(priv2048KeySpec);
    PublicKey pub2048Key = fact.generatePublic(pub2048KeySpec);

    //
    // key without CRT coefficients
    //
    PrivateKeyInfo keyInfo = PrivateKeyInfo.getInstance(privKey.getEncoded());
    BigInteger zero = BigInteger.valueOf(0);
    PKCS8EncodedKeySpec noCrtSpec =
        new PKCS8EncodedKeySpec(
            new PrivateKeyInfo(
                    keyInfo.getPrivateKeyAlgorithm(),
                    new org.mightyfish.asn1.pkcs.RSAPrivateKey(
                        privKeySpec.getModulus(),
                        privKeySpec.getPublicExponent(),
                        privKeySpec.getPrivateExponent(),
                        zero,
                        zero,
                        zero,
                        zero,
                        zero))
                .getEncoded());

    PrivateKey noCrtKey = fact.generatePrivate(noCrtSpec);
    if (noCrtKey instanceof RSAPrivateCrtKey) {
      fail("private key without CRT coefficients returned as CRT key");
    }

    //
    // No Padding
    //
    Cipher c = Cipher.getInstance("RSA", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    byte[] out = c.doFinal(input);

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // No Padding - incremental
    //
    c = Cipher.getInstance("RSA", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    c.update(input);

    out = c.doFinal();

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // No Padding - incremental - explicit use of NONE in mode.
    //
    c = Cipher.getInstance("RSA/NONE/NoPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    c.update(input);

    out = c.doFinal();

    if (!areEqual(out, output[0])) {
      fail(
          "NoPadding test failed on encrypt expected "
              + new String(Hex.encode(output[0]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // No Padding - maximum length
    //
    c = Cipher.getInstance("RSA", "BC");

    byte[] modBytes = ((RSAPublicKey) pubKey).getModulus().toByteArray();
    byte[] maxInput = new byte[modBytes.length - 1];

    maxInput[0] |= 0x7f;

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(maxInput);

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, maxInput)) {
      fail(
          "NoPadding test failed on decrypt expected "
              + new String(Hex.encode(maxInput))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // PKCS1 V 1.5
    //
    c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[1])) {
      fail(
          "PKCS1 test failed on encrypt expected "
              + new String(Hex.encode(output[1]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "PKCS1 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // PKCS1 V 1.5 - NONE
    //
    c = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[1])) {
      fail(
          "PKCS1 test failed on encrypt expected "
              + new String(Hex.encode(output[1]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "PKCS1 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // OAEP - SHA1
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[2])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    AlgorithmParameters oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-1 parameters");
    }

    //
    // OAEP - SHA224
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA224AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[3])) {
      fail(
          "OAEP SHA-224 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-224 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-224 parameters");
    }

    //
    // OAEP - SHA 256
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[4])) {
      fail(
          "OAEP SHA-256 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-256 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-256 parameters");
    }

    //
    // OAEP - SHA 384
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA384AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[5])) {
      fail(
          "OAEP SHA-384 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, priv2048Key);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP SHA-384 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default sha-384 parameters");
    }

    //
    // OAEP - MD5
    //
    c = Cipher.getInstance("RSA/NONE/OAEPWithMD5AndMGF1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[6])) {
      fail(
          "OAEP MD5 test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP MD5 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0])))
            .getEncoded())) {
      fail("OAEP test failed default md5 parameters");
    }

    //
    // OAEP - SHA1 with default parameters
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(Cipher.ENCRYPT_MODE, pubKey, OAEPParameterSpec.DEFAULT, rand);

    out = c.doFinal(input);

    if (!areEqual(out, output[2])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    oaepP = c.getParameters();

    if (!areEqual(oaepP.getEncoded(), new byte[] {0x30, 0x00})) {
      fail("OAEP test failed default parameters");
    }

    //
    // OAEP - SHA1 with specified string
    //
    c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC");

    c.init(
        Cipher.ENCRYPT_MODE,
        pubKey,
        new OAEPParameterSpec(
            "SHA1",
            "MGF1",
            new MGF1ParameterSpec("SHA1"),
            new PSource.PSpecified(new byte[] {1, 2, 3, 4, 5})),
        rand);

    out = c.doFinal(input);

    oaepP = c.getParameters();

    if (!areEqual(
        oaepP.getEncoded(),
        new RSAESOAEPparams(
                new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_mgf1,
                    new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)),
                new AlgorithmIdentifier(
                    PKCSObjectIdentifiers.id_pSpecified,
                    new DEROctetString(new byte[] {1, 2, 3, 4, 5})))
            .getEncoded())) {
      fail("OAEP test failed changed sha-1 parameters");
    }

    if (!areEqual(out, output[7])) {
      fail(
          "OAEP test failed on encrypt expected "
              + new String(Hex.encode(output[2]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC");

    c.init(Cipher.DECRYPT_MODE, privKey, oaepP);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "OAEP test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // ISO9796-1
    //
    byte[] isoInput =
        Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210");
    PrivateKey isoPrivKey = fact.generatePrivate(isoPrivKeySpec);
    PublicKey isoPubKey = fact.generatePublic(isoPubKeySpec);

    c = Cipher.getInstance("RSA/NONE/ISO9796-1Padding", "BC");

    c.init(Cipher.ENCRYPT_MODE, isoPrivKey);

    out = c.doFinal(isoInput);

    if (!areEqual(out, output[8])) {
      fail(
          "ISO9796-1 test failed on encrypt expected "
              + new String(Hex.encode(output[3]))
              + " got "
              + new String(Hex.encode(out)));
    }

    c.init(Cipher.DECRYPT_MODE, isoPubKey);

    out = c.doFinal(out);

    if (!areEqual(out, isoInput)) {
      fail(
          "ISO9796-1 test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    //
    // generation with parameters test.
    //
    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC");

    //
    // 768 bit RSA with e = 2^16-1
    //
    keyPairGen.initialize(
        new RSAKeyGenParameterSpec(768, BigInteger.valueOf(65537)), new SecureRandom());

    KeyPair kp = keyPairGen.generateKeyPair();

    pubKey = kp.getPublic();
    privKey = kp.getPrivate();

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.doFinal(input);

    c.init(Cipher.DECRYPT_MODE, privKey);

    out = c.doFinal(out);

    if (!areEqual(out, input)) {
      fail(
          "key generation test failed on decrypt expected "
              + new String(Hex.encode(input))
              + " got "
              + new String(Hex.encode(out)));
    }

    //
    // comparison check
    //
    KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC");

    RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey) keyFact.translateKey(privKey);

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    crtKey =
        (RSAPrivateCrtKey) keyFact.generatePrivate(new PKCS8EncodedKeySpec(privKey.getEncoded()));

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    crtKey = (RSAPrivateCrtKey) serializeDeserialize(privKey);

    if (!privKey.equals(crtKey)) {
      fail("private key equality check failed");
    }

    if (privKey.hashCode() != crtKey.hashCode()) {
      fail("private key hashCode check failed");
    }

    RSAPublicKey copyKey = (RSAPublicKey) keyFact.translateKey(pubKey);

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    copyKey = (RSAPublicKey) keyFact.generatePublic(new X509EncodedKeySpec(pubKey.getEncoded()));

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    copyKey = (RSAPublicKey) serializeDeserialize(pubKey);

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    if (pubKey.hashCode() != copyKey.hashCode()) {
      fail("public key hashCode check failed");
    }

    //
    // test an OAEP key
    //
    SubjectPublicKeyInfo oaepKey =
        new SubjectPublicKeyInfo(
            new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, new RSAESOAEPparams()),
            SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()).parsePublicKey());

    copyKey =
        (RSAPublicKey)
            serializeDeserialize(
                keyFact.generatePublic(new X509EncodedKeySpec(oaepKey.getEncoded())));

    if (!pubKey.equals(copyKey)) {
      fail("public key equality check failed");
    }

    if (pubKey.hashCode() != copyKey.hashCode()) {
      fail("public key hashCode check failed");
    }

    if (!Arrays.areEqual(copyKey.getEncoded(), oaepKey.getEncoded())) {
      fail("encoding does not match");
    }

    oaepCompatibilityTest("SHA-1", priv2048Key, pub2048Key);
    // TODO: oaepCompatibilityTest("SHA-224", priv2048Key, pub2048Key);      commented out as fails
    // in JDK 1.7
    oaepCompatibilityTest("SHA-256", priv2048Key, pub2048Key);
    oaepCompatibilityTest("SHA-384", priv2048Key, pub2048Key);
    oaepCompatibilityTest("SHA-512", priv2048Key, pub2048Key);

    SecureRandom random = new SecureRandom();
    rawModeTest("SHA1withRSA", X509ObjectIdentifiers.id_SHA1, priv2048Key, pub2048Key, random);
    rawModeTest("MD5withRSA", PKCSObjectIdentifiers.md5, priv2048Key, pub2048Key, random);
    rawModeTest(
        "RIPEMD128withRSA", TeleTrusTObjectIdentifiers.ripemd128, priv2048Key, pub2048Key, random);

    // init reset test
    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.update(new byte[40]);

    c.init(Cipher.ENCRYPT_MODE, pubKey, rand);

    out = c.update(new byte[40]);
  }
  public void performTest() throws Exception {
    PEMParser pemRd = openPEMResource("test.pem");
    Object o;
    PEMKeyPair pemPair;
    KeyPair pair;

    while ((o = pemRd.readObject()) != null) {
      if (o instanceof KeyPair) {
        // pair = (KeyPair)o;

        // System.out.println(pair.getPublic());
        // System.out.println(pair.getPrivate());
      } else {
        // System.out.println(o.toString());
      }
    }

    // test bogus lines before begin are ignored.
    pemRd = openPEMResource("extratest.pem");

    while ((o = pemRd.readObject()) != null) {
      if (!(o instanceof X509CertificateHolder)) {
        fail("wrong object found");
      }
    }

    //
    // pkcs 7 data
    //
    pemRd = openPEMResource("pkcs7.pem");
    ContentInfo d = (ContentInfo) pemRd.readObject();

    if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) {
      fail("failed envelopedData check");
    }

    //
    // ECKey
    //
    pemRd = openPEMResource("eckey.pem");
    ASN1ObjectIdentifier ecOID = (ASN1ObjectIdentifier) pemRd.readObject();
    X9ECParameters ecSpec = ECNamedCurveTable.getByOID(ecOID);

    if (ecSpec == null) {
      fail("ecSpec not found for named curve");
    }

    pemPair = (PEMKeyPair) pemRd.readObject();

    pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair);

    Signature sgr = Signature.getInstance("ECDSA", "BC");

    sgr.initSign(pair.getPrivate());

    byte[] message = new byte[] {(byte) 'a', (byte) 'b', (byte) 'c'};

    sgr.update(message);

    byte[] sigBytes = sgr.sign();

    sgr.initVerify(pair.getPublic());

    sgr.update(message);

    if (!sgr.verify(sigBytes)) {
      fail("EC verification failed");
    }

    if (!pair.getPublic().getAlgorithm().equals("ECDSA")) {
      fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm());
    }

    if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) {
      fail("wrong algorithm name on private");
    }

    //
    // ECKey -- explicit parameters
    //
    pemRd = openPEMResource("ecexpparam.pem");
    ecSpec = (X9ECParameters) pemRd.readObject();

    pemPair = (PEMKeyPair) pemRd.readObject();

    pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair);

    sgr = Signature.getInstance("ECDSA", "BC");

    sgr.initSign(pair.getPrivate());

    message = new byte[] {(byte) 'a', (byte) 'b', (byte) 'c'};

    sgr.update(message);

    sigBytes = sgr.sign();

    sgr.initVerify(pair.getPublic());

    sgr.update(message);

    if (!sgr.verify(sigBytes)) {
      fail("EC verification failed");
    }

    if (!pair.getPublic().getAlgorithm().equals("ECDSA")) {
      fail("wrong algorithm name on public got: " + pair.getPublic().getAlgorithm());
    }

    if (!pair.getPrivate().getAlgorithm().equals("ECDSA")) {
      fail("wrong algorithm name on private");
    }

    //
    // writer/parser test
    //
    KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");

    pair = kpGen.generateKeyPair();

    keyPairTest("RSA", pair);

    kpGen = KeyPairGenerator.getInstance("DSA", "BC");
    kpGen.initialize(512, new SecureRandom());
    pair = kpGen.generateKeyPair();

    keyPairTest("DSA", pair);

    //
    // PKCS7
    //
    ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    PEMWriter pWrt = new PEMWriter(new OutputStreamWriter(bOut));

    pWrt.writeObject(d);

    pWrt.close();

    pemRd = new PEMParser(new InputStreamReader(new ByteArrayInputStream(bOut.toByteArray())));
    d = (ContentInfo) pemRd.readObject();

    if (!d.getContentType().equals(CMSObjectIdentifiers.envelopedData)) {
      fail("failed envelopedData recode check");
    }

    // OpenSSL test cases (as embedded resources)
    doOpenSslDsaTest("unencrypted");
    doOpenSslRsaTest("unencrypted");

    doOpenSslTests("aes128");
    doOpenSslTests("aes192");
    doOpenSslTests("aes256");
    doOpenSslTests("blowfish");
    doOpenSslTests("des1");
    doOpenSslTests("des2");
    doOpenSslTests("des3");
    doOpenSslTests("rc2_128");

    doOpenSslDsaTest("rc2_40_cbc");
    doOpenSslRsaTest("rc2_40_cbc");
    doOpenSslDsaTest("rc2_64_cbc");
    doOpenSslRsaTest("rc2_64_cbc");

    doDudPasswordTest("7fd98", 0, "corrupted stream - out of bounds length found");
    doDudPasswordTest("ef677", 1, "corrupted stream - out of bounds length found");
    doDudPasswordTest("800ce", 2, "unknown tag 26 encountered");
    doDudPasswordTest("b6cd8", 3, "DEF length 81 object truncated by 56");
    doDudPasswordTest("28ce09", 4, "DEF length 110 object truncated by 28");
    doDudPasswordTest("2ac3b9", 5, "DER length more than 4 bytes: 11");
    doDudPasswordTest("2cba96", 6, "DEF length 100 object truncated by 35");
    doDudPasswordTest("2e3354", 7, "DEF length 42 object truncated by 9");
    doDudPasswordTest("2f4142", 8, "DER length more than 4 bytes: 14");
    doDudPasswordTest("2fe9bb", 9, "DER length more than 4 bytes: 65");
    doDudPasswordTest("3ee7a8", 10, "DER length more than 4 bytes: 57");
    doDudPasswordTest("41af75", 11, "unknown tag 16 encountered");
    doDudPasswordTest("1704a5", 12, "corrupted stream detected");
    doDudPasswordTest(
        "1c5822", 13, "unknown object in getInstance: org.mightyfish.asn1.DERUTF8String");
    doDudPasswordTest("5a3d16", 14, "corrupted stream detected");
    doDudPasswordTest("8d0c97", 15, "corrupted stream detected");
    doDudPasswordTest("bc0daf", 16, "corrupted stream detected");
    doDudPasswordTest("aaf9c4d", 17, "corrupted stream - out of bounds length found");

    doNoPasswordTest();

    // encrypted private key test
    InputDecryptorProvider pkcs8Prov =
        new JceOpenSSLPKCS8DecryptorProviderBuilder().build("password".toCharArray());
    pemRd = openPEMResource("enckey.pem");

    PKCS8EncryptedPrivateKeyInfo encPrivKeyInfo = (PKCS8EncryptedPrivateKeyInfo) pemRd.readObject();
    JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");

    RSAPrivateCrtKey privKey =
        (RSAPrivateCrtKey) converter.getPrivateKey(encPrivKeyInfo.decryptPrivateKeyInfo(pkcs8Prov));

    if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) {
      fail("decryption of private key data check failed");
    }

    // general PKCS8 test

    pemRd = openPEMResource("pkcs8test.pem");

    Object privInfo;

    while ((privInfo = pemRd.readObject()) != null) {
      if (privInfo instanceof PrivateKeyInfo) {
        privKey = (RSAPrivateCrtKey) converter.getPrivateKey(PrivateKeyInfo.getInstance(privInfo));
      } else {
        privKey =
            (RSAPrivateCrtKey)
                converter.getPrivateKey(
                    ((PKCS8EncryptedPrivateKeyInfo) privInfo).decryptPrivateKeyInfo(pkcs8Prov));
      }
      if (!privKey.getPublicExponent().equals(new BigInteger("10001", 16))) {
        fail("decryption of private key data check failed");
      }
    }
  }