ccrypto-java 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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