jruby-pgp 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +20 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +37 -0
- data/Rakefile +21 -0
- data/ext/org/sgonyea/pgp/Encryptor.java +293 -0
- data/ext/org/sgonyea/pgp/PGP.java +49 -0
- data/jruby-pgp.gemspec +24 -0
- data/lib/jruby-pgp.rb +1 -0
- data/lib/pgp.rb +24 -0
- data/lib/pgp/decryptor.rb +58 -0
- data/lib/pgp/encryptor.rb +28 -0
- data/lib/pgp/jars/bcpg-jdk15on-147.jar +0 -0
- data/lib/pgp/jars/bcprov-jdk15on-147.jar +0 -0
- data/lib/pgp/private_key.rb +34 -0
- data/lib/pgp/version.rb +3 -0
- data/spec/lib/pgp/encryptor_spec.rb +22 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/fixtures/private_key.asc +63 -0
- data/spec/support/fixtures/public_key.asc +36 -0
- metadata +111 -0
data/.gitignore
ADDED
@@ -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
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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
|
+
}
|
data/jruby-pgp.gemspec
ADDED
@@ -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
|
data/lib/jruby-pgp.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'pgp'
|
data/lib/pgp.rb
ADDED
@@ -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
|
Binary file
|
Binary file
|
@@ -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
|
data/lib/pgp/version.rb
ADDED
@@ -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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|