ccrypto-java 0.1.0 → 0.2.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.java-version +1 -1
  3. data/.release_history.yml +4 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +68 -53
  7. data/Rakefile +2 -1
  8. data/bin/console +14 -0
  9. data/jars/bcjmail-jdk18on-172.jar +0 -0
  10. data/jars/bcmail-jdk18on-172.jar +0 -0
  11. data/jars/bcpg-jdk18on-172.1.jar +0 -0
  12. data/jars/bcpkix-jdk18on-172.jar +0 -0
  13. data/jars/bcprov-ext-jdk18on-172.jar +0 -0
  14. data/jars/bcprov-jdk18on-172.jar +0 -0
  15. data/jars/bctls-jdk18on-172.jar +0 -0
  16. data/jars/bcutil-jdk18on-172.jar +0 -0
  17. data/lib/ccrypto/java/bc_const_mapping.rb +42 -0
  18. data/lib/ccrypto/java/data_conversion.rb +23 -2
  19. data/lib/ccrypto/java/engines/argon2_engine.rb +95 -0
  20. data/lib/ccrypto/java/engines/asn1_engine.rb +2 -1
  21. data/lib/ccrypto/java/engines/bcrypt_engine.rb +56 -0
  22. data/lib/ccrypto/java/engines/cipher_engine.rb +462 -130
  23. data/lib/ccrypto/java/engines/compression_engine.rb +7 -28
  24. data/lib/ccrypto/java/engines/crystal_dilithium_engine.rb +226 -0
  25. data/lib/ccrypto/java/engines/crystal_kyber_engine.rb +260 -0
  26. data/lib/ccrypto/java/engines/decompression_engine.rb +5 -4
  27. data/lib/ccrypto/java/engines/digest_engine.rb +221 -139
  28. data/lib/ccrypto/java/engines/ecc_engine.rb +249 -96
  29. data/lib/ccrypto/java/engines/ed25519_engine.rb +211 -0
  30. data/lib/ccrypto/java/engines/hkdf_engine.rb +82 -23
  31. data/lib/ccrypto/java/engines/hmac_engine.rb +98 -23
  32. data/lib/ccrypto/java/engines/pbkdf2_engine.rb +82 -33
  33. data/lib/ccrypto/java/engines/pkcs7_engine.rb +44 -33
  34. data/lib/ccrypto/java/engines/rsa_engine.rb +85 -31
  35. data/lib/ccrypto/java/engines/scrypt_engine.rb +12 -3
  36. data/lib/ccrypto/java/engines/secret_key_engine.rb +77 -12
  37. data/lib/ccrypto/java/engines/secret_sharing_engine.rb +17 -2
  38. data/lib/ccrypto/java/engines/x25519_engine.rb +249 -0
  39. data/lib/ccrypto/java/engines/x509_csr_engine.rb +141 -0
  40. data/lib/ccrypto/java/engines/x509_engine.rb +365 -71
  41. data/lib/ccrypto/java/ext/secret_key.rb +37 -25
  42. data/lib/ccrypto/java/ext/x509_cert.rb +429 -5
  43. data/lib/ccrypto/java/ext/x509_csr.rb +151 -0
  44. data/lib/ccrypto/java/jce_provider.rb +0 -11
  45. data/lib/ccrypto/java/keystore/jce_keystore.rb +205 -0
  46. data/lib/ccrypto/java/keystore/jks_keystore.rb +52 -0
  47. data/lib/ccrypto/java/keystore/keystore.rb +97 -0
  48. data/lib/ccrypto/java/keystore/pem_keystore.rb +147 -0
  49. data/lib/ccrypto/java/keystore/pkcs12_keystore.rb +56 -0
  50. data/lib/ccrypto/java/utils/comparator.rb +25 -2
  51. data/lib/ccrypto/java/version.rb +1 -1
  52. data/lib/ccrypto/java.rb +46 -0
  53. data/lib/ccrypto/provider.rb +139 -3
  54. metadata +40 -24
  55. data/ccrypto-java.gemspec +0 -44
  56. data/jars/bcmail-jdk15on-165.jar +0 -0
  57. data/jars/bcpg-jdk15on-165.jar +0 -0
  58. data/jars/bcpkix-jdk15on-165.jar +0 -0
  59. data/jars/bcprov-ext-jdk15on-165.jar +0 -0
  60. data/jars/bcprov-jdk15on-165.jar +0 -0
  61. data/jars/bctls-jdk15on-165.jar +0 -0
  62. data/lib/ccrypto/java/keybundle_store/pkcs12.rb +0 -125
