ccrypto-java 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.java-version +1 -0
- data/.rspec +3 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +94 -0
- data/README.md +150 -0
- data/Rakefile +10 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ccrypto-java.gemspec +44 -0
- data/jars/bcmail-jdk15on-165.jar +0 -0
- data/jars/bcpg-jdk15on-165.jar +0 -0
- data/jars/bcpkix-jdk15on-165.jar +0 -0
- data/jars/bcprov-ext-jdk15on-165.jar +0 -0
- data/jars/bcprov-jdk15on-165.jar +0 -0
- data/jars/bctls-jdk15on-165.jar +0 -0
- data/jars/shamir-0.6.1-p.jar +0 -0
- data/lib/ccrypto/java/data_conversion.rb +80 -0
- data/lib/ccrypto/java/engines/asn1_engine.rb +161 -0
- data/lib/ccrypto/java/engines/asn1_object.rb +12 -0
- data/lib/ccrypto/java/engines/cipher_engine.rb +255 -0
- data/lib/ccrypto/java/engines/compression_engine.rb +92 -0
- data/lib/ccrypto/java/engines/data_conversion_engine.rb +9 -0
- data/lib/ccrypto/java/engines/decompression_engine.rb +48 -0
- data/lib/ccrypto/java/engines/digest_engine.rb +208 -0
- data/lib/ccrypto/java/engines/ecc_engine.rb +263 -0
- data/lib/ccrypto/java/engines/hkdf_engine.rb +72 -0
- data/lib/ccrypto/java/engines/hmac_engine.rb +75 -0
- data/lib/ccrypto/java/engines/pbkdf2_engine.rb +87 -0
- data/lib/ccrypto/java/engines/pkcs7_engine.rb +558 -0
- data/lib/ccrypto/java/engines/rsa_engine.rb +572 -0
- data/lib/ccrypto/java/engines/scrypt_engine.rb +35 -0
- data/lib/ccrypto/java/engines/secret_key_engine.rb +44 -0
- data/lib/ccrypto/java/engines/secret_sharing_engine.rb +59 -0
- data/lib/ccrypto/java/engines/secure_random_engine.rb +76 -0
- data/lib/ccrypto/java/engines/x509_engine.rb +311 -0
- data/lib/ccrypto/java/ext/secret_key.rb +75 -0
- data/lib/ccrypto/java/ext/x509_cert.rb +48 -0
- data/lib/ccrypto/java/jce_provider.rb +52 -0
- data/lib/ccrypto/java/keybundle_store/pkcs12.rb +125 -0
- data/lib/ccrypto/java/utils/comparator.rb +20 -0
- data/lib/ccrypto/java/utils/memory_buffer.rb +77 -0
- data/lib/ccrypto/java/utils/native_helper.rb +19 -0
- data/lib/ccrypto/java/version.rb +7 -0
- data/lib/ccrypto/java.rb +30 -0
- data/lib/ccrypto/provider.rb +132 -0
- metadata +144 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
require_relative '../data_conversion'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
module Java
|
6
|
+
class SecureRandomEngine
|
7
|
+
include TR::CondUtils
|
8
|
+
extend DataConversion
|
9
|
+
|
10
|
+
|
11
|
+
def self.random_bytes(size, &block)
|
12
|
+
buf = ::Java::byte[size].new
|
13
|
+
engine(&block).next_bytes(buf)
|
14
|
+
buf
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.random_hex(size,&block)
|
18
|
+
to_hex(random_bytes(size,&block))
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.random_b64(size, &block)
|
22
|
+
to_b64(random_bytes(size, &block))
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.random_uuid
|
26
|
+
java.util.UUID.randomUUID.to_s
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.random_alphanu(size, &block)
|
30
|
+
SecureRandom.alphanumeric(size)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.random_number(val, &block)
|
34
|
+
if val.is_a?(Range)
|
35
|
+
v = engine(&block).next_int(val.max)
|
36
|
+
if v < val.min
|
37
|
+
v = v+val.min
|
38
|
+
end
|
39
|
+
v
|
40
|
+
elsif val.is_a?(Integer)
|
41
|
+
engine(&block).next_int(val)
|
42
|
+
elsif is_empty?(val)
|
43
|
+
engine(&block).next_double
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
private
|
49
|
+
def self.engine(&block)
|
50
|
+
if @srEngine.nil?
|
51
|
+
srJceProvider = nil
|
52
|
+
algo = "NativePRNG"
|
53
|
+
if block
|
54
|
+
jceProv = block.call(:jce_provider)
|
55
|
+
srJceProvider = jceProv
|
56
|
+
|
57
|
+
al = block.call(:secure_random_engine_name)
|
58
|
+
algo = al if not_empty?(al)
|
59
|
+
else
|
60
|
+
algo = "NativePRNG"
|
61
|
+
end
|
62
|
+
|
63
|
+
if srJceProvider.nil?
|
64
|
+
@srEngine = java.security.SecureRandom.getInstance(algo)
|
65
|
+
else
|
66
|
+
@srEngine = java.security.SecureRandom.getInstance(algo,srJceProvider)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
@srEngine
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,311 @@
|
|
1
|
+
|
2
|
+
module Ccrypto
|
3
|
+
module Java
|
4
|
+
|
5
|
+
class X509Engine
|
6
|
+
include TR::CondUtils
|
7
|
+
|
8
|
+
include TeLogger::TeLogHelper
|
9
|
+
|
10
|
+
teLogger_tag :j_x509
|
11
|
+
|
12
|
+
def initialize(certProf)
|
13
|
+
@certProfile = certProf
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate(issuerKey, &block)
|
17
|
+
|
18
|
+
cp = @certProfile
|
19
|
+
|
20
|
+
raise X509EngineException, "Issuer key must be given" if issuerKey.nil?
|
21
|
+
raise X509EngineException, "Issuer key must be a private key. Given #{issuerKey}" if not issuerKey.is_a?(Ccrypto::PrivateKey)
|
22
|
+
|
23
|
+
prov = Ccrypto::Java::JCEProvider::DEFProv
|
24
|
+
signSpec = nil
|
25
|
+
if block
|
26
|
+
uprov = block.call(:jce_provider_name)
|
27
|
+
prov if not_empty?(uprov)
|
28
|
+
signSpec = block.call(:sign_spec)
|
29
|
+
signHash = block.call(:sign_hash)
|
30
|
+
end
|
31
|
+
|
32
|
+
signHash = :sha256 if is_empty?(signHash)
|
33
|
+
|
34
|
+
validFrom = cp.not_before
|
35
|
+
validTo = cp.not_after
|
36
|
+
|
37
|
+
extUtils = org.bouncycastle.cert.bc.BcX509ExtensionUtils.new
|
38
|
+
|
39
|
+
if cp.serial.is_a?(java.math.BigInteger)
|
40
|
+
serial = cp.serial
|
41
|
+
else
|
42
|
+
serial = java.math.BigInteger.new(cp.serial, 16)
|
43
|
+
end
|
44
|
+
|
45
|
+
iss = cp.issuer_cert
|
46
|
+
if not_empty?(iss)
|
47
|
+
raise X509EngineException, "Issuer certificate must be Ccrypto::X509Cert object (#{iss.class})" if not iss.is_a?(Ccrypto::X509Cert) #iss.is_a?(java.security.cert.Certificate)
|
48
|
+
|
49
|
+
certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(Ccrypto::X509Cert.to_java_cert(iss), serial, validFrom, validTo, to_cert_subject, cp.public_key)
|
50
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.Extension::authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(iss.getPublicKey.encoded)))
|
51
|
+
|
52
|
+
else
|
53
|
+
|
54
|
+
name = to_cert_subject
|
55
|
+
certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(name, serial, validFrom, validTo, name, cp.public_key.native_pubKey)
|
56
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.Extension::authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(cp.public_key.to_bin)))
|
57
|
+
end
|
58
|
+
|
59
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.Extension::basicConstraints, true, org.bouncycastle.asn1.x509.BasicConstraints.new(true)) if cp.gen_issuer_cert?
|
60
|
+
|
61
|
+
#certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, false, org.bouncycastle.asn1.x509.KeyUsage.new(to_keyusage))
|
62
|
+
#criticalKu = 0
|
63
|
+
#nonCriticalKu = 0
|
64
|
+
kuv = 0
|
65
|
+
criticalKu = false
|
66
|
+
cp.key_usage.selected.each do |ku, critical|
|
67
|
+
case ku
|
68
|
+
when :digitalSignature
|
69
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::digitalSignature
|
70
|
+
when :nonRepudiation
|
71
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::nonRepudiation
|
72
|
+
when :keyEncipherment
|
73
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::keyEncipherment
|
74
|
+
when :dataEncipherment
|
75
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::dataEncipherment
|
76
|
+
when :keyAgreement
|
77
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::keyAgreement
|
78
|
+
when :keyCertSign
|
79
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::keyCertSign
|
80
|
+
when :crlSign
|
81
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::cRLSign
|
82
|
+
when :encipherOnly
|
83
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::encipherOnly
|
84
|
+
when :decipherOnly
|
85
|
+
kur = org.bouncycastle.asn1.x509::KeyUsage::decipherOnly
|
86
|
+
end
|
87
|
+
|
88
|
+
criticalKu = critical if critical
|
89
|
+
|
90
|
+
kuv |= kur
|
91
|
+
|
92
|
+
#if critical
|
93
|
+
# criticalKu |= kur
|
94
|
+
#else
|
95
|
+
# nonCriticalKu |= kur
|
96
|
+
#end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, criticalKu, org.bouncycastle.asn1.x509.KeyUsage.new(kuv))
|
101
|
+
#certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, true, org.bouncycastle.asn1.x509.KeyUsage.new(criticalKu)) if criticalKu != 0
|
102
|
+
#certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, false, org.bouncycastle.asn1.x509.KeyUsage.new(nonCriticalKu)) if nonCriticalKu != 0
|
103
|
+
|
104
|
+
ekuCritical = false
|
105
|
+
eku = java.util.Vector.new
|
106
|
+
#ekuCritical = java.util.Vector.new
|
107
|
+
#ekuNonCritical = java.util.Vector.new
|
108
|
+
cp.ext_key_usage.selected.each do |ku,critical|
|
109
|
+
case ku
|
110
|
+
when :allPurpose
|
111
|
+
kur = org.bouncycastle.asn1.x509.KeyPurposeId::anyExtendedKeyUsage
|
112
|
+
when :serverAuth
|
113
|
+
kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_serverAuth
|
114
|
+
when :clientAuth
|
115
|
+
kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_clientAuth
|
116
|
+
when :codeSigning
|
117
|
+
kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_codeSigning
|
118
|
+
when :emailProtection
|
119
|
+
kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_emailProtection
|
120
|
+
when :timestamping
|
121
|
+
kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_timeStamping
|
122
|
+
when :ocspSigning
|
123
|
+
kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_OCSPSigning
|
124
|
+
end
|
125
|
+
|
126
|
+
ekuCritical = critical if critical
|
127
|
+
eku.add_element(kur)
|
128
|
+
#if critical
|
129
|
+
# ekuCritical.add_element(kur)
|
130
|
+
#else
|
131
|
+
# ekuNonCritical.add_element(kur)
|
132
|
+
#end
|
133
|
+
end
|
134
|
+
|
135
|
+
#extKeyUsage = java.util.Vector.new
|
136
|
+
cp.domain_key_usage.each do |dku, critical|
|
137
|
+
kur = org.bouncycastle.asn1.DERObjectIdentifier.new(dku)
|
138
|
+
|
139
|
+
ekuCritical = critical if critical
|
140
|
+
eku.add_element(kur)
|
141
|
+
#if critical
|
142
|
+
# ekuCritical.add_element(kur)
|
143
|
+
#else
|
144
|
+
# ekuNonCritical.add_element(kur)
|
145
|
+
#end
|
146
|
+
end
|
147
|
+
|
148
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, ekuCritical, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(eku)) if not_empty?(eku)
|
149
|
+
#certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, true, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(ekuCritical)) if not_empty?(ekuCritical)
|
150
|
+
#certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, false, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(ekuNonCritical)) if not_empty?(ekuNonCritical)
|
151
|
+
#certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, false, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(extKeyUsage)) if not extKeyUsage.is_empty?
|
152
|
+
|
153
|
+
altName = []
|
154
|
+
cp.email.each do |e|
|
155
|
+
altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::rfc822Name,e)
|
156
|
+
end
|
157
|
+
|
158
|
+
cp.dns_name.each do |d|
|
159
|
+
altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::dNSName,d)
|
160
|
+
end
|
161
|
+
|
162
|
+
cp.ip_addr.each do |d|
|
163
|
+
altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::iPAddress,d)
|
164
|
+
end
|
165
|
+
|
166
|
+
cp.uri.each do |u|
|
167
|
+
altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier,u)
|
168
|
+
end
|
169
|
+
|
170
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.Extension::subjectAlternativeName, false, org.bouncycastle.asn1.x509.GeneralNames.new(altName.to_java(org.bouncycastle.asn1.x509.GeneralName)) )
|
171
|
+
|
172
|
+
if not_empty?(cp.crl_dist_point)
|
173
|
+
crls = []
|
174
|
+
cp.crl_dist_point.each do |c|
|
175
|
+
crls << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(c))
|
176
|
+
end
|
177
|
+
gns = org.bouncycastle.asn1.x509.GeneralNames.new(crls.to_java(org.bouncycastle.asn1.x509.GeneralName))
|
178
|
+
dpn = org.bouncycastle.asn1.x509.DistributionPointName.new(gns)
|
179
|
+
dp = org.bouncycastle.asn1.x509.DistributionPoint.new(dpn,nil,nil)
|
180
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.X509Extensions::CRLDistributionPoints,false,org.bouncycastle.asn1.DERSequence.new(dp))
|
181
|
+
end
|
182
|
+
|
183
|
+
aia = []
|
184
|
+
cp.ocsp_url.each do |o|
|
185
|
+
ov = org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(o))
|
186
|
+
aia << org.bouncycastle.asn1.x509.AccessDescription.new(org.bouncycastle.asn1.x509.AccessDescription.id_ad_ocsp, ov)
|
187
|
+
end
|
188
|
+
|
189
|
+
cp.issuer_url.each do |i|
|
190
|
+
iv = org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(i))
|
191
|
+
aia << org.bouncycastle.asn1.x509.AccessDescription.new(org.bouncycastle.asn1.x509.AccessDescription.id_ad_caIssuers, iv)
|
192
|
+
end
|
193
|
+
|
194
|
+
if not_empty?(aia)
|
195
|
+
authorityInformationAccess = org.bouncycastle.asn1.x509.AuthorityInformationAccess.new(aia.to_java(org.bouncycastle.asn1.x509.AccessDescription))
|
196
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.X509Extensions::AuthorityInfoAccess, false, authorityInformationAccess)
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
certGen.addExtension(org.bouncycastle.asn1.x509.Extension::subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(cp.public_key.to_bin)))
|
201
|
+
|
202
|
+
signAlgo = nil
|
203
|
+
if is_empty?(signSpec)
|
204
|
+
gKey = issuerKey
|
205
|
+
loop do
|
206
|
+
case gKey
|
207
|
+
when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
|
208
|
+
signAlgo = "#{signHash.to_s.upcase}WithECDSA"
|
209
|
+
break
|
210
|
+
when java.security.interfaces.RSAPrivateKey , org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey
|
211
|
+
signAlgo = "#{signHash.to_s.upcase}WithRSA"
|
212
|
+
break
|
213
|
+
when Ccrypto::PrivateKey
|
214
|
+
teLogger.debug "Found Ccrypto::Private key #{gKey}."
|
215
|
+
gKey = gKey.native_privKey
|
216
|
+
else
|
217
|
+
raise X509EngineException, "Unsupported issuer key type '#{gKey}'"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
else
|
221
|
+
end
|
222
|
+
|
223
|
+
#signAlgo = "SHA256WithECDSA"
|
224
|
+
#signer = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(signAlgo).setProvider(prov).build(issuerKey.private_key)
|
225
|
+
signer = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(signAlgo).setProvider(prov).build(gKey)
|
226
|
+
|
227
|
+
cert = org.bouncycastle.cert.jcajce.JcaX509CertificateConverter.new().setProvider(prov).getCertificate(certGen.build(signer))
|
228
|
+
cert
|
229
|
+
|
230
|
+
Ccrypto::X509Cert.new(cert)
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
def to_cert_subject
|
235
|
+
|
236
|
+
builder = org.bouncycastle.asn1.x500.X500NameBuilder.new
|
237
|
+
builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::CN, @certProfile.owner_name)
|
238
|
+
|
239
|
+
builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::O, @certProfile.org) if not_empty?(@certProfile.org)
|
240
|
+
|
241
|
+
@certProfile.org_unit.each do |ou|
|
242
|
+
builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::OU, ou)
|
243
|
+
end
|
244
|
+
|
245
|
+
#builder.addRDN(Java::OrgBouncycastleAsn1X500Style::BCStyle::SN, serial) if @serial != nil and not @serial.empty?
|
246
|
+
|
247
|
+
e = @certProfile.email.first
|
248
|
+
if not_empty?(e)
|
249
|
+
builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::EmailAddress, e)
|
250
|
+
end
|
251
|
+
|
252
|
+
builder.build
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
#def to_keyusage
|
257
|
+
# kur = 0
|
258
|
+
# @certProfile.key_usage.selected.each do |ku|
|
259
|
+
# case ku
|
260
|
+
# when :digitalSignature
|
261
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::digitalSignature
|
262
|
+
# when :nonRepudiation
|
263
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::nonRepudiation
|
264
|
+
# when :keyEncipherment
|
265
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::keyEncipherment
|
266
|
+
# when :dataEncipherment
|
267
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::dataEncipherment
|
268
|
+
# when :keyAgreement
|
269
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::keyAgreement
|
270
|
+
# when :keyCertSign
|
271
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::keyCertSign
|
272
|
+
# when :crlSign
|
273
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::cRLSign
|
274
|
+
# when :encipherOnly
|
275
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::encipherOnly
|
276
|
+
# when :decipherOnly
|
277
|
+
# kur |= org.bouncycastle.asn1.x509::KeyUsage::decipherOnly
|
278
|
+
# end
|
279
|
+
# end
|
280
|
+
|
281
|
+
# kur
|
282
|
+
#end
|
283
|
+
|
284
|
+
def to_extkeyusage
|
285
|
+
kur = java.util.Vector.new
|
286
|
+
@certProfile.ext_key_usage.selected.each do |ku|
|
287
|
+
case ku
|
288
|
+
when :allPurpose
|
289
|
+
kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::anyExtendedKeyUsage
|
290
|
+
when :serverAuth
|
291
|
+
kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_serverAuth
|
292
|
+
when :clientAuth
|
293
|
+
kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_clientAuth
|
294
|
+
when :codeSigning
|
295
|
+
kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_codeSigning
|
296
|
+
when :emailProtection
|
297
|
+
kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_emailProtection
|
298
|
+
when :timestamping
|
299
|
+
kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_timeStamping
|
300
|
+
when :ocspSigning
|
301
|
+
kur.add_element org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_OCSPSigning
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
kur
|
306
|
+
end
|
307
|
+
|
308
|
+
end
|
309
|
+
|
310
|
+
end
|
311
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
|
2
|
+
require_relative '../data_conversion'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
class SecretKey
|
6
|
+
include Java::DataConversion
|
7
|
+
|
8
|
+
include TeLogger::TeLogHelper
|
9
|
+
teLogger_tag :j_secretkey_ext
|
10
|
+
|
11
|
+
def to_jce_secret_key
|
12
|
+
case @key
|
13
|
+
when javax.crypto.spec.SecretKeySpec
|
14
|
+
@key
|
15
|
+
when ::Java::byte[]
|
16
|
+
javax.crypto.spec.SecretKeySpec.new(@key, @algo.to_s)
|
17
|
+
|
18
|
+
else
|
19
|
+
case @key.key
|
20
|
+
when javax.crypto.spec.SecretKeySpec
|
21
|
+
@key.key
|
22
|
+
when ::Java::byte[]
|
23
|
+
javax.crypto.spec.SecretKeySpec.new(@key.key, @algo.to_s)
|
24
|
+
else
|
25
|
+
raise Ccrypto::Error, "Unknown key to conver to jce #{@key.key}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_bin
|
31
|
+
case @key
|
32
|
+
when javax.crypto.spec.SecretKeySpec
|
33
|
+
@key.encoded
|
34
|
+
else
|
35
|
+
raise Ccrypto::Error, "Unsupported key type #{@key.class}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def length
|
40
|
+
case @key
|
41
|
+
when javax.crypto.spec.SecretKeySpec
|
42
|
+
@key.encoded.length
|
43
|
+
when ::Java::byte[]
|
44
|
+
@key.length
|
45
|
+
else
|
46
|
+
@key.key.encoded.length
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def equals?(key)
|
51
|
+
case key
|
52
|
+
when Ccrypto::SecretKey
|
53
|
+
teLogger.debug "Given key is Ccrypto::SecretKey"
|
54
|
+
to_jce_secret_key.encoded == key.to_jce_secret_key.encoded
|
55
|
+
when javax.crypto.spec.SecretKeySpec
|
56
|
+
teLogger.debug "Given key is java SecretKeySpec"
|
57
|
+
to_jce_secret_key.encoded == key.encoded
|
58
|
+
when ::Java::byte[]
|
59
|
+
to_jce_secret_key.encoded == key
|
60
|
+
when String
|
61
|
+
to_jce_secret_key.encoded == to_java_bytes(key)
|
62
|
+
else
|
63
|
+
teLogger.debug "Not sure how to compare : #{self} / #{key}"
|
64
|
+
to_jce_secret_key == key
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
#def each_char(&block)
|
69
|
+
# to_bin.each do |b|
|
70
|
+
# block.call(b)
|
71
|
+
# end
|
72
|
+
#end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Ccrypto
|
4
|
+
class X509Cert
|
5
|
+
include TR::CondUtils
|
6
|
+
|
7
|
+
def to_der
|
8
|
+
@nativeX509.encoded
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(mtd, *args, &block)
|
12
|
+
@nativeX509.send(mtd, *args, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def equal?(cert)
|
16
|
+
if cert.nil?
|
17
|
+
if @nativeX509.nil?
|
18
|
+
true
|
19
|
+
else
|
20
|
+
false
|
21
|
+
end
|
22
|
+
else
|
23
|
+
|
24
|
+
tcert = self.class.to_java_cert(cert)
|
25
|
+
lcert = self.class.to_java_cert(@nativeX509)
|
26
|
+
|
27
|
+
tcert.encoded == @nativeX509.encoded
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.to_java_cert(cert)
|
32
|
+
raise X509CertException, "Given certificate to convert to Java certificate object is empty" if is_empty?(cert)
|
33
|
+
|
34
|
+
case cert
|
35
|
+
when java.security.cert.Certificate
|
36
|
+
cert
|
37
|
+
when org.bouncycastle.cert.X509CertificateHolder
|
38
|
+
cert.to_java_cert
|
39
|
+
when Ccrypto::X509Cert
|
40
|
+
to_java_cert(cert.nativeX509)
|
41
|
+
else
|
42
|
+
raise X509CertException, "Unknown certificate type #{cert} for conversion"
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
require 'singleton'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
module Java
|
6
|
+
|
7
|
+
class JCEProviderException < StandardError; end
|
8
|
+
|
9
|
+
class JCEProvider
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
BCProv = org.bouncycastle.jce.provider.BouncyCastleProvider.new
|
13
|
+
DEFProv = BCProv
|
14
|
+
|
15
|
+
def add_provider(prov = nil)
|
16
|
+
case prov
|
17
|
+
when java.security.Provider
|
18
|
+
java.security.Security.add_provider(prov) if not is_provider_registered?(prov)
|
19
|
+
else
|
20
|
+
java.security.Security.add_provider(DEFProv) if not is_provider_registered?(DEFProv)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def is_provider_registered?(prov)
|
25
|
+
case prov
|
26
|
+
when String
|
27
|
+
java.security.Security.providers.to_a.map { |v| v.name }.include?(prov)
|
28
|
+
when java.security.Provider
|
29
|
+
java.security.Security.get_providers.to_a.include?(prov)
|
30
|
+
else
|
31
|
+
false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_bc_provider
|
36
|
+
add_provider
|
37
|
+
end
|
38
|
+
|
39
|
+
#def set_default_provider(prov)
|
40
|
+
|
41
|
+
# case prov
|
42
|
+
# when String
|
43
|
+
# when java.security.Provider
|
44
|
+
# add_provider(prov) if not is_provider_registered?(prov)
|
45
|
+
# @defProvider = prov
|
46
|
+
# end
|
47
|
+
|
48
|
+
#end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
|
2
|
+
require_relative '../data_conversion'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
module Java
|
6
|
+
|
7
|
+
module PKCS12
|
8
|
+
include TR::CondUtils
|
9
|
+
include DataConversion
|
10
|
+
|
11
|
+
class PKCS12StorageException < KeyBundleStorageException; end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
include DataConversion
|
15
|
+
|
16
|
+
def from_pkcs12(bin, &block)
|
17
|
+
|
18
|
+
raise PKCS12StorageException, "block is required" if not block
|
19
|
+
|
20
|
+
storeType = block.call(:store_type)
|
21
|
+
storeType = "PKCS12" if is_empty?(storeType)
|
22
|
+
|
23
|
+
prof = block.call(:jce_provider)
|
24
|
+
if not_empty?(prof)
|
25
|
+
ks = java.security.KeyStore.getInstance(storeType, prof)
|
26
|
+
else
|
27
|
+
ks = java.security.KeyStore.getInstance(storeType)
|
28
|
+
end
|
29
|
+
|
30
|
+
pass = block.call(:p12_pass) || block.call(:jks_pass)
|
31
|
+
name = block.call(:p12_name) || block.call(:jks_name)
|
32
|
+
|
33
|
+
#case bin
|
34
|
+
#when String
|
35
|
+
# bbin = bin.to_java_bytes
|
36
|
+
#when ::Java::byte[]
|
37
|
+
# bbin = bin
|
38
|
+
#else
|
39
|
+
# raise KeypairEngineException, "Java byte array is expected. Given #{bin.class}"
|
40
|
+
#end
|
41
|
+
|
42
|
+
bbin = to_java_bytes(bin)
|
43
|
+
|
44
|
+
ks.load(java.io.ByteArrayInputStream.new(bbin),pass.to_java.toCharArray)
|
45
|
+
|
46
|
+
name = ks.aliases.to_a.first if is_empty?(name)
|
47
|
+
|
48
|
+
userCert = Ccrypto::X509Cert.new(ks.getCertificate(name))
|
49
|
+
chain = ks.get_certificate_chain(name).collect { |c| Ccrypto::X509Cert.new(c) }
|
50
|
+
chain = chain.delete_if { |c| c.equal?(userCert) }
|
51
|
+
|
52
|
+
key = ks.getKey(name, pass.to_java.toCharArray)
|
53
|
+
case key
|
54
|
+
when java.security.interfaces.ECPrivateKey
|
55
|
+
[Ccrypto::Java::ECCKeyBundle.new(key), userCert, chain]
|
56
|
+
when java.security.interfaces.RSAPrivateKey
|
57
|
+
[Ccrypto::Java::RSAKeyBundle.new(key), userCert, chain]
|
58
|
+
else
|
59
|
+
raise PKCS12StorageException, "Unknown key type #{key}"
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
def self.included(klass)
|
66
|
+
klass.extend(ClassMethods)
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_pkcs12(&block)
|
70
|
+
|
71
|
+
raise KeypairEngineException, "block is required" if not block
|
72
|
+
|
73
|
+
storeType = block.call(:store_type)
|
74
|
+
storeType = "PKCS12" if is_empty?(storeType)
|
75
|
+
|
76
|
+
prof = block.call(:jce_provider)
|
77
|
+
if not_empty?(prof)
|
78
|
+
ks = java.security.KeyStore.getInstance(storeType, prof)
|
79
|
+
else
|
80
|
+
ks = java.security.KeyStore.getInstance(storeType)
|
81
|
+
end
|
82
|
+
|
83
|
+
ks.load(nil,nil)
|
84
|
+
|
85
|
+
gcert = block.call(:cert)
|
86
|
+
raise KeypairEngineException, "PKCS12 requires the X.509 certificate" if is_empty?(gcert)
|
87
|
+
|
88
|
+
ca = block.call(:certchain) || [cert]
|
89
|
+
ca = [cert] if is_empty?(ca)
|
90
|
+
ca = ca.unshift(gcert) if not ca.first.equal?(gcert)
|
91
|
+
ca = ca.collect { |c|
|
92
|
+
Ccrypto::X509Cert.to_java_cert(c)
|
93
|
+
}
|
94
|
+
|
95
|
+
pass = block.call(:p12_pass) || block.call(:jks_pass)
|
96
|
+
raise KeypairEngineException, "Password is required" if is_empty?(pass)
|
97
|
+
|
98
|
+
name = block.call(:p12_name) || block.call(:jks_name)
|
99
|
+
name = "Ccrypto P12" if is_empty?(name)
|
100
|
+
|
101
|
+
keypair = block.call(:keypair)
|
102
|
+
raise KeypairEngineException, "Keypair is required" if is_empty?(keypair)
|
103
|
+
|
104
|
+
ks.setKeyEntry(name, keypair.private, pass.to_java.toCharArray, ca.to_java(java.security.cert.Certificate))
|
105
|
+
|
106
|
+
baos = java.io.ByteArrayOutputStream.new
|
107
|
+
ks.store(baos, pass.to_java.toCharArray)
|
108
|
+
res = baos.toByteArray
|
109
|
+
|
110
|
+
outForm = block.call(:out_format)
|
111
|
+
case outForm
|
112
|
+
when :b64
|
113
|
+
to_b64(res)
|
114
|
+
when :hex
|
115
|
+
to_hex(res)
|
116
|
+
else
|
117
|
+
res
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|