@SuppressWarnings( "unchecked" ) private static Iterator<PGPPublicKeyEncryptedData> getEncryptedObjects( final byte[] message ) throws IOException { try { final PGPObjectFactory factory = new PGPObjectFactory( PGPUtil.getDecoderStream( new ByteArrayInputStream( message ) ), new JcaKeyFingerprintCalculator() ); final Object first = factory.nextObject(); final Object list = ( first instanceof PGPEncryptedDataList ) ? first : factory.nextObject(); return ( ( PGPEncryptedDataList ) list ).getEncryptedDataObjects(); } catch ( IOException e ) { throw new IOException( e ); } }
public PGPPublicKeyRing getPublicKey(final InputStream in) { Object obj; try { final PGPObjectFactory pgpFact = new PGPObjectFactory( PGPUtil.getDecoderStream(in)); obj = pgpFact.nextObject(); } catch (final Exception e) { throw new IllegalStateException(e); } if (obj instanceof PGPPublicKeyRing) { final PGPPublicKeyRing keyRing = (PGPPublicKeyRing) obj; rememberKey(keyRing); return keyRing; } throw new IllegalStateException("Pblic key not available"); }
/** * Opens a new {@link Decryptor} (Reading Step 1/3) * * <p>This is the first step in opening a ghostryde file. After this method, you'll want to * call {@link #openDecompressor(Decryptor)}. * * @param input is an {@link InputStream} of the ghostryde file data. * @param privateKey is the private encryption key of the recipient (which is us!) * @throws IOException * @throws PGPException */ @CheckReturnValue public Decryptor openDecryptor(@WillNotClose InputStream input, PGPPrivateKey privateKey) throws IOException, PGPException { checkNotNull(privateKey, "privateKey"); PGPObjectFactory fact = new BcPGPObjectFactory(checkNotNull(input, "input")); PGPEncryptedDataList crypts = pgpCast(fact.nextObject(), PGPEncryptedDataList.class); checkState(crypts.size() > 0); if (crypts.size() > 1) { logger.warningfmt("crypts.size() is %d (should be 1)", crypts.size()); } PGPPublicKeyEncryptedData crypt = pgpCast(crypts.get(0), PGPPublicKeyEncryptedData.class); if (crypt.getKeyID() != privateKey.getKeyID()) { throw new PGPException(String.format( "Message was encrypted for keyid %x but ours is %x", crypt.getKeyID(), privateKey.getKeyID())); } return new Decryptor( crypt.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey)), crypt); }
@Test public void testCompressDecompress() throws Exception { // Compress the data and write out a compressed data OpenPGP message. byte[] data; try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { PGPCompressedDataGenerator kompressor = new PGPCompressedDataGenerator(ZIP); try (OutputStream output2 = kompressor.open(output)) { output2.write(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); } data = output.toByteArray(); } logger.info("Compressed data: " + dumpHex(data)); // Decompress the data. try (ByteArrayInputStream input = new ByteArrayInputStream(data)) { PGPObjectFactory pgpFact = new BcPGPObjectFactory(input); PGPCompressedData object = (PGPCompressedData) pgpFact.nextObject(); InputStream original = object.getDataStream(); // Closing this would close input. assertThat(CharStreams.toString(new InputStreamReader(original, UTF_8))) .isEqualTo(FALL_OF_HYPERION_A_DREAM); assertThat(pgpFact.nextObject()).isNull(); } }
/** * Verify a PGP signature. * * @param file the file * @param signature the signature * @param key the public key * @return true if the signature is verified * @throws Exception anything preventing the verification to happen */ public static boolean verifySignature( InputStream file, InputStream signature, PGPPublicKey key) throws Exception { InputStream sigInputStream = PGPUtil.getDecoderStream(signature); PGPObjectFactory pgpObjectFactory = new PGPObjectFactory(sigInputStream, new BcKeyFingerprintCalculator()); PGPSignatureList sigList = (PGPSignatureList) pgpObjectFactory.nextObject(); PGPSignature pgpSignature = sigList.get(0); pgpSignature.init(new BcPGPContentVerifierBuilderProvider(), key); try (InputStream inArtifact = new BufferedInputStream(file)) { int t; while ((t = inArtifact.read()) >= 0) { pgpSignature.update((byte) t); } } return pgpSignature.verify(); }
public OpenPGPSecretKey(String keyId, InputStream secretKeyRing, char[] password) throws IOException { PGPObjectFactory pgpObjectFactory = new BcPGPObjectFactory(PGPUtil.getDecoderStream(secretKeyRing)); for (Object it = pgpObjectFactory.nextObject(); it != null; it = pgpObjectFactory.nextObject()) { PGPSecretKeyRing pgpSecretKeyRing = (PGPSecretKeyRing) it; PGPSecretKey pgpSecretKey = pgpSecretKeyRing.getSecretKey(); if (keyId == null || keyId.isEmpty() || Long.valueOf(keyId, 16) == (pgpSecretKey.getKeyID() & MASK)) { this.secretKey = pgpSecretKey; break; } } // sanity check if (secretKey == null) { throw new IllegalArgumentException("Secret key " + keyId + " not found"); } this.password = password; }
private void validateData(byte[] data) throws IOException, PGPException { PGPObjectFactory pgpFact = new PGPObjectFactory(data); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); InputStream pIn = c1.getDataStream(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = pIn.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), "hello world! !dlrow olleh".getBytes())) { fail("compression test failed"); } }
private PGPSignatureList readSignatureFile(final File signatureFile) throws PGPVerifyException { AssertUtil.assertNotNull(signatureFile, "signatureFile"); if (!signatureFile.isFile() || !signatureFile.canRead()) throw new PGPVerifyException("The signature-file does not exist or is not readable: " + signatureFile.getAbsolutePath()); try { final InputStream in = new BufferedInputStream(castStream(signatureFile.createInputStream())); try { final PGPObjectFactory objectFactory = new PGPObjectFactory( PGPUtil.getDecoderStream(in), new BcKeyFingerprintCalculator()); final PGPSignatureList sl = (PGPSignatureList) objectFactory.nextObject(); return sl; } finally { in.close(); } } catch (final Exception e) { throw new PGPVerifyException(signatureFile.getAbsolutePath() + ": " + e, e); } }
/** * *********************************************** */ private static PGPLiteralData asLiteral( final InputStream clear ) throws IOException, PGPException { final PGPObjectFactory plainFact = new PGPObjectFactory( clear, new JcaKeyFingerprintCalculator() ); final Object message = plainFact.nextObject(); if ( message instanceof PGPCompressedData ) { final PGPCompressedData cData = ( PGPCompressedData ) message; final PGPObjectFactory pgpFact = new PGPObjectFactory( cData.getDataStream(), new JcaKeyFingerprintCalculator() ); // Find the first PGPLiteralData object Object object = null; for ( int safety = 0; ( safety++ < 1000 ) && !( object instanceof PGPLiteralData ); object = pgpFact.nextObject() ) { //ignore } return ( PGPLiteralData ) object; } else if ( message instanceof PGPLiteralData ) { return ( PGPLiteralData ) message; } else if ( message instanceof PGPOnePassSignatureList ) { throw new PGPException( "encrypted message contains a signed message - not literal data." ); } else { throw new PGPException( "message is not a simple encrypted file - type unknown: " + message.getClass().getName() ); } }
/** * Extracts a {@link PGPSignature} object from a blob of {@code .sig} data. * * @throws SignatureException if a signature object couldn't be extracted for any reason. */ private static PGPSignature pgpExtractSignature(@Tainted byte[] signature) throws SignatureException { try { ByteArrayInputStream input = new ByteArrayInputStream(signature); PGPObjectFactory decoder = new BcPGPObjectFactory(PGPUtil.getDecoderStream(input)); Object object = decoder.nextObject(); if (object == null) { throw new SignatureException(String.format( "No OpenPGP packets found in signature.\n%s", dumpHex(signature))); } if (!(object instanceof PGPSignatureList)) { throw new SignatureException(String.format( "Expected PGPSignatureList packet but got %s\n%s", object.getClass().getSimpleName(), dumpHex(signature))); } PGPSignatureList sigs = (PGPSignatureList) object; if (sigs.isEmpty()) { throw new SignatureException(String.format( "PGPSignatureList doesn't have a PGPSignature.\n%s", dumpHex(signature))); } return sigs.get(0); } catch (IOException e) { throw new SignatureException(String.format( "Failed to extract PGPSignature object from .sig blob.\n%s", dumpHex(signature)), e); } }
@Test public void testSignVerify_Detached() throws Exception { // Load the keys. PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY); PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY); PGPPublicKey publicKey = publicKeyRing.getPublicKey(); PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey()); // Sign the data and write signature data to "signatureFile". // Note: RSA_GENERAL will encrypt AND sign. RSA_SIGN and RSA_ENCRYPT are deprecated. PGPSignatureGenerator signer = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256)); signer.init(PGPSignature.BINARY_DOCUMENT, privateKey); addUserInfoToSignature(publicKey, signer); signer.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); ByteArrayOutputStream output = new ByteArrayOutputStream(); signer.generate().encode(output); byte[] signatureFileData = output.toByteArray(); logger.info(".sig file data: " + dumpHex(signatureFileData)); // Load algorithm information and signature data from "signatureFileData". PGPSignature sig; try (ByteArrayInputStream input = new ByteArrayInputStream(signatureFileData)) { PGPObjectFactory pgpFact = new BcPGPObjectFactory(input); PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); assertThat(sigList.size()).isEqualTo(1); sig = sigList.get(0); } // Use "onePass" and "sig" to verify "publicKey" signed the text. sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey); sig.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); assertThat(sig.verify()).isTrue(); // Verify that they DIDN'T sign the text "hello monster". sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey); sig.update("hello monster".getBytes(UTF_8)); assertThat(sig.verify()).isFalse(); }
@Test public void testEncryptDecrypt_ExplicitStyle() throws Exception { int bufferSize = 64 * 1024; // Alice loads Bob's "publicKey" into memory. PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY); PGPPublicKey publicKey = publicKeyRing.getPublicKey(); // Alice encrypts the secret message for Bob using his "publicKey". PGPEncryptedDataGenerator encryptor = new PGPEncryptedDataGenerator( new BcPGPDataEncryptorBuilder(AES_128)); encryptor.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey)); byte[] encryptedData; try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { try (OutputStream output2 = encryptor.open(output, new byte[bufferSize])) { output2.write(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); } encryptedData = output.toByteArray(); } logger.info("Encrypted data: " + dumpHex(encryptedData)); // Bob loads his "privateKey" into memory. PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY); PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey()); // Bob decrypt's the OpenPGP message (w/ ciphertext) using his "privateKey". try (ByteArrayInputStream input = new ByteArrayInputStream(encryptedData)) { PGPObjectFactory pgpFact = new BcPGPObjectFactory(input); PGPEncryptedDataList encDataList = (PGPEncryptedDataList) pgpFact.nextObject(); assertThat(encDataList.size()).isEqualTo(1); PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData) encDataList.get(0); assertThat(encData.getKeyID()).isEqualTo(publicKey.getKeyID()); assertThat(encData.getKeyID()).isEqualTo(privateKey.getKeyID()); try (InputStream original = encData.getDataStream(new BcPublicKeyDataDecryptorFactory(privateKey))) { assertThat(CharStreams.toString(new InputStreamReader(original, UTF_8))) .isEqualTo(FALL_OF_HYPERION_A_DREAM); } } }
private void verifySignature(PGPObjectFactory pgpFactory, PGPOnePassSignature signature) throws IOException, PGPException, SignatureException { if (signature != null) { PGPSignatureList sigList = (PGPSignatureList) pgpFactory.nextObject(); if (!signature.verify(getSignatureWithKeyId(signature.getKeyID(), sigList))) { throw new SignatureException("Verification of the PGP signature with the key ID " + signature.getKeyID() + " failed. The PGP message may have been tampered."); } } }
private PGPSignature readSignature(PushCertificate cert) throws IOException { ArmoredInputStream in = new ArmoredInputStream(new ByteArrayInputStream(Constants.encode(cert.getSignature()))); PGPObjectFactory factory = new BcPGPObjectFactory(in); Object obj; while ((obj = factory.nextObject()) != null) { if (obj instanceof PGPSignatureList) { PGPSignatureList sigs = (PGPSignatureList) obj; if (!sigs.isEmpty()) { return sigs.get(0); } } } return null; }
@Override public synchronized ImportKeysResult importKeys(IInputStream _in) { assertNotNull(_in, "in"); InputStream in = castStream(_in); final ImportKeysResult importKeysResult = new ImportKeysResult(); boolean modified = false; try { in = PGPUtil.getDecoderStream(in); final PGPObjectFactory pgpF = new PGPObjectFactory(in, new BcKeyFingerprintCalculator()); Object o; while ((o = pgpF.nextObject()) != null) { if (o instanceof PGPPublicKeyRing) modified |= importPublicKeyRing(importKeysResult, (PGPPublicKeyRing) o); else if (o instanceof PGPSecretKeyRing) modified |= importSecretKeyRing(importKeysResult, (PGPSecretKeyRing) o); else throw new IllegalStateException("Unexpected object in InputStream (only PGPPublicKeyRing and PGPSecretKeyRing are supported): " + o); } } catch (IOException | PGPException x) { throw new RuntimeException(x); } if (modified) // make sure the localRevision is incremented, even if the timestamp does not change (e.g. because the time resolution of the file system is too low). incLocalRevision(); return importKeysResult; }
public static <T> T extractPGPObject(final Class<T> type, final InputStream inputStream) throws IOException { final PGPObjectFactory objectFactory = new PGPObjectFactory(new ArmoredInputStream(inputStream), new BcKeyFingerprintCalculator()); Object object; while ((object = objectFactory.nextObject()) != null) { if (type.isAssignableFrom(object.getClass())) { return type.cast(object); } } throw new IllegalArgumentException("Input text does not contain a PGP object"); }
public void revocationTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(pub7, new BcKeyFingerprintCalculator()); Iterator it = pgpPub.getPublicKeys(); PGPPublicKey masterKey = null; while (it.hasNext()) { PGPPublicKey k = (PGPPublicKey)it.next(); if (k.isMasterKey()) { masterKey = k; continue; } } PGPSignature sig =((PGPSignatureList)new PGPObjectFactory(pub7revoke).nextObject()).get(0); sig.init(new BcPGPContentVerifierBuilderProvider(), masterKey); if (!sig.verifyCertification(masterKey)) { fail("failed to verify revocation certification"); } }
private void bufferTest( PGPLiteralDataGenerator generator, byte[] buf, int i) throws IOException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); OutputStream out = generator.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, PGPLiteralData.CONSOLE, i, new Date()); out.write(buf, 0, i); generator.close(); PGPObjectFactory fact = new PGPObjectFactory(bOut.toByteArray()); PGPLiteralData data = (PGPLiteralData)fact.nextObject(); InputStream in = data.getInputStream(); for (int count = 0; count != i; count++) { if (in.read() != (buf[count] & 0xff)) { fail("failed readback test - length = " + i); } } }
private void testCompression( int type) throws IOException, PGPException { ByteArrayOutputStream bOut = new ByteArrayOutputStream(); PGPCompressedDataGenerator cPacket = new PGPCompressedDataGenerator(type); OutputStream out = cPacket.open(new UncloseableOutputStream(bOut)); out.write("hello world!".getBytes()); out.close(); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject(); InputStream pIn = c1.getDataStream(); bOut.reset(); int ch; while ((ch = pIn.read()) >= 0) { bOut.write(ch); } if (!areEqual(bOut.toByteArray(), "hello world!".getBytes())) { fail("compression test failed"); } }
private PGPObjectFactory loadSig( String sigName) throws Exception { FileInputStream fIn = new FileInputStream(getDataHome() + "/sigs/" + sigName); return new PGPObjectFactory(fIn); }
private void testDecrypt(PGPSecretKeyRing secretKeyRing) throws Exception { PGPObjectFactory pgpF = new PGPObjectFactory(testMessage); PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0); PGPSecretKey secretKey = secretKeyRing.getSecretKey(); // secretKeyRing.getSecretKey(encP.getKeyID()); // // PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey()extractPrivateKey(null); // // clear = encP.getDataStream(pgpPrivKey, "BC"); // // bOut.reset(); // // while ((ch = clear.read()) >= 0) // { // bOut.write(ch); // } // // out = bOut.toByteArray(); // // if (!areEqual(out, text)) // { // fail("wrong plain text in generated packet"); // } }
private static DecryptionResult verifySignature(DecryptionResult result, PGPObjectFactory pgpFact, PGPOnePassSignature ops) throws PGPException, IOException { Object object = pgpFact.nextObject(); // nullable if (!(object instanceof PGPSignatureList)) { LOGGER.warning("invalid signature packet"); result.errors.add(Coder.Error.INVALID_SIGNATURE_DATA); return result; } PGPSignatureList signatureList = (PGPSignatureList) object; if (signatureList.isEmpty()) { LOGGER.warning("no signature in signature list"); result.errors.add(Coder.Error.INVALID_SIGNATURE_DATA); return result; } PGPSignature signature = signatureList.get(0); // TODO signature.getCreationTime() if (ops.verify(signature)) { // signature verification successful! result.signing = Coder.Signing.VERIFIED; } else { LOGGER.warning("signature verification failed"); result.errors.add(Coder.Error.INVALID_SIGNATURE); } return result; }
public static boolean isEncryptedFile(Path file) { try (FileInputStream input = new FileInputStream(file.toFile())) { PGPObjectFactory factory = new PGPObjectFactory(input, FP_CALC); Object o = factory.nextObject(); return o instanceof PGPEncryptedDataList || o instanceof PGPMarker; // NOTE: exception class is not well defined for non-pgp data } catch(IOException | RuntimeException ex) { return false; } }
private PGPSignatureList readSignatureFile(final String resourcePath) throws IOException { final InputStream signatureIn = PGPTest.class.getResourceAsStream(resourcePath); final PGPObjectFactory objectFactory = new PGPObjectFactory( PGPUtil.getDecoderStream(signatureIn), new BcKeyFingerprintCalculator()); final PGPSignatureList sl = (PGPSignatureList) objectFactory.nextObject(); signatureIn.close(); return sl; }
private PGPSignature getPgpSignature() { try { final InputStream decoderStream = PGPUtil.getDecoderStream(new ByteArrayInputStream(signature)); final PGPObjectFactory objectFactory = new BcPGPObjectFactory(decoderStream); final PGPSignatureList signatureList = (PGPSignatureList) objectFactory.nextObject(); if ((signatureList == null) || (signatureList.size() != 1)) { throw new IllegalArgumentException("Couldn't read PGP signature"); } return signatureList.get(0); } catch (IOException e) { throw new IllegalArgumentException(e); } }
/** * decrypt the passed in message stream */ private byte[] decryptMessage( byte[] message, Date date) throws Exception { PGPObjectFactory pgpF = new BcPGPObjectFactory(message); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); PGPObjectFactory pgpFact = new BcPGPObjectFactory(clear); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt") && !ld.getFileName().equals("_CONSOLE")) { fail("wrong filename in packet"); } if (!ld.getModificationTime().equals(date)) { fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); } InputStream unc = ld.getInputStream(); int ch; while ((ch = unc.read()) >= 0) { bOut.write(ch); } if (pbe.isIntegrityProtected() && !pbe.verify()) { fail("integrity check failed"); } return bOut.toByteArray(); }
private byte[] decryptMessageBuffered( byte[] message, Date date) throws Exception { PGPObjectFactory pgpF = new PGPObjectFactory(message, new BcKeyFingerprintCalculator()); PGPEncryptedDataList enc = (PGPEncryptedDataList)pgpF.nextObject(); PGPPBEEncryptedData pbe = (PGPPBEEncryptedData)enc.get(0); InputStream clear = pbe.getDataStream(new BcPBEDataDecryptorFactory(pass, new BcPGPDigestCalculatorProvider())); PGPObjectFactory pgpFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator()); PGPLiteralData ld = (PGPLiteralData)pgpFact.nextObject(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt") && !ld.getFileName().equals("_CONSOLE")) { fail("wrong filename in packet"); } if (!ld.getModificationTime().equals(date)) { fail("wrong modification time in packet: " + ld.getModificationTime().getTime() + " " + date.getTime()); } InputStream unc = ld.getInputStream(); byte[] buf = new byte[1024]; int len; while ((len = unc.read(buf)) >= 0) { bOut.write(buf, 0, len); } if (pbe.isIntegrityProtected() && !pbe.verify()) { fail("integrity check failed"); } return bOut.toByteArray(); }
/** * Generated signature test * * @param sKey * @param pgpPrivKey */ public void generateTest( PGPSecretKeyRing sKey, PGPPublicKey pgpPubKey, PGPPrivateKey pgpPrivKey) throws Exception { String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs(); String primaryUserID = (String)it.next(); spGen.setSignerUserID(true, primaryUserID); sGen.setHashedSubpackets(spGen.generate()); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bOut); PGPObjectFactory pgpFact = new BcPGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } }
@Test public void testSignVerify_OnePass() throws Exception { // Load the keys. PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY); PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY); PGPPublicKey publicKey = publicKeyRing.getPublicKey(); PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey()); // Sign the data and write signature data to "signatureFile". PGPSignatureGenerator signer = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256)); signer.init(PGPSignature.BINARY_DOCUMENT, privateKey); addUserInfoToSignature(publicKey, signer); ByteArrayOutputStream output = new ByteArrayOutputStream(); signer.generateOnePassVersion(false).encode(output); signer.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); signer.generate().encode(output); byte[] signatureFileData = output.toByteArray(); logger.info(".sig file data: " + dumpHex(signatureFileData)); // Load algorithm information and signature data from "signatureFileData". PGPSignature sig; PGPOnePassSignature onePass; try (ByteArrayInputStream input = new ByteArrayInputStream(signatureFileData)) { PGPObjectFactory pgpFact = new BcPGPObjectFactory(input); PGPOnePassSignatureList onePassList = (PGPOnePassSignatureList) pgpFact.nextObject(); PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); assertThat(onePassList.size()).isEqualTo(1); assertThat(sigList.size()).isEqualTo(1); onePass = onePassList.get(0); sig = sigList.get(0); } // Use "onePass" and "sig" to verify "publicKey" signed the text. onePass.init(new BcPGPContentVerifierBuilderProvider(), publicKey); onePass.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); assertThat(onePass.verify(sig)).isTrue(); // Verify that they DIDN'T sign the text "hello monster". onePass.init(new BcPGPContentVerifierBuilderProvider(), publicKey); onePass.update("hello monster".getBytes(UTF_8)); assertThat(onePass.verify(sig)).isFalse(); }
/** * Validate pgp signature of license * * @param licenseText base64 encoded pgp signed license * @return The plain license in json (if validation is successful) * @throws PGPException if validation fails */ public static String validateLicense(String licenseText) throws PGPException { licenseText = licenseText.trim().replaceAll("\\r|\\n", ""); licenseText = licenseText.replace("---- SCHNIPP (Armored PGP signed JSON as base64) ----",""); licenseText = licenseText.replace("---- SCHNAPP ----",""); try { final byte[] armoredPgp = BaseEncoding.base64().decode(licenseText); final ArmoredInputStream in = new ArmoredInputStream(new ByteArrayInputStream(armoredPgp)); // // read the input, making sure we ignore the last newline. // // https://github.com/bcgit/bc-java/blob/master/pg/src/test/java/org/bouncycastle/openpgp/test/PGPClearSignedSignatureTest.java final ByteArrayOutputStream bout = new ByteArrayOutputStream(); int ch; while ((ch = in.read()) >= 0 && in.isClearText()) { bout.write((byte) ch); } final KeyFingerPrintCalculator c = new BcKeyFingerprintCalculator(); final PGPObjectFactory factory = new PGPObjectFactory(in, c); final PGPSignatureList sigL = (PGPSignatureList) factory.nextObject(); final PGPPublicKeyRingCollection pgpRings = new PGPPublicKeyRingCollection(new ArmoredInputStream( LicenseHelper.class.getResourceAsStream("/KEYS")), c); if (sigL == null || pgpRings == null || sigL.size() == 0 || pgpRings.size() == 0) { throw new PGPException("Cannot find license signature"); } final PGPSignature sig = sigL.get(0); final PGPPublicKey publicKey = pgpRings.getPublicKey(sig.getKeyID()); if (publicKey == null || sig == null) { throw new PGPException("license signature key mismatch"); } sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey); final ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); final InputStream sigIn = new ByteArrayInputStream(bout.toByteArray()); int lookAhead = readInputLine(lineOut, sigIn); processLine(sig, lineOut.toByteArray()); if (lookAhead != -1) { do { lookAhead = readInputLine(lineOut, lookAhead, sigIn); sig.update((byte) '\r'); sig.update((byte) '\n'); processLine(sig, lineOut.toByteArray()); } while (lookAhead != -1); } if (!sig.verify()) { throw new PGPException("Invalid license signature"); } return bout.toString(); } catch (final Exception e) { throw new PGPException(e.toString(), e); } }
@Override public String decryptAndVerify(String messageIn) throws IOException, SignatureVerificationException { try { /* Stage zero: Convert to ASCII armored format and open a decoding stream */ InputStream is = new ByteArrayInputStream(Base64.decode(messageIn)); InputStream decoderStream = PGPUtil.getDecoderStream(is); /* Stage one: Init a decrypting stream */ PGPObjectFactory pgpFactory = new PGPObjectFactory(decoderStream); PGPEncryptedDataList cryptedDataList = (PGPEncryptedDataList) pgpFactory.nextObject(); PGPPublicKeyEncryptedData cryptedData = (PGPPublicKeyEncryptedData) cryptedDataList.get(0); InputStream clearStream = cryptedData.getDataStream(getCryptingPrivateKey(), _provider); /* Stage two: Seperate the XML data from the signatures */ PGPObjectFactory plainFact = new PGPObjectFactory(clearStream); PGPOnePassSignatureList onePassSignatureList = (PGPOnePassSignatureList) plainFact.nextObject(); PGPLiteralData literalData = (PGPLiteralData) plainFact.nextObject(); String xmlMessage = IOUtils.toString(literalData.getInputStream()); PGPSignatureList signatureList = (PGPSignatureList) plainFact.nextObject(); /* Stage three: Verify signature */ PGPOnePassSignature ops = onePassSignatureList.get(0); PGPPublicKey key = _remotePublicKeyRing.getPublicKey(ops.getKeyID()); ops.initVerify(key, _provider); ops.update(xmlMessage.getBytes()); if (!ops.verify(signatureList.get(0))) { throw new SignatureVerificationException("Failed to verify message signature. Message authenticity cannot be thrusted."); } return xmlMessage; } catch (PGPException pgpException) { throw new IOException("PGP subsystem problem.", pgpException); } catch (SignatureException signException) { throw new IOException("PGP subsystem problem.", signException); } catch (Throwable t) { throw new IOException("Unknown error occured in PGP subsystem: " + t.getMessage(), t); } }