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,221 @@
|
|
1
|
+
|
2
|
+
require_relative 'io_utils'
|
3
|
+
|
4
|
+
module PkernelJce
|
5
|
+
module CRL
|
6
|
+
def generate(identity, opts = {}, &block)
|
7
|
+
|
8
|
+
if identity.nil?
|
9
|
+
raise PkernelJce::Error, "Identity is nil in generating CRL"
|
10
|
+
end
|
11
|
+
|
12
|
+
tbpCerts = opts[:tbpCerts]
|
13
|
+
# allow empty CRL
|
14
|
+
tbpCerts = {} if tbpCerts.nil?
|
15
|
+
|
16
|
+
prov = opts[:provider]
|
17
|
+
if prov.nil?
|
18
|
+
prov = PkernelJce::Provider.add_default
|
19
|
+
else
|
20
|
+
PkernelJce::Provider.add_provider(prov)
|
21
|
+
end
|
22
|
+
|
23
|
+
validity = opts[:validity] || 1
|
24
|
+
validityUnit = opts[:validity_unit] || :days
|
25
|
+
signAlgo = opts[:hashAlgo]
|
26
|
+
if signAlgo.nil?
|
27
|
+
signAlgo = PkernelJce::KeyPair.derive_signing_algo(identity.privKey, "SHA256")
|
28
|
+
end
|
29
|
+
PkernelJce::GConf.instance.glog.debug "Signing algo for CRL is #{signAlgo}"
|
30
|
+
|
31
|
+
crlGen = org.bouncycastle.x509.X509V2CRLGenerator.new
|
32
|
+
validFrom = Time.now
|
33
|
+
validTo = validFrom.advance( validityUnit => validity )
|
34
|
+
# CRL validity should not be more then issuer's
|
35
|
+
if validFrom.to_java_date.before(identity.certificate.not_before)
|
36
|
+
PkernelJce::GConf.instance.glog.debug "CRL new valid from has adjusted to match with issuer valid from : #{validFrom} [Original] / #{identity.certificate.not_before} [Issuer's certificate not before]"
|
37
|
+
validFrom = identity.certificate.not_before
|
38
|
+
end
|
39
|
+
|
40
|
+
if validTo.to_java_date.after(identity.certificate.not_after)
|
41
|
+
PkernelJce::GConf.instance.glog.debug "CRL new valid until has adjusted to match with issuer validity to : #{validTo} [Original] / #{identity.certificate.not_after} [Issuer's certificate not after]"
|
42
|
+
validTo = identity.certificate.not_after
|
43
|
+
end
|
44
|
+
PkernelJce::GConf.instance.glog.debug "CRL validity #{validFrom} - #{validTo}"
|
45
|
+
|
46
|
+
crlGen.issuer_dn = identity.certificate.getSubjectX500Principal
|
47
|
+
crlGen.this_update = validFrom
|
48
|
+
crlGen.next_update = validTo
|
49
|
+
crlGen.signature_algorithm = signAlgo
|
50
|
+
|
51
|
+
tbpCerts.each do |k,v|
|
52
|
+
cert = k
|
53
|
+
opts = v
|
54
|
+
time = opts[:time] || java.util.Date.new
|
55
|
+
reason = opts[:reason] || Pkernel::CRLReason::UNSPECIFIED
|
56
|
+
crlGen.addCRLEntry(cert.getSerialNumber, time, reason)
|
57
|
+
PkernelJce::GConf.instance.glog.debug "Added cert into entry"
|
58
|
+
end
|
59
|
+
|
60
|
+
PkernelJce::GConf.instance.glog.debug "Generating CRL from issuer '#{identity.certificate.subjectDN.to_s}' [Provider #{prov.name}]"
|
61
|
+
crl = crlGen.generateX509CRL(identity.privKey, prov.name)
|
62
|
+
crl
|
63
|
+
|
64
|
+
end
|
65
|
+
# end generate
|
66
|
+
|
67
|
+
def ensure_java_crl(crl)
|
68
|
+
if crl.nil?
|
69
|
+
raise PkernelJce::Error, "CRL given to convert to java object is nil"
|
70
|
+
end
|
71
|
+
|
72
|
+
if crl.java_kind_of?(Java::OrgBouncycastleCert::X509CRLHolder)
|
73
|
+
org.bouncycastle.cert.jcajce.JcaX509CRLConverter.new.getCRL(crl)
|
74
|
+
else
|
75
|
+
crl
|
76
|
+
end
|
77
|
+
end
|
78
|
+
alias_method :to_java_crl, :ensure_java_crl
|
79
|
+
#
|
80
|
+
# end ensure_java_crl / to_java_crl
|
81
|
+
#
|
82
|
+
|
83
|
+
def ensure_bc_crl(crl)
|
84
|
+
if crl.nil?
|
85
|
+
raise PkernelJce::Error, "CRL given to convert to BC object is nil"
|
86
|
+
end
|
87
|
+
|
88
|
+
if crl.java_kind_of?(Java::OrgBouncycastleCert::X509CRLHolder)
|
89
|
+
crl
|
90
|
+
else
|
91
|
+
org.bouncycastle.cert.X509CRLHolder.new(java.io.ByteArrayInputStream.new(crl.encoded))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
alias_method :to_bc_crl, :ensure_bc_crl
|
95
|
+
#
|
96
|
+
# end to_bc_crl / ensure_bc_crl
|
97
|
+
#
|
98
|
+
|
99
|
+
def is_signature_valid?(crl, opts = { }) #issuer)
|
100
|
+
if crl.nil?
|
101
|
+
raise PkernelJce::Error, "CRL pass to test signature validity for CRL is nil"
|
102
|
+
end
|
103
|
+
|
104
|
+
issuer_cert = opts[:issuer_cert]
|
105
|
+
issuer_key = opts[:issuer_key]
|
106
|
+
if not issuer_cert.nil?
|
107
|
+
pubKey = PkernelJce::Certificate.public_key(issuer_cert)
|
108
|
+
elsif not issuer_key.nil?
|
109
|
+
pubKey = PkernelJce::KeyPair.public_key(issuer_key)
|
110
|
+
else
|
111
|
+
raise PkernelJce::Error, "Neither issuer cert or key is available for signature verification"
|
112
|
+
end
|
113
|
+
#if issuer.nil?
|
114
|
+
# raise PkernelJce::Error, "Issuer pass to test signature validity for CRL is nil"
|
115
|
+
#end
|
116
|
+
|
117
|
+
#if PkernelJce::Certificate.is_cert_object?(issuer)
|
118
|
+
# pubKey = PkernelJce::Certificate.public_key(issuer)
|
119
|
+
#else
|
120
|
+
# pubKey = PkernelJce::KeyPair.public_key(issuer)
|
121
|
+
#end
|
122
|
+
|
123
|
+
crl = ensure_java_crl(crl)
|
124
|
+
begin
|
125
|
+
crl.verify(pubKey)
|
126
|
+
true
|
127
|
+
rescue Exception => ex
|
128
|
+
PkernelJce::GConf.instance.glog.error ex
|
129
|
+
false
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def is_revoked?(crl,cert,&block)
|
134
|
+
if crl.revoked_certificates.nil? or crl.revoked_certificates.length == 0
|
135
|
+
false
|
136
|
+
else
|
137
|
+
crl = ensure_java_crl(crl)
|
138
|
+
now = java.util.Date.new
|
139
|
+
if crl.next_update.before(now)
|
140
|
+
# expired
|
141
|
+
if block
|
142
|
+
cont = block.call(:expired, { valid_until: crl.next_update, issuer: crl.issuer_x500_principal })
|
143
|
+
if not cont
|
144
|
+
raise PkernelJce::Error, "CRL expired at #{crl.next_update}. Revocation check aborted."
|
145
|
+
else
|
146
|
+
PkernelJce::GConf.instance.glog.warn "Revocation checked against expired CRL [CRL Expired on #{crl.next_update} / Ref Date : #{now}] based on application request."
|
147
|
+
end
|
148
|
+
else
|
149
|
+
raise PkernelJce::Error, "CRL expired at #{crl.next_update}. Revocation check aborted."
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
c = PkernelJce::Certificate.to_bc_cert(cert)
|
154
|
+
revokedInfo = crl.get_revoked_certificate(c.serial_number)
|
155
|
+
if revokedInfo.nil?
|
156
|
+
[false,nil]
|
157
|
+
else
|
158
|
+
[true, { reason: revokedInfo.revocation_reason, on: revokedInfo.revocation_date, object: revokedInfo }]
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def dump(crl, opts = {})
|
164
|
+
|
165
|
+
if crl.nil?
|
166
|
+
raise PkernelJce::Error, "Given CRL to dump is nil."
|
167
|
+
end
|
168
|
+
|
169
|
+
file = opts[:file]
|
170
|
+
|
171
|
+
if not (file.nil? or file.empty?)
|
172
|
+
os = java.io.FileOutputStream.new(file)
|
173
|
+
else
|
174
|
+
os = java.io.ByteArrayOutputStream.new
|
175
|
+
end
|
176
|
+
|
177
|
+
os.write(crl.encoded)
|
178
|
+
os.flush
|
179
|
+
os.close
|
180
|
+
|
181
|
+
if (file.nil? or file.empty?)
|
182
|
+
os.toByteArray
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
# end dump
|
187
|
+
|
188
|
+
def load(opts = {})
|
189
|
+
file = opts[:file]
|
190
|
+
bin = opts[:bin]
|
191
|
+
|
192
|
+
if not (file.nil? or file.empty?)
|
193
|
+
crlbin = PkernelJce::IoUtils.file_to_memory_byte_array(file)
|
194
|
+
elsif not bin.nil?
|
195
|
+
crlbin = PkernelJce::IoUtils.ensure_java_bytes(bin)
|
196
|
+
else
|
197
|
+
raise PkernelJce::Error, "No source to load CRL from"
|
198
|
+
end
|
199
|
+
|
200
|
+
# this option shall load the CRL in Java
|
201
|
+
#crl = java.security.cert.CertificateFactory.getInstance("X.509").generateCRL(java.io.ByteArrayInputStream.new(crlbin))
|
202
|
+
|
203
|
+
# this option shall load the CRL in BC but under Java interface
|
204
|
+
prov = PkernelJce::Provider.add_default
|
205
|
+
crl = java.security.cert.CertificateFactory.getInstance("X.509",prov).generateCRL(java.io.ByteArrayInputStream.new(crlbin))
|
206
|
+
|
207
|
+
# this option shall load the CRL in BC too but under BC interface
|
208
|
+
#crl = org.bouncycastle.cert.X509CRLHolder.new(crlbin)
|
209
|
+
|
210
|
+
crl
|
211
|
+
end
|
212
|
+
# end load
|
213
|
+
|
214
|
+
end
|
215
|
+
# end module CRL
|
216
|
+
|
217
|
+
class CRLCore
|
218
|
+
extend CRL
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
|
2
|
+
require 'pkernel'
|
3
|
+
require_relative 'provider'
|
4
|
+
require_relative 'utils'
|
5
|
+
require_relative 'global'
|
6
|
+
require_relative 'error'
|
7
|
+
|
8
|
+
module PkernelJce
|
9
|
+
module CSR
|
10
|
+
|
11
|
+
def generate(identity, opts = {} )
|
12
|
+
|
13
|
+
owner = opts[:owner]
|
14
|
+
if owner.nil? and identity.certificate.nil?
|
15
|
+
raise PkernelJce::Error, "Either Owner or Certificate must exist to issue CSR"
|
16
|
+
elsif not owner.nil?
|
17
|
+
subject = owner.to_x500_subject
|
18
|
+
elsif not identity.certificate.nil?
|
19
|
+
subject = PkernelJce::Certificate.ensure_java_cert(identity.certificate).subject_dn
|
20
|
+
end
|
21
|
+
|
22
|
+
signHash = opts[:signHash] || "SHA256"
|
23
|
+
signAlgo = opts[:signAlgo]
|
24
|
+
if signAlgo.nil?
|
25
|
+
signAlgo = PkernelJce::KeyPair.derive_signing_algo(identity.privKey,signHash)
|
26
|
+
end
|
27
|
+
provider = opts[:provider]
|
28
|
+
if provider.nil?
|
29
|
+
PkernelJce::GConf.instance.glog.debug "Adding default provider"
|
30
|
+
prov = PkernelJce::Provider.add_default
|
31
|
+
else
|
32
|
+
PkernelJce::GConf.instance.glog.debug "Adding provider #{provider.name}"
|
33
|
+
prov = PkernelJce::Provider.add_provider(provider)
|
34
|
+
end
|
35
|
+
|
36
|
+
#p10Builder = org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder.new(subject, PkernelJce::KeyPair.public_key(identity.privKey))
|
37
|
+
p10Builder = org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder.new(subject, identity.pubKey)
|
38
|
+
sign = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(signAlgo).setProvider(prov).build(identity.privKey)
|
39
|
+
csr = p10Builder.build(sign)
|
40
|
+
csr
|
41
|
+
end
|
42
|
+
# end generate()
|
43
|
+
|
44
|
+
def dump(csr, params = {})
|
45
|
+
if csr.nil?
|
46
|
+
raise PkernelJce::Error, "CSR object to be written is nil"
|
47
|
+
end
|
48
|
+
|
49
|
+
file = params[:file]
|
50
|
+
baos = java.io.ByteArrayOutputStream.new
|
51
|
+
|
52
|
+
if not file.nil?
|
53
|
+
PkernelJce::GConf.instance.glog.debug "Dump CRL to file '#{file}'"
|
54
|
+
writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(java.io.FileOutputStream.new(file)))
|
55
|
+
else
|
56
|
+
PkernelJce::GConf.instance.glog.debug "Dump CRL to memory"
|
57
|
+
writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(baos))
|
58
|
+
end
|
59
|
+
|
60
|
+
begin
|
61
|
+
writer.writeObject(csr)
|
62
|
+
ensure
|
63
|
+
writer.flush
|
64
|
+
writer.close
|
65
|
+
end
|
66
|
+
|
67
|
+
if file.nil?
|
68
|
+
baos.toByteArray
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
# end dump
|
73
|
+
|
74
|
+
|
75
|
+
def load(options = {})
|
76
|
+
#todo is this content pem or binary?
|
77
|
+
# now assumed is pem
|
78
|
+
file = options[:file]
|
79
|
+
bin = options[:bin]
|
80
|
+
|
81
|
+
if not file.nil? and not file.empty?
|
82
|
+
PkernelJce::GConf.instance.glog.debug "Load CSR from #{file}"
|
83
|
+
f = java.io.File.new(file)
|
84
|
+
if f.exists?
|
85
|
+
reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.FileInputStream.new(f)))
|
86
|
+
else
|
87
|
+
raise PkernelJce::Error, "File '#{f.absolute_path}' not found"
|
88
|
+
end
|
89
|
+
|
90
|
+
elsif not bin.nil?
|
91
|
+
PkernelJce::GConf.instance.glog.debug "Load CSR from memory"
|
92
|
+
reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(bin)))
|
93
|
+
else
|
94
|
+
raise PkernelJce::Error, "No bin or file input is given to load"
|
95
|
+
end
|
96
|
+
|
97
|
+
obj = reader.readObject
|
98
|
+
end
|
99
|
+
# end load
|
100
|
+
|
101
|
+
def is_signature_valid?(csr)
|
102
|
+
cvProv = org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder.new.build(csr.getSubjectPublicKeyInfo)
|
103
|
+
csr.isSignatureValid(cvProv)
|
104
|
+
end
|
105
|
+
# end is_signature_valid?
|
106
|
+
|
107
|
+
def public_key(csr)
|
108
|
+
if csr.nil?
|
109
|
+
raise PkernelJce::Error, "CSR given to extract public key is nil"
|
110
|
+
end
|
111
|
+
|
112
|
+
org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new.getPublicKey(csr.getSubjectPublicKeyInfo)
|
113
|
+
end
|
114
|
+
# end public_key
|
115
|
+
|
116
|
+
end
|
117
|
+
# end module csr
|
118
|
+
|
119
|
+
|
120
|
+
class CSRProxy
|
121
|
+
extend CSR
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
require 'singleton'
|
3
|
+
require 'tlogger'
|
4
|
+
|
5
|
+
module PkernelJce
|
6
|
+
class GConf
|
7
|
+
include Singleton
|
8
|
+
attr_reader :logger_params, :glog
|
9
|
+
def initialize
|
10
|
+
@logger_params = STDOUT
|
11
|
+
@glog = Tlogger.new(STDOUT)
|
12
|
+
@glog.tag = :pkernel_jce
|
13
|
+
@glog.show_source
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,333 @@
|
|
1
|
+
|
2
|
+
require_relative 'provider'
|
3
|
+
require_relative 'csr'
|
4
|
+
|
5
|
+
module PkernelJce
|
6
|
+
|
7
|
+
#
|
8
|
+
# Identity
|
9
|
+
# Identity is abstraction consist of keypair + certificate, stored separately
|
10
|
+
#
|
11
|
+
#class Identity
|
12
|
+
# attr_reader :priv_key, :cert, :keystore, :chain
|
13
|
+
# def initialize(opts = {})
|
14
|
+
# @priv_key = opts[:priv_key]
|
15
|
+
# @cert = opts[:cert]
|
16
|
+
# @keystore = opts[:keystore]
|
17
|
+
# @chain = opts[:chain]
|
18
|
+
# end
|
19
|
+
#end
|
20
|
+
# end Identity
|
21
|
+
#
|
22
|
+
|
23
|
+
class Pkernel::Identity
|
24
|
+
|
25
|
+
def key=(val)
|
26
|
+
@key = val
|
27
|
+
if not @key.nil?
|
28
|
+
@privKey = PkernelJce::KeyPair.private_key(@key)
|
29
|
+
@pubKey = PkernelJce::KeyPair.public_key(@key)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def key
|
34
|
+
if @key.nil?
|
35
|
+
if not @privKey.nil?
|
36
|
+
if not @pubKey.nil?
|
37
|
+
@key = java.security.KeyPair.new(@pubKey,@privKey)
|
38
|
+
elsif not @certificate.nil?
|
39
|
+
@key = java.security.KeyPair.new(@certificate.public_key,@privKey)
|
40
|
+
else
|
41
|
+
# no possible to generate without public key
|
42
|
+
end
|
43
|
+
else
|
44
|
+
# not possible to generate without private key
|
45
|
+
end
|
46
|
+
else
|
47
|
+
# key is not nil...
|
48
|
+
end
|
49
|
+
|
50
|
+
@key
|
51
|
+
end
|
52
|
+
|
53
|
+
def privKey
|
54
|
+
if @privKey.nil? and not @key.nil?
|
55
|
+
@privKey = PkernelJce::KeyPair.private_key(@key)
|
56
|
+
end
|
57
|
+
@privKey
|
58
|
+
end
|
59
|
+
|
60
|
+
def pubKey
|
61
|
+
if @pubKey.nil?
|
62
|
+
if not @key.nil?
|
63
|
+
@pubKey = PkernelJce::KeyPair.public_key(@key)
|
64
|
+
elsif not @certificate.nil?
|
65
|
+
@pubKey = PkernelJce::KeyPair.public_key(@certificate)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
@pubKey
|
70
|
+
end
|
71
|
+
|
72
|
+
def certificate
|
73
|
+
if not @certificate.nil? and @certificate.java_kind_of?(Java::OrgBouncycastleCert::X509CertificateHolder)
|
74
|
+
@certificate = @certificate.to_java_cert
|
75
|
+
end
|
76
|
+
@certificate
|
77
|
+
end
|
78
|
+
|
79
|
+
# In java world, JCE/JCA provides switchable engine to call if it is software/hardware
|
80
|
+
# This provider is tightly related to private key.
|
81
|
+
# Since private key is encapsulated in this object, might as well keep the pointer here.
|
82
|
+
# Whoever want to use the private key, also should check the provider to load correct
|
83
|
+
# signing engine
|
84
|
+
def provider=(val)
|
85
|
+
if not val.nil?
|
86
|
+
if val.is_a?(String) and not val.empty?
|
87
|
+
@provider = PkernelJce::Provider.add_provider(val)
|
88
|
+
else
|
89
|
+
@provider = PkernelJce::Provider.add_provider(val)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def provider
|
95
|
+
if @provider.nil?
|
96
|
+
PkernelJce::GConf.instance.glog.debug "Provider is nil in Identity object. Setting it to default provider '#{PkernelJce::Provider::DefProvider.name}'"
|
97
|
+
@provider = PkernelJce::Provider.add_default
|
98
|
+
end
|
99
|
+
|
100
|
+
@provider
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# IdentityFactory
|
106
|
+
#
|
107
|
+
module IdentityFactory
|
108
|
+
|
109
|
+
def build_from_components(key, cert = nil, chain = [], provider = nil)
|
110
|
+
if key.nil?
|
111
|
+
raise PkernelJce::Error, "Key cannot be nil to build identity"
|
112
|
+
end
|
113
|
+
|
114
|
+
id = Pkernel::Identity.new( { key: key, certificate: cert, chain: chain } )
|
115
|
+
if cert.nil?
|
116
|
+
class_eval do
|
117
|
+
include PkernelJce::IdentityManagement
|
118
|
+
end
|
119
|
+
else
|
120
|
+
c = PkernelJce::Certificate.ensure_java_cert(cert)
|
121
|
+
if PkernelJce::Certificate.is_issuer_cert?(c)
|
122
|
+
class_eval do
|
123
|
+
include PkernelJce::IdentityIssuer
|
124
|
+
include PkernelJce::IdentityManagement
|
125
|
+
end
|
126
|
+
else
|
127
|
+
class_eval do
|
128
|
+
include PkernelJce::IdentityManagement
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
id.provider = provider
|
134
|
+
|
135
|
+
id
|
136
|
+
end
|
137
|
+
alias_method :build, :build_from_components
|
138
|
+
# end build_from_components
|
139
|
+
|
140
|
+
def dump(id, opts = {})
|
141
|
+
|
142
|
+
if id.nil?
|
143
|
+
raise PkernelJce::Error, "Identity object is nil in write to keystore"
|
144
|
+
end
|
145
|
+
|
146
|
+
prov = opts[:provider]
|
147
|
+
if prov.nil?
|
148
|
+
prov = PkernelJce::Provider.add_default
|
149
|
+
else
|
150
|
+
prov = PkernelJce::Provider.add_provider(prov)
|
151
|
+
end
|
152
|
+
|
153
|
+
format = opts[:format]
|
154
|
+
format = :p12 if format.nil?
|
155
|
+
sFormat = format
|
156
|
+
case format
|
157
|
+
when :p12, :pkcs12
|
158
|
+
PkernelJce::GConf.instance.glog.debug "Loading PKCS12 keystore"
|
159
|
+
ks = java.security.KeyStore.getInstance("PKCS12",prov)
|
160
|
+
sFormat = :p12
|
161
|
+
when :jks
|
162
|
+
PkernelJce::GConf.instance.glog.debug "Loading JKS keystore"
|
163
|
+
ks = java.security.KeyStore.getInstance("JKS")
|
164
|
+
sFormat = :jks
|
165
|
+
else
|
166
|
+
PkernelJce::GConf.instance.glog.debug "Loading '#{format}' keystore"
|
167
|
+
if prov.nil?
|
168
|
+
ks = java.security.KeyStore.getInstance(format)
|
169
|
+
else
|
170
|
+
ks = java.security.KeyStore.getInstance(format, prov)
|
171
|
+
end
|
172
|
+
sFormat = format
|
173
|
+
end
|
174
|
+
|
175
|
+
result = { }
|
176
|
+
pass = opts[:password]
|
177
|
+
if pass.nil? or pass.empty?
|
178
|
+
PkernelJce::GConf.instance.glog.warn "Password is not given to dump identity. Random password shall be generated."
|
179
|
+
pass = SecureRandom.hex(8)
|
180
|
+
result[:password] = pass
|
181
|
+
#raise PkernelJce::Error, "Password should not be empty for identity storage"
|
182
|
+
end
|
183
|
+
|
184
|
+
chain = id.chain.map do |c|
|
185
|
+
if c.java_kind_of?(org.bouncycastle.cert.X509CertificateHolder)
|
186
|
+
c.to_java_cert
|
187
|
+
else
|
188
|
+
c
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
name = opts[:key_name] || "Pkernel JCE"
|
193
|
+
|
194
|
+
ks.load(nil,nil)
|
195
|
+
ks.setKeyEntry(name, id.privKey, pass.to_java.toCharArray, chain.to_java(java.security.cert.Certificate))
|
196
|
+
baos = java.io.ByteArrayOutputStream.new
|
197
|
+
|
198
|
+
file = opts[:file]
|
199
|
+
if file.nil? or file.empty?
|
200
|
+
ks.store(baos, pass.to_java.toCharArray)
|
201
|
+
baos.toByteArray
|
202
|
+
else
|
203
|
+
fos = java.io.FileOutputStream.new(file)
|
204
|
+
ks.store(fos, pass.to_java.toCharArray)
|
205
|
+
fos.flush
|
206
|
+
fos.close
|
207
|
+
end
|
208
|
+
|
209
|
+
result
|
210
|
+
end
|
211
|
+
|
212
|
+
def load(opts = {})
|
213
|
+
|
214
|
+
prov = opts[:provider]
|
215
|
+
if prov.nil?
|
216
|
+
prov = PkernelJce::Provider.add_default
|
217
|
+
else
|
218
|
+
prov = PkernelJce::Provider.add_provider(prov)
|
219
|
+
end
|
220
|
+
|
221
|
+
format = opts[:format]
|
222
|
+
format = :p12 if format.nil?
|
223
|
+
sFormat = format
|
224
|
+
case format
|
225
|
+
when :p12, :pkcs12
|
226
|
+
PkernelJce::GConf.instance.glog.debug "Loading PKCS12 keystore"
|
227
|
+
ks = java.security.KeyStore.getInstance("PKCS12",prov)
|
228
|
+
sFormat = :p12
|
229
|
+
when :jks
|
230
|
+
PkernelJce::GConf.instance.glog.debug "Loading JKS keystore"
|
231
|
+
ks = java.security.KeyStore.getInstance("JKS")
|
232
|
+
sFormat = :jks
|
233
|
+
else
|
234
|
+
PkernelJce::GConf.instance.glog.debug "Loading '#{format}' keystore"
|
235
|
+
if prov.nil?
|
236
|
+
ks = java.security.KeyStore.getInstance(format.to_s)
|
237
|
+
else
|
238
|
+
ks = java.security.KeyStore.getInstance(format.to_s, prov)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
pass = opts[:password] || ''
|
243
|
+
|
244
|
+
file = opts[:file]
|
245
|
+
bin = opts[:bin]
|
246
|
+
baos = java.io.ByteArrayOutputStream.new
|
247
|
+
|
248
|
+
if not file.nil? or not file.empty?
|
249
|
+
fis = java.io.FileInputStream.new(file)
|
250
|
+
ks.load(fis,pass.to_java.toCharArray)
|
251
|
+
fis.close
|
252
|
+
elsif bin.nil?
|
253
|
+
ks.load(java.io.ByteArrayInputStream.new(bin),pass.to_java.toCharArray)
|
254
|
+
else
|
255
|
+
raise PkernelJce::Error, "No file or bin is given to load identity"
|
256
|
+
end
|
257
|
+
|
258
|
+
name = opts[:key_name] || ks.aliases.to_a[0]
|
259
|
+
|
260
|
+
key = ks.getKey(name,pass.to_java.toCharArray)
|
261
|
+
cert = ks.getCertificate(name)
|
262
|
+
chain = ks.getCertificateChain(name)
|
263
|
+
|
264
|
+
id = Pkernel::Identity.new( { privKey: key, certificate: cert, chain: chain } )
|
265
|
+
id
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
# end IdentityFactory
|
270
|
+
|
271
|
+
|
272
|
+
module IdentityIssuer
|
273
|
+
|
274
|
+
#def issue_cert(identity, opts = {})
|
275
|
+
# src = opts[:source]
|
276
|
+
# if src.nil? or src.empty?
|
277
|
+
# raise PkernelJce::Error, "Issue cert requires source key indicating either from CSR or Owner structure"
|
278
|
+
# end
|
279
|
+
|
280
|
+
# conf = opts[:config]
|
281
|
+
# if conf.nil? or conf.empty?
|
282
|
+
# raise PkernelJce::Error, "Config for certificate generation is not given!"
|
283
|
+
# end
|
284
|
+
|
285
|
+
# if src[:csr_file].nil?
|
286
|
+
# csrBin = PkernelJce::CSRCore.load({ file: src[:csr_file] })
|
287
|
+
# elsif src[:csr].nil?
|
288
|
+
# owner = Pkernel::Certificate::Owner.load_from_csr(src[:csr])
|
289
|
+
# elsif src[:owner].nil?
|
290
|
+
#
|
291
|
+
# else
|
292
|
+
# raise PkernelJce::Error, "No CSR or Owner is given to issue certificate"
|
293
|
+
# end
|
294
|
+
|
295
|
+
# issuerKey = PkernelJce::KeyPair.private_key(identity.privKey)
|
296
|
+
|
297
|
+
# conf[:owner] = owner
|
298
|
+
|
299
|
+
# cert = @cdriver.generate(conf) do |v|
|
300
|
+
# case v
|
301
|
+
# when :signAlgo
|
302
|
+
# PkernelJce::KeyPair.derive_signing_algo(issuerKey, "SHA256")
|
303
|
+
# when :issuerKey
|
304
|
+
# issuerKey
|
305
|
+
# when :issuerCert
|
306
|
+
# when :keyUsage
|
307
|
+
# when :extKeyUsage
|
308
|
+
# end
|
309
|
+
# end
|
310
|
+
|
311
|
+
#end
|
312
|
+
|
313
|
+
end
|
314
|
+
# end IdentityIssuer
|
315
|
+
|
316
|
+
module IdentityManagement
|
317
|
+
|
318
|
+
def destroy
|
319
|
+
PkernelJce::GConf.instance.glog.warn "Destroy not implemented for JCE context"
|
320
|
+
end
|
321
|
+
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
|
326
|
+
class IdentityEngine
|
327
|
+
extend IdentityFactory
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|
331
|
+
|
332
|
+
|
333
|
+
|