@@ -0,0 +1,141 @@
1
+
2
+
3
+ module Ccrypto
4
+ module Java
5
+
6
+ class X509CSREngine
7
+ include TR::CondUtils
8
+ include TeLogger::TeLogHelper
9
+ teLogger_tag :j_csr
10
+
11
+ def initialize(csrProf)
12
+ @csrProfile = csrProf
13
+ end
14
+
15
+ def generate(privKey, &block)
16
+
17
+ cp = @csrProfile
18
+
19
+ subject = to_cert_subject(cp)
20
+
21
+ signHash = cp.hashAlgo
22
+ raise X509CSREngineException, "Certificate hash algorithm '#{signHash}' is not supported" if not DigestEngine.is_digest_supported?(signHash)
23
+
24
+ provider = block.call(:jce_provider) if block
25
+
26
+ if provider.nil?
27
+ teLogger.debug "Adding default provider"
28
+ prov = Ccrypto::Java::JCEProvider::DEFProv
29
+ else
30
+ teLogger.debug "Adding provider #{provider.name}"
31
+ prov = Ccrypto::Java::JCEProvider.add_provider(provider)
32
+ end
33
+
34
+ foundDigest = DigestEngine.find_digest_config(signHash)
35
+ if foundDigest.length == 1
36
+ selDigest = foundDigest.first
37
+ else
38
+ ## prompt user for digest
39
+ if block
40
+ selDigest = block.call(:multiple_digest_algo_found, foundDigest)
41
+ else
42
+ raise X509EngineException, "Multiple digest algo found but not given a block. Not able to proceed."
43
+ end
44
+ end
45
+ signHashVal = selDigest.provider_config[:algo_name].gsub("-","")
46
+
47
+
48
+ #signHashVal = DigestEngine.find_digest_config(signHash).provider_config[:algo_name]
49
+ #signHashVal.gsub!("-","")
50
+
51
+ signAlgo = nil
52
+ gKey = privKey
53
+ loop do
54
+ case gKey
55
+ when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
56
+ signAlgo = "#{signHashVal}WithECDSA"
57
+ break
58
+ when java.security.interfaces.RSAPrivateKey , org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey
59
+ signAlgo = "#{signHashVal}WithRSA"
60
+ break
61
+ when Ccrypto::PrivateKey
62
+ teLogger.debug "Found Ccrypto::Private key #{gKey}."
63
+ gKey = gKey.native_privKey
64
+ else
65
+ raise X509CSREngineException, "Unsupported signing key type '#{gKey}'"
66
+ end
67
+ end
68
+
69
+ p10Builder = org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder.new(subject, cp.public_key)
70
+
71
+ ext = []
72
+ cp.email.each do |e|
73
+ ext << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName.rfc822Name,e)
74
+ end
75
+
76
+ cp.dns_name.each do |dn|
77
+ ext << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName.dNSName,dn)
78
+ end
79
+
80
+ cp.ip_addr.each do |ip|
81
+ ext << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName.iPAddress,ip)
82
+ end
83
+
84
+ cp.uri.each do |u|
85
+ ext << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName.uniformResourceIdentifier,u)
86
+ end
87
+
88
+ #cp.custom_extension.each do |k,v|
89
+ # val = v[:value]
90
+ # val = "" if is_empty?(val)
91
+ # ev = org.bouncycastle.asn1.x509.Extension.new(org.bouncycastle.asn1.DERObjectIdentifier.new(k), v[:critical], org.bouncycastle.asn1.DEROctetString.new(val.to_java.getBytes))
92
+ # ext << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName.otherName,ev)
93
+ #end
94
+
95
+ gn = org.bouncycastle.asn1.x509.GeneralNames.new(ext.to_java(org.bouncycastle.asn1.x509.GeneralName))
96
+ eg = org.bouncycastle.asn1.x509.ExtensionsGenerator.new
97
+ eg.addExtension(org.bouncycastle.asn1.x509.Extension.subjectAlternativeName, false, gn)
98
+
99
+ cp.custom_extension.each do |k,v|
100
+ val = v[:value]
101
+ val = "" if is_empty?(val)
102
+ ev = org.bouncycastle.asn1.x509.Extension.new(org.bouncycastle.asn1.ASN1ObjectIdentifier.new(k), v[:critical], org.bouncycastle.asn1.DEROctetString.new(val.to_java.getBytes))
103
+ eg.addExtension(ev)
104
+ end
105
+
106
+
107
+ p10Builder.addAttribute(org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, eg.generate)
108
+
109
+ sign = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(signAlgo).setProvider(prov).build(gKey)
110
+ csr = p10Builder.build(sign)
111
+
112
+ Ccrypto::X509CSR.new(csr)
113
+
114
+ end
115
+
116
+
117
+ private
118
+ def to_cert_subject(cp)
119
+
120
+ builder = org.bouncycastle.asn1.x500.X500NameBuilder.new
121
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::CN, cp.owner_name)
122
+
123
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::O, cp.org) if not_empty?(cp.org)
124
+
125
+ cp.org_unit.each do |ou|
126
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::OU, ou)
127
+ end
128
+
129
+ e = cp.email.first
130
+ if not_empty?(e)
131
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::EmailAddress, e)
132
+ end
133
+
134
+ builder.build
135
+
136
+ end
137
+
138
+ end
139
+
140
+ end
141
+ end
@@ -1,35 +1,54 @@
1
1
 
