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.
- 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
|