/** * Verify a signature. Only return true if signature matches calculated signature of signedData * and if it was signed by the publicKey * * @param signedData * @param signature * @return */ public boolean verify(InputStream signedData, InputStream signature) { try { signature = PGPUtil.getDecoderStream(signature); JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(signature); PGPSignature sig = ((PGPSignatureList) pgpFact.nextObject()).get(0); PGPPublicKey key = pgpPubRingCollection.getPublicKey(sig.getKeyID()); sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), key); byte[] buff = new byte[1024]; int read = 0; while ((read = signedData.read(buff)) != -1) { sig.update(buff, 0, read); } signedData.close(); return sig.verify(); } catch (Exception ex) { // can we put a logger here please? return false; } }
/** * 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(); }
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); } }
@Test public void verifyGoodSignature() throws Exception { final PGPPublicKeyRingCollection publicKeyRing = getPublicKeyRingWithTrustedKeys(); final PGPSignatureList sl = readSignatureFile("/content1.sig"); assertThat(sl.isEmpty()).isFalse(); assertThat(sl.size()).isEqualTo(1); PGPSignature signature = sl.get(0); signature.init(new BcPGPContentVerifierBuilderProvider(), publicKeyRing.getPublicKey(signature.getKeyID())); InputStream contentIn = PGPTest.class.getResourceAsStream("/content1"); byte[] buf = new byte[4096]; int len; while (0 <= (len = contentIn.read(buf))) { signature.update(buf, 0, len); } contentIn.close(); assertThat(signature.verify()).isTrue(); }
@Test public void verifyBadSignature() throws Exception { final PGPPublicKeyRingCollection publicKeyRing = getPublicKeyRingWithTrustedKeys(); final PGPSignatureList sl = readSignatureFile("/content1.sig"); assertThat(sl.isEmpty()).isFalse(); assertThat(sl.size()).isEqualTo(1); PGPSignature signature = sl.get(0); signature.init(new BcPGPContentVerifierBuilderProvider(), publicKeyRing.getPublicKey(signature.getKeyID())); InputStream contentIn = PGPTest.class.getResourceAsStream("/content1"); byte[] buf = new byte[4096]; int len; while (0 <= (len = contentIn.read(buf))) { buf[0] = 0; signature.update(buf, 0, len); } contentIn.close(); assertThat(signature.verify()).isFalse(); }
public ContentAndSignatures( final byte[] decryptedContent, final PGPOnePassSignatureList onePassSignatureList, final PGPSignatureList signatureList ) { this.decryptedContent = decryptedContent; this.onePassSignatureList = onePassSignatureList; this.signatureList = signatureList; }
private static void doVerify( JcaPGPObjectFactory objectFactory, PGPOnePassSignature onePassSignature ) throws IOException, PGPException { PGPSignatureList signatures = ( PGPSignatureList ) objectFactory.nextObject(); if ( !onePassSignature.verify( signatures.get( 0 ) ) ) { throw new PGPDataValidationException( "Signature verification failed" ); } }
/** * 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(); }
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."); } } }
protected PGPSignature getSignatureWithKeyId(long keyID, PGPSignatureList sigList) { for (int i = 0; i < sigList.size(); i++) { PGPSignature signature = sigList.get(i); if (keyID == signature.getKeyID()) { return signature; } } throw new IllegalStateException("PGP signature is inconsistent"); }
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; }
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 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; }
/** * Verify the specified {@code file}. * @param file the file to be verified. Must not be <code>null</code>. There must be a second file * with the same name and the additional suffix ".sig" next to this file (in the same directory). * This secondary file is a so-called detached signature. * @throws PGPVerifyException if the given {@code file} could not be verified successfully. Either * there is no detached-signature-file, or its signature is broken or its signature does not match * any of the {@linkplain #getPublicKeyRingWithTrustedKeys() trusted keys}. */ public void verify(final File file, final File signatureFile) throws PGPVerifyException { AssertUtil.assertNotNull(file, "file"); AssertUtil.assertNotNull(signatureFile, "signatureFile"); final PGPSignatureList sl = readSignatureFile(signatureFile); final PGPPublicKeyRingCollection publicKeyRing = getPublicKeyRingWithTrustedKeys(); for (int index = 0; index < sl.size(); ++index) { try { final PGPSignature signature = sl.get(index); signature.init(new BcPGPContentVerifierBuilderProvider(), publicKeyRing.getPublicKey(signature.getKeyID())); final InputStream contentIn = castStream(file.createInputStream()); try { final byte[] buf = new byte[16 * 1024]; int len; while (0 <= (len = contentIn.read(buf))) { if (len > 0) signature.update(buf, 0, len); } } finally { contentIn.close(); } if (signature.verify()) return; } catch (final Exception e) { throw new PGPVerifyException(file.getAbsolutePath() + ": " + e, e); } } throw new PGPVerifyException(file.getAbsolutePath()); }
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); } }
/** * 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"); } }
public static boolean verifyClearSign( byte[] message, PGPPublicKeyRing pgpRings ) throws IOException, PGPException, SignatureException { ArmoredInputStream aIn = new ArmoredInputStream( new ByteArrayInputStream( message ) ); ByteArrayOutputStream bout = new ByteArrayOutputStream(); // // write out signed section using the local line separator. // note: trailing white space needs to be removed from the end of // each line RFC 4880 Section 7.1 // ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); boolean isFirstLineClearText = aIn.isClearText(); int lookAhead = readInputLine( lineOut, aIn ); if ( lookAhead != -1 && isFirstLineClearText ) { bout.write( lineOut.toByteArray() ); while ( lookAhead != -1 && aIn.isClearText() ) { lookAhead = readInputLine( lineOut, lookAhead, aIn ); bout.write( lineOut.toByteArray() ); } } JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory( aIn ); PGPSignatureList p3 = ( PGPSignatureList ) pgpFact.nextObject(); PGPSignature sig = p3.get( 0 ); PGPPublicKey publicKey = pgpRings.getPublicKey( sig.getKeyID() ); sig.init( new JcaPGPContentVerifierBuilderProvider().setProvider( "BC" ), publicKey ); // // read the input, making sure we ignore the last newline. // InputStream sigIn = new ByteArrayInputStream( bout.toByteArray() ); 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 ); } sigIn.close(); return sig.verify(); }
public PGPSignatureList getSignatureList() { return signatureList; }
public String verifySignature(String message) throws PGPInvalidSignatureException, PGPSignatureVerificationException { try { ArmoredInputStream aIn = new ArmoredInputStream(new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8))); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = aIn.read()) >= 0 && aIn.isClearText()) { bOut.write((byte) ch); } JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(aIn); PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject(); checkState(p3 != null && p3.size() >= 1, "No signatures"); PGPSignature sig = p3.get(0); sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey.getSigningKey()); ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); byte[] content = bOut.toByteArray(); InputStream sigIn = new ByteArrayInputStream(content); 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()) { return new String(content, StandardCharsets.UTF_8); } throw new PGPInvalidSignatureException( "Invalid signature, received keyId=" + Long.toHexString(sig.getKeyID()).toUpperCase() ); } catch (IOException | PGPException e) { throw new PGPSignatureVerificationException("Error verifying message", e); } }
@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); } }
private void verifySignature(final PGPOnePassSignatureList onePassSignatureList, final PGPSignatureList signatureList, final InputStream signedDataIn, final OutputStream signedDataOut) throws SignatureException, IOException { assertNotNull(onePassSignatureList, "onePassSignatureList"); assertNotNull(signatureList, "signatureList"); assertNotNull(signedDataIn, "signedDataIn"); setSignPgpKey(null); setPgpSignature(null); setSignPgpKeyIds(null); if (onePassSignatureList.size() == 0) return; // there is no signature final Set<PgpKeyId> pgpKeyIds = new HashSet<>(); try { PGPPublicKey publicKey = null; for (int i = 0; i < onePassSignatureList.size(); i++) { final PGPOnePassSignature ops = onePassSignatureList.get(i); pgpKeyIds.add(new PgpKeyId(ops.getKeyID())); if (getPgpSignature() != null) continue; final BcPgpKey bcPgpKey = pgp.getBcPgpKey(new PgpKeyId(ops.getKeyID())); if (bcPgpKey != null) { publicKey = bcPgpKey.getPublicKey(); ops.init(new BcPGPContentVerifierBuilderProvider(), publicKey); final byte[] buf = new byte[64 * 1024]; int bytesRead; while ((bytesRead = signedDataIn.read(buf)) > 0) { ops.update(buf, 0, bytesRead); if (signedDataOut != null) signedDataOut.write(buf, 0, bytesRead); } final PGPSignature signature = signatureList.get(i); if (ops.verify(signature)) { setSignPgpKey(bcPgpKey.getPgpKey()); setPgpSignature(pgp.createPgpSignature(signature)); } else throw new SignatureException("Signature verification failed!"); } } } catch (final PGPException x) { throw new IOException(x); } setSignPgpKeyIds(pgpKeyIds); logger.debug("verifySignature: signingPgpKeyIds={}", pgpKeyIds); if (getPgpSignature() == null && isFailOnMissingSignPgpKey()) throw new MissingSigningPgpKeyException(pgpKeyIds, "The data was signed using the following PGP-keys, of which none could be found in the local key-ring: " + pgpKeyIds); }
private void testMissingSubpackets(byte[] signature) throws IOException { PGPObjectFactory f = new PGPObjectFactory(signature); Object obj = f.nextObject(); while (!(obj instanceof PGPSignatureList)) { obj = f.nextObject(); if (obj instanceof PGPLiteralData) { InputStream in = ((PGPLiteralData)obj).getDataStream(); Streams.drain(in); } } PGPSignature sig = ((PGPSignatureList)obj).get(0); if (sig.getVersion() > 3) { PGPSignatureSubpacketVector v = sig.getHashedSubPackets(); if (v.getKeyExpirationTime() != 0) { fail("key expiration time not zero for missing subpackets"); } if (!sig.hasSubpackets()) { fail("hasSubpackets() returns false with packets"); } } else { if (sig.getHashedSubPackets() != null) { fail("hashed sub packets found when none expected"); } if (sig.getUnhashedSubPackets() != null) { fail("unhashed sub packets found when none expected"); } if (sig.hasSubpackets()) { fail("hasSubpackets() returns true with no packets"); } } }
private void verifySignature( byte[] encodedSig, int hashAlgorithm, PGPPublicKey pubKey, byte[] original) throws IOException, PGPException, NoSuchProviderException, SignatureException { PGPObjectFactory pgpFact = new PGPObjectFactory(encodedSig); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), pubKey); int ch; while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); PGPSignature sig = p3.get(0); Date creationTime = sig.getCreationTime(); Date now = new Date(); // Check creationTime is recent if (creationTime.after(now) || creationTime.before(new Date(now.getTime() - 10 * 60 * 1000))) { fail("bad creation time in signature: " + creationTime); } if (sig.getKeyID() != pubKey.getKeyID()) { fail("key id mismatch in signature"); } if (!ops.verify(sig)) { fail("Failed generated signature check - " + hashAlgorithm); } sig.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), pubKey); for (int i = 0; i != original.length; i++) { sig.update(original[i]); } sig.update(original); if (!sig.verify()) { fail("Failed generated signature check against original data"); } }
private void doSigGenerateTest(String privateKeyFile, String publicKeyFile, int digest) throws Exception { PGPSecretKeyRing secRing = loadSecretKey(privateKeyFile); PGPPublicKeyRing pubRing = loadPublicKey(publicKeyFile); String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PublicKeyAlgorithmTags.DSA, digest, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, secRing.getSecretKey().extractPrivateKey("test".toCharArray(), "BC")); BCPGOutputStream bcOut = new BCPGOutputStream(bOut); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bcOut), 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(bcOut); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); assertEquals(digest, ops.getHashAlgorithm()); assertEquals(PublicKeyAlgorithmTags.DSA, ops.getKeyAlgorithm()); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.initVerify(pubRing.getPublicKey(), "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); PGPSignature sig = p3.get(0); assertEquals(digest, sig.getHashAlgorithm()); assertEquals(PublicKeyAlgorithmTags.DSA, sig.getKeyAlgorithm()); assertTrue(ops.verify(sig)); }
private void messageTest( String message, String type) throws Exception { ArmoredInputStream aIn = new ArmoredInputStream(new ByteArrayInputStream(message.getBytes())); String[] headers = aIn.getArmorHeaders(); if (headers == null || headers.length != 1) { fail("wrong number of headers found"); } if (!"Hash: SHA256".equals(headers[0])) { fail("header value wrong: " + headers[0]); } // // read the input, making sure we ingore the last newline. // ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int ch; while ((ch = aIn.read()) >= 0 && aIn.isClearText()) { bOut.write((byte)ch); } PGPPublicKeyRingCollection pgpRings = new PGPPublicKeyRingCollection(publicKey); PGPObjectFactory pgpFact = new PGPObjectFactory(aIn); PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); PGPSignature sig = p3.get(0); sig.initVerify(pgpRings.getPublicKey(sig.getKeyID()), "BC"); ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); 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()) { fail("signature failed to verify in " + type); } }
private boolean verifyPGPSignature(Artifact artifact, Artifact ascArtifact) throws MojoFailureException { final File artifactFile = artifact.getFile(); final File signatureFile = ascArtifact.getFile(); final Map<Integer, String> weakSignatures = ImmutableMap.<Integer, String>builder() .put(1, "MD5") .put(4, "DOUBLE_SHA") .put(5, "MD2") .put(6, "TIGER_192") .put(7, "HAVAL_5_160") .put(11, "SHA224") .build(); getLog().debug("Artifact file: " + artifactFile); getLog().debug("Artifact sign: " + signatureFile); try { InputStream sigInputStream = PGPUtil.getDecoderStream(new FileInputStream(signatureFile)); PGPObjectFactory pgpObjectFactory = new PGPObjectFactory(sigInputStream, new BcKeyFingerprintCalculator()); PGPSignatureList sigList = (PGPSignatureList) pgpObjectFactory.nextObject(); if (sigList == null) { throw new MojoFailureException("Invalid signature file: " + signatureFile); } PGPSignature pgpSignature = sigList.get(0); PGPPublicKey publicKey = pgpKeysCache.getKey(pgpSignature.getKeyID()); if (!keysMap.isValidKey(artifact, publicKey)) { String msg = String.format("%s=0x%X", ArtifactUtils.key(artifact), publicKey.getKeyID()); String keyUrl = pgpKeysCache.getUrlForShowKey(publicKey.getKeyID()); getLog().error(String.format("Not allowed artifact %s and keyID:\n\t%s\n\t%s\n", artifact.getId(), msg, keyUrl)); return false; } pgpSignature.init(new BcPGPContentVerifierBuilderProvider(), publicKey); try (InputStream inArtifact = new BufferedInputStream(new FileInputStream(artifactFile))) { int t; while ((t = inArtifact.read()) >= 0) { pgpSignature.update((byte) t); } } String msgFormat = "%s PGP Signature %s\n KeyId: 0x%X UserIds: %s"; if (pgpSignature.verify()) { getLog().info(String.format(msgFormat, artifact.getId(), "OK", publicKey.getKeyID(), Lists.newArrayList(publicKey.getUserIDs()))); if (weakSignatures.containsKey(pgpSignature.getHashAlgorithm())) { if (failWeakSignature) { getLog().error("Weak signature algorithm used: " + weakSignatures.get(pgpSignature.getHashAlgorithm())); throw new MojoFailureException("Weak signature algorithm used: " + weakSignatures.get(pgpSignature.getHashAlgorithm())); } else { getLog().warn("Weak signature algorithm used: " + weakSignatures.get(pgpSignature.getHashAlgorithm())); } } return true; } else { getLog().warn(String.format(msgFormat, artifact.getId(), "ERROR", publicKey.getKeyID(), Lists.newArrayList(publicKey.getUserIDs()))); getLog().warn(artifactFile.toString()); getLog().warn(signatureFile.toString()); return false; } } catch (IOException | PGPException e) { throw new MojoFailureException(e.getMessage(), e); } }
/** * 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 PGPObjectFactory(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"); } }