private static boolean isValidCertification(PGPPublicKey key, PGPSignature sig, String userId) throws PGPException { if (sig.getSignatureType() != PGPSignature.DEFAULT_CERTIFICATION && sig.getSignatureType() != PGPSignature.POSITIVE_CERTIFICATION) { return false; } if (sig.getKeyID() != key.getKeyID()) { return false; } // TODO(dborowitz): Handle certification revocations: // - Is there a revocation by either this key or another key trusted by the // server? // - Does such a revocation postdate all other valid certifications? sig.init(new BcPGPContentVerifierBuilderProvider(), key); return sig.verifyCertification(userId, key); }
/** * 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(); }
@Test public void testPackageSignature() throws IOException, PackagingException, PGPException, SignatureException, org.bouncycastle.openpgp.PGPException, NoSuchProviderException { final File debFile = createPackage(ImmutableList.<Resource>of( new StringResource("hello world", true, "/tmp/test.txt", USER, USER, TarEntry.DEFAULT_FILE_MODE) )); final File packageDir = temporaryFolder.newFolder(); ArchiveUtils.extractAr(debFile, packageDir); final File pgpSignatureFile = new File(packageDir, "_gpgorigin"); assertTrue(pgpSignatureFile.exists()); try (final InputStream keyringIn = PGPUtil.getDecoderStream(PackageBuilderTest.class.getResourceAsStream("public.asc"))) { try (final InputStream signatureIn = PGPUtil.getDecoderStream(new FileInputStream(pgpSignatureFile))) { final PGPPublicKey publicKey = ((PGPPublicKeyRing) new BcPGPPublicKeyRingCollection(keyringIn).getKeyRings().next()).getPublicKey(); final PGPSignature signature = ((PGPSignatureList) new BcPGPObjectFactory(signatureIn).nextObject()).get(0); signature.init(new BcPGPContentVerifierBuilderProvider(), publicKey); signature.update(Files.asByteSource(new File(packageDir, "debian-binary")).read()); signature.update(Files.asByteSource(new File(packageDir, "control.tar.gz")).read()); signature.update(Files.asByteSource(new File(packageDir, "data.tar.gz")).read()); assertTrue(signature.verify()); } } }
private final static boolean isGoodUIDSignature (PGPSignature sig, PGPPublicKey masterpk, String uid, boolean self, PrimaryKeyFinder kf, KeyInfo signer_info, StringBuilder errors) throws PGPException,SignatureException,IOException { List<PGPPublicKey> signers = findSigners (sig, masterpk, self, kf, "'"+uid+"'", errors); if (signers == null) { return false; } for (PGPPublicKey signer: signers) { sig.init(new BcPGPContentVerifierBuilderProvider(), signer); if (!sig.verifyCertification(uid, masterpk)) { errors.append ("Skipping certification "+niceSig(sig)+" for '"+uid+ "' because the signature is invalid.\n"); continue; } if (isSignatureCurrent(sig, errors)) { signer_info.setKey(signer); return true; } } return false; }
private final static boolean isGoodAttributeSignature (PGPSignature sig, PGPPublicKey masterpk, PGPUserAttributeSubpacketVector attr, boolean self, PrimaryKeyFinder kf, KeyInfo signer_info, StringBuilder errors) throws PGPException,SignatureException,IOException { List<PGPPublicKey> signers = findSigners (sig, masterpk, self, kf, "attribute", errors); if (signers == null) { return false; } for (PGPPublicKey signer: signers) { sig.init(new BcPGPContentVerifierBuilderProvider(), signer); if (!sig.verifyCertification(attr, masterpk)) { errors.append ("Skipping certification "+niceSig(sig)+ " for attribute because the signature is invalid.\n"); continue; } if (isSignatureCurrent(sig, errors)) { signer_info.setKey(signer); return true; } } return false; }
@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(); }
@SuppressWarnings("deprecation") private static void pgpVerifySignature(byte[] data, byte[] signature, PGPPublicKey publicKey) throws PGPException, SignatureException { Security.addProvider(new BouncyCastleProvider()); PGPSignature sig = pgpExtractSignature(signature); sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey); sig.update(data); if (!sig.verify()) { throw new SignatureException(String.format( "MarksDB PGP signature verification failed.\n%s", dumpHex(signature))); } }
@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 PGPSignature scanRevocations( PGPPublicKey key, Date now, List<PGPSignature> revocations, Map<Long, RevocationKey> revokers) throws PGPException { @SuppressWarnings("unchecked") Iterator<PGPSignature> allSigs = key.getSignatures(); while (allSigs.hasNext()) { PGPSignature sig = allSigs.next(); switch (sig.getSignatureType()) { case KEY_REVOCATION: if (sig.getKeyID() == key.getKeyID()) { sig.init(new BcPGPContentVerifierBuilderProvider(), key); if (sig.verifyCertification(key)) { return sig; } } else { RevocationReason reason = getRevocationReason(sig); if (reason != null && isRevocationValid(sig, reason, now)) { revocations.add(sig); } } break; case DIRECT_KEY: RevocationKey r = getRevocationKey(key, sig); if (r != null) { revokers.put(Fingerprint.getId(r.getFingerprint()), r); } break; } } return null; }
private RevocationKey getRevocationKey(PGPPublicKey key, PGPSignature sig) throws PGPException { if (sig.getKeyID() != key.getKeyID()) { return null; } SignatureSubpacket sub = sig.getHashedSubPackets().getSubpacket(REVOCATION_KEY); if (sub == null) { return null; } sig.init(new BcPGPContentVerifierBuilderProvider(), key); if (!sig.verifyCertification(key)) { return null; } return new RevocationKey(sub.isCritical(), sub.isLongLength(), sub.getData()); }
/** * Choose the public key that produced a signature. * * <p> * * @param keyRings candidate keys. * @param sig signature object. * @param data signed payload. * @return the key chosen from {@code keyRings} that was able to verify the signature, or {@code * null} if none was found. * @throws PGPException if an error occurred verifying the signature. */ public static PGPPublicKey getSigner( Iterable<PGPPublicKeyRing> keyRings, PGPSignature sig, byte[] data) throws PGPException { for (PGPPublicKeyRing kr : keyRings) { PGPPublicKey k = kr.getPublicKey(); sig.init(new BcPGPContentVerifierBuilderProvider(), k); sig.update(data); if (sig.verify()) { return k; } } 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 final static boolean isGoodSubkeySignature (PGPSignature sig, PGPPublicKey signer, PGPPublicKey primary, PGPPublicKey subkey, StringBuilder errors) throws PGPException,SignatureException,IOException { sig.init(new BcPGPContentVerifierBuilderProvider(), signer); return sig.verifyCertification(primary, subkey) && isSignatureCurrent(sig, errors); }
private final static boolean isGoodDirectSignature (PGPSignature sig, PGPPublicKey signer, PGPPublicKey target, StringBuilder errors) throws PGPException,SignatureException,IOException { sig.init(new BcPGPContentVerifierBuilderProvider(), signer); boolean ok; // There's a bug that prevents sig.verifyCertification(signer) // working for DIRECT_KEY signatures. // // So, re-implement the code again here. if (sig.getSignatureType() == PGPSignature.DIRECT_KEY) { byte[] bytes = target.getPublicKeyPacket().getEncodedContents(); sig.update((byte)0x99); sig.update((byte)(bytes.length >> 8)); sig.update((byte)(bytes.length)); sig.update(bytes); ok = sig.verify(); } else { ok = sig.verifyCertification(target); } // If we have a good signature, also ensure the signature // hasn't expired. return ok && isSignatureCurrent(sig, errors); }
/** * 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()); }
/** * Decrypts the message and verifies its signature and integrity packet. * * @param encrypted the encrypted message body * @return the decrypted message body * @throws CryptographicException if any error occurs while processing the message. This should * be taken as an indicator that the message has been tampered * with or is invalid, and that retrying the operation would be * pointless. */ public byte[] read(InputStream encrypted) throws CryptographicException { try { final PGPPublicKeyEncryptedData encryptedData = getEncryptedData(encrypted); final InputStream decryptedData = encryptedData.getDataStream(new BcPublicKeyDataDecryptorFactory(recipient.getUnlockedSubKey().getPrivateKey())); final InputStream decompressedData = getCompressedData(decryptedData); final PGPObjectFactory factory = getFactory(decompressedData); final PGPOnePassSignature signature = getOnePassSignature(signer, factory); signature.init(new BcPGPContentVerifierBuilderProvider(), signer.getMasterKey().getPublicKey()); final InputStream body = getLiteralData(factory); final ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] b = new byte[BUFFER_SIZE]; int r; while ((r = body.read(b)) >= 0) { output.write(b, 0, r); signature.update(b, 0, r); } if (!signature.verify(getSignature(signer, factory))) { throw new CryptographicException("Invalid signature"); } if (!encryptedData.verify()) { throw new CryptographicException("Integrity check failed"); } return output.toByteArray(); } catch (IOException | ClassCastException | GeneralSecurityException | PGPException e) { throw new CryptographicException(e); } }
public boolean verify(final PGPPublicKey publicKey) { try { final PGPSignature pgpSignature = getPgpSignature(); if (pgpSignature.getKeyAlgorithm() != publicKey.getAlgorithm()) { return false; } pgpSignature.init(new BcPGPContentVerifierBuilderProvider(), publicKey); if (clearText) { // read the input, making sure we ignore the last newline. final InputStream signatureIn = new ByteArrayInputStream(content); final ByteArrayOutputStream lineOut = new ByteArrayOutputStream(); int lookAhead = readInputLine(lineOut, signatureIn); processLine(pgpSignature, lineOut.toByteArray()); if (lookAhead != -1) { do { lookAhead = readInputLine(lineOut, lookAhead, signatureIn); pgpSignature.update((byte) '\r'); pgpSignature.update((byte) '\n'); processLine(pgpSignature, lineOut.toByteArray()); } while (lookAhead != -1); } signatureIn.close(); } else { pgpSignature.update(content); } return pgpSignature.verify(); } catch (Exception e) { throw new IllegalArgumentException(e); } }
/** * Helper for signature verification. */ protected PGPContentVerifierBuilderProvider getVerifierProvider() { return new BcPGPContentVerifierBuilderProvider(); }
private void existingEmbeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(embeddedJPEGKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); Iterator it = pubKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = pubKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature sig = (PGPSignature)sigs.next(); sig.init(new BcPGPContentVerifierBuilderProvider(), pubKey); if (!sig.verifyCertification(attributes, pubKey)) { fail("signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed user attributes signature check"); } count++; } if (count != 1) { fail("didn't find user attributes"); } }
private void embeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); PGPSecretKeyRing pgpSec = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); PGPUserAttributeSubpacketVectorGenerator vGen = new PGPUserAttributeSubpacketVectorGenerator(); vGen.setImageAttribute(ImageAttribute.JPEG, jpegImage); PGPUserAttributeSubpacketVector uVec = vGen.generate(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, pgpSec.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass))); PGPSignature sig = sGen.generateCertification(uVec, pubKey); PGPPublicKey nKey = PGPPublicKey.addCertification(pubKey, uVec, sig); Iterator it = nKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = nKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature s = (PGPSignature)sigs.next(); s.init(new BcPGPContentVerifierBuilderProvider(), pubKey); if (!s.verifyCertification(attributes, pubKey)) { fail("added signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed added user attributes signature check"); } count++; } if (count != 1) { fail("didn't find added user attributes"); } nKey = PGPPublicKey.removeCertification(nKey, uVec); count = 0; for (it = nKey.getUserAttributes(); it.hasNext();) { count++; } if (count != 0) { fail("found attributes where none expected"); } }
public void generateTest() throws Exception { char[] passPhrase = "hello".toCharArray(); DSAParametersGenerator dsaPGen = new DSAParametersGenerator(); dsaPGen.init(512, 10, new SecureRandom()); DSAKeyPairGenerator dsaKpg = new DSAKeyPairGenerator(); dsaKpg.init(new DSAKeyGenerationParameters(new SecureRandom(), dsaPGen.generateParameters())); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // AsymmetricCipherKeyPair dsaKp = dsaKpg.generateKeyPair(); ElGamalKeyPairGenerator elgKpg = new ElGamalKeyPairGenerator(); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameters elParams = new ElGamalParameters(p, g); elgKpg.init(new ElGamalKeyGenerationParameters(new SecureRandom(), elParams)); // // this is quicker because we are using pregenerated parameters. // AsymmetricCipherKeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new BcPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new BcPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", null, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } }
public void generateSha1Test() throws Exception { char[] passPhrase = "hello".toCharArray(); DSAParametersGenerator dsaPGen = new DSAParametersGenerator(); dsaPGen.init(512, 10, new SecureRandom()); DSAKeyPairGenerator dsaKpg = new DSAKeyPairGenerator(); dsaKpg.init(new DSAKeyGenerationParameters(new SecureRandom(), dsaPGen.generateParameters())); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // AsymmetricCipherKeyPair dsaKp = dsaKpg.generateKeyPair(); ElGamalKeyPairGenerator elgKpg = new ElGamalKeyPairGenerator(); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameters elParams = new ElGamalParameters(p, g); elgKpg.init(new ElGamalKeyGenerationParameters(new SecureRandom(), elParams)); // // this is quicker because we are using pregenerated parameters. // AsymmetricCipherKeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new BcPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new BcPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPDigestCalculator chkSumCalc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", chkSumCalc, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } }
/** * 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 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); } }
/** * @see MessageSigner#verifyMessage(InputStream, InputStream, InputStream) * * @param publicKeyOfSender * the public key of the sender of the message * @param message * the message / data to verify * @param signatureStream * the (detached) signature * @return */ @Override public boolean verifyMessage(InputStream publicKeyOfSender, InputStream message, InputStream signatureStream) { LOGGER.trace("verifyMessage(InputStream, InputStream, InputStream)"); LOGGER.trace("Public Key: {}, Data: {}, Signature: {}", publicKeyOfSender == null ? "not set" : "set", message == null ? "not set" : "set", signatureStream == null ? "not set" : "set"); boolean result = false; LOGGER.debug("Wrapping signature stream in ArmoredInputStream"); try( InputStream armordPublicKeyStream = new ArmoredInputStream(signatureStream) ) { Object pgpObject; PGPObjectFactory pgpObjectFactory = new PGPObjectFactory(armordPublicKeyStream, new BcKeyFingerprintCalculator()); LOGGER.debug("Iterating over PGP objects in stream"); while( (pgpObject = pgpObjectFactory.nextObject()) != null ) { if( pgpObject instanceof PGPSignatureList ) { LOGGER.debug("Signature List found"); PGPSignatureList signatureList = (PGPSignatureList)pgpObject; LOGGER.debug("Iterating over signature list"); Iterator<PGPSignature> signatureIterator = signatureList.iterator(); while( signatureIterator.hasNext() ) { LOGGER.debug("Checking next signature"); final PGPSignature signature = signatureIterator.next(); PGPPublicKey pgpPublicKey = findPublicKey(publicKeyOfSender, new KeyFilter<PGPPublicKey>() { @Override public boolean accept(PGPPublicKey pgpKey) { return pgpKey.getKeyID() == signature.getKeyID(); } }); if( pgpPublicKey != null ) { signature.init(new BcPGPContentVerifierBuilderProvider(), pgpPublicKey); LOGGER.debug("Processing signature data"); IOUtils.process(message, new IOUtils.StreamHandler() { @Override public void handleStreamBuffer(byte[] buffer, int offset, int length) throws IOException { signature.update(buffer, offset, length); } }); result = signature.verify(); LOGGER.info("Verify Signature: {}", result); } else { LOGGER.warn("No public key found for signature. Key ID: {}", signature.getKeyID()); } } } } } catch (IOException | PGPException e) { LOGGER.error("{}", e.getMessage()); result &= false; } return result; }
private void checkRevocations( PGPPublicKey key, List<PGPSignature> revocations, Map<Long, RevocationKey> revokers, List<String> problems) throws PGPException, IOException { for (PGPSignature revocation : revocations) { RevocationKey revoker = revokers.get(revocation.getKeyID()); if (revoker == null) { continue; // Not a designated revoker. } byte[] rfp = revoker.getFingerprint(); PGPPublicKeyRing revokerKeyRing = store.get(rfp); if (revokerKeyRing == null) { // Revoker is authorized and there is a revocation signature by this // revoker, but the key is not in the store so we can't verify the // signature. log.info( "Key " + Fingerprint.toString(key.getFingerprint()) + " is revoked by " + Fingerprint.toString(rfp) + ", which is not in the store. Assuming revocation is valid."); problems.add(reasonToString(getRevocationReason(revocation))); continue; } PGPPublicKey rk = revokerKeyRing.getPublicKey(); if (rk.getAlgorithm() != revoker.getAlgorithm()) { continue; } if (!checkBasic(rk, revocation.getCreationTime()).isOk()) { // Revoker's key was expired or revoked at time of revocation, so the // revocation is invalid. continue; } revocation.init(new BcPGPContentVerifierBuilderProvider(), rk); if (revocation.verifyCertification(key)) { problems.add(reasonToString(getRevocationReason(revocation))); } } }
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); }
/** * Verifies detached PGP signatures against GPG/openPGP RSA public keys. Does currently not work with openssl or JCA/JCE keys. * * @param pubKeyFile Path to file providing the public key to use * @param sigFile Path to detached signature file * @param dataFile Path to signed data file * @return {@code true} if signature is valid, {@code false} if signature is not valid * @throws Exception throws various exceptions in case something went wrong. Main reason should be that key or * signature could be extracted from the provided files due to a "bad" format.<br> * <code>FileNotFoundException, IOException, SignatureException, PGPException</code> */ public static VerifyStatusEnum verifySignature(File pubKeyFile, File sigFile, File dataFile) throws Exception { InputStream inputStream; int bytesRead; PGPPublicKey publicKey; PGPSignature pgpSignature; boolean result; // Read keys from file inputStream = PGPUtil.getDecoderStream(new FileInputStream(pubKeyFile)); PGPPublicKeyRingCollection publicKeyRingCollection = new PGPPublicKeyRingCollection(inputStream, new JcaKeyFingerprintCalculator()); inputStream.close(); Iterator<PGPPublicKeyRing> iterator = publicKeyRingCollection.getKeyRings(); PGPPublicKeyRing pgpPublicKeyRing; if (iterator.hasNext()) { pgpPublicKeyRing = iterator.next(); } else { throw new PGPException("Could not find public keyring in provided key file"); } // Would be the solution for multiple keys in one file // Iterator<PGPPublicKey> kIt; // kIt = pgpPublicKeyRing.getPublicKeys(); // publicKey = pgpPublicKeyRing.getPublicKey(0xF5B84436F379A1C6L); // Read signature from file inputStream = PGPUtil.getDecoderStream(new FileInputStream(sigFile)); PGPObjectFactory pgpObjectFactory = new PGPObjectFactory(inputStream, new JcaKeyFingerprintCalculator()); Object o = pgpObjectFactory.nextObject(); if (o instanceof PGPSignatureList) { PGPSignatureList signatureList = (PGPSignatureList) o; checkArgument(!signatureList.isEmpty(), "signatureList must not be empty"); pgpSignature = signatureList.get(0); } else if (o instanceof PGPSignature) { pgpSignature = (PGPSignature) o; } else { throw new SignatureException("Could not find signature in provided signature file"); } inputStream.close(); log.debug("KeyID used in signature: %X\n", pgpSignature.getKeyID()); publicKey = pgpPublicKeyRing.getPublicKey(pgpSignature.getKeyID()); // If signature is not matching the key used for signing we fail if (publicKey == null) return VerifyStatusEnum.FAIL; log.debug("The ID of the selected key is %X\n", publicKey.getKeyID()); pgpSignature.init(new BcPGPContentVerifierBuilderProvider(), publicKey); // Read file to verify byte[] data = new byte[1024]; inputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(dataFile))); while (true) { bytesRead = inputStream.read(data, 0, 1024); if (bytesRead == -1) break; pgpSignature.update(data, 0, bytesRead); } inputStream.close(); // Verify the signature result = pgpSignature.verify(); return result ? VerifyStatusEnum.OK : VerifyStatusEnum.FAIL; }
public void generateTest() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(512); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(elParams); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", PGPEncryptedData.AES_256, passPhrase, null, null, new SecureRandom(), "BC"); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } }
public void generateSha1Test() throws Exception { char[] passPhrase = "hello".toCharArray(); KeyPairGenerator dsaKpg = KeyPairGenerator.getInstance("DSA", "BC"); dsaKpg.initialize(512); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // KeyPair dsaKp = dsaKpg.generateKeyPair(); KeyPairGenerator elgKpg = KeyPairGenerator.getInstance("ELGAMAL", "BC"); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameterSpec elParams = new ElGamalParameterSpec(p, g); elgKpg.initialize(elParams); // // this is quicker because we are using pregenerated parameters. // KeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new PGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new PGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", PGPEncryptedData.AES_256, passPhrase, true, null, null, new SecureRandom(), "BC"); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } }
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); } }
private static boolean verifyKeySignature(PGPPublicKey publicKey, PGPSignature sig) throws PGPException { sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey); return sig.verifyCertification(publicKey); }
private static boolean verifyUidSignature(PGPPublicKey publicKey, PGPSignature sig, PGPPublicKey signerKey, String uid) throws PGPException { sig.init(new BcPGPContentVerifierBuilderProvider(), signerKey); return sig.verifyCertification(uid, publicKey); }