Example usage for org.bouncycastle.openssl PEMParser readObject

List of usage examples for org.bouncycastle.openssl PEMParser readObject

Introduction

In this page you can find the example usage for org.bouncycastle.openssl PEMParser readObject.

Prototype

public Object readObject() throws IOException 

Source Link

Document

Read the next PEM object attempting to interpret the header and create a higher level object from the content.

Usage

From source file:org.cryptoworkshop.ximix.node.core.XimixNodeContext.java

License:Apache License

public XimixNodeContext(Map<String, ServicesConnection> peerMap, final Config nodeConfig,
        EventNotifier eventNotifier) throws ConfigException {

    this.description = nodeConfig.getConfigObject("description", new DescriptionConfigFactory())
            .getDescription();/*w ww  .ja va 2  s  .  c o m*/

    this.peerMap = Collections.synchronizedMap(new HashMap<>(peerMap));

    this.decouplers.put(Decoupler.BOARD_LISTENER, Executors.newSingleThreadExecutor());
    this.decouplers.put(Decoupler.BOARD_REGISTRY, Executors.newSingleThreadExecutor());
    this.decouplers.put(Decoupler.LISTENER, Executors.newSingleThreadExecutor());
    this.decouplers.put(Decoupler.SERVICES, Executors.newSingleThreadExecutor());
    this.decouplers.put(Decoupler.SHARING, Executors.newSingleThreadExecutor());
    this.decouplers.put(Decoupler.MONITOR, Executors.newSingleThreadExecutor());

    this.eventNotifier = eventNotifier;

    this.name = nodeConfig.getStringProperty("name"); // TODO:
    this.homeDirectory = nodeConfig.getHomeDirectory();

    this.peerMap.remove(this.name);

    this.ecKeyManager = new ECKeyManager(this);
    this.blsKeyManager = new BLSKeyManager(this);
    try {
        this.keyManagerCaStore = KeyStore.getInstance("PKCS12", "BC");
    } catch (GeneralSecurityException e) {
        throw new ConfigException("unable to create key store object: " + e.getMessage(), e);
    }

    if (homeDirectory != null) {
        try {
            PEMParser pParse = new PEMParser(new FileReader(
                    new File(homeDirectory, nodeConfig.getStringProperty("trustAnchor") + ".pem")));

            trustAnchor = new JcaX509CertificateConverter().setProvider("BC")
                    .getCertificate((X509CertificateHolder) pParse.readObject());

            pParse.close();
        } catch (Exception e) {
            throw new ConfigException("unable to read trust anchor: " + e.getMessage(), e);
        }

        try {
            File keyManagerCaStoreFile = new File(homeDirectory,
                    nodeConfig.getStringProperty("keyManagerStore") + ".p12");

            char[] keyManagerPasswd = nodeConfig.getStringProperty("keyManagerPassword").toCharArray();

            keyManagerCaStore.load(new FileInputStream(keyManagerCaStoreFile), keyManagerPasswd);

            setupKeyManager(homeDirectory, keyManagerPasswd, ecKeyManager);
            setupKeyManager(homeDirectory, keyManagerPasswd, blsKeyManager);
        } catch (GeneralSecurityException e) {
            throw new ConfigException("unable to create node key store: " + e.getMessage(), e);
        } catch (IOException e) {
            throw new ConfigException("unable to read node key store: " + e.getMessage(), e);
        }
    } else {
        // running in memory only mode.
        try {
            PEMParser pParse = new PEMParser(new InputStreamReader(this.getClass()
                    .getResourceAsStream("/conf/" + nodeConfig.getStringProperty("trustAnchor") + ".pem")));

            trustAnchor = new JcaX509CertificateConverter().setProvider("BC")
                    .getCertificate((X509CertificateHolder) pParse.readObject());

            pParse.close();
        } catch (Exception e) {
            throw new ConfigException("unable to read trust anchor: " + e.getMessage(), e);
        }

        try {
            char[] keyManagerPasswd = nodeConfig.getStringProperty("keyManagerPassword").toCharArray();

            keyManagerCaStore.load(
                    this.getClass().getResourceAsStream(
                            "/conf/" + nodeConfig.getStringProperty("keyManagerStore") + ".p12"),
                    keyManagerPasswd);
        } catch (GeneralSecurityException e) {
            throw new ConfigException("unable to create node key store: " + e.getMessage(), e);
        } catch (IOException e) {
            throw new ConfigException("unable to read node key store: " + e.getMessage(), e);
        }
    }

    remoteServicesCache = new RemoteServicesCache(this);

    this.listeningSocketInfo = new ListeningSocketInfo(name, nodeConfig.getIntegerProperty("portNo"),
            nodeConfig.getIntegerProperty("portBacklog"), nodeConfig.getStringProperty("portAddress"));

    //
    // we schedule this bit to a new thread as the services require node context as an argument
    // and we want to make sure they are well formed.
    //
    this.getDecoupler(Decoupler.SERVICES).execute(new Runnable() {
        @Override
        public void run() {
            try {
                List<ServiceConfig> configs = nodeConfig.getConfigObjects("services", new NodeConfigFactory());
                for (ServiceConfig config : configs) {
                    if (config.getThrowable() != null) {
                        getEventNotifier().notify(EventNotifier.Level.ERROR, config.getThrowable());
                    }
                }
            } catch (ConfigException e) {
                getEventNotifier().notify(EventNotifier.Level.ERROR, "Configuration error: " + e.getMessage(),
                        e);
            } finally {
                setupCompleteLatch.countDown();
            }
        }
    });
    // now activate our peer connections

    for (final String node : getPeerMap().keySet()) {
        connectionExecutor.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    getPeerMap().get(node).activate();
                } catch (Exception e) {
                    getEventNotifier().notify(EventNotifier.Level.WARN,
                            "Node " + node + " currently unavailable: " + e.getMessage(), e);
                }
            }
        });
    }
}

From source file:org.cryptoworkshop.ximix.test.tests.ShuffleDownloadDecryptionTest.java

License:Apache License

