/** * Builds a {@link Verifier} for each specified signature * for which a verification key is available. */ protected List<Verifier> buildVerifiers(Iterator signatures) throws PGPException { ArrayList<Verifier> verifiers = new ArrayList<Verifier>(); while (signatures.hasNext()) { Verifier verifier = null; Object signature = signatures.next(); if (signature instanceof PGPSignature) verifier = new Verifier((PGPSignature) signature); else if (signature instanceof PGPOnePassSignature) verifier = new Verifier((PGPOnePassSignature) signature); if (verifier != null && verifier.isKeyAvailable()) verifiers.add(verifier); } return verifiers; }
public void setSig1(PGPOnePassSignature s) throws PGPException { sig1 = s; key = getRing().findById(s.getKeyID()); if (key == null) { if (Decryptor.this.log.isLoggable(Level.INFO)) Decryptor.this.log.info("not found verification key " + Util.formatKeyId(s.getKeyID())); return; } Subkey subkey = key.findById(s.getKeyID()); if (subkey == null || !subkey.isForVerification()) key = null; else s.init(getVerifierProvider(), subkey.getPublicKey()); if (Decryptor.this.log.isLoggable(Level.INFO)) Decryptor.this.log.info((key == null ? "not " : "") + "using verification key " + subkey); }
public static boolean verifySignature( ContentAndSignatures contentAndSignatures, PGPPublicKey publicKey ) throws PGPException { Preconditions.checkNotNull( contentAndSignatures ); Preconditions.checkNotNull( publicKey ); try { for ( int i = 0; i < contentAndSignatures.getOnePassSignatureList().size(); i++ ) { PGPOnePassSignature ops = contentAndSignatures.getOnePassSignatureList().get( 0 ); ops.init( new JcaPGPContentVerifierBuilderProvider().setProvider( provider ), publicKey ); ops.update( contentAndSignatures.getDecryptedContent() ); PGPSignature signature = contentAndSignatures.getSignatureList().get( i ); if ( !ops.verify( signature ) ) { return false; } } return true; } catch ( Exception e ) { throw new PGPException( "Error in verifySignature", e ); } }
private static byte[] readSign( JcaPGPObjectFactory objectFactory, PGPOnePassSignature onePassSignature ) throws IOException { InputStream is = getInputStream( objectFactory ); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int ch; while ( ( ch = is.read() ) >= 0 ) { onePassSignature.update( ( byte ) ch ); bos.write( ch ); } return bos.toByteArray(); }
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" ); } }
private static PGPOnePassSignature getOnePassSignature( PGPPublicKey publicKey, JcaPGPObjectFactory pgpFact ) throws IOException, PGPException { PGPOnePassSignatureList p1 = ( PGPOnePassSignatureList ) pgpFact.nextObject(); PGPOnePassSignature onePassSignature = p1.get( 0 ); onePassSignature.init( new JcaPGPContentVerifierBuilderProvider().setProvider( "BC" ), publicKey ); return onePassSignature; }
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 PGPOnePassSignature getSignature(Exchange exchange, PGPOnePassSignatureList signatureList) throws Exception { if (SIGNATURE_VERIFICATION_OPTION_IGNORE.equals(getSignatureVerificationOption())) { return null; } if (SIGNATURE_VERIFICATION_OPTION_NO_SIGNATURE_ALLOWED.equals(getSignatureVerificationOption())) { throw new PGPException( "PGP message contains a signature although a signature is not expected. Either change the configuration of the PGP decryptor or send a PGP message with no signature."); } List<String> allowedUserIds = determineSignaturenUserIds(exchange); for (int i = 0; i < signatureList.size(); i++) { PGPOnePassSignature signature = signatureList.get(i); // Determine public key from signature keyId PGPPublicKey sigPublicKey = publicKeyAccessor.getPublicKey(exchange, signature.getKeyID(), allowedUserIds); if (sigPublicKey == null) { continue; } // choose that signature for which a public key exists! signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider(getProvider()), sigPublicKey); return signature; } if (signatureList.isEmpty()) { return null; } else { throw new IllegalArgumentException("Cannot verify the PGP signature: No public key found for the key ID(s) contained in the PGP signature(s). " + "Either the received PGP message contains a signature from an unexpected sender or the Public Keyring does not contain the public key of the sender."); } }
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 Verifier(PGPOnePassSignature s) throws PGPException { this(); setSig1(s); }
/** * 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(); }
@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 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)); }
/** * 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"); } }
public static byte[] verify( byte signedData[], PGPPublicKey publicKey ) throws IOException, PGPException { JcaPGPObjectFactory objectFactory = getObjectFactory( signedData ); PGPOnePassSignature onePassSignature = getOnePassSignature( publicKey, objectFactory ); byte data[] = readSign( objectFactory, onePassSignature ); doVerify( objectFactory, onePassSignature ); return data; }