Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ test/version_tmp
tmp

# Skip our compiled jruby-pgp.jar
lib/pgp/jruby-pgp.jar
#lib/pgp/jruby-pgp.jar
65 changes: 44 additions & 21 deletions ext/org/sgonyea/pgp/Decryptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,21 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Date;
import java.util.Iterator;

import org.bouncycastle.bcpg.ArmoredOutputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedData;
import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
import org.bouncycastle.openpgp.PGPEncryptedDataList;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPLiteralData;
import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
import org.bouncycastle.openpgp.PGPObjectFactory;
import org.bouncycastle.openpgp.PGPPrivateKey;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.*;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;

public class Decryptor {

private PGPSecretKeyRingCollection _privateKeys;
private PGPPublicKeyRingCollection _publicKeys;

private String passphrase;

Expand All @@ -66,6 +53,10 @@ public void setPrivateKeys(PGPSecretKeyRingCollection privateKeys) {
_privateKeys = privateKeys;
}

public void setPublicKeys(PGPPublicKeyRingCollection publicKeys) {
_publicKeys = publicKeys;
}

public void setPassphrase(String passphrase) {
this.passphrase = passphrase;
}
Expand All @@ -87,13 +78,13 @@ public PGPPrivateKey findPrivateKey(long keyID)
**/

public byte[] decryptBytes(byte[] encryptedBytes)
throws IOException, PGPException, NoSuchProviderException {
throws IOException, PGPException, NoSuchProviderException, SignatureException, VerificationFailedException {
InputStream stream = new ByteArrayInputStream(encryptedBytes);
return decryptStream(stream);
}

public byte[] decryptStream(InputStream encryptedStream)
throws IOException, PGPException, NoSuchProviderException {
throws IOException, PGPException, NoSuchProviderException, SignatureException, VerificationFailedException {

InputStream decoderStream = PGPUtil.getDecoderStream(encryptedStream);

Expand Down Expand Up @@ -135,17 +126,49 @@ public byte[] decryptStream(InputStream encryptedStream)

pgpFactory = new PGPObjectFactory(compressedData.getDataStream());

literallyTheRealFuckingData = (PGPLiteralData) pgpFactory.nextObject();
PGPOnePassSignatureList opsList = null;
PGPOnePassSignature ops = null;
PGPPublicKey signingKey = null;
Object obj = pgpFactory.nextObject();
if (obj instanceof PGPOnePassSignatureList) {
opsList = (PGPOnePassSignatureList) obj;
ops = opsList.get(0);
if (_publicKeys != null) {
signingKey = _publicKeys.getPublicKey(ops.getKeyID());
// TODO warn on key not found
}
// TODO warn on no public keys set
if (signingKey != null) {
ops.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), signingKey);
}

literallyTheRealFuckingData = (PGPLiteralData) pgpFactory.nextObject();
} else if (obj instanceof PGPLiteralData) {
literallyTheRealFuckingData = (PGPLiteralData) obj;
} else {
throw new RuntimeException("unexpected object");
}

decryptedDataStream = literallyTheRealFuckingData.getInputStream();

int ch;
while ((ch = decryptedDataStream.read()) >= 0)
while ((ch = decryptedDataStream.read()) >= 0) {
if (signingKey != null) {
ops.update((byte)ch);
}
outputStream.write(ch);
}

returnBytes = outputStream.toByteArray();
outputStream.close();

if (signingKey != null) {
PGPSignatureList sigList = (PGPSignatureList) pgpFactory.nextObject();
if (!ops.verify(sigList.get(0))) {
throw new VerificationFailedException("Error: Signature could not be verified.");
}
}

return returnBytes;
}

Expand Down
4 changes: 2 additions & 2 deletions jruby-pgp.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ Gem::Specification.new do |gem|
gem.summary = %q{This is a Java+JRuby wrapper around the Bouncy Castle PGP APIs}
gem.homepage = 'https://github.com/sgonyea/jruby-pgp'

gem.files = `git ls-files`.split($/) + %w[lib/pgp/jruby-pgp.jar]
gem.files = `git ls-files`.split($/)
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.require_paths = ['lib']

gem.add_dependency 'jruby-openssl'
#gem.add_dependency 'jruby-openssl'

gem.add_development_dependency 'rake'
gem.add_development_dependency 'rspec'
Expand Down
23 changes: 23 additions & 0 deletions lib/pgp/decryptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ def add_keys_from_file(filename)
self.private_keys = keyring_from_file(filename)
end

def add_public_keys(key_string)
self.public_keys = public_keyring_from_string(key_string)
end

def add_public_keys_from_file(filename)
self.public_keys = public_keyring_from_file(filename)
end

def decrypt(encrypted_data)
input_stream = PGP.string_to_bais(encrypted_data)
decrypted_data = decrypt_stream(input_stream)
Expand All @@ -36,5 +44,20 @@ def keyring_from_stream(stream)
PGPSecretKeyRingCollection.new(yafs)
end

def public_keyring_from_file(filename)
file = File.open(filename)
public_keyring_from_stream(file.to_inputstream)
end

def public_keyring_from_string(string)
input_stream = PGP.string_to_bais(string)
public_keyring_from_stream(input_stream)
end

def public_keyring_from_stream(stream)
yafs = PGPUtil.get_decoder_stream(stream)
PGPPublicKeyRingCollection.new(yafs)
end

end
end
Binary file added lib/pgp/jruby-pgp.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion lib/pgp/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module PGP
VERSION = '0.3.0'
VERSION = '0.4.0'
end