ccrypto-java 0.1.0
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/.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
|