2
+ require_relative '../bc_const_mapping'
3
+
2
4
  module Ccrypto
3
5
  module Java
4
6
 
5
7
  class X509Engine
6
8
  include TR::CondUtils
7
9
 
8
- include TeLogger::TeLogHelper
10
+ def self.cert_to_bin(cert)
11
+ cert.encoded
12
+ end
9
13
 
10
- teLogger_tag :j_x509
14
+ def self.bin_to_cert(bin)
15
+ cf = java.security.cert.CertificateFactory.getInstance("X509",JCEProvider::DEFProv)
16
+ cf.generateCertificate(bin)
17
+ end
11
18
 
12
19
  def initialize(certProf)
13
20
  @certProfile = certProf
14
21
  end
15
22
 
16
23
  def generate(issuerKey, &block)
24
+ if @certProfile.csr.nil?
25
+ generate_from_cert_profile(@certProfile, issuerKey, &block)
26
+ else
27
+ generate_from_csr(@certProfile, issuerKey, &block)
28
+ end
29
+ end
30
+
31
+ def generate_from_csr(cp, issuerKey, &block)
32
+
33
+ csrObj = Ccrypto::X509CSR.new(cp.csr)
34
+ csrCp = csrObj.csr_info
17
35
 
18
- cp = @certProfile
19
36
 
20
37
  raise X509EngineException, "Issuer key must be given" if issuerKey.nil?
21
38
  raise X509EngineException, "Issuer key must be a private key. Given #{issuerKey}" if not issuerKey.is_a?(Ccrypto::PrivateKey)
22
39
 
23
40
  prov = Ccrypto::Java::JCEProvider::DEFProv
41
+ signHash = cp.hashAlgo
24
42
  signSpec = nil
25
43
  if block
26
44
  uprov = block.call(:jce_provider_name)
27
45
  prov if not_empty?(uprov)
28
46
  signSpec = block.call(:sign_spec)
29
- signHash = block.call(:sign_hash)
47
+ signHash = block.call(:sign_hash) if is_empty?(signHash)
30
48
  end
