jruby-pgp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ # Skip our compiled jruby-pgp.jar
20
+ lib/pgp/jruby-pgp.jar
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jruby-pgp.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Scott Gonyea
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,37 @@
1
+ # PGP
2
+
3
+ This is a Java + JRuby wrapper around the Bouncy Castle PGP APIs.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'jruby-pgp'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install jruby-pgp
18
+
19
+ ## Usage
20
+
21
+ This gem currently features everything I need and nothing I don't. Pull requests are very much welcome;
22
+ feature requests will be considered.
23
+
24
+ The general goal is to provide fast, non-terrible wrappers around the Bouncy Castle PGP APIs. Bare-metal
25
+ JRuby code will then plug into those wrappers, to minimize memory bloat. Directly hooking JRuby into the
26
+ BC PGP APIs is certainly possible, but they are a poorly designed pile of rocks. Using these APIs from
27
+ JRuby can yield some unwanted bloat, especially when you're resource constrained:
28
+
29
+ [Example using BC PGP directly from JRuby](https://gist.github.com/1954648)
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create new Pull Request
@@ -0,0 +1,21 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/javaextensiontask'
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ Rake::JavaExtensionTask.new('jruby-pgp') do |ext|
7
+ jruby_home = RbConfig::CONFIG['prefix']
8
+ jars = ["#{jruby_home}/lib/jruby.jar"] + FileList['lib/pgp/jars/*.jar']
9
+
10
+ ext.ext_dir = 'ext'
11
+ ext.lib_dir = 'lib/pgp'
12
+ ext.classpath = jars.map { |x| File.expand_path x }.join ':'
13
+ end
14
+
15
+ RSpec::Core::RakeTask.new(:rcov) do |task|
16
+ task.rcov = true
17
+ end
18
+
19
+ task :default => %w(compile spec)
20
+
21
+ task :build => :compile
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Much of this code was stolen from this Stack Overflow post:
3
+ * http://stackoverflow.com/questions/3939447/how-to-encrypt-a-string-stream-with-bouncycastle-pgp-without-starting-with-a-fil
4
+ *
5
+ * In addition to the java versions of this lump of code, that have been floating around on the internet:
6
+ * https://gist.github.com/1954648
7
+ *
8
+ * Thanks to everyone who has posted on the topic of Bouncy Castle's PGP Library.
9
+ */
10
+
11
+ package org.sgonyea.pgp;
12
+
13
+ import java.io.ByteArrayInputStream;
14
+ import java.io.ByteArrayOutputStream;
15
+ import java.io.File;
16
+ import java.io.FileInputStream;
17
+ import java.io.FileOutputStream;
18
+ import java.io.IOException;
19
+ import java.io.InputStream;
20
+ import java.io.OutputStream;
21
+ import java.security.NoSuchProviderException;
22
+ import java.security.SecureRandom;
23
+ import java.security.Security;
24
+ import java.util.Date;
25
+ import java.util.Iterator;
26
+ import java.util.List;
27
+ import java.util.ArrayList;
28
+
29
+ import org.bouncycastle.bcpg.ArmoredOutputStream;
30
+ import org.bouncycastle.bcpg.CompressionAlgorithmTags;
31
+ import org.bouncycastle.jce.provider.BouncyCastleProvider;
32
+ import org.bouncycastle.openpgp.PGPCompressedData;
33
+ import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
34
+ import org.bouncycastle.openpgp.PGPEncryptedData;
35
+ import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
36
+ import org.bouncycastle.openpgp.PGPEncryptedDataList;
37
+ import org.bouncycastle.openpgp.PGPException;
38
+ import org.bouncycastle.openpgp.PGPLiteralData;
39
+ import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
40
+ import org.bouncycastle.openpgp.PGPObjectFactory;
41
+ import org.bouncycastle.openpgp.PGPPrivateKey;
42
+ import org.bouncycastle.openpgp.PGPPublicKey;
43
+ import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
44
+ import org.bouncycastle.openpgp.PGPPublicKeyRing;
45
+ import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
46
+ import org.bouncycastle.openpgp.PGPSecretKey;
47
+ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
48
+ import org.bouncycastle.openpgp.PGPUtil;
49
+ import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder;
50
+ import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator;
51
+
52
+ public class Encryptor {
53
+ private List<PGPPublicKey> _publicKeys;
54
+ private List<BcPublicKeyKeyEncryptionMethodGenerator> _publicKeyEMGs;
55
+ private boolean _integrityCheck;
56
+ private boolean _asciiArmor;
57
+ private char _format;
58
+ private int _compression;
59
+ private int _algorithm;
60
+
61
+ private void init() {
62
+ _publicKeys = new ArrayList<PGPPublicKey>();
63
+ _publicKeyEMGs = new ArrayList<BcPublicKeyKeyEncryptionMethodGenerator>();
64
+ _integrityCheck = true;
65
+ _asciiArmor = true;
66
+
67
+ useBinaryFormat();
68
+ useZIPCompression();
69
+
70
+ _algorithm = PGPEncryptedData.CAST5;
71
+ }
72
+
73
+ public Encryptor() {
74
+ init();
75
+ }
76
+
77
+ public Encryptor(PGPPublicKey publicKey) {
78
+ init();
79
+ addPublicKey(publicKey);
80
+ }
81
+
82
+ public Encryptor(List<PGPPublicKey> publicKeys) {
83
+ init();
84
+ addPublicKeys(publicKeys);
85
+ }
86
+
87
+
88
+ /**
89
+ * Accessor and Attribute Helper Methods
90
+ */
91
+
92
+ /* integrityCheck */
93
+ public void setIntegrityCheck(boolean integrityCheck) {
94
+ _integrityCheck = integrityCheck;
95
+ }
96
+
97
+ public boolean getIntegrityCheck() {
98
+ return _integrityCheck;
99
+ }
100
+
101
+ /* asciiArmor */
102
+ public void setAsciiArmor(boolean asciiArmor) {
103
+ _asciiArmor = asciiArmor;
104
+ }
105
+
106
+ public boolean getAsciiArmor() {
107
+ return _asciiArmor;
108
+ }
109
+
110
+ /* publicKeys */
111
+ public void setPublicKeys(List<PGPPublicKey> publicKeys) {
112
+ _publicKeys = publicKeys;
113
+
114
+ clearPublicKeyEMGs();
115
+ addToPublicKeyEMG(publicKeys);
116
+ }
117
+
118
+ public List<PGPPublicKey> getPublicKeys() {
119
+ return _publicKeys;
120
+ }
121
+
122
+ public void addPublicKey(PGPPublicKey publicKey) {
123
+ _publicKeys.add(publicKey);
124
+ addToPublicKeyEMG(publicKey);
125
+ }
126
+
127
+ public void addPublicKeys(List<PGPPublicKey> publicKeys) {
128
+ _publicKeys.addAll(publicKeys);
129
+
130
+ addToPublicKeyEMG(publicKeys);
131
+ }
132
+
133
+ /* publicKeyEMGs */
134
+ public List<BcPublicKeyKeyEncryptionMethodGenerator> getPublicKeyEMGs() {
135
+ return _publicKeyEMGs;
136
+ }
137
+
138
+ public void clearPublicKeyEMGs() {
139
+ _publicKeyEMGs = new ArrayList<BcPublicKeyKeyEncryptionMethodGenerator>();
140
+ }
141
+
142
+ public void addToPublicKeyEMG(PGPPublicKey publicKey) {
143
+ _publicKeyEMGs.add(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
144
+ }
145
+
146
+ public void addToPublicKeyEMG(List<PGPPublicKey> publicKeys) {
147
+ for(PGPPublicKey publicKey : publicKeys) {
148
+ addToPublicKeyEMG(publicKey);
149
+ }
150
+ }
151
+
152
+ /* format */
153
+ public char getFormat() {
154
+ return _format;
155
+ }
156
+
157
+ public void setFormat(char format) {
158
+ switch(format) {
159
+ case PGPLiteralData.BINARY:
160
+ case PGPLiteralData.TEXT:
161
+ case PGPLiteralData.UTF8: _format = format; break;
162
+ default:
163
+ throw new IllegalArgumentException("Invalid format. Acceptable formats: 'b', 't', or 'u' (respectively: binary, text, or utf8)");
164
+ }
165
+ }
166
+ public void useBinaryFormat() { setFormat(PGPLiteralData.BINARY); }
167
+ public void useTextFormat() { setFormat(PGPLiteralData.TEXT); }
168
+ public void useUTF8Format() { setFormat(PGPLiteralData.UTF8); }
169
+
170
+ /* compression */
171
+ public int getCompression() {
172
+ return _compression;
173
+ }
174
+
175
+ public void setCompression(int compression) {
176
+ _compression = compression;
177
+ }
178
+ public void useNoCompression() { setCompression(CompressionAlgorithmTags.UNCOMPRESSED); }
179
+ public void useZIPCompression() { setCompression(CompressionAlgorithmTags.ZIP); }
180
+ public void useZLIBCompression() { setCompression(CompressionAlgorithmTags.ZLIB); }
181
+ public void useBZIP2Compression() { setCompression(CompressionAlgorithmTags.BZIP2); }
182
+
183
+ /* algorithm */
184
+ public int getAlgorithm() {
185
+ return _algorithm;
186
+ }
187
+
188
+ /**
189
+ * @see org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags
190
+ */
191
+ public void setAlgorithm(int algorithm) {
192
+ _algorithm = algorithm;
193
+ }
194
+
195
+ /** End Accessor Methods **/
196
+
197
+
198
+ /**
199
+ * Encryption Class / Static Methods
200
+ */
201
+
202
+ /**
203
+ * This method preserves the much of the original API, so that you can just call the class method should you need to.
204
+ */
205
+ public static byte[] encrypt(byte[] clearData, List<PGPPublicKey> publicKeys, String fileName, boolean withIntegrityCheck, boolean armor)
206
+ throws IOException, PGPException, NoSuchProviderException {
207
+ Encryptor encryptor = new Encryptor(publicKeys);
208
+
209
+ return encryptor.encrypt(clearData, fileName);
210
+ }
211
+
212
+
213
+ /**
214
+ * Encryption Instance Methods
215
+ */
216
+ public byte[] encrypt(byte[] clearData, String fileName)
217
+ throws IOException, PGPException, NoSuchProviderException {
218
+ return encrypt(clearData, fileName, new Date());
219
+ }
220
+
221
+ /**
222
+ * Allows you to override the modificationTime. This method was split off
223
+ * for mock-free testing of encrypted output.
224
+ */
225
+ public byte[] encrypt(byte[] clearData, String fileName, Date modificationTime)
226
+ throws IOException, PGPException, NoSuchProviderException {
227
+ if (fileName == null)
228
+ fileName = PGPLiteralData.CONSOLE;
229
+
230
+ PGPEncryptedDataGenerator pgpDataGenerator = newPGPDataGenerator();
231
+ PGPLiteralDataGenerator dataGenerator = new PGPLiteralDataGenerator();
232
+ PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(getCompression());
233
+
234
+ ByteArrayOutputStream compressedOutput = new ByteArrayOutputStream();
235
+ ByteArrayOutputStream encryptedOutput = new ByteArrayOutputStream();
236
+
237
+ OutputStream compressedDataStream = compressedDataGenerator.open(compressedOutput); // open it with the final
238
+ OutputStream output = encryptedOutput;
239
+ OutputStream compressorStream;
240
+ OutputStream encryptorStream;
241
+
242
+ byte[] compressedBytes;
243
+
244
+ // Step 1: Compress the data
245
+ compressorStream = dataGenerator.open(
246
+ compressedDataStream, // the compressed output stream
247
+ getFormat(),
248
+ fileName, // "filename" to store
249
+ clearData.length, // length of clear data
250
+ modificationTime // current time
251
+ );
252
+ compressorStream.write(clearData);
253
+
254
+ dataGenerator.close();
255
+ compressedDataGenerator.close();
256
+
257
+ compressedBytes = compressedOutput.toByteArray();
258
+
259
+
260
+ // Step 2: ASCII Armor the data if desired
261
+ output = encryptedOutput;
262
+ if (getAsciiArmor())
263
+ output = new ArmoredOutputStream(output);
264
+
265
+
266
+ // Step 3: Encrypt the data
267
+ encryptorStream = pgpDataGenerator.open(output, compressedBytes.length);
268
+ encryptorStream.write(compressedBytes);
269
+ encryptorStream.close();
270
+
271
+ output.close();
272
+
273
+ // Return the data as a byte array
274
+ return encryptedOutput.toByteArray();
275
+ }
276
+
277
+ public PGPEncryptedDataGenerator newPGPDataGenerator() {
278
+ PGPEncryptedDataGenerator generator;
279
+ BcPGPDataEncryptorBuilder builder;
280
+
281
+ builder = new BcPGPDataEncryptorBuilder(getAlgorithm());
282
+ builder.setWithIntegrityPacket(getIntegrityCheck());
283
+
284
+ generator = new PGPEncryptedDataGenerator(builder);
285
+
286
+ // Add all our public keys to the Data Generator
287
+ for(BcPublicKeyKeyEncryptionMethodGenerator fml : getPublicKeyEMGs()) {
288
+ generator.addMethod(fml);
289
+ }
290
+
291
+ return generator;
292
+ }
293
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Much of this code was stolen from this Stack Overflow post:
3
+ * http://stackoverflow.com/questions/3939447/how-to-encrypt-a-string-stream-with-bouncycastle-pgp-without-starting-with-a-fil
4
+ *
5
+ * In addition to the java versions of this lump of code, that have been floating around on the internet:
6
+ * https://gist.github.com/1954648
7
+ *
8
+ * Thanks to everyone who has posted on the topic of Bouncy Castle's PGP Library.
9
+ */
10
+
11
+ package org.sgonyea.pgp;
12
+
13
+ import java.io.ByteArrayInputStream;
14
+ import java.io.ByteArrayOutputStream;
15
+ import java.io.File;
16
+ import java.io.FileInputStream;
17
+ import java.io.FileOutputStream;
18
+ import java.io.IOException;
19
+ import java.io.InputStream;
20
+ import java.io.OutputStream;
21
+ import java.security.NoSuchProviderException;
22
+ import java.security.SecureRandom;
23
+ import java.security.Security;
24
+ import java.util.Date;
25
+ import java.util.Iterator;
26
+
27
+ import org.bouncycastle.bcpg.ArmoredOutputStream;
28
+ import org.bouncycastle.jce.provider.BouncyCastleProvider;
29
+ import org.bouncycastle.openpgp.PGPCompressedData;
30
+ import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
31
+ import org.bouncycastle.openpgp.PGPEncryptedData;
32
+ import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
33
+ import org.bouncycastle.openpgp.PGPEncryptedDataList;
34
+ import org.bouncycastle.openpgp.PGPException;
35
+ import org.bouncycastle.openpgp.PGPLiteralData;
36
+ import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
37
+ import org.bouncycastle.openpgp.PGPObjectFactory;
38
+ import org.bouncycastle.openpgp.PGPPrivateKey;
39
+ import org.bouncycastle.openpgp.PGPPublicKey;
40
+ import org.bouncycastle.openpgp.PGPPublicKeyEncryptedData;
41
+ import org.bouncycastle.openpgp.PGPPublicKeyRing;
42
+ import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
43
+ import org.bouncycastle.openpgp.PGPSecretKey;
44
+ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
45
+ import org.bouncycastle.openpgp.PGPUtil;
46
+
47
+ public class PGP {
48
+
49
+ }
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'pgp/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = 'jruby-pgp'
9
+ gem.version = PGP::VERSION
10
+ gem.authors = ['Scott Gonyea']
11
+ gem.email = ['me@sgonyea.com']
12
+ gem.description = %q{PGP for JRuby}
13
+ gem.summary = %q{This is a Java+JRuby wrapper around the Bouncy Castle PGP APIs}
14
+ gem.homepage = 'https://github.com/sgonyea/jruby-pgp'
15
+
16
+ gem.files = `git ls-files`.split($/) + %w[lib/pgp/jruby-pgp.jar]
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ['lib']
20
+
21
+ gem.add_development_dependency 'rake'
22
+ gem.add_development_dependency 'rspec'
23
+ gem.add_development_dependency 'rake-compiler'
24
+ end
@@ -0,0 +1 @@
1
+ require 'pgp'
@@ -0,0 +1,24 @@
1
+ require 'java'
2
+ require 'pgp/jars/bcprov-jdk15on-147.jar'
3
+ require 'pgp/jars/bcpg-jdk15on-147.jar'
4
+ require 'pgp/jruby-pgp.jar'
5
+
6
+ require 'pgp/decryptor'
7
+ require 'pgp/encryptor'
8
+ require 'pgp/private_key'
9
+
10
+ module PGP
11
+ autoload :VERSION, 'pgp/version'
12
+
13
+ BC_Provider_Code = "BC"
14
+
15
+ java_import 'java.io.ByteArrayInputStream'
16
+ java_import 'java.security.Security'
17
+ java_import 'org.bouncycastle.jce.provider.BouncyCastleProvider'
18
+
19
+ Security.add_provider BouncyCastleProvider.new
20
+
21
+ def self.string_to_bais(string)
22
+ ByteArrayInputStream.new string.to_java_bytes
23
+ end
24
+ end
@@ -0,0 +1,58 @@
1
+ module PGP
2
+ class Decryptor
3
+ include_package "org.bouncycastle.openpgp"
4
+
5
+ java_import 'java.io.ByteArrayOutputStream'
6
+
7
+ def self.decrypt(encrypted_text, private_key_file)
8
+ bytes = PGP.string_to_bais(encrypted_text)
9
+ dec_s = PGPUtil.get_decoder_stream(bytes)
10
+ pgp_f = PGPObjectFactory.new(dec_s)
11
+
12
+ enc_data = pgp_f.next_object
13
+ enc_data = pgp_f.next_object unless PGPEncryptedDataList === enc_data
14
+
15
+ data_enumerator = enc_data.get_encrypted_data_objects
16
+
17
+ sec_key = nil
18
+ pbe = nil
19
+
20
+ data_enumerator.each do |pubkey_enc_data|
21
+ pbe = pubkey_enc_data
22
+ key_id = pubkey_enc_data.get_key_id
23
+ sec_key = PrivateKey.from_file(private_key_file, key_id)
24
+
25
+ if sec_key.nil?
26
+ # @todo: Should we notify Airbrake?
27
+ Ace.logger.debug "This may be cause for concern. The data being decrypted has a key_id of '#{key_id}', which can not be found in the private key file '#{CE_Private_Key}'."
28
+ else
29
+ break
30
+ end
31
+ end
32
+
33
+ clear = pbe.get_data_stream(sec_key, BC_Provider_Code)
34
+
35
+ plain_fact = PGPObjectFactory.new(clear)
36
+
37
+ message = plain_fact.next_object
38
+
39
+ if(PGPCompressedData === message)
40
+ pgp_fact = PGPObjectFactory.new(message.get_data_stream)
41
+ message = pgp_fact.next_object
42
+ end
43
+
44
+ baos = ByteArrayOutputStream.new
45
+
46
+ if(PGPLiteralData === message)
47
+ unc = message.get_input_stream
48
+ while((ch = unc.read) >= 0)
49
+ baos.write(ch)
50
+ end
51
+ end
52
+
53
+ baos.to_string
54
+ end
55
+
56
+
57
+ end
58
+ end
@@ -0,0 +1,28 @@
1
+ module PGP
2
+ class Encryptor < org.sgonyea.pgp.Encryptor
3
+ include_package "org.bouncycastle.openpgp"
4
+
5
+ def add_keys_from_file(filename)
6
+ key_enumerator = keyring_from_file(filename).get_key_rings
7
+
8
+ key_enumerator.each do |pk_ring|
9
+ pk_enumerator = pk_ring.get_public_keys
10
+
11
+ pk_enumerator.each do |key|
12
+ next unless key.is_encryption_key
13
+
14
+ add_public_key key
15
+ end
16
+ end
17
+ end
18
+
19
+ protected
20
+ def keyring_from_file(filename)
21
+ file = File.open(filename)
22
+ yafs = PGPUtil.get_decoder_stream(file.to_inputstream)
23
+
24
+ PGPPublicKeyRingCollection.new(yafs)
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ module PGP
2
+ # This is more module than class. Eventually it will probably inherit from
3
+ # the PGPPrivateKey class and make using it less ghoulish.
4
+ class PrivateKey
5
+ include_package "org.bouncycastle.openpgp"
6
+
7
+ def self.from_string(string, key_id)
8
+ stream = PGP.string_to_bais(string)
9
+ pgp_sec = keyring_from_stream(stream)
10
+ sec_key = pgp_sec.get_secret_key(key_id)
11
+
12
+ sec_key.extract_private_key(nil, BC_Provider_Code) if sec_key
13
+ end
14
+
15
+ def self.from_file(filename, key_id)
16
+ pgp_sec = keyring_from_file(filename)
17
+ sec_key = pgp_sec.get_secret_key(key_id)
18
+
19
+ sec_key.extract_private_key(nil, BC_Provider_Code) if sec_key
20
+ end
21
+
22
+ protected
23
+ def self.keyring_from_file(filename)
24
+ file = File.open(filename)
25
+ keyring_from_stream(file.to_inputstream)
26
+ end
27
+
28
+ def self.keyring_from_stream(stream)
29
+ yafs = PGPUtil.get_decoder_stream(stream)
30
+ PGPSecretKeyRingCollection.new(yafs)
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module PGP
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGP::Encryptor do
4
+ let(:private_key_path) { Fixtures_Path.join('private_key.asc').to_s }
5
+ let(:public_key_path) { Fixtures_Path.join('public_key.asc').to_s }
6
+
7
+ describe '#encrypt' do
8
+ let(:string) { "FooBar" }
9
+ let(:encryptor) { PGP::Encryptor.new }
10
+
11
+ before {
12
+ encryptor.add_keys_from_file(public_key_path)
13
+ }
14
+
15
+ it "it's encrypted string should be decryptable. durr" do
16
+ encrypted_string = encryptor.encrypt(string.to_java_bytes, "some filename")
17
+
18
+ PGP::Decryptor.decrypt(String.from_java_bytes(encrypted_string), private_key_path).should == string
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,25 @@
1
+ require 'bundler/setup'
2
+
3
+ Bundler.require :development, :test
4
+
5
+ require 'jruby-pgp'
6
+
7
+ Fixtures_Path = Bundler.root + 'spec/support/fixtures/'
8
+
9
+ # This file was generated by the `rspec --init` command. Conventionally, all
10
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
11
+ # Require this file using `require "spec_helper"` to ensure that it is only
12
+ # loaded once.
13
+ #
14
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
15
+ RSpec.configure do |config|
16
+ config.treat_symbols_as_metadata_keys_with_true_values = true
17
+ config.run_all_when_everything_filtered = true
18
+ config.filter_run :focus
19
+
20
+ # Run specs in random order to surface order dependencies. If you find an
21
+ # order dependency and want to debug it, you can fix the order by providing
22
+ # the seed, which is printed after each run.
23
+ # --seed 1234
24
+ config.order = 'random'
25
+ end
@@ -0,0 +1,63 @@
1
+ -----BEGIN PGP PRIVATE KEY BLOCK-----
2
+ Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
+
4
+ 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
62
+ =Xb/x
63
+ -----END PGP PRIVATE KEY BLOCK-----
@@ -0,0 +1,36 @@
1
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
2
+ Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
3
+
4
+ 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
34
+ Jkt3CWvXLoN0LHFHnS56KNOYpHWKPd3Z1HeD6w==
35
+ =vAW+
36
+ -----END PGP PUBLIC KEY BLOCK-----
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jruby-pgp
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Scott Gonyea
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-11-17 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake-compiler
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
48
+ description: PGP for JRuby
49
+ email:
50
+ - me@sgonyea.com
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - .rspec
60
+ - Gemfile
61
+ - LICENSE.txt
62
+ - README.md
63
+ - Rakefile
64
+ - ext/org/sgonyea/pgp/Encryptor.java
65
+ - ext/org/sgonyea/pgp/PGP.java
66
+ - jruby-pgp.gemspec
67
+ - lib/jruby-pgp.rb
68
+ - lib/pgp.rb
69
+ - lib/pgp/decryptor.rb
70
+ - lib/pgp/encryptor.rb
71
+ - lib/pgp/jars/bcpg-jdk15on-147.jar
72
+ - lib/pgp/jars/bcprov-jdk15on-147.jar
73
+ - lib/pgp/private_key.rb
74
+ - lib/pgp/version.rb
75
+ - spec/lib/pgp/encryptor_spec.rb
76
+ - spec/spec_helper.rb
77
+ - spec/support/fixtures/private_key.asc
78
+ - spec/support/fixtures/public_key.asc
79
+ - lib/pgp/jruby-pgp.jar
80
+ homepage: https://github.com/sgonyea/jruby-pgp
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options: []
85
+
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ requirements: []
101
+
102
+ rubyforge_project:
103
+ rubygems_version: 1.8.24
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: This is a Java+JRuby wrapper around the Bouncy Castle PGP APIs
107
+ test_files:
108
+ - spec/lib/pgp/encryptor_spec.rb
109
+ - spec/spec_helper.rb
110
+ - spec/support/fixtures/private_key.asc
111
+ - spec/support/fixtures/public_key.asc