jruby-pgp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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