31
49
 
32
50
  signHash = :sha256 if is_empty?(signHash)
51
+ raise X509EngineException, "Given digest algo '#{signHash}' is not suported" if not DigestEngine.is_digest_supported?(signHash)
33
52
 
34
53
  validFrom = cp.not_before
35
54
  validTo = cp.not_after
@@ -42,16 +61,260 @@ module Ccrypto
42
61
  serial = java.math.BigInteger.new(cp.serial, 16)
43
62
  end
44
63
 
64
+ iss = cp.issuer_cert
65
+ if not_empty?(iss)
66
+ raise X509EngineException, "Issuer certificate must be Ccrypto::X509Cert object (#{iss.class})" if not iss.is_a?(Ccrypto::X509Cert)
67
+
68
+ certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(Ccrypto::X509Cert.to_java_cert(iss), serial, validFrom, validTo, to_cert_subject(csrCp), csrCp.public_key)
69
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(iss.getPublicKey.encoded)))
70
+
71
+ else
72
+
73
+ name = to_cert_subject(csrCp)
74
+ certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(name, serial, validFrom, validTo, name, csrCp.public_key.native_pubKey)
75
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(csrCp.public_key.to_bin)))
76
+ end
77
+
78
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::basicConstraints, true, org.bouncycastle.asn1.x509.BasicConstraints.new(true)) if cp.gen_issuer_cert?
79
+
80
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, false, org.bouncycastle.asn1.x509.KeyUsage.new(to_keyusage))
81
+ #criticalKu = 0
82
+ #nonCriticalKu = 0
83
+ kuv = 0
84
+ criticalKu = false
85
+ cp.key_usage.selected.each do |ku, critical|
86
+ kur = BCConstMapping::KeyUsageMapping[ku]
87
+ #case ku
88
+ #when :digitalSignature
89
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::digitalSignature
90
+ #when :nonRepudiation
91
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::nonRepudiation
92
+ #when :keyEncipherment
93
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::keyEncipherment
94
+ #when :dataEncipherment
95
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::dataEncipherment
96
+ #when :keyAgreement
97
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::keyAgreement
98
+ #when :keyCertSign
99
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::keyCertSign
100
+ #when :crlSign
101
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::cRLSign
102
+ #when :encipherOnly
103
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::encipherOnly
104
+ #when :decipherOnly
105
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::decipherOnly
106
+ #end
107
+
108
+ criticalKu = critical if critical
109
+
110
+ kuv |= kur
111
+
112
+ #if critical
113
+ # criticalKu |= kur
114
+ #else
115
+ # nonCriticalKu |= kur
116
+ #end
117
+
118
+ end
119
+
120
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, criticalKu, org.bouncycastle.asn1.x509.KeyUsage.new(kuv))
121
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, true, org.bouncycastle.asn1.x509.KeyUsage.new(criticalKu)) if criticalKu != 0
122
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::keyUsage, false, org.bouncycastle.asn1.x509.KeyUsage.new(nonCriticalKu)) if nonCriticalKu != 0
123
+
124
+ ekuCritical = false
125
+ eku = java.util.Vector.new
126
+ #ekuCritical = java.util.Vector.new
127
+ #ekuNonCritical = java.util.Vector.new
128
+ cp.ext_key_usage.selected.each do |ku,critical|
129
+ kur = BCConstMapping::ExtKeyUsageMapping[ku]
130
+ #case ku
131
+ #when :allPurpose
132
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::anyExtendedKeyUsage
133
+ #when :serverAuth
134
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_serverAuth
135
+ #when :clientAuth
136
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_clientAuth
137
+ #when :codeSigning
138
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_codeSigning
139
+ #when :emailProtection
140
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_emailProtection
141
+ #when :timeStamping
142
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_timeStamping
143
+ #when :ocspSigning
144
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_OCSPSigning
145
+ #end
146
+
147
+ ekuCritical = critical if critical
148
+ eku.add_element(kur)
149
+ #if critical
150
+ # ekuCritical.add_element(kur)
151
+ #else
152
+ # ekuNonCritical.add_element(kur)
153
+ #end
154
+ end
155
+
156
+ #extKeyUsage = java.util.Vector.new
157
+ cp.domain_key_usage.each do |dku, critical|
158
+ #kur = org.bouncycastle.asn1.DERObjectIdentifier.new(dku)
159
+ kur = org.bouncycastle.asn1.ASN1ObjectIdentifier.new(dku)
160
+
161
+ ekuCritical = critical if critical
162
+ eku.add_element(kur)
163
+ #if critical
164
+ # ekuCritical.add_element(kur)
165
+ #else
166
+ # ekuNonCritical.add_element(kur)
167
+ #end
168
+ end
169
+
170
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, ekuCritical, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(eku)) if not_empty?(eku)
171
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, true, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(ekuCritical)) if not_empty?(ekuCritical)
172
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, false, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(ekuNonCritical)) if not_empty?(ekuNonCritical)
173
+ #certGen.addExtension(org.bouncycastle.asn1.x509.Extension::extendedKeyUsage, false, org.bouncycastle.asn1.x509.ExtendedKeyUsage.new(extKeyUsage)) if not extKeyUsage.is_empty?
174
+
175
+ altName = []
176
+ csrCp.email.uniq.each do |e|
177
+ altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::rfc822Name,e)
178
+ end
179
+
180
+ csrCp.dns_name.uniq.each do |d|
181
+ altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::dNSName,d)
182
+ end
183
+
184
+ csrCp.ip_addr.uniq.each do |d|
185
+ altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::iPAddress,d)
186
+ end
187
+
188
+ csrCp.uri.uniq.each do |u|
189
+ altName << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier,u)
190
+ end
191
+
192
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::subjectAlternativeName, false, org.bouncycastle.asn1.x509.GeneralNames.new(altName.to_java(org.bouncycastle.asn1.x509.GeneralName)) )
193
+
194
+ csrCp.custom_extension.each do |k, v|
195
+ val = v[:value]
196
+ val = "" if is_empty?(val)
197
+ #ev = org.bouncycastle.asn1.x509.Extension.new(org.bouncycastle.asn1.DERObjectIdentifier.new(k), v[:critical], org.bouncycastle.asn1.DEROctetString.new(val.to_java.getBytes))
198
+ ev = org.bouncycastle.asn1.x509.Extension.new(org.bouncycastle.asn1.ASN1ObjectIdentifier.new(k), v[:critical], org.bouncycastle.asn1.DEROctetString.new(val.to_java.getBytes))
199
+ certGen.addExtension(ev)
200
+ end
201
+
202
+
203
+ if not_empty?(cp.crl_dist_point)
204
+ crls = []
205
+ cp.crl_dist_point.each do |c|
206
+ crls << org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(c))
207
+ end
208
+ gns = org.bouncycastle.asn1.x509.GeneralNames.new(crls.to_java(org.bouncycastle.asn1.x509.GeneralName))
209
+ dpn = org.bouncycastle.asn1.x509.DistributionPointName.new(gns)
210
+ dp = org.bouncycastle.asn1.x509.DistributionPoint.new(dpn,nil,nil)
211
+ certGen.addExtension(org.bouncycastle.asn1.x509.X509Extensions::CRLDistributionPoints,false,org.bouncycastle.asn1.DERSequence.new(dp))
212
+ end
213
+
214
+ aia = []
215
+ cp.ocsp_url.each do |o|
216
+ ov = org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(o))
217
+ aia << org.bouncycastle.asn1.x509.AccessDescription.new(org.bouncycastle.asn1.x509.AccessDescription.id_ad_ocsp, ov)
218
+ end
219
+
220
+ cp.issuer_url.each do |i|
221
+ iv = org.bouncycastle.asn1.x509.GeneralName.new(org.bouncycastle.asn1.x509.GeneralName::uniformResourceIdentifier, org.bouncycastle.asn1.DERIA5String.new(i))
222
+ aia << org.bouncycastle.asn1.x509.AccessDescription.new(org.bouncycastle.asn1.x509.AccessDescription.id_ad_caIssuers, iv)
223
+ end
224
+
225
+ if not_empty?(aia)
226
+ authorityInformationAccess = org.bouncycastle.asn1.x509.AuthorityInformationAccess.new(aia.to_java(org.bouncycastle.asn1.x509.AccessDescription))
227
+ certGen.addExtension(org.bouncycastle.asn1.x509.X509Extensions::AuthorityInfoAccess, false, authorityInformationAccess)
228
+ end
229
+
230
+
231
+ certGen.addExtension(org.bouncycastle.asn1.x509.Extension::subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(csrCp.public_key.to_bin)))
232
+
233
+ signAlgo = nil
234
+ # alreacy check if digest algo exist or not at the entry of the method
235
+ foundDigest = DigestEngine.find_digest_config(signHash)
236
+ if foundDigest.length == 1
237
+ selDigest = foundDigest.first
238
+ else
239
+ ## prompt user for digest
240
+ if block
241
+ selDigest = block.call(:multiple_digest_algo_found, foundDigest)
242
+ else
243
+ raise X509EngineException, "Multiple digest algo configuration found based on given value '#{signHash}' but not given a block. Not able to proceed."
244
+ end
245
+ end
246
+ signHashVal = selDigest.provider_config[:algo_name].gsub("-","")
247
+
248
+ gKey = issuerKey
249
+ loop do
250
+ case gKey
251
+ when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
252
+ signAlgo = "#{signHashVal}WithECDSA"
253
+ break
254
+ when java.security.interfaces.RSAPrivateKey , org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey
255
+ signAlgo = "#{signHashVal}WithRSA"
256
+ break
257
+ when Ccrypto::PrivateKey
258
+ logger.debug "Found Ccrypto::Private key #{gKey}."
259
+ gKey = gKey.native_privKey
260
+ else
261
+ raise X509EngineException, "Unsupported issuer key type '#{gKey}'"
262
+ end
263
+ end
264
+
265
+ #signAlgo = "SHA256WithECDSA"
266
+ #signer = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(signAlgo).setProvider(prov).build(issuerKey.private_key)
267
+ signer = org.bouncycastle.operator.jcajce.JcaContentSignerBuilder.new(signAlgo).setProvider(prov).build(gKey)
268
+
269
+ cert = org.bouncycastle.cert.jcajce.JcaX509CertificateConverter.new().setProvider(prov).getCertificate(certGen.build(signer))
270
+ cert
271
+
272
+ Ccrypto::X509Cert.new(cert)
273
+
274
+ end
275
+
276
+
277
+ def generate_from_cert_profile(cp, issuerKey, &block)
278
+
279
+ raise X509EngineException, "Issuer key must be given" if issuerKey.nil?
280
+ raise X509EngineException, "Issuer key must be a private key. Given #{issuerKey}" if not issuerKey.is_a?(Ccrypto::PrivateKey)
281
+
282
+ prov = Ccrypto::Java::JCEProvider::DEFProv
283
+ signHash = cp.hashAlgo
284
+ signSpec = nil
285
+ if block
286
+ uprov = block.call(:jce_provider_name)
287
+ prov if not_empty?(uprov)
288
+ signSpec = block.call(:sign_spec)
289
+ signHash = block.call(:sign_hash) if is_empty?(signHash)
290
+ end
291
+
292
+ signHash = :sha256 if is_empty?(signHash)
293
+ raise X509EngineException, "Given digest algo '#{signHash}' is not suported" if not DigestEngine.is_digest_supported?(signHash)
294
+
295
+ validFrom = cp.not_before
296
+ validTo = cp.not_after
297
+
298
+ extUtils = org.bouncycastle.cert.bc.BcX509ExtensionUtils.new
299
+
300
+ if is_empty?(cp.serial)
301
+ serial = SecureRandom.hex(16)
302
+ elsif cp.serial.is_a?(java.math.BigInteger)
303
+ serial = cp.serial
304
+ else
305
+ serial = java.math.BigInteger.new(cp.serial, 16)
306
+ end
307
+
45
308
  iss = cp.issuer_cert
