pkernel_jce 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.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.ruby-version +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +56 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/jars/bcmail-jdk15on-157.jar +0 -0
- data/jars/bcpg-jdk15on-157.jar +0 -0
- data/jars/bcpkix-jdk15on-157.jar +0 -0
- data/jars/bcprov-ext-jdk15on-157.jar +0 -0
- data/jars/bcprov-jdk15on-157.jar +0 -0
- data/lib/pkernel_jce/bc_helpers.rb +51 -0
- data/lib/pkernel_jce/certificate.rb +467 -0
- data/lib/pkernel_jce/certificate_owner.rb +90 -0
- data/lib/pkernel_jce/crl.rb +221 -0
- data/lib/pkernel_jce/csr.rb +126 -0
- data/lib/pkernel_jce/error.rb +7 -0
- data/lib/pkernel_jce/global.rb +17 -0
- data/lib/pkernel_jce/identity.rb +333 -0
- data/lib/pkernel_jce/io_utils.rb +45 -0
- data/lib/pkernel_jce/keypair.rb +359 -0
- data/lib/pkernel_jce/ocsp.rb +415 -0
- data/lib/pkernel_jce/provider.rb +40 -0
- data/lib/pkernel_jce/rfc3161.rb +389 -0
- data/lib/pkernel_jce/utils.rb +59 -0
- data/lib/pkernel_jce/version.rb +3 -0
- data/lib/pkernel_jce.rb +102 -0
- data/pkernel_jce.gemspec +45 -0
- metadata +146 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
module PkernelJce
|
3
|
+
module IoUtils
|
4
|
+
|
5
|
+
def IoUtils.file_to_memory_byte_array(path)
|
6
|
+
if path.nil? or path.empty?
|
7
|
+
raise PkernelJce::Error, "Given path '#{path}' to load to memory is nil or empty"
|
8
|
+
else
|
9
|
+
f = java.io.File.new(path)
|
10
|
+
b = Java::byte[f.length].new
|
11
|
+
dis = java.io.DataInputStream.new(java.io.FileInputStream.new(f))
|
12
|
+
dis.readFully(b)
|
13
|
+
dis.close
|
14
|
+
|
15
|
+
b
|
16
|
+
end
|
17
|
+
end
|
18
|
+
# end file_to_memory_byte_array
|
19
|
+
#
|
20
|
+
|
21
|
+
def IoUtils.ensure_java_bytes(bin)
|
22
|
+
if not bin.java_kind_of?(Java::byte[])
|
23
|
+
bin.to_java_bytes
|
24
|
+
else
|
25
|
+
bin
|
26
|
+
end
|
27
|
+
end
|
28
|
+
# end ensure_java_bytes
|
29
|
+
#
|
30
|
+
|
31
|
+
def IoUtils.to_hex(bin)
|
32
|
+
String.from_java_bytes(org.bouncycastle.util.encoders.Hex.encode(bin))
|
33
|
+
end
|
34
|
+
|
35
|
+
def IoUtils.from_hex(str)
|
36
|
+
org.bouncycastle.util.encoders.Hex.decode(str)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
# end IoUtils
|
41
|
+
#
|
42
|
+
|
43
|
+
end
|
44
|
+
# end PkernelJce
|
45
|
+
#
|
@@ -0,0 +1,359 @@
|
|
1
|
+
|
2
|
+
require 'pkernel'
|
3
|
+
|
4
|
+
require_relative 'provider'
|
5
|
+
require_relative 'global'
|
6
|
+
|
7
|
+
module PkernelJce
|
8
|
+
module KeyPair
|
9
|
+
|
10
|
+
def generate(algo, conf = {})
|
11
|
+
|
12
|
+
log = conf[:log]
|
13
|
+
if log.nil?
|
14
|
+
log = GConf.instance.glog
|
15
|
+
end
|
16
|
+
|
17
|
+
prov = conf[:provider]
|
18
|
+
#log.debug "Provider is #{prov == nil ? 'nil' : prov.name}"
|
19
|
+
|
20
|
+
case algo.to_s.upcase
|
21
|
+
when "RSA"
|
22
|
+
len = conf[:len] || 2048
|
23
|
+
log.debug "Generating RSA #{len} bits with provider #{prov == nil ? 'default' : prov.name}"
|
24
|
+
if prov.nil?
|
25
|
+
kpg = java.security.KeyPairGenerator.getInstance("RSA")
|
26
|
+
else
|
27
|
+
PkernelJce::Provider.add_provider(prov)
|
28
|
+
kpg = java.security.KeyPairGenerator.getInstance("RSA", prov)
|
29
|
+
end
|
30
|
+
|
31
|
+
kpg.java_send :initialize, [Java::int], len
|
32
|
+
kpg.generate_key_pair
|
33
|
+
when "DSA"
|
34
|
+
len = conf[:len] || 2048
|
35
|
+
log.debug "Generating DSA #{len} bits with provider #{prov == nil ? 'default' : prov.name}"
|
36
|
+
if prov.nil?
|
37
|
+
kpg = java.security.KeyPairGenerator.getInstance("DSA")
|
38
|
+
else
|
39
|
+
PkernelJce::Provider.add_provider(prov)
|
40
|
+
kpg = java.security.KeyPairGenerator.getInstance("DSA", prov)
|
41
|
+
end
|
42
|
+
kpg.java_send :initialize, [Java::int], len
|
43
|
+
kpg.generate_key_pair
|
44
|
+
when "ECC","EC"
|
45
|
+
# this only supported by bc?
|
46
|
+
curve = conf[:curve] || "prime256v1"
|
47
|
+
if prov.nil?
|
48
|
+
#kpg = java.security.KeyPairGenerator.getInstance("ECDSA")
|
49
|
+
# default Java does not have ECDSA yet as of Java 8
|
50
|
+
prov = PkernelJce::Provider.add_default
|
51
|
+
end
|
52
|
+
log.debug "Generating ECC curve '#{curve}' with provider #{prov == nil ? 'default' : prov.name}"
|
53
|
+
|
54
|
+
PkernelJce::Provider.add_provider(prov)
|
55
|
+
kpg = java.security.KeyPairGenerator.getInstance("ECDSA", prov)
|
56
|
+
kpg.java_send :initialize, [java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom], java.security.spec.ECGenParameterSpec.new(curve), java.security.SecureRandom.new
|
57
|
+
kpg.generate_key_pair
|
58
|
+
else
|
59
|
+
log.error "Unknown '#{algo}' for java keypair"
|
60
|
+
raise PkernelJce::Error, "Unknown algo '#{algo}' for java keypair"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
# end generate
|
64
|
+
#
|
65
|
+
|
66
|
+
def KeyPair.key_type(key)
|
67
|
+
if key.java_kind_of?(java.security.KeyPair)
|
68
|
+
privKey = key.getPrivate
|
69
|
+
else
|
70
|
+
# given is private key
|
71
|
+
privKey = key
|
72
|
+
end
|
73
|
+
|
74
|
+
case privKey
|
75
|
+
when java.security.interfaces.RSAPrivateCrtKey
|
76
|
+
Pkernel::KeyPair::RSA_KEY_NAME
|
77
|
+
when Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey
|
78
|
+
Pkernel::KeyPair::DSA_KEY_NAME
|
79
|
+
when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
|
80
|
+
Pkernel::KeyPair::EC_KEY_NAME
|
81
|
+
else
|
82
|
+
raise PkernelJce::Error, "Unknown priv key type '#{privKey.class}'"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
#
|
86
|
+
# end get_key_type
|
87
|
+
#
|
88
|
+
|
89
|
+
def KeyPair.pub_key_type(key)
|
90
|
+
if key.java_kind_of?(java.security.KeyPair)
|
91
|
+
pubKey = key.public
|
92
|
+
elsif PkernelJce::Certificate.is_cert_object?(key)
|
93
|
+
pubKey = PkernelJce::Certificate.public_key(key)
|
94
|
+
else
|
95
|
+
pubKey = key
|
96
|
+
end
|
97
|
+
|
98
|
+
case pubKey
|
99
|
+
when java.security.interfaces.RSAPublicKey
|
100
|
+
Pkernel::KeyPair::RSA_KEY_NAME
|
101
|
+
when Java::sun.security.provider.DSAPublicKey, Java::OrgBouncycastleJcajceProviderAsymmetricDsa::BCDSAPublicKey
|
102
|
+
Pkernel::KeyPair::DSA_KEY_NAME
|
103
|
+
when Java::OrgBouncycastleJcajceProviderAsymmetricEc::BCECPublicKey
|
104
|
+
Pkernel::KeyPair::EC_KEY_NAME
|
105
|
+
else
|
106
|
+
raise PkernelJce::Error, "Unknown pub key type '#{pubKey.class}'"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def KeyPair.ensure_java_keypair(kp)
|
111
|
+
raise PkernelJce::Error, "Keypair to check for Java keypair type is nil" if kp.nil?
|
112
|
+
end
|
113
|
+
|
114
|
+
def KeyPair.is_public_key?(key)
|
115
|
+
if key.nil?
|
116
|
+
false
|
117
|
+
else
|
118
|
+
case key
|
119
|
+
when java.security.interfaces.RSAPublicKey, Java::OrgBouncycastleJcajceProviderAsymmetricDsa::BCDSAPublicKey,Java::sun.security.provider.DSAPublicKey, Java::OrgBouncycastleJcajceProviderAsymmetricEc::BCECPublicKey
|
120
|
+
true
|
121
|
+
else
|
122
|
+
false
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def KeyPair.is_private_key?(key)
|
128
|
+
if key.nil?
|
129
|
+
false
|
130
|
+
else
|
131
|
+
case key
|
132
|
+
when java.security.interfaces.RSAPrivateCrtKey, Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
|
133
|
+
true
|
134
|
+
else
|
135
|
+
false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def KeyPair.is_keypair?(key)
|
141
|
+
if key.nil?
|
142
|
+
false
|
143
|
+
else
|
144
|
+
case key
|
145
|
+
when java.security.KeyPair
|
146
|
+
true
|
147
|
+
else
|
148
|
+
false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def KeyPair.public_key(priv)
|
154
|
+
if priv.nil?
|
155
|
+
raise PkernelJce::Error, "Cannot derive public key from nil key"
|
156
|
+
else
|
157
|
+
if priv.java_kind_of?(java.security.KeyPair)
|
158
|
+
priv.getPublic
|
159
|
+
elsif priv.java_kind_of?(java.security.PrivateKey)
|
160
|
+
type = key_type(priv)
|
161
|
+
case type
|
162
|
+
when Pkernel::KeyPair::RSA_KEY_NAME
|
163
|
+
java.security.KeyFactory.getInstance("RSA").generatePublic(java.security.spec.RSAPublicKeySpec.new(priv.modulus, priv.public_exponent))
|
164
|
+
when Pkernel::KeyPair::DSA_KEY_NAME
|
165
|
+
y = priv.params.g.to_java.modPow(priv.x, priv.params.p)
|
166
|
+
spec = java.security.spec.DSAPublicKeySpec.new(y, priv.params.p, priv.params.q, priv.params.g)
|
167
|
+
prov = PkernelJce::Provider.add_default
|
168
|
+
java.security.KeyFactory.getInstance("DSA",prov).generatePublic(spec)
|
169
|
+
when Pkernel::KeyPair::EC_KEY_NAME
|
170
|
+
d = priv.d;
|
171
|
+
q = priv.parameters.g.to_java.multiply(d);
|
172
|
+
pubSpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(q, priv.parameters);
|
173
|
+
prov = PkernelJce::Provider.add_default
|
174
|
+
java.security.KeyFactory.getInstance("EC",prov).generatePublic(pubSpec)
|
175
|
+
else
|
176
|
+
end
|
177
|
+
elsif priv.java_kind_of?(java.security.PublicKey)
|
178
|
+
priv
|
179
|
+
elsif priv.java_kind_of?(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo)
|
180
|
+
org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new.getPublicKey(priv)
|
181
|
+
elsif priv.java_kind_of?(org.bouncycastle.cert.X509CertificateHolder)
|
182
|
+
org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new.getPublicKey(priv.subject_public_key_info)
|
183
|
+
elsif priv.java_kind_of?(java.security.cert.Certificate)
|
184
|
+
priv.public_key
|
185
|
+
else
|
186
|
+
raise PkernelJce::Error, "Unsupported key type '#{priv.class}' to convert to public key"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
# end public_key(priv)
|
191
|
+
#
|
192
|
+
|
193
|
+
# harmonize the private key acquiring
|
194
|
+
# There are BC and Java, keypair and private key
|
195
|
+
def KeyPair.private_key(kp)
|
196
|
+
if kp.nil?
|
197
|
+
raise PkernelJce::Error, "Cannot derive private key from nil private key"
|
198
|
+
else
|
199
|
+
case kp
|
200
|
+
when java.security.KeyPair
|
201
|
+
kp.private
|
202
|
+
when java.security.PrivateKey
|
203
|
+
kp
|
204
|
+
else
|
205
|
+
raise PkernelJce::Error, "Unsupported key type '#{kp}' to derive private key from."
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def KeyPair.derive_signing_algo(kp, hashAlgo = "SHA256")
|
211
|
+
raise PkernelJce::Error, "Hashing algo should not be nil while deriving signing algo" if hashAlgo.nil?
|
212
|
+
|
213
|
+
PkernelJce::GConf.instance.glog.debug "Derive signing algo for key '#{kp.class}'"
|
214
|
+
|
215
|
+
if KeyPair.is_keypair?(kp)
|
216
|
+
type = PkernelJce::KeyPair.key_type(KeyPair.private_key(kp))
|
217
|
+
elsif KeyPair.is_public_key?(kp)
|
218
|
+
type = PkernelJce::KeyPair.pub_key_type(kp)
|
219
|
+
elsif Certificate.is_cert_object?(kp)
|
220
|
+
type = PkernelJce::KeyPair.pub_key_type(Certificate.public_key(kp))
|
221
|
+
elsif KeyPair.is_private_key?(kp)
|
222
|
+
type = PkernelJce::KeyPair.key_type(kp)
|
223
|
+
else
|
224
|
+
raise PkernelJce::Error, "Unknown key type to derive signing key algo from"
|
225
|
+
end
|
226
|
+
|
227
|
+
#type = PkernelJce::KeyPair.key_type(kp)
|
228
|
+
case type
|
229
|
+
when Pkernel::KeyPair::RSA_KEY_NAME
|
230
|
+
"#{hashAlgo}with#{type.upcase}"
|
231
|
+
when Pkernel::KeyPair::DSA_KEY_NAME
|
232
|
+
"#{hashAlgo}with#{type.upcase}"
|
233
|
+
when Pkernel::KeyPair::EC_KEY_NAME
|
234
|
+
"#{hashAlgo}with#{type.upcase}DSA"
|
235
|
+
else
|
236
|
+
raise PkernelJce::Error, "Unsupported type to derive signing algo '#{type}'"
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def dump(keypair, options = {})
|
241
|
+
if keypair.nil?
|
242
|
+
raise PkernelJce::Error, "Keypair is nil during writing PEM"
|
243
|
+
end
|
244
|
+
|
245
|
+
# outputStream only make sense in Java world
|
246
|
+
#os = options[:outputStream]
|
247
|
+
file = options[:file]
|
248
|
+
pass = options[:password]
|
249
|
+
|
250
|
+
binOut = java.io.ByteArrayOutputStream.new
|
251
|
+
|
252
|
+
if file.nil?
|
253
|
+
PkernelJce::GConf.instance.glog.debug "Dump output to memory"
|
254
|
+
# return binary to caller
|
255
|
+
writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(binOut));
|
256
|
+
else
|
257
|
+
PkernelJce::GConf.instance.glog.debug "Dump output to file '#{file}'"
|
258
|
+
out = java.io.FileOutputStream.new(file)
|
259
|
+
writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(out));
|
260
|
+
end
|
261
|
+
|
262
|
+
begin
|
263
|
+
if pass.nil? or pass.empty?
|
264
|
+
writer.writeObject(keypair.getPrivate)
|
265
|
+
else
|
266
|
+
builder = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder.new(org.bouncycastle.openssl.PKCS8Generator::AES_256_CBC).setProvider(PkernelJce::Provider::DefProvider).setPasssword(pass.to_java.toCharArray());
|
267
|
+
|
268
|
+
pkcs8 = org.bouncycastle.openssl.jcajce.JcaPKCS8Generator.new(keypair.getPrivate, builder.build);
|
269
|
+
writer.writeObject(pkcs8)
|
270
|
+
end
|
271
|
+
ensure
|
272
|
+
writer.flush
|
273
|
+
writer.close
|
274
|
+
end
|
275
|
+
|
276
|
+
if file.nil?
|
277
|
+
binOut.toByteArray
|
278
|
+
end
|
279
|
+
end
|
280
|
+
# end dump
|
281
|
+
|
282
|
+
def load(opts = {}, &block)
|
283
|
+
#is = opts[:inputStream]
|
284
|
+
#if is.nil?
|
285
|
+
# raise PkernelJce::Error, "InputStream not given"
|
286
|
+
#end
|
287
|
+
file = opts[:file]
|
288
|
+
bin = opts[:bin]
|
289
|
+
|
290
|
+
baos = java.io.ByteArrayOutputStream.new
|
291
|
+
|
292
|
+
if not file.nil? and not file.empty?
|
293
|
+
PkernelJce::GConf.instance.glog.debug "Load keypair from file '#{file}'"
|
294
|
+
f = java.io.File.new(file)
|
295
|
+
if f.exists?
|
296
|
+
b = Java::byte[f.length].new
|
297
|
+
dis = java.io.DataInputStream.new(java.io.FileInputStream.new(f))
|
298
|
+
dis.readFully(b)
|
299
|
+
dis.close
|
300
|
+
|
301
|
+
baos.write(b)
|
302
|
+
else
|
303
|
+
raise PkernelJce::Error, "Given file to load '#{f.absolute_path}' does not exist"
|
304
|
+
end
|
305
|
+
elsif not bin.nil?
|
306
|
+
PkernelJce::GConf.instance.glog.debug "Load keypair from memory"
|
307
|
+
baos.write(bin)
|
308
|
+
else
|
309
|
+
raise PkernelJce::Error, "No 'file' or 'bin' is defined to load keypair"
|
310
|
+
end
|
311
|
+
|
312
|
+
prov = opts[:provider] || PkernelJce::Provider::DefProvider
|
313
|
+
prov = PkernelJce::Provider.add_provider(prov)
|
314
|
+
|
315
|
+
reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(baos.toByteArray)))
|
316
|
+
obj = reader.readObject
|
317
|
+
#p obj.inspect
|
318
|
+
#p obj.methods.sort
|
319
|
+
#p obj.java_kind_of?(org.bouncycastle.openssl.PEMEncryptedKeyPair)
|
320
|
+
if obj.is_a?(org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo)
|
321
|
+
pass = opts[:password]
|
322
|
+
if pass.nil?
|
323
|
+
if block
|
324
|
+
pass = block.call(:password)
|
325
|
+
else
|
326
|
+
raise PkernelJce::Error, "PEM key is encrypted. Please provide a password to load the key."
|
327
|
+
end
|
328
|
+
end
|
329
|
+
decProv = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder.new.setProvider(PkernelJce::Provider::DefProvider).build(pass.to_java.toCharArray)
|
330
|
+
keyinfo = obj.decryptPrivateKeyInfo(decProv)
|
331
|
+
|
332
|
+
converter = org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new
|
333
|
+
converter.getPrivateKey(keyinfo)
|
334
|
+
else
|
335
|
+
keySpec = java.security.spec.PKCS8EncodedKeySpec.new(obj.getPrivateKeyInfo.encoded)
|
336
|
+
# Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm
|
337
|
+
# OID and use that to construct a KeyFactory.
|
338
|
+
bIn = org.bouncycastle.asn1.ASN1InputStream.new(java.io.ByteArrayInputStream.new(keySpec.getEncoded()));
|
339
|
+
pki = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(bIn.readObject());
|
340
|
+
algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
|
341
|
+
java.security.KeyFactory.getInstance(algOid,prov).generatePrivate(keySpec);
|
342
|
+
|
343
|
+
#privKey = java.security.KeyFactory.getInstance("RSA").generatePrivate(keySpec)
|
344
|
+
#privKey
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|
348
|
+
# end load()
|
349
|
+
#
|
350
|
+
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
class KeyPairEngine
|
355
|
+
extend KeyPair
|
356
|
+
end
|
357
|
+
|
358
|
+
end
|
359
|
+
|