private void doShuffleDownloadTest(int numberOfPoints) throws Exception {
    SquelchingThrowableHandler handler = new SquelchingThrowableHandler();
    handler.squelchType(SocketException.class);

    PEMParser pemParser = new PEMParser(
            new InputStreamReader(this.getClass().getResourceAsStream("/conf/trustCa.pem")));
    X509Certificate trustAnchor;/* w w  w . jav  a  2s.  co  m*/

    try {
        trustAnchor = new JcaX509CertificateConverter().setProvider("BC")
                .getCertificate((X509CertificateHolder) pemParser.readObject());
    } catch (Exception e) {
        throw new IllegalStateException("Can't parse trust anchor.", e);
    }

    //
    // Set up nodes.
    //
    File tmpDir = File.createTempFile("xmx", ".wrk");
    tmpDir.delete();

    tmpDir.mkdir();

    XimixNode nodeOne = getXimixNode(new File(tmpDir, "node1"), "/conf/mixnet.xml", "/conf/node1.xml", handler);
    NodeTestUtil.launch(nodeOne);

    XimixNode nodeTwo = getXimixNode(new File(tmpDir, "node2"), "/conf/mixnet.xml", "/conf/node2.xml", handler);
    NodeTestUtil.launch(nodeTwo);

    XimixNode nodeThree = getXimixNode(new File(tmpDir, "node3"), "/conf/mixnet.xml", "/conf/node3.xml",
            handler);
    NodeTestUtil.launch(nodeThree);

    XimixNode nodeFour = getXimixNode(new File(tmpDir, "node4"), "/conf/mixnet.xml", "/conf/node4.xml",
            handler);
    NodeTestUtil.launch(nodeFour);

    XimixNode nodeFive = getXimixNode(new File(tmpDir, "node5"), "/conf/mixnet.xml", "/conf/node5.xml",
            handler);
    NodeTestUtil.launch(nodeFive);

    SecureRandom random = new SecureRandom();

    XimixRegistrar adminRegistrar = XimixRegistrarFactory
            .createAdminServiceRegistrar(ResourceAnchor.load("/conf/mixnet.xml"), new TestNotifier());

    KeyGenerationService keyGenerationService = adminRegistrar.connect(KeyGenerationService.class);

    KeyGenerationOptions keyGenOptions = new KeyGenerationOptions.Builder(Algorithm.EC_ELGAMAL, "secp256r1")
            .withThreshold(4).withNodes("A", "B", "C", "D", "E").build();

    byte[] encPubKey = keyGenerationService.generatePublicKey("ECKEY", keyGenOptions);

    CommandService commandService = adminRegistrar.connect(CommandService.class);

    commandService.createBoard("FRED", new BoardCreationOptions.Builder("B").build());

    UploadService client = adminRegistrar.connect(UploadService.class);

    final ECPublicKeyParameters pubKey = (ECPublicKeyParameters) PublicKeyFactory.createKey(encPubKey);

    final ECElGamalEncryptor encryptor = new ECElGamalEncryptor();

    encryptor.init(pubKey);

    //
    // Set up plain text and upload encrypted pair.
    //
    final ECPoint[] plainText1 = new ECPoint[numberOfPoints];
    final ECPoint[] plainText2 = new ECPoint[numberOfPoints];
    final Set<ECPoint> plain1 = new HashSet<>();
    final Set<ECPoint> plain2 = new HashSet<>();

    //
    // Encrypt and submit.
    //
    for (int i = 0; i < plainText1.length; i++) {
        plainText1[i] = generatePoint(pubKey.getParameters(), random);
        plainText2[i] = generatePoint(pubKey.getParameters(), random);

        plain1.add(plainText1[i]);
        plain2.add(plainText2[i]);

        PairSequence encrypted = new PairSequence(
                new ECPair[] { encryptor.encrypt(plainText1[i]), encryptor.encrypt(plainText2[i]) });

        client.uploadMessage("FRED", encrypted.getEncoded());
    }

    //
    // Perform shuffle.
    //
    final CountDownLatch shufflerLatch = new CountDownLatch(1);

    final AtomicBoolean shuffleCompleted = new AtomicBoolean(false);
    final AtomicBoolean shuffleFailed = new AtomicBoolean(false);
    final AtomicReference<Thread> shuffleThread = new AtomicReference<>();
    final Map<String, byte[]> seedCommitmentMap = new HashMap<>();

    ShuffleOperationListener shuffleListener = new ShuffleOperationListener() {
        @Override
        public void commit(Map<String, byte[]> seedCommitments) {
            seedCommitmentMap.putAll(seedCommitments);
        }

        @Override
        public void completed() {
            shuffleCompleted.set(true);
            TestUtil.checkThread(shuffleThread);
            shufflerLatch.countDown();
        }

        @Override
        public void status(ShuffleStatus statusObject) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        public void failed(ShuffleStatus errorObject) {
            shuffleFailed.set(true);
            shufflerLatch.countDown();
            TestUtil.checkThread(shuffleThread);
        }
    };

    Operation<ShuffleOperationListener> shuffleOp = commandService.doShuffleAndMove("FRED",
            new ShuffleOptions.Builder(MultiColumnRowTransform.NAME).withKeyID("ECKEY").build(),
            shuffleListener, "A", "C", "D");

    shufflerLatch.await();

    //
    // Fail if operation did not complete in the nominated time frame.
    //
    //TestCase.assertTrue("Shuffle timed out.", shufflerLatch.await(20, TimeUnit.SECONDS));

    //
    // Check that failed and completed methods are exclusive.
    //

    TestCase.assertNotSame("Failed flag and completed flag must be different.", shuffleCompleted.get(),
            shuffleFailed.get());

    //
    // Check for success of shuffle.
    //
    TestCase.assertTrue(shuffleCompleted.get());

    //
    // Check that shuffle did not fail.
    //
    TestCase.assertFalse(shuffleFailed.get());

    Map<String, byte[][]> seedAndWitnessesMap = commandService.downloadShuffleSeedsAndWitnesses("FRED",
            shuffleOp.getOperationNumber(), "A", "C", "D");

    SignedDataVerifier signatureVerifier = new SignedDataVerifier(trustAnchor);

    final CountDownLatch transcriptCompleted = new CountDownLatch(1);

    final Map<Integer, byte[]> generalTranscripts = new TreeMap<>();

    ShuffleTranscriptsDownloadOperationListener transcriptListener = new ShuffleTranscriptsDownloadOperationListener() {
        @Override
        public void shuffleTranscriptArrived(long operationNumber, int stepNumber, InputStream transcript) {
            try {
                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                BufferedInputStream bIn = new BufferedInputStream(transcript);

                int ch;
                while ((ch = bIn.read()) >= 0) {
                    bOut.write(ch);
                }
                bOut.close();

                generalTranscripts.put(stepNumber, bOut.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void completed() {
            transcriptCompleted.countDown();
        }

        @Override
        public void status(String statusObject) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        public void failed(String errorObject) {
            System.err.println("failed: " + errorObject);
            transcriptCompleted.countDown();
        }
    };

    commandService.downloadShuffleTranscripts("FRED", shuffleOp.getOperationNumber(),
            new ShuffleTranscriptOptions.Builder(TranscriptType.GENERAL).build(), transcriptListener, "A", "C",
            "D");

    transcriptCompleted.await();

    LinkIndexVerifier.Builder builder = new LinkIndexVerifier.Builder(numberOfPoints);

    builder.setNetworkSeeds(seedCommitmentMap, seedAndWitnessesMap);

    for (Integer step : generalTranscripts.keySet()) {
        byte[] bytes = generalTranscripts.get(step);

        if (signatureVerifier.signatureVerified(new CMSSignedDataParser(
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), bytes))) {
            builder.addTranscript(new ByteArrayInputStream(bytes));
        } else {
            fail("General commitment check signature failed");
        }
    }

    LinkIndexVerifier linkVerifier = builder.build();

    byte[] challengeSeed = linkVerifier.getChallengeSeed();

    System.err.println("network seed: " + new String(Hex.encode(challengeSeed)));

    for (Integer step : generalTranscripts.keySet()) {
        byte[] bytes = generalTranscripts.get(step);

        if (!signatureVerifier.signatureVerified(new CMSSignedDataParser(
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), bytes))) {
            fail("General commitment check signature failed");
        }
    }

    //
    // added the distributed seed
    //
    final Map<Integer, byte[]> witnessTranscripts = new TreeMap<>();

    final CountDownLatch witnessTranscriptCompleted = new CountDownLatch(1);
    transcriptListener = new ShuffleTranscriptsDownloadOperationListener() {
        @Override
        public void shuffleTranscriptArrived(long operationNumber, int stepNumber, InputStream transcript) {
            try {
                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                BufferedInputStream bIn = new BufferedInputStream(transcript);

                int ch;
                while ((ch = bIn.read()) >= 0) {
                    bOut.write(ch);
                }
                bOut.close();

                witnessTranscripts.put(stepNumber, bOut.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void completed() {
            witnessTranscriptCompleted.countDown();
        }

        @Override
        public void status(String statusObject) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        public void failed(String errorObject) {
            witnessTranscriptCompleted.countDown();
        }
    };

    commandService.downloadShuffleTranscripts("FRED", shuffleOp.getOperationNumber(),
            new ShuffleTranscriptOptions.Builder(TranscriptType.WITNESSES).withChallengeSeed(challengeSeed)
                    .build(),
            transcriptListener, "A", "C", "D");

    witnessTranscriptCompleted.await();

    for (Integer step : witnessTranscripts.keySet()) {
        byte[] bytes = witnessTranscripts.get(step);

        if (!signatureVerifier.signatureVerified(new CMSSignedDataParser(
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), bytes))) {
            fail("Witness commitment check signature failed");
        }
    }

    //
    // verify the witness transcripts are correctly generated
    //
    for (Integer step : witnessTranscripts.keySet()) {
        byte[] bytes = witnessTranscripts.get(step);

        linkVerifier.verify(step, false, new ByteArrayInputStream(bytes));
    }

    //
    // verify the revealed commitments.
    //
    for (Integer key : witnessTranscripts.keySet()) {
        byte[] transcript = witnessTranscripts.get(key);
        byte[] initialTranscript = generalTranscripts.get(key);
        byte[] nextTranscript = generalTranscripts.get(key + 1);

        ECShuffledTranscriptVerifier verifier = new ECShuffledTranscriptVerifier(pubKey,
                new ByteArrayInputStream(transcript), new ByteArrayInputStream(initialTranscript),
                new ByteArrayInputStream(nextTranscript));

        verifier.verify();
    }

    System.err.println("transcripts verified");

    Map<String, InputStream> streamSeedCommitments = new HashMap<>();
    for (String key : seedCommitmentMap.keySet()) {
        streamSeedCommitments.put(key, new ByteArrayInputStream(seedCommitmentMap.get(key)));
    }

    Map<String, InputStream> streamSeedsAndWitnesses = new HashMap<>();
    for (String key : seedAndWitnessesMap.keySet()) {
        byte[][] sAndW = seedAndWitnessesMap.get(key);
        streamSeedsAndWitnesses.put(key,
                new ByteArrayInputStream(new SeedAndWitnessMessage(sAndW[0], sAndW[1]).getEncoded()));
    }

    Map<Integer, InputStream> streamWitnessTranscripts = new HashMap<>();
    for (Integer key : witnessTranscripts.keySet()) {
        streamWitnessTranscripts.put(key, new ByteArrayInputStream(witnessTranscripts.get(key)));
    }

    Map<Integer, InputStream> streamGeneralTranscripts = new HashMap<>();
    for (Integer key : generalTranscripts.keySet()) {
        streamGeneralTranscripts.put(key, new ByteArrayInputStream(generalTranscripts.get(key)));
    }

    final CountDownLatch shuffleOutputDownloadCompleted = new CountDownLatch(1);

    commandService.downloadShuffleResult("FRED",
            new DownloadShuffleResultOptions.Builder().withKeyID("ECKEY").withThreshold(4)
                    .withPairingEnabled(true).withNodes("A", "B", "C", "D").build(),
            streamSeedCommitments, streamSeedsAndWitnesses, streamGeneralTranscripts, streamWitnessTranscripts,
            new DownloadOperationListener() {
                @Override
                public void messageDownloaded(int index, byte[] message, List<byte[]> proofs) {
                    PointSequence decrypted = PointSequence.getInstance(pubKey.getParameters().getCurve(),
                            message);

                    Assert.assertTrue(plain1.remove(decrypted.getECPoints()[0])
                            && plain2.remove(decrypted.getECPoints()[1]));
                }

                @Override
                public void completed() {
                    shuffleOutputDownloadCompleted.countDown();
                }

                @Override
                public void status(String statusObject) {
                    System.err.println("status: " + statusObject);
                }

                @Override
                public void failed(String errorObject) {
                    shuffleOutputDownloadCompleted.countDown();
                    System.err.println("failed " + errorObject);
                }
            });

    shuffleOutputDownloadCompleted.await();

    TestCase.assertTrue(plain1.isEmpty());
    TestCase.assertTrue(plain2.isEmpty());

    NodeTestUtil.shutdownNodes();
    client.shutdown();
    commandService.shutdown();

    delete(tmpDir);
}

From source file:org.cryptoworkshop.ximix.test.tests.ShuffleDownloadDecryptionTest.java

License:Apache License

private void doTestWithPairingFlag(int numberOfPoints, boolean isPairingEnabled) throws Exception {
    SquelchingThrowableHandler handler = new SquelchingThrowableHandler();
    handler.squelchType(SocketException.class);

    PEMParser pemParser = new PEMParser(
            new InputStreamReader(this.getClass().getResourceAsStream("/conf/trustCa.pem")));
    X509Certificate trustAnchor;//from  ww  w .  j  a va  2s  .  c  om

    try {
        trustAnchor = new JcaX509CertificateConverter().setProvider("BC")
                .getCertificate((X509CertificateHolder) pemParser.readObject());
    } catch (Exception e) {
        throw new IllegalStateException("Can't parse trust anchor.", e);
    }

    //
    // Set up nodes.
    //
    File tmpDir = File.createTempFile("xmx", ".wrk");
    tmpDir.delete();

    tmpDir.mkdir();

    XimixNode nodeOne = getXimixNode(new File(tmpDir, "node1"), "/conf/mixnet.xml", "/conf/node1.xml", handler);
    NodeTestUtil.launch(nodeOne);

    XimixNode nodeTwo = getXimixNode(new File(tmpDir, "node2"), "/conf/mixnet.xml", "/conf/node2.xml", handler);
    NodeTestUtil.launch(nodeTwo);

    XimixNode nodeThree = getXimixNode(new File(tmpDir, "node3"), "/conf/mixnet.xml", "/conf/node3.xml",
            handler);
    NodeTestUtil.launch(nodeThree);

    XimixNode nodeFour = getXimixNode(new File(tmpDir, "node4"), "/conf/mixnet.xml", "/conf/node4.xml",
            handler);
    NodeTestUtil.launch(nodeFour);

    XimixNode nodeFive = getXimixNode(new File(tmpDir, "node5"), "/conf/mixnet.xml", "/conf/node5.xml",
            handler);
    NodeTestUtil.launch(nodeFive);

    SecureRandom random = new SecureRandom();

    XimixRegistrar adminRegistrar = XimixRegistrarFactory
            .createAdminServiceRegistrar(ResourceAnchor.load("/conf/mixnet.xml"), new TestNotifier());

    KeyGenerationService keyGenerationService = adminRegistrar.connect(KeyGenerationService.class);

    KeyGenerationOptions keyGenOptions = new KeyGenerationOptions.Builder(Algorithm.EC_ELGAMAL, "secp256r1")
            .withThreshold(4).withNodes("A", "B", "C", "D", "E").build();

    byte[] encPubKey = keyGenerationService.generatePublicKey("ECKEY", keyGenOptions);

    CommandService commandService = adminRegistrar.connect(CommandService.class);

    commandService.createBoard("FRED", new BoardCreationOptions.Builder("B").build());

    UploadService client = adminRegistrar.connect(UploadService.class);

    final ECPublicKeyParameters pubKey = (ECPublicKeyParameters) PublicKeyFactory.createKey(encPubKey);

    final ECElGamalEncryptor encryptor = new ECElGamalEncryptor();

    encryptor.init(pubKey);

    //
    // Set up plain text and upload encrypted pair.
    //
    final ECPoint[] plainText1 = new ECPoint[numberOfPoints];
    final ECPoint[] plainText2 = new ECPoint[numberOfPoints];
    final Set<ECPoint> plain1 = new HashSet<>();
    final Set<ECPoint> plain2 = new HashSet<>();

    //
    // Encrypt and submit.
    //
    for (int i = 0; i < plainText1.length; i++) {
        plainText1[i] = generatePoint(pubKey.getParameters(), random);
        plainText2[i] = generatePoint(pubKey.getParameters(), random);

        plain1.add(plainText1[i]);
        plain2.add(plainText2[i]);

        PairSequence encrypted = new PairSequence(
                new ECPair[] { encryptor.encrypt(plainText1[i]), encryptor.encrypt(plainText2[i]) });

        client.uploadMessage("FRED", encrypted.getEncoded());
    }

    //
    // Perform shuffle.
    //
    final CountDownLatch shufflerLatch = new CountDownLatch(1);

    final AtomicBoolean shuffleCompleted = new AtomicBoolean(false);
    final AtomicBoolean shuffleFailed = new AtomicBoolean(false);
    final AtomicReference<Thread> shuffleThread = new AtomicReference<>();
    final Map<String, byte[]> seedCommitmentMap = new HashMap<>();

    ShuffleOperationListener shuffleListener = new ShuffleOperationListener() {
        @Override
        public void commit(Map<String, byte[]> seedCommitments) {
            seedCommitmentMap.putAll(seedCommitments);
        }

        @Override
        public void completed() {
            shuffleCompleted.set(true);
            TestUtil.checkThread(shuffleThread);
            shufflerLatch.countDown();
        }

        @Override
        public void status(ShuffleStatus statusObject) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        public void failed(ShuffleStatus errorObject) {
            shuffleFailed.set(true);
            shufflerLatch.countDown();
            TestUtil.checkThread(shuffleThread);
        }
    };

    Operation<ShuffleOperationListener> shuffleOp = commandService.doShuffleAndMove("FRED",
            new ShuffleOptions.Builder(MultiColumnRowTransform.NAME).withKeyID("ECKEY").build(),
            shuffleListener, "A", "A", "C", "D");

    shufflerLatch.await();

    //
    // Fail if operation did not complete in the nominated time frame.
    //
    //TestCase.assertTrue("Shuffle timed out.", shufflerLatch.await(20, TimeUnit.SECONDS));

    //
    // Check that failed and completed methods are exclusive.
    //

    TestCase.assertNotSame("Failed flag and completed flag must be different.", shuffleCompleted.get(),
            shuffleFailed.get());

    //
    // Check for success of shuffle.
    //
    TestCase.assertTrue(shuffleCompleted.get());

    //
    // Check that shuffle did not fail.
    //
    TestCase.assertFalse(shuffleFailed.get());

    Map<String, byte[][]> seedAndWitnessesMap = commandService.downloadShuffleSeedsAndWitnesses("FRED",
            shuffleOp.getOperationNumber(), "A", "C", "D");

    SignedDataVerifier signatureVerifier = new SignedDataVerifier(trustAnchor);

    final CountDownLatch transcriptCompleted = new CountDownLatch(1);

    final Map<Integer, byte[]> generalTranscripts = new TreeMap<>();

    ShuffleTranscriptsDownloadOperationListener transcriptListener = new ShuffleTranscriptsDownloadOperationListener() {
        @Override
        public void shuffleTranscriptArrived(long operationNumber, int stepNumber, InputStream transcript) {
            try {
                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                BufferedInputStream bIn = new BufferedInputStream(transcript);

                int ch;
                while ((ch = bIn.read()) >= 0) {
                    bOut.write(ch);
                }
                bOut.close();

                generalTranscripts.put(stepNumber, bOut.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void completed() {
            transcriptCompleted.countDown();
        }

        @Override
        public void status(String statusObject) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        public void failed(String errorObject) {
            System.err.println("failed: " + errorObject);
            transcriptCompleted.countDown();
        }
    };

    commandService.downloadShuffleTranscripts("FRED", shuffleOp.getOperationNumber(),
            new ShuffleTranscriptOptions.Builder(TranscriptType.GENERAL).withPairingEnabled(isPairingEnabled)
                    .build(),
            transcriptListener, "A", "C", "D");

    transcriptCompleted.await();

    LinkIndexVerifier.Builder builder = new LinkIndexVerifier.Builder(numberOfPoints);

    builder.setNetworkSeeds(seedCommitmentMap, seedAndWitnessesMap);

    for (Integer step : generalTranscripts.keySet()) {
        byte[] bytes = generalTranscripts.get(step);

        if (signatureVerifier.signatureVerified(new CMSSignedDataParser(
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), bytes))) {
            builder.addTranscript(new ByteArrayInputStream(bytes));
        } else {
            fail("General commitment check signature failed");
        }
    }

    LinkIndexVerifier linkVerifier = builder.build();

    byte[] challengeSeed = linkVerifier.getChallengeSeed();

    System.err.println("network seed: " + new String(Hex.encode(challengeSeed)));

    for (Integer step : generalTranscripts.keySet()) {
        byte[] bytes = generalTranscripts.get(step);

        if (!signatureVerifier.signatureVerified(new CMSSignedDataParser(
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), bytes))) {
            fail("General commitment check signature failed");
        }
    }

    //
    // added the distributed seed
    //
    final Map<Integer, byte[]> witnessTranscripts = new TreeMap<>();

    final CountDownLatch witnessTranscriptCompleted = new CountDownLatch(1);
    transcriptListener = new ShuffleTranscriptsDownloadOperationListener() {
        @Override
        public void shuffleTranscriptArrived(long operationNumber, int stepNumber, InputStream transcript) {
            try {
                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                BufferedInputStream bIn = new BufferedInputStream(transcript);

                int ch;
                while ((ch = bIn.read()) >= 0) {
                    bOut.write(ch);
                }
                bOut.close();

                witnessTranscripts.put(stepNumber, bOut.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void completed() {
            witnessTranscriptCompleted.countDown();
        }

        @Override
        public void status(String statusObject) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        public void failed(String errorObject) {
            witnessTranscriptCompleted.countDown();
        }
    };

    commandService
            .downloadShuffleTranscripts("FRED", shuffleOp.getOperationNumber(),
                    new ShuffleTranscriptOptions.Builder(TranscriptType.WITNESSES)
                            .withChallengeSeed(challengeSeed).withPairingEnabled(isPairingEnabled).build(),
                    transcriptListener, "A", "C", "D");

    witnessTranscriptCompleted.await();

    for (Integer step : witnessTranscripts.keySet()) {
        byte[] bytes = witnessTranscripts.get(step);

        if (!signatureVerifier.signatureVerified(new CMSSignedDataParser(
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), bytes))) {
            System.err.println("Witness commitment check signature failed");
        }
    }

    //
    // verify the witness transcripts are correctly generated
    //
    for (Integer step : witnessTranscripts.keySet()) {
        byte[] bytes = witnessTranscripts.get(step);

        linkVerifier.verify(step, isPairingEnabled, new ByteArrayInputStream(bytes));
    }

    //
    // verify the revealed commitments.
    //
    for (Integer key : witnessTranscripts.keySet()) {
        byte[] transcript = witnessTranscripts.get(key);
        byte[] initialTranscript = generalTranscripts.get(key);
        byte[] nextTranscript = generalTranscripts.get(key + 1);

        ECShuffledTranscriptVerifier verifier = new ECShuffledTranscriptVerifier(pubKey,
                new ByteArrayInputStream(transcript), new ByteArrayInputStream(initialTranscript),
                new ByteArrayInputStream(nextTranscript));

        verifier.verify();
    }

    Map<String, InputStream> streamSeedCommitments = new HashMap<>();
    for (String key : seedCommitmentMap.keySet()) {
        streamSeedCommitments.put(key, new ByteArrayInputStream(seedCommitmentMap.get(key)));
    }

    Map<String, InputStream> streamSeedsAndWitnesses = new HashMap<>();
    for (String key : seedAndWitnessesMap.keySet()) {
        byte[][] sAndW = seedAndWitnessesMap.get(key);
        streamSeedsAndWitnesses.put(key,
                new ByteArrayInputStream(new SeedAndWitnessMessage(sAndW[0], sAndW[1]).getEncoded()));
    }

    Map<Integer, InputStream> streamWitnessTranscripts = new HashMap<>();
    for (Integer key : witnessTranscripts.keySet()) {
        streamWitnessTranscripts.put(key, new ByteArrayInputStream(witnessTranscripts.get(key)));
    }

    Map<Integer, InputStream> streamGeneralTranscripts = new HashMap<>();
    for (Integer key : generalTranscripts.keySet()) {
        streamGeneralTranscripts.put(key, new ByteArrayInputStream(generalTranscripts.get(key)));
    }

    final CountDownLatch shuffleOutputDownloadCompleted = new CountDownLatch(1);

    commandService.downloadShuffleResult("FRED",
            new DownloadShuffleResultOptions.Builder().withKeyID("ECKEY").withThreshold(4)
                    .withPairingEnabled(isPairingEnabled).withNodes("A", "B", "C", "D").build(),
            streamSeedCommitments, streamSeedsAndWitnesses, streamGeneralTranscripts, streamWitnessTranscripts,
            new DownloadOperationListener() {
                @Override
                public void messageDownloaded(int index, byte[] message, List<byte[]> proofs) {
                    PointSequence decrypted = PointSequence.getInstance(pubKey.getParameters().getCurve(),
                            message);

                    Assert.assertTrue(plain1.remove(decrypted.getECPoints()[0])
                            && plain2.remove(decrypted.getECPoints()[1]));
                }

                @Override
                public void completed() {
                    shuffleOutputDownloadCompleted.countDown();
                }

                @Override
                public void status(String statusObject) {
                    System.err.println("status: " + statusObject);
                }

                @Override
                public void failed(String errorObject) {
                    shuffleOutputDownloadCompleted.countDown();
                    System.err.println("failed " + errorObject);
                }
            });

    shuffleOutputDownloadCompleted.await();

    TestCase.assertTrue(plain1.isEmpty());
    TestCase.assertTrue(plain2.isEmpty());

    NodeTestUtil.shutdownNodes();
    client.shutdown();
    commandService.shutdown();

    delete(tmpDir);
}

From source file:org.dataone.proto.trove.net.SocketFactoryManager.java

License:Apache License

/**
 * Load PEM file contents into in-memory keystore NOTE: this implementation uses Bouncy Castle security provider
 *
 * @return the keystore that will provide the material
 * @throws KeyStoreException//from   w w w .  j ava  2s.c  o m
 * @throws CertificateException
 * @throws NoSuchAlgorithmException
 * @throws IOException
 */
private KeyStore getKeyStore()
        throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {

    // if the location has been set, use it
    KeyStore keyStore = null;
    Object pemObject = null;

    keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, keyStorePassword.toCharArray());

    // get the private key and certificate from the PEM
    // TODO: find a way to do this with default Java provider (not Bouncy Castle)?
    Security.addProvider(new BouncyCastleProvider());
    PEMParser pemReader = new PEMParser(new FileReader(clientCertificateLocation));

    X509Certificate certificate = null;
    PrivateKey privateKey = null;
    KeyPair keyPair = null;

    while ((pemObject = pemReader.readObject()) != null) {
        if (pemObject instanceof PrivateKey) {
            privateKey = (PrivateKey) pemObject;
        } else if (pemObject instanceof KeyPair) {
            keyPair = (KeyPair) pemObject;
            privateKey = keyPair.getPrivate();
        } else if (pemObject instanceof X509Certificate) {
            certificate = (X509Certificate) pemObject;
        }
    }
    if (certificate == null) {
        log.warn("Certificate is null");
    } else {
        if (certificate.getSubjectX500Principal().getName(X500Principal.RFC2253)
                .equals(certificate.getIssuerX500Principal().getName(X500Principal.RFC2253))) {
            log.warn("Certificate is Self Signed");
        }
    }
    Certificate[] chain = new Certificate[] { certificate };

    // set the entry
    keyStore.setKeyEntry("cilogon", privateKey, keyStorePassword.toCharArray(), chain);

    return keyStore;

}

From source file:org.elasticsearch.xpack.core.ssl.CertificateGenerateToolTests.java

License:Open Source License

public void testGeneratingSignedCertificates() throws Exception {
    Path tempDir = initTempDir();
    Path outputFile = tempDir.resolve("out.zip");
    Path instanceFile = writeInstancesTo(tempDir.resolve("instances.yml"));
    Collection<CertificateInformation> certInfos = CertificateGenerateTool.parseFile(instanceFile);
    assertEquals(4, certInfos.size());/*from  w  w  w .j av a  2s  . co  m*/

    final int keysize = randomFrom(1024, 2048);
    final int days = randomIntBetween(1, 1024);
    KeyPair keyPair = CertGenUtils.generateKeyPair(keysize);
    X509Certificate caCert = CertGenUtils.generateCACertificate(new X500Principal("CN=test ca"), keyPair, days);

    final boolean generatedCa = randomBoolean();
    final char[] keyPassword = randomBoolean() ? SecuritySettingsSourceField.TEST_PASSWORD.toCharArray() : null;
    final char[] pkcs12Password = randomBoolean() ? randomAlphaOfLengthBetween(1, 12).toCharArray() : null;
    assertFalse(Files.exists(outputFile));
    CAInfo caInfo = new CAInfo(caCert, keyPair.getPrivate(), generatedCa, keyPassword);
    CertificateGenerateTool.generateAndWriteSignedCertificates(outputFile, certInfos, caInfo, keysize, days,
            pkcs12Password);
    assertTrue(Files.exists(outputFile));

    Set<PosixFilePermission> perms = Files.getPosixFilePermissions(outputFile);
    assertTrue(perms.toString(), perms.contains(PosixFilePermission.OWNER_READ));
    assertTrue(perms.toString(), perms.contains(PosixFilePermission.OWNER_WRITE));
    assertEquals(perms.toString(), 2, perms.size());

    FileSystem fileSystem = FileSystems.newFileSystem(new URI("jar:" + outputFile.toUri()),
            Collections.emptyMap());
    Path zipRoot = fileSystem.getPath("/");

    if (generatedCa) {
        assertTrue(Files.exists(zipRoot.resolve("ca")));
        assertTrue(Files.exists(zipRoot.resolve("ca").resolve("ca.crt")));
        assertTrue(Files.exists(zipRoot.resolve("ca").resolve("ca.key")));
        // check the CA cert
        try (InputStream input = Files.newInputStream(zipRoot.resolve("ca").resolve("ca.crt"))) {
            X509Certificate parsedCaCert = readX509Certificate(input);
            assertThat(parsedCaCert.getSubjectX500Principal().getName(), containsString("test ca"));
            assertEquals(caCert, parsedCaCert);
            long daysBetween = ChronoUnit.DAYS.between(caCert.getNotBefore().toInstant(),
                    caCert.getNotAfter().toInstant());
            assertEquals(days, (int) daysBetween);
        }

        // check the CA key
        if (keyPassword != null) {
            try (Reader reader = Files.newBufferedReader(zipRoot.resolve("ca").resolve("ca.key"))) {
                PEMParser pemParser = new PEMParser(reader);
                Object parsed = pemParser.readObject();
                assertThat(parsed, instanceOf(PEMEncryptedKeyPair.class));
                char[] zeroChars = new char[keyPassword.length];
                Arrays.fill(zeroChars, (char) 0);
                assertArrayEquals(zeroChars, keyPassword);
            }
        }

        PrivateKey privateKey = PemUtils.readPrivateKey(zipRoot.resolve("ca").resolve("ca.key"),
                () -> keyPassword != null ? SecuritySettingsSourceField.TEST_PASSWORD.toCharArray() : null);
        assertEquals(caInfo.privateKey, privateKey);
    } else {
        assertFalse(Files.exists(zipRoot.resolve("ca")));
    }

    for (CertificateInformation certInfo : certInfos) {
        String filename = certInfo.name.filename;
        assertTrue(Files.exists(zipRoot.resolve(filename)));
        final Path cert = zipRoot.resolve(filename + "/" + filename + ".crt");
        assertTrue(Files.exists(cert));
        assertTrue(Files.exists(zipRoot.resolve(filename + "/" + filename + ".key")));
        final Path p12 = zipRoot.resolve(filename + "/" + filename + ".p12");
        try (InputStream input = Files.newInputStream(cert)) {
            X509Certificate certificate = readX509Certificate(input);
            assertEquals(certInfo.name.x500Principal.toString(),
                    certificate.getSubjectX500Principal().getName());
            final int sanCount = certInfo.ipAddresses.size() + certInfo.dnsNames.size()
                    + certInfo.commonNames.size();
            if (sanCount == 0) {
                assertNull(certificate.getSubjectAlternativeNames());
            } else {
                X509CertificateHolder x509CertHolder = new X509CertificateHolder(certificate.getEncoded());
                GeneralNames subjAltNames = GeneralNames.fromExtensions(x509CertHolder.getExtensions(),
                        Extension.subjectAlternativeName);
                assertSubjAltNames(subjAltNames, certInfo);
            }
            if (pkcs12Password != null) {
                assertThat(p12, pathExists(p12));
                try (InputStream in = Files.newInputStream(p12)) {
                    final KeyStore ks = KeyStore.getInstance("PKCS12");
                    ks.load(in, pkcs12Password);
                    final Certificate p12Certificate = ks.getCertificate(certInfo.name.originalName);
                    assertThat("Certificate " + certInfo.name, p12Certificate, notNullValue());
                    assertThat(p12Certificate, equalTo(certificate));
                    final Key key = ks.getKey(certInfo.name.originalName, pkcs12Password);
                    assertThat(key, notNullValue());
                }
            } else {
                assertThat(p12, not(pathExists(p12)));
            }
        }
    }
}

From source file:org.elasticsearch.xpack.core.ssl.CertificateToolTests.java

License:Open Source License

public void testGeneratingSignedPemCertificates() throws Exception {
    Path tempDir = initTempDir();
    Path outputFile = tempDir.resolve("out.zip");
    Path instanceFile = writeInstancesTo(tempDir.resolve("instances.yml"));
    Collection<CertificateInformation> certInfos = CertificateTool.parseFile(instanceFile);
    assertEquals(4, certInfos.size());//  ww  w.  ja va2  s . com

    int keySize = randomFrom(1024, 2048);
    int days = randomIntBetween(1, 1024);

    KeyPair keyPair = CertGenUtils.generateKeyPair(keySize);
    X509Certificate caCert = CertGenUtils.generateCACertificate(new X500Principal("CN=test ca"), keyPair, days);

    final boolean generatedCa = randomBoolean();
    final boolean keepCaKey = generatedCa && randomBoolean();
    final String keyPassword = randomBoolean() ? SecuritySettingsSourceField.TEST_PASSWORD : null;

    assertFalse(Files.exists(outputFile));
    CAInfo caInfo = new CAInfo(caCert, keyPair.getPrivate(), generatedCa,
            keyPassword == null ? null : keyPassword.toCharArray());
    final GenerateCertificateCommand command = new GenerateCertificateCommand();
    List<String> args = CollectionUtils.arrayAsArrayList("-keysize", String.valueOf(keySize), "-days",
            String.valueOf(days), "-pem");
    if (keyPassword != null) {
        args.add("-pass");
        args.add(keyPassword);
    }
    if (keepCaKey) {
        args.add("-keep-ca-key");
    }
    final OptionSet options = command.getParser().parse(Strings.toStringArray(args));

    command.generateAndWriteSignedCertificates(outputFile, true, options, certInfos, caInfo, null);
    assertTrue(Files.exists(outputFile));

    Set<PosixFilePermission> perms = Files.getPosixFilePermissions(outputFile);
    assertTrue(perms.toString(), perms.contains(PosixFilePermission.OWNER_READ));
    assertTrue(perms.toString(), perms.contains(PosixFilePermission.OWNER_WRITE));
    assertEquals(perms.toString(), 2, perms.size());

    FileSystem fileSystem = FileSystems.newFileSystem(new URI("jar:" + outputFile.toUri()),
            Collections.emptyMap());
    Path zipRoot = fileSystem.getPath("/");

    if (generatedCa) {
        assertTrue(Files.exists(zipRoot.resolve("ca")));
        assertTrue(Files.exists(zipRoot.resolve("ca").resolve("ca.crt")));
        // check the CA cert
        try (InputStream input = Files.newInputStream(zipRoot.resolve("ca").resolve("ca.crt"))) {
            X509Certificate parsedCaCert = readX509Certificate(input);
            assertThat(parsedCaCert.getSubjectX500Principal().getName(), containsString("test ca"));
            assertEquals(caCert, parsedCaCert);
            long daysBetween = getDurationInDays(caCert);
            assertEquals(days, (int) daysBetween);
        }

        if (keepCaKey) {
            assertTrue(Files.exists(zipRoot.resolve("ca").resolve("ca.key")));
            // check the CA key
            if (keyPassword != null) {
                try (Reader reader = Files.newBufferedReader(zipRoot.resolve("ca").resolve("ca.key"))) {
                    PEMParser pemParser = new PEMParser(reader);
                    Object parsed = pemParser.readObject();
                    assertThat(parsed, instanceOf(PEMEncryptedKeyPair.class));
                    char[] zeroChars = new char[caInfo.password.length];
                    Arrays.fill(zeroChars, (char) 0);
                    assertArrayEquals(zeroChars, caInfo.password);
                }
            }

            PrivateKey privateKey = PemUtils.readPrivateKey(zipRoot.resolve("ca").resolve("ca.key"),
                    () -> keyPassword != null ? keyPassword.toCharArray() : null);
            assertEquals(caInfo.certAndKey.key, privateKey);
        }
    } else {
        assertFalse(Files.exists(zipRoot.resolve("ca")));
    }

    for (CertificateInformation certInfo : certInfos) {
        String filename = certInfo.name.filename;
        assertTrue(Files.exists(zipRoot.resolve(filename)));
        final Path cert = zipRoot.resolve(filename + "/" + filename + ".crt");
        assertTrue(Files.exists(cert));
        assertTrue(Files.exists(zipRoot.resolve(filename + "/" + filename + ".key")));
        final Path p12 = zipRoot.resolve(filename + "/" + filename + ".p12");
        try (InputStream input = Files.newInputStream(cert)) {
            X509Certificate certificate = readX509Certificate(input);
            assertEquals(certInfo.name.x500Principal.toString(),
                    certificate.getSubjectX500Principal().getName());
            final int sanCount = certInfo.ipAddresses.size() + certInfo.dnsNames.size()
                    + certInfo.commonNames.size();
            if (sanCount == 0) {
                assertNull(certificate.getSubjectAlternativeNames());
            } else {
                X509CertificateHolder x509CertHolder = new X509CertificateHolder(certificate.getEncoded());
                GeneralNames subjAltNames = GeneralNames.fromExtensions(x509CertHolder.getExtensions(),
                        Extension.subjectAlternativeName);
                assertSubjAltNames(subjAltNames, certInfo);
            }
            assertThat(p12, Matchers.not(TestMatchers.pathExists(p12)));
        }
    }
}

From source file:org.hyperledger.fabric.sdk.security.CryptoPrimitivesTest.java

License:Open Source License

@Before
public void setUp() throws Exception {
    // TODO should do this in @BeforeClass. Need to find out how to get to
    // files from static junit method
    BufferedInputStream bis = new BufferedInputStream(this.getClass().getResourceAsStream("/ca.crt"));
    testCACert = cf.generateCertificate(bis);
    bis.close();//from  w w  w  .j  a v  a 2  s  .com
    crypto.addCACertificateToTrustStore(testCACert, "ca");

    bis = new BufferedInputStream(this.getClass().getResourceAsStream("/keypair-signed.crt"));
    Certificate cert = cf.generateCertificate(bis);
    bis.close();

    // TODO: get PEM file without dropping down to BouncyCastle ?
    PEMParser pem = new PEMParser(new FileReader(this.getClass().getResource("/keypair-signed.key").getFile()));
    PEMKeyPair bcKeyPair = (PEMKeyPair) pem.readObject();
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bcKeyPair.getPrivateKeyInfo().getEncoded());
    PrivateKey key = kf.generatePrivate(keySpec);

    Certificate[] certificates = new Certificate[] { cert, testCACert };
    crypto.getTrustStore().setKeyEntry("key", key, "123456".toCharArray(), certificates);
    pem.close();
}

From source file:org.hyperledger.fabric_ca.sdkintegration.HFCAClientIT.java

License:Apache License

TBSCertList.CRLEntry[] parseCRL(String crl) throws Exception {

    Base64.Decoder b64dec = Base64.getDecoder();
    final byte[] decode = b64dec.decode(crl.getBytes(UTF_8));

    PEMParser pem = new PEMParser(new StringReader(new String(decode)));
    X509CRLHolder holder = (X509CRLHolder) pem.readObject();

    return holder.toASN1Structure().getRevokedCertificates();
}

From source file:org.jclouds.docker.suppliers.SSLContextBuilder.java

License:Apache License

private static PrivateKey getKey(String privateKey) {
    PEMParser pemParser = new PEMParser(new StringReader(privateKey));
    try {//from   ww  w .  j  av  a2s  .  com
        Object object = pemParser.readObject();
        if (Security.getProvider("BC") == null) {
            Security.addProvider(new BouncyCastleProvider());
        }
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        KeyPair keyPair = converter.getKeyPair((PEMKeyPair) object);
        return keyPair.getPrivate();
    } catch (IOException ex) {
        throw new RuntimeException("Invalid private key", ex);
    } finally {
        Closeables2.closeQuietly(pemParser);
    }
}

From source file:org.jclouds.docker.suppliers.SSLContextWithKeysSupplier.java

License:Apache License

private static PrivateKey getKey(String privateKey) {

    try {//ww w  .j  a  v  a2s .com
        PEMParser pemParser = new PEMParser(new StringReader(privateKey));
        Object object = pemParser.readObject();
        if (Security.getProvider("BC") == null) {
            Security.addProvider(new BouncyCastleProvider());
        }
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        KeyPair keyPair = converter.getKeyPair((PEMKeyPair) object);
        return keyPair.getPrivate();
    } catch (IOException ex) {
        throw new RuntimeException("Invalid private key", ex);
    }
}