46
309
  if not_empty?(iss)
47
310
  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
311
 
49
- certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(Ccrypto::X509Cert.to_java_cert(iss), serial, validFrom, validTo, to_cert_subject, cp.public_key)
312
+ certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(Ccrypto::X509Cert.to_java_cert(iss), serial, validFrom, validTo, to_cert_subject(cp), cp.public_key)
50
313
  certGen.addExtension(org.bouncycastle.asn1.x509.Extension::authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(iss.getPublicKey.encoded)))
51
314
 
52
315
  else
53
316
 
54
- name = to_cert_subject
317
+ name = to_cert_subject(cp)
55
318
  certGen = org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder.new(name, serial, validFrom, validTo, name, cp.public_key.native_pubKey)
56
319
  certGen.addExtension(org.bouncycastle.asn1.x509.Extension::authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(cp.public_key.to_bin)))
57
320
  end
@@ -64,26 +327,27 @@ module Ccrypto
64
327
  kuv = 0
65
328
  criticalKu = false
66
329
  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
330
+ kur = BCConstMapping::KeyUsageMapping[ku]
331
+ #case ku
332
+ #when :digitalSignature
333
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::digitalSignature
334
+ #when :nonRepudiation
335
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::nonRepudiation
336
+ #when :keyEncipherment
337
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::keyEncipherment
338
+ #when :dataEncipherment
339
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::dataEncipherment
340
+ #when :keyAgreement
341
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::keyAgreement
342
+ #when :keyCertSign
343
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::keyCertSign
344
+ #when :crlSign
345
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::cRLSign
346
+ #when :encipherOnly
347
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::encipherOnly
348
+ #when :decipherOnly
349
+ # kur = org.bouncycastle.asn1.x509::KeyUsage::decipherOnly
350
+ #end
87
351
 
88
352
  criticalKu = critical if critical
89
353
 
@@ -106,22 +370,23 @@ module Ccrypto
106
370
  #ekuCritical = java.util.Vector.new
107
371
  #ekuNonCritical = java.util.Vector.new
108
372
  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
373
+ kur = BCConstMapping::ExtKeyUsageMapping[ku]
374
+ #case ku
375
+ #when :allPurpose
376
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::anyExtendedKeyUsage
377
+ #when :serverAuth
378
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_serverAuth
379
+ #when :clientAuth
380
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_clientAuth
381
+ #when :codeSigning
382
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_codeSigning
383
+ #when :emailProtection
384
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_emailProtection
385
+ #when :timeStamping
386
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_timeStamping
387
+ #when :ocspSigning
388
+ # kur = org.bouncycastle.asn1.x509.KeyPurposeId::id_kp_OCSPSigning
389
+ #end
125
390
 
126
391
  ekuCritical = critical if critical
127
392
  eku.add_element(kur)
@@ -134,7 +399,8 @@ module Ccrypto
134
399
 
135
400
  #extKeyUsage = java.util.Vector.new
136
401
  cp.domain_key_usage.each do |dku, critical|
137
- kur = org.bouncycastle.asn1.DERObjectIdentifier.new(dku)
402
+ #kur = org.bouncycastle.asn1.DERObjectIdentifier.new(dku)
403
+ kur = org.bouncycastle.asn1.ASN1ObjectIdentifier.new(dku)
138
404
 
139
405
  ekuCritical = critical if critical
140
406
  eku.add_element(kur)
@@ -169,6 +435,14 @@ module Ccrypto
169
435
 
170
436
  certGen.addExtension(org.bouncycastle.asn1.x509.Extension::subjectAlternativeName, false, org.bouncycastle.asn1.x509.GeneralNames.new(altName.to_java(org.bouncycastle.asn1.x509.GeneralName)) )
171
437
 
438
+ cp.custom_extension.each do |k, v|
439
+ val = v[:value]
440
+ val = "" if is_empty?(val)
441
+ #ev = org.bouncycastle.asn1.x509.Extension.new(org.bouncycastle.asn1.DERObjectIdentifier.new(k), v[:critical], org.bouncycastle.asn1.DEROctetString.new(val.to_java.getBytes))
442
+ ev = org.bouncycastle.asn1.x509.Extension.new(org.bouncycastle.asn1.ASN1ObjectIdentifier.new(k), v[:critical], org.bouncycastle.asn1.DEROctetString.new(val.to_java.getBytes))
443
+ certGen.addExtension(ev)
444
+ end
445
+
172
446
  if not_empty?(cp.crl_dist_point)
173
447
  crls = []
174
448
  cp.crl_dist_point.each do |c|
@@ -200,24 +474,39 @@ module Ccrypto
200
474
  certGen.addExtension(org.bouncycastle.asn1.x509.Extension::subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo.getInstance(cp.public_key.to_bin)))
201
475
 
202
476
  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
477
+
478
+ # alreacy check if digest algo exist or not at the entry of the method
479
+ foundDigest = DigestEngine.find_digest_config(signHash)
480
+ if foundDigest.length == 1
481
+ selDigest = foundDigest.first
220
482
  else
483
+ p foundDigest
484
+ ## prompt user for digest
485
+ if block
486
+ selDigest = block.call(:multiple_digest_algo_found, foundDigest)
487
+ else
488
+ raise X509EngineException, "Multiple digest algo found but not given a block. Not able to proceed."
489
+ end
490
+ end
491
+ signHashVal = selDigest.provider_config[:algo_name].gsub("-","")
492
+
493
+ #signHashVal = DigestEngine.find_digest_config(signHash).provider_config[:algo_name].gsub("-","")
494
+
495
+ gKey = issuerKey
496
+ loop do
497
+ case gKey
498
+ when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey
499
+ signAlgo = "#{signHashVal}WithECDSA"
500
+ break
501
+ when java.security.interfaces.RSAPrivateKey , org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPrivateCrtKey
502
+ signAlgo = "#{signHashVal}WithRSA"
503
+ break
504
+ when Ccrypto::PrivateKey
505
+ logger.debug "Found Ccrypto::Private key #{gKey}."
506
+ gKey = gKey.native_privKey
507
+ else
508
+ raise X509EngineException, "Unsupported issuer key type '#{gKey}'"
509
+ end
221
510
  end
222
511
 
223
512
  #signAlgo = "SHA256WithECDSA"
@@ -231,23 +520,21 @@ module Ccrypto
231
520
 
232
521
  end
233
522
 
234
- def to_cert_subject
523
+ def to_cert_subject(cp)
235
524
 
236
525
  builder = org.bouncycastle.asn1.x500.X500NameBuilder.new
237
- builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::CN, @certProfile.owner_name)
526
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::CN, cp.owner_name)
238
527
 
239
- builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::O, @certProfile.org) if not_empty?(@certProfile.org)
528
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::O, cp.org) if not_empty?(cp.org)
240
529
 
241
- @certProfile.org_unit.each do |ou|
242
- builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::OU, ou)
530
+ cp.org_unit.each do |ou|
531
+ builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::OU, ou) if not_empty?(ou)
243
532
  end
244
533
 
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
534
+ #e = cp.email.first
535
+ #if not_empty?(e)
536
+ # builder.addRDN(org.bouncycastle.asn1.x500.style::BCStyle::EmailAddress, e)
537
+ #end
251
538
 
252
539
  builder.build
253
540
 
@@ -305,6 +592,13 @@ module Ccrypto
305
592
  kur
306
593
  end
307
594
 
595
+ def self.logger(&block)
596
+ Ccrypto::Java.logger(:x509_eng, &block)
597
+ end
598
+ def logger(&block)
599
+ self.class.logger(&block)
600
+ end
601
+
308
602
  end
309
603
 
310
604
  end