pax_global_header00006660000000000000000000000064131366162160014517gustar00rootroot0000000000000052 comment=db0823f0d8dd94cea85cabaa9acd970ccd4407bc jruby-openssl-0.9.21/000077500000000000000000000000001313661621600144245ustar00rootroot00000000000000jruby-openssl-0.9.21/.classpath000066400000000000000000000017351313661621600164150ustar00rootroot00000000000000 jruby-openssl-0.9.21/.gitignore000066400000000000000000000001041313661621600164070ustar00rootroot00000000000000*.gemspec.xml pkg *.jar target build.log .idea *.iml *.lock lib/org jruby-openssl-0.9.21/.settings/000077500000000000000000000000001313661621600163425ustar00rootroot00000000000000jruby-openssl-0.9.21/.settings/org.eclipse.core.resources.prefs000066400000000000000000000001251313661621600245530ustar00rootroot00000000000000eclipse.preferences.version=1 encoding//src/main/java=utf-8 encoding/=utf-8 jruby-openssl-0.9.21/.settings/org.eclipse.jdt.core.prefs000066400000000000000000000003561313661621600233300ustar00rootroot00000000000000eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.6 jruby-openssl-0.9.21/.settings/org.eclipse.m2e.core.prefs000066400000000000000000000001261313661621600232250ustar00rootroot00000000000000activeProfiles= eclipse.preferences.version=1 resolveWorkspaceProjects=true version=1 jruby-openssl-0.9.21/.travis.yml000066400000000000000000000061061313661621600165400ustar00rootroot00000000000000language: ruby sudo: false jdk: - oraclejdk7 - oraclejdk8 env: - TEST_PROFILE=test-1.6.8 - TEST_PROFILE=test-1.7.4 - TEST_PROFILE=test-1.7.13 - TEST_PROFILE=test-1.7.18 - TEST_PROFILE=test-1.7.26 - TEST_PROFILE=test-9.0.5.0 - TEST_PROFILE=test-9.1.8.0 - TEST_PROFILE=test-9.1.12.0 install: if [[ -v BUNDLE_INSTALL ]]; then jruby -S bundle install; else echo ""; fi script: if [[ -v TEST_COMMAND ]]; then $TEST_COMMAND; else mvn verify -P $TEST_PROFILE; fi matrix: allow_failures: #- env: TEST_PROFILE=test-1.7.22 # seems as an embed loading bug (same with 1.7.23) - env: TEST_COMMAND="jruby -S rake integration:install integration:test" rvm: jruby-1.7.24 - env: TEST_COMMAND="jruby -S rake integration:install integration:test" rvm: jruby-1.7.18 include: - jdk: oraclejdk7 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn test-compile && jruby -S rake test" BUNDLE_INSTALL=true rvm: jruby-1.7.24 - jdk: oraclejdk7 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn test-compile && jruby -S rake test" BUNDLE_INSTALL=true rvm: jruby-1.7.25 - jdk: oraclejdk7 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn test-compile && jruby -S rake test" BUNDLE_INSTALL=true rvm: jruby-1.7.26 # - jdk: openjdk6 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn verify -P test-1.6.8" BUNDLE_INSTALL=true RUBY_MAVEN_VERSION=3.3.8 rvm: jruby-1.7.22 - jdk: openjdk6 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn verify -P test-1.7.4" BUNDLE_INSTALL=true RUBY_MAVEN_VERSION=3.3.8 rvm: jruby-1.7.22 - jdk: openjdk6 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn verify -P test-1.7.13" BUNDLE_INSTALL=true RUBY_MAVEN_VERSION=3.3.8 rvm: jruby-1.7.22 - jdk: openjdk6 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn verify -P test-1.7.18" BUNDLE_INSTALL=true RUBY_MAVEN_VERSION=3.3.8 rvm: jruby-1.7.22 - jdk: openjdk6 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn verify -P test-1.7.24" BUNDLE_INSTALL=true RUBY_MAVEN_VERSION=3.3.8 rvm: jruby-1.7.22 - jdk: openjdk6 env: TEST_COMMAND="jruby -rbundler/setup -S rmvn verify -P test-1.7.26" BUNDLE_INSTALL=true RUBY_MAVEN_VERSION=3.3.8 rvm: jruby-1.7.22 # - jdk: oraclejdk8 env: TEST_COMMAND="jruby -S rake integration:install integration:test" rvm: jruby-1.7.26 - jdk: oraclejdk7 env: TEST_COMMAND="jruby -S rake integration:install integration:test" rvm: jruby-1.7.18 - jdk: oraclejdk8 env: TEST_COMMAND="jruby -S rake integration:install integration:test" rvm: jruby-9.0.5.0 - jdk: oraclejdk7 env: TEST_COMMAND="jruby -S rake integration:install integration:test" rvm: jruby-9.1.2.0 - jdk: oraclejdk8 env: TEST_COMMAND="jruby -S rake integration:install integration:test" rvm: jruby-9.1.5.0 notifications: irc: channels: - "irc.freenode.org#jruby" on_success: change on_failure: always template: - "%{repository} (%{branch}:%{commit} by %{author}): %{message} (%{build_url})" skip_join: true jruby-openssl-0.9.21/BUILDING.md000066400000000000000000000046551313661621600161550ustar00rootroot00000000000000## JRuby-OpenSSL The project is using [Maven](http://maven.apache.org/download.cgi) for build. Maven enhanced with JRuby using [Polyglot](https://github.com/takari/polyglot-maven), allows the build to be written using a Ruby DSL - check [*Mavenfile*](Mavenfile). If you're coming from a Ruby world and do not have Maven setup, you can alternatively `jruby -S gem install ruby-maven` and use the `rmvn` executable (instead of `mvn`). ### Building The usual `mvn package` builds a .gem that includes the JRuby extension .jar ### Testing Tests `mvn test` are run by default with Maven using JRuby plugins. When the ext .jar is build (`rake jar` or `mvn package -Dmaven.test.skip=true`) one can run a tests Ruby-style e.g. `jruby -Ilib:. src/test/ruby/test_bn.rb` ### Releasing * fill in [History.md](History.md) change-log entries for release * update `VERSION` at [lib/jopenssl/version.rb](lib/jopenssl/version.rb), make sure [pom.xml](pom.xml) is regenerated e.g. using `rmvn validate` and `git commit` the changes * (optional) signing artifacts is preferred thus find your GPG key * `mvn -Prelease -DupdateReleaseInfo=true -Dgpg.keyname=A7A374B9 clean deploy` * (advised) examine and close the repository to push it to Sonatype's staging * (advised) run JRuby's full suite using the staged new jruby-openssl gem e.g. https://github.com/jruby/jruby/commit/1df6315e9145195f19ad862be5e3a5 * (advised) release the staging repository at Sonatype's if all is well * (optional) update JRuby to bundle new jruby-openssl gem (remove staging) e.g. https://github.com/jruby/jruby/commit/8750e736491825eec1d1954a07d492 * gem push the build gem from pkg/ e.g. `gem push pkg/jruby-openssl-0.9.15.gem` * tag the release e.g. `git tag v0.9.15` * update `VERSION` to next SNAPSHOT (e.g. `"0.9.16.dev"`) and commit make sure [pom.xml](pom.xml) is regenerated (`rmvn validate`) * `git push origin master --tags` * (advised) ... take the rest of the day off! #### Manually Deploying When a release went by only pushing to http://rubygems.org/ one can still push to Sonatype's Maven repos, rename *jruby-openssl-x.x.x-java.gem* (when it is downloaded from https://rubygems.org/gems/jruby-openssl) to follow Maven's naming conventions (stripping the *-java* suffix) and "mvn deploy" by hand : ``` mvn deploy:deploy-file -Dfile=jruby-openssl-0.9.15.gem -DpomFile=pom.xml -DrepositoryId=ossrh -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ ```jruby-openssl-0.9.21/Gemfile000066400000000000000000000004061313661621600157170ustar00rootroot00000000000000source 'https://rubygems.org' # Specify your gem's dependencies in the gemspec gemspec # for less surprises with newer releases gem 'jar-dependencies', '~> 0.3.11', :require => nil # for the rake task gem 'ruby-maven', ENV['RUBY_MAVEN_VERSION'] || '~> 3.3.8' jruby-openssl-0.9.21/History.md000066400000000000000000000560161313661621600164170ustar00rootroot00000000000000## 0.9.21 * adjust X.509 value handling to parse subjectAltName recursively (#134) * SKI expected to be always octet wrapped - do not check for length (#131) * respect jruby.preferred.prng and use/tune its SecureRandom defaults trying to avoid BC generator's constant attempts for seeding itself as an attempt to 'fix' low-entropy systems wating for */dev/random* * Random#add; Random#egd shall return true on JVM * move "DEFAULT" special case handling to match OpenSSL behaviour (#136) (jruby/jruby#2193) * If data is not provided, extract it from the PKCS7 instance (#132) * Add cipher suite strings for IBM JRE (#126) - thanks @ysohda * use the helper to printStackTrace (no System.err printing by default) * add OCSP support (#124) - thanks so very much @lampad * add support for renegotiation_cb on SSLContext (#121) - thanks @lampad ## 0.9.20 * upgrade Bouncy-Castle to 1.56 http://bouncycastle.org/releasenotes.html (additional security and robustness with 10 CVEs submitted as a result) * add a dummy SSLContext#security_level= implementation * no dup-ing for SSLContext/SSLSocket and X509 Store/StoreContext * implement PKey initialize_copy (dup-ing) * digest can be passed in as a String on PKey#sign/verify * DSA+SHA1 is actually a supported algorithm * reset signed-request -> sub-sequent req.verify will work correctly * allow for digest name to be passed into Cert#sign * be less fatal on Java 9 won't attempt reflective SPIs when accessibility checks fail! * remove obsolete (deprecated) renamed classes * verify correct WaitReadable is raised on connect_nonblock (jruby/jruby#1716) * non-connected ssl socket raises EPIPE on connect_nonblock (MRI compat) * fine to close a SSLSocket which is not-yet-connected (like in MRI) * fix NPE when reading private keys (with passwd) (jruby/jruby#1784) ## 0.9.19 * re-use secure random from thread-context on SSL context initialization * preliminary OpenSSL 1.1 (Ruby 2.4) compatibility bits (#112) * try using thread-shared secure random gen (in PKey-s) where possible * implement PKeyDSA#syssign and PKeyDSA#sysverify methods * avoid (unnecessary) byte[] copies in PKey#sign/verify * fix ClassCastException error in X509Store.verify (#113) * align BH#hash with eql? (+ equals/hashCode on Java) ## 0.9.18 * handle X.509 authorityKeyIdentifier parsing somehow right (#102) * simple resolution for handling subjectAltName multiple DNS: names (#102) * upgrading BC to 1.55 normalize "brainpoolP512t1" curve name for BC 1.55 compatibility * allow for X509::Certificate to be converted to a Java certificate * at least OpenSSL.debug potential env read failure on set_default_paths * negative BN values are always considered not prime. * Don't print a warning for missing client certs (#110) ## 0.9.17 * temporarily register BC provider on X.509 factory (work-around for #94) * support Cipher#auth_tag and auth_data for GCM ciphers (e.g. aes-128-gcm) * need to drop support for BC <= 1.50 due EC support (N/A in older BCs) * (somehow working) draft at implementing PKey::EC (elliptic curve support) DH encryption expected to behave correctly * make sure (initial) BC security provider registration works! ... when **-Djruby.openssl.provider.register=true** (due #94) * Make ALL cipherstring match ECDHE cihphers (#91) * fix X.509 indexBySubject returning correct index * try to handle `SSLContext.session=` and also try answering `session_reused?` * handle equals/hashCode on SSL::Session and raise on timeout int overflow * Allow DSA private keys to be initialized from parameters. (#83) * Instantiate both the private and public keys when setting parameters. (#82) ## 0.9.16 * add hard dependency to jar-dependencies (#74) * Recognize Android java.version (#81) ## 0.9.15 * always return a Fixnum from `OpenSSL::SSL::Session#timeout`, OpenSSL defaults to 300 (been causing net/http.rb issues with timeouts on JRuby 9K) ## 0.9.14 * upgrade to using BC **1.54** as default (all versions >= 1.49 are supported) for Bouncy-Castle release notes see http://bouncycastle.org/releasenotes.html * basic support for prompting for PEM password (working for RSA/DSA priv.key) * avoid NPE due version field in X509Cert - make sure it's treated as 0 (#78) and fix settting ceritificate.serial = number * default WairReadable/Writable backtraces to JRuby's -Xerrno.backtrace * use hardcoded jks type for loading cacerts - for Java 9 compatibility (#79) ## 0.9.13 JRuby-OpenSSL is the first release that aims to be Ruby **2.3** compatible. * SSLSocket#sysread do not copy bytes from buffer - re-use the backing array * handle read_nonblock EOF as nil when exception: false (Ruby 2.3 compatibility) * start exposing VERSION constant(s) directly on Jopenssl module * better not throw EOF on SSLSocket#sysclose for compatibility with MRI * setup "dummy" OpenSSL::OPENSSL_LIBRARY_VERSION constant for compatibility * Ruby 2.3 compatibility - adjust to changes in MRI's openssl .rb parts * update openssl/ssl.rb based on MRI 2.2's version * disable backtrace generation for wait non-block errors (use an empty array) * support SSLSocket#accept_nonblock/connect_nonblock with exception: false * support `exception: false` with syswrite_nonblock and sysread_nonblock * remove 'RSA' from RSA public key headers (#76) ## 0.9.12 * when the Cipher/Signature needs to be created via java reflection use a constructor which avoids verifying the bouncy-castle jars (which is the main reason for using reflection since some classloader setups fails to verify those jars) (#73) * force US locale for date formatting otherwise it uses system locale, which is inconsistent with MRI. * X509::Store.set_default_paths ignores FileNotFound errors like MRI does (#68) * check type on X509::Store.verify throw a TypeError if the argument is not a OpenSSL::X509::Certificate (#69) * keep the default x509 certs and directories in line with MRI, only if they do not exists fallback on cacerts from the java.home/lib/security/cacerts * bring the default ca-certs paths/location more in line with MRI and fallback on jvm truststore (java.home/lib/security/cacerts) when needed ## 0.9.11 * add TLSv1_1_client, TLSv1_1_server, TLSv1_2_client and TLSv1_2_server options to ssl_version (#65) * **regression** make sure we hold a buffered reader so that the loop continues reading PEMs - previously introduced an incompatibility with cert verify (#67) * support negotiating up to TLS1_1 and TLS1_2 when the server supports these ssl_versions (#63) ## 0.9.10 * **regression** reverted fix for #49 (as it needs more work/testing) : keep the default x509 certs and directories in line with MRI (#49), only if they do not exists fallback on cacerts from the java.home/lib/security/cacerts ## 0.9.9 * **regression** causing to re-package a RaiseException in `SSLSocket#accept` * fix load error: jopenssl/load -- java.lang.VerifyError: using BC 1.51 or 1.52 (#62) * keep the default x509 certs and directories in line with MRI (#49), only if they do not exists fallback on cacerts from the java.home/lib/security/cacerts ## 0.9.8 * refactor `PKCS5.pbkdf2_hmac_sha1` to use BC APIs thus less dependent on provider internals (jruby/jruby#3025) * HMAC - use our SimpleKey impl so that there's less[] copy ... also allows for an empty key to work like MRI (jruby/jruby#2854) * fixing oaep encryption to use correct algorithm (#54) * [experimental] support NOT loading any (BC) jars on our own ... (#10) * disable DHE (by default) on Java <= 7 ... on Java 8 we (still) force 1024/2048 (see jruby/jruby#2872 and #45) * **regression** handle parsing of "incomplete" X.509 certs like MRI does (#42) * implement a CRL/certificate caching (for now off by default) in Lookup ... set *-J-Djruby.openssl.x509.lookup.cache=true* to enable * improve Store helper concurrency (with less synchronization) * reviewed OpenSSL's .rb parts to match those present in MRI 1.9.3 / 2.2.2 * initial support for `OpenSSL::SSL::Session` (id, time, timeout work) * session_cache_mode as present in OpenSSL makes no sense with Java APIs * use the set SSLContext#session_cache_size on the underlying javax.net API * tidy up SSLSocket's internals + add stack-trace debugging on accept/connect * add SSLSocket ssl_version property like MRI has (#38) * avoid unnecessary `_initialize` naming - it's confusing to see in JVM tools * use SecurityHelper to get a X.509 certificate factory we'll know prefer BC's X.509 factory over the built-in (Sun provider) one ## 0.9.7 * put in some more ossl to jsse mappings for SSL/TLS (SSL_DHE_xxx, TLS_ECDH_xxx, TLS_ECDHE_xxx) * exclude SSLv2 in reported METHODS (all fine to close jruby/jruby#1874) * support passing ssl_version as an argument to initialize SSLContext.new ... * now that we've matched w MRI's SSLContext::METHODS don't report custom ones * more ssl_version= compatibility fixes that match MRI (jruby/jruby#1736) * support setting ssl_version = "TLSv1_1" (or "TLSv1_2") just like MRI * **regression** make sure version is set when reading encoded certificate + signature algorithm should be read as well when decoding certificate (#39) * better accept handshake errors instead of "General SSLEngine problem (#37) * trying to decode DER application specific objects (based on patch from #36) * we've not been compatible with MRI's DES (EDE) - partly due DES(3) ECB fixing jruby/jruby#2617 as well as jruby/jruby#931 * exclude reporting algorithms with CFB-1 cipher mode as supported (due #35) * do not change CFB1 to CFB ... it's something different (although broken on BC) * attempt to deal with update/final buffering incompatibility with MRI * fix HMAC digest incorrect when data contains invalid characters (#33) * add Gemfile and specify ruby-maven as dependency * use SafePropertyAccessor to access properties instead of directly (#28) * make sure SSLSocket's cipher and hostname are nil by default (avoids NPE) * update to (packed) BC version 1.50 + start declaring 1.51 as semi-supported ## 0.9.6 * ClassCastException still happen deep within BC - turn them into SignatureExeption * make sure empty object can be serialize via to_pem * use the classname as message in case the exception has no message (jruby/jruby#2249) * make sure X509Object list is synchronized properly * use JRubyFile to get input-stream to file-resource fixes #11 * Cache the discovered classes for digest engines. Fixes #15. * avoid the rest of Ruby.getGlobalRuntime usages - only worked in 1 runtime envs * refactored CRL - using light-weight BC API (avoids deprecated X.509 generator) * implement X509::Certificate#to_text for happiness (the MRI-way - only RSA for now) * allow to "fake" our inspect() support and match MRI's X509::Certificate#inspect * decode BC's ASN1Enumarated into a OpenSSL::ASN1::Enumerated * we can (ASN.1) encode an infinite-length bit-string constructive * turns out all ASN1 primitives in MRI have the infinite_length attribute * support (so-far only dummy) @servername_cb attribute on SSLSocket * handle (CRL) extension's issuerAltName wrapping without an exception * fix SSL (cert) verification - now working on 1.8/1.9 better than before * do not skip first 2 bytes of key identifier hash when encoding to hex! * match X.509 extension short-comings of the Java API in order to align with MRI * improve cert.extension's value - *extendedKeyUsage* was not returned correctly * make sure ASN1::ObjectId.new(...).ln and ASN1::ObjectId.new(...).sn are correct! * better working to_der conversion esp. with constructives (indefinite lengths) * improve our ASN1 decoding for better MRI compatibility * avoiding Krypt gem dependency completely (was used for OpenSSL::PKCS5) * cleanup OpenSSL::Digest internals - make sure block_length works for more * OpenSSL deprecated_warning_flag and check_func API compatibility stubs * do not force loading of jar-dependencies + possibly respect jars skipped * X509::Name.to_a compatibility - MRI seems to never return "UNDEF" experimental support for passing down "real" Java JCE cipher names * rewriten Cipher internals - now faster, slimmer and more compatible than ever! * rebuilt our global ASN1Registry and refactored it (back) internally to use string oids * report OpenSSL::VERSION **1.1.0** since 1.9.3 * fill RaiseException's cause whenever we use a factory passing down a Throwable * allow X509::Revoked.serial= to receive an integer * make sure X509::CRL's to_text representation si (fully) MRI compatible * handle authority key-id unwrapping correctly in X509::Extension#value * long time coming - OpenSSL::X509::CRL support for loading revoked entries (#5) * Reflect Java cacert location in DEFAULT_CERT_* constants (jruby/jruby#1953) * X509::Certificate.new MRI compatibility + make sure inspect works the same * BN.inspect() and make sure BN.new(0) works just fine (both as in MRI) * X509::CRL instantiation compatibility with MRI * inspect() X509::Certificate an X509::CRL just like MRI does * handle OpenSSL::X509::Store.add error messages correctly (fix based on #6) * update to using BC 1.49 by default (still compatible with older versions) * implement X509::StoreContext#current_crl method * support X509::StoreContext cleanup and error_depth instance methods * support disabling of warnings using system property -Djruby.openssl.warn * Throw error when chain certs are *not* OpenSSL::X509::Certificate (#3) * avoid using JRuby IO APIs (will likely not work in 9k) * make 'jopenssl/load' also work on jruby-1.6.8 mode 1.9 ## 0.9.5 MASSIVE internal "rewrite" to avoid depending on a registered (BC) security provider. This releases restores compatibility with BC version 1.47 while being compatible with newer bouncy-castle jars as well (1.48, 1.49 and 1.50). * handle SSLErrorWaitReadable/Writable as SSLErrors on Ruby 1.8 and 1.9 mode * Treat SSL NOT_HANDSHAKING as FINISHED * only add DER.TRUE when encoding X.509 extension when non-critical * do not der encode non-critical flag in X509::Extension (jruby/jruby#389) * SSLContext internals + support `SSLContext::METHODS` correctly (jruby/jruby#1596) * correct visibility of initialize* and respond_to_missing? methods * fix spinning indefinitely on partial TLS record (jruby/jruby#1280) * Support file input for PKey::RSA.new * fix bug https://github.com/jruby/jruby/issues/1156 * openssl: add handling for base 0 to new and to_s ## 0.9.4 * Fix compatibility wiht Bouncy Castle 1.49. ## 0.9.3 * Allow options passed to nonblock methods (not impl'ed yet) * Make ClassIndex into an enum, to prevent issues like jruby/jruby#1004 == ... ## 0.7.7 This release includes bug fixes. * JRUBY-6622: Support loading encrypted RSA key with PBES2 * JRUBY-4326: Confusing (and late) OpenSSL error message * JRUBY-6579: Avoid ClassCastException for public key loading * JRUBY-6515: sending UTF-8 data over SSL can hang with openssl * Update tests to sync with CRuby ruby_1_9_3 ## 0.7.6 This release includes initial implementation of PKCS12 by Owen Ou. * JRUBY-5066: Implement OpenSSL::PKCS12 (only for simple case) * JRUBY-6385: Assertion failure with -J-ea ## 0.7.5 This release improved 1.9 mode support with help of Duncan Mak . Now jruby-ossl gem includes both 1.8 and 1.9 libraries and part of features should work fine on 1.9 mode, too. * JRUBY-6270: Wrong keyUsage check for SSL server * JRUBY-6260: OpenSSL::ASN1::Integer#value incompatibility * JRUBY-6044: Improve Ecrypted RSA/DSA pem support * JRUBY-5972: Allow to load/dump empty PKCS7 data * JRUBY-5834: Fix X509Name handling; X509Name RDN can include multiple elements * JRUBY-5362: Improved 1.9 support * JRUBY-4992: Warn if loaded by non JRuby interpreter ## 0.7.4 * JRUBY-5519: Avoid String encoding dependency in DER loading. PEM loading failed on JRuby 1.6.x. Fixed. * JRUBY-5510: Add debug information to released jar * JRUBY-5478: Update bouncycastle jars to the latest version. (1.46) ## 0.7.3 * JRUBY-5200: Net::IMAP + SSL(imaps) login could hang. Fixed. * JRUBY-5253: Allow to load the certificate file which includes private key for activemarchant compatibility. * JRUBY-5267: Added SSL socket error-checks to avoid busy loop under an unknown condition. * JRUBY-5316: Improvements for J9's IBMJCE support. Now all testcases pass on J9 JDK 6. ## 0.7.2 * JRUBY-5126: Ignore Cipher#reset and Cipher#iv= when it's a stream cipher (Net::SSH compatibility) * JRUBY-5125: let Cipher#name for 'rc4' to be 'RC4' (Net::SSH compatibility) * JRUBY-5096: Fixed inconsistent Certificate verification behavior * JRUBY-5060: Avoid NPE from to_pem for empty X509 Objects * JRUBY-5059: SSLSocket ignores Timeout (Fixed) * JRUBY-4965: implemented OpenSSL::Config * JRUBY-5023: make Certificate#signature_algorithm return correct algo name; "sha1WithRSAEncryption" instead of "SHA1" * JRUBY-5024: let HMAC.new accept a String as a digest name * JRUBY-5018: SSLSocket holds selectors, keys, preventing quick cleanup of resources when dereferenced ## 0.7.1 NOTE: Now BouncyCastle jars has moved out to its own gem "bouncy-castle-java" http://rubygems.org/gems/bouncy-castle-java. You don't need to care about it because "jruby-openssl" gem depends on it from now on. * JRUBY-4826 net/https client possibly raises "rbuf_fill': End of file reached (EOFError)" for HTTP chunked read. * JRUBY-4900: Set proper String to OpenSSL::OPENSSL_VERSION. Make sure it's not an OpenSSL artifact: "OpenSSL 0.9.8b 04 May 2006 (JRuby-OpenSSL fake)" -> "jruby-ossl 0.7.1" * JRUBY-4975: Moving BouncyCastle jars out to its own gem. ## 0.7 * Follow MRI 1.8.7 openssl API changes * Fixes so that jruby-openssl can run on appengine * Many bug and compatibility fixes, see below. * This is the last release that will be compatible with JRuby 1.4.x. * Compatibility issues - JRUBY-4342: Follow ruby-openssl of CRuby 1.8.7. - JRUBY-4346: Sync tests with tests for ruby-openssl of CRuby 1.8.7. - JRUBY-4444: OpenSSL crash running RubyGems tests - JRUBY-4075: Net::SSH gives OpenSSL::Cipher::CipherError "No message available" - JRUBY-4076: Net::SSH padding error using 3des-cbc on Solaris - JRUBY-4541: jruby-openssl doesn't load on App Engine. - JRUBY-4077: Net::SSH "all authorization methods failed" Solaris -> Solaris - JRUBY-4535: Issues with the BouncyCastle provider - JRUBY-4510: JRuby-OpenSSL crashes when JCE fails a initialise bcprov - JRUBY-4343: Update BouncyCastle jar to upstream version; jdk14-139 -> jdk15-144 Cipher issues - JRUBY-4012: Initialization vector length handled differently than in MRI (longer IV sequence are trimmed to fit the required) - JRUBY-4473: Implemented DSA key generation - JRUBY-4472: Cipher does not support RC4 and CAST - JRUBY-4577: InvalidParameterException 'Wrong keysize: must be equal to 112 or 168' for DES3 + SunJCE SSL and X.509(PKIX) issues - JRUBY-4384: TCP socket connection causes busy loop of SSL server - JRUBY-4370: Implement SSLContext#ciphers - JRUBY-4688: SSLContext#ciphers does not accept 'DEFAULT' - JRUBY-4357: SSLContext#{setup,ssl_version=} are not implemented - JRUBY-4397: SSLContext#extra_chain_cert and SSLContext#client_ca - JRUBY-4684: SSLContext#verify_depth is ignored - JRUBY-4398: SSLContext#options does not affect to SSL sessions - JRUBY-4360: Implement SSLSocket#verify_result and dependents - JRUBY-3829: SSLSocket#read should clear given buffer before concatenating (ByteBuffer.java:328:in `allocate': java.lang.IllegalArgumentException when returning SOAP queries over a certain size) - JRUBY-4686: SSLSocket can drop last chunk of data just before inbound channel close - JRUBY-4369: X509Store#verify_callback is not called - JRUBY-4409: OpenSSL::X509::Store#add_file corrupts when it includes certificates which have the same subject (problem with ruby-openid-apps-discovery (github jruby-openssl issue #2)) - JRUBY-4333: PKCS#8 formatted privkey read - JRUBY-4454: Loading Key file as a Certificate causes NPE - JRUBY-4455: calling X509::Certificate#sign for the Certificate initialized from PEM causes IllegalStateException PKCS#7 issues - JRUBY-4379: PKCS7#sign failed for DES3 cipher algorithm - JRUBY-4428: Allow to use DES-EDE3-CBC in PKCS#7 w/o the Policy Files (rake test doesn't finish on JDK5 w/o policy files update) Misc - JRUBY-4574: jruby-openssl deprecation warning cleanup - JRUBY-4591: jruby-1.4 support ## 0.6 * This is a recommended upgrade to jruby-openssl. A security problem involving peer certificate verification was found where failed verification silently did nothing, making affected applications vulnerable to attackers. Attackers could lead a client application to believe that a secure connection to a rogue SSL server is legitimate. Attackers could also penetrate client-validated SSL server applications with a dummy certificate. Your application would be vulnerable if you're using the 'net/https' library with OpenSSL::SSL::VERIFY_PEER mode and any version of jruby-openssl prior to 0.6. Thanks to NaHi (NAKAMURA Hiroshi) for finding the problem and providing the fix. See http://www.jruby.org/2009/12/07/vulnerability-in-jruby-openssl.html for details. * This release addresses CVE-2009-4123 which was reserved for the above vulnerability. * Many fixes from NaHi, including issues related to certificate verification and certificate store purpose verification. - implement OpenSSL::X509::Store#set_default_paths - MRI compat. fix: OpenSSL::X509::Store#add_file - Fix nsCertType handling. - Fix Cipher#key_len for DES-EDE3: 16 should be 24. - Modified test expectations around Cipher#final. * Public keys are lazily instantiated when the X509::Certificate#public_key method is called (Dave Garcia) ## 0.5.2 Multiple bugs fixed: * JRUBY-3895 Could not verify server signature with net-ssh against Cygwin * JRUBY-3864 jruby-openssl depends on Base64Coder from JvYAMLb * JRUBY-3790 JRuby-OpenSSL test_post_connection_check is not passing * JRUBY-3767 OpenSSL ssl implementation doesn't support client auth * JRUBY-3673 jRuby-OpenSSL does not properly load certificate authority file ## 0.5.1 * Multiple fixes by Brice Figureau to get net/ssh working. Requires JRuby 1.3.1 to be 100% * Fix by Frederic Jean for a character-decoding issue for some certificates ## 0.5 * Fixed JRUBY-3614: Unsupported HMAC algorithm (HMACSHA-256) * Fixed JRUBY-3570: ActiveMerchant's AuthorizeNet Gateway throws OpenSSL Cert Validation Error, when there should be no error * Fixed JRUBY-3557 Class cast exception in PKeyRSA.java * Fixed JRUBY-3468 X.509 certificates: subjectKeyIdentifier corrupted * Fixed JRUBY-3285 Unsupported HMAC algorithm (HMACSHA1) error when generating digest * Misc code cleanup ## 0.2 * Enable remaining tests; fix a nil string issue in SSLSocket.sysread (JRUBY-1888) * Fix socket buffering issue by setting socket IO sync = true * Fix bad file descriptor issue caused by unnecessary close (JRUBY-2152) * Fix AES key length (JRUBY-2187) * Fix cipher initialization (JRUBY-1100) * Now, only compatible with JRuby 1.1 ## 0.1.1 * Fixed blocker issue preventing HTTPS/SSL from working (JRUBY-1222) ## 0.1 * PLEASE NOTE: This release is not compatible with JRuby releases earlier than 1.0.3 or 1.1b2. If you must use JRuby 1.0.2 or earlier, please install the 0.6 release. * Release coincides with JRuby 1.0.3 and JRuby 1.1b2 releases * Simultaneous support for JRuby trunk and 1.0 branch * Start of support for OpenSSL::BN ## 0.0.5 and prior * Initial versions with maintenance updates jruby-openssl-0.9.21/LICENSE.txt000066400000000000000000000037661313661621600162630ustar00rootroot00000000000000JRuby-OpenSSL is distributed under the same license as JRuby a tri EPL/GPL/LGPL license. You can use it, redistribute it and/or modify it under the terms of the: Eclipse Public License version 1.0 GNU General Public License version 2.0 GNU Lesser General Public License version 2.1 The contents of this file are subject to the Common Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Copyright (C) 2007-2009 Ola Bini Copyright (C) 2009-2017 The JRuby Team Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the EPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the EPL, the GPL or the LGPL. JRuby-OpenSSL includes software by The Legion of the Bouncy Castle Inc. Please, visit (http://bouncycastle.org/license.html) for licensing details. jruby-openssl-0.9.21/Mavenfile000066400000000000000000000173721313661621600162670ustar00rootroot00000000000000#-*- mode: ruby -*- gemspec :jar => 'jopenssl', :include_jars => true sonatype_url = 'https://oss.sonatype.org/content/repositories/snapshots/' snapshot_repository :id => 'sonatype', :url => sonatype_url distribution_management do snapshot_repository :id => :ossrh, :url => 'https://oss.sonatype.org/content/repositories/snapshots' repository :id => :ossrh, :url => 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' end java_target = '1.6' gen_sources = '${basedir}/target/generated-sources' # hard-coded in AnnotationBinder plugin( 'org.codehaus.mojo:exec-maven-plugin', '1.3.2' ) do =begin invoker_main = '-Djruby.bytecode.version=${compiler.target}' #invoker_main << ' -classpath ' invoker_main << ' org.jruby.anno.InvokerGenerator' invoker_main << " #{gen_sources}/annotated_classes.txt ${project.build.outputDirectory}" dependency 'org.jruby', 'jruby-core', '${jruby.version}' execute_goal :java, :id => 'invoker-generator', :phase => 'process-classes', :mainClass => 'org.jruby.anno.InvokerGenerator', :classpathScope => 'compile', #:arguments => [ '${gen.sources}/annotated_classes.txt', '${project.build.outputDirectory}' ] do :commandlineArgs => "#{gen_sources}/annotated_classes.txt ${project.build.outputDirectory}", :classpathScope => 'runtime', :additionalClasspathElements => [ '${project.build.outputDirectory}' ], :includeProjectDependencies => false, :includePluginDependencies => true do #systemProperties do # property '-Djruby.bytecode.version=${compiler.target}' #end =end execute_goal :exec, :id => 'invoker-generator', :phase => 'process-classes', :executable => 'java', :classpathScope => 'compile', :arguments => [ "-Djruby.bytecode.version=#{java_target}", '-classpath', xml( '' ), 'org.jruby.anno.InvokerGenerator', "#{gen_sources}/annotated_classes.txt", '${project.build.outputDirectory}' ] end plugin( 'org.codehaus.mojo:build-helper-maven-plugin', '1.9' ) do execute_goal 'add-source', :phase => 'process-classes', :sources => [ gen_sources ] end plugin( :compiler, '3.1', :source => '1.6', :target => java_target, :encoding => 'UTF-8', :debug => true, :showWarnings => true, :showDeprecation => true, :generatedSourcesDirectory => gen_sources, :annotationProcessors => [ 'org.jruby.anno.AnnotationBinder' ], :compilerArgs => [ '-XDignore.symbol.file=true' ] ) do #execute_goal :compile, :id => 'annotation-binder', :phase => 'compile', # :generatedSourcesDirectory => gen_sources, #:outputDirectory => gen_sources, # :annotationProcessors => [ 'org.jruby.anno.AnnotationBinder' ], # :proc => 'only', # :compilerReuseStrategy => 'alwaysNew', # :useIncrementalCompilation => false, :fork => true, :verbose => true, # :compilerArgs => [ '-XDignore.symbol.file=true', '-J-Dfile.encoding=UTF-8' ] execute_goal :compile, :id => 'compile-populators', :phase => 'process-classes', :includes => [ 'org/jruby/gen/**/*.java' ], :optimize => true, :compilerArgs => [ '-XDignore.symbol.file=true' ] # NOTE: maybe '-J-Xbootclasspath/p:${unsafe.jar}' ... as well ?! end plugin :clean do execute_goals( 'clean', :id => 'default-clean', :phase => 'clean', 'filesets' => [ { :directory => 'lib', :includes => [ 'jopenssl.jar' ] }, { :directory => 'lib/org' }, { :directory => 'target', :includes => [ '*' ] } ], 'failOnError' => 'false' ) end # NOTE: unfortunately we can not use 1.6.8 to generate invokers ... # although we'd like to compile against 1.6 to make sure all is well jar 'org.jruby:jruby-core', '1.7.17', :scope => :provided # 1.6.8 jar 'junit:junit', '4.11', :scope => :test jruby_plugin! :gem do # when installing dependent gems we want to use the built in openssl # not the one from this lib directory # we compile against jruby-core-1.7.17 and want to keep this out of # the plugin execution here execute_goal :id => 'default-initialize', :addProjectClasspath => false, :libDirectory => 'something-which-does-not-exists' execute_goals :id => 'default-push', :skip => true end # we want to have the snapshots on oss.sonatype.org and the released gems # on maven central plugin :deploy, '2.8.1' do execute_goals( :deploy, :skip => false ) end supported_bc_versions = %w{ 1.51 1.52 1.53 1.54 } # due EC support dropped <= 1.50 default_bc_version = File.expand_path('lib/jopenssl/version.rb', File.dirname(__FILE__)) default_bc_version = default_bc_version[/BOUNCY_CASTLE_VERSION\s?=\s?'(.*?)'/, 1] properties( 'jruby.plugins.version' => '1.0.10', 'jruby.versions' => '1.7.18', 'bc.versions' => default_bc_version, 'invoker.test' => '${bc.versions}', # allow to skip all tests with -Dmaven.test.skip 'invoker.skip' => '${maven.test.skip}', 'runit.dir' => 'src/test/ruby/**/test_*.rb', # use this version of jruby for ALL the jruby-maven-plugins 'jruby.version' => '1.7.18', # dump pom.xml as readonly when running 'rmvn' 'polyglot.dump.pom' => 'pom.xml', 'polyglot.dump.readonly' => true, 'tesla.dump.pom' => 'pom.xml', 'tesla.dump.readonly' => true ) # make sure we have the embedded jars in place before we run runit plugin plugin! :dependency do execute_goal 'copy-dependencies', :phase => 'generate-test-resources', :outputDirectory => '${basedir}/lib', :useRepositoryLayout => true, :includeGroupIds => 'org.bouncycastle' end jruby_plugin(:runit) { execute_goal( :test, :runitDirectory => '${runit.dir}' ) } invoker_run_options = { :id => 'tests-with-different-bc-versions', :projectsDirectory => 'integration', :pomIncludes => [ '*/pom.xml' ], :streamLogs => true, # pass those properties on to the test project :properties => { 'jruby.versions' => '${jruby.versions}', 'jruby.modes' => '${jruby.modes}', 'jruby.openssl.version' => '${project.version}', 'bc.versions' => '${bc.versions}', 'runit.dir' => '${runit.dir}' } } profile :id => 'test-1.6.8' do plugin :invoker, '1.8' do execute_goals( :install, :run, invoker_run_options ) end properties 'jruby.versions' => '1.6.8', 'jruby.modes' => '1.8,1.9', 'bc.versions' => supported_bc_versions.join(',') end profile :id => 'test-1.7.4' do plugin :invoker, '1.8' do execute_goals( :install, :run, invoker_run_options ) end properties 'jruby.versions' => '1.7.4', 'jruby.modes' => '1.8,1.9', 'bc.versions' => supported_bc_versions.join(',') end jruby_1_7_versions = %w{ 1.7.13 1.7.15 1.7.16 1.7.18 1.7.20 1.7.22 1.7.23 } jruby_1_7_versions += %w{ 1.7.24 1.7.25 1.7.26 1.7.27 } jruby_1_7_versions.each { |version| profile :id => "test-#{version}" do plugin :invoker, '1.8' do execute_goals( :install, :run, invoker_run_options ) end properties 'jruby.versions' => version, 'jruby.modes' => '1.8,1.9,2.0', 'bc.versions' => supported_bc_versions.join(',') end } jruby_9_K_versions = %w{ 9.0.1.0 9.0.5.0 9.1.2.0 9.1.5.0 9.1.8.0 9.1.12.0 } jruby_9_K_versions.each { |version| profile :id => "test-#{version}" do plugin :invoker, '1.8' do execute_goals( :install, :run, invoker_run_options ) end # NOTE: we're work-around 9K maven-runit version bug (due minitest changes) ! # ... still can not build with 9K : https://github.com/jruby/jruby/issues/3184 properties 'jruby.version' => version, 'jruby.versions' => version, 'bc.versions' => supported_bc_versions.join(',') end } profile :id => 'release' do plugin :gpg, '1.5' do execute_goal :sign, :phase => :verify end end # vim: syntax=Ruby jruby-openssl-0.9.21/README.md000066400000000000000000000053411313661621600157060ustar00rootroot00000000000000# JRuby-OpenSSL [JRuby-OpenSSL](https://github.com/jruby/jruby-openssl) is an add-on gem for [JRuby](http://jruby.org) that emulates the Ruby OpenSSL native library. Under the hood uses the [Bouncy Castle Crypto APIs](http://www.bouncycastle.org/). Each jruby-openssl gem release includes a certain version, usually the latest available, of the library (namely BC Provider and PKIX/CMS/EAC/PKCS/OCSP/TSP/OPENSSL jars). Please report bugs and incompatibilities (preferably with test-cases) to either the JRuby [mailing list][1] or the [bug tracker][2]. ## Compatibility | JRuby-OpenSSL | JRuby compat | JVM compat | supported BC | | ------------- |:-------------:| ----------:| ------------:| | 0.9.6 | 1.6.8-9.0.2 | Java 6-8 | 1.47-1.50 | | 0.9.12 | 1.6.8-9.0.5 | Java 6-8 | 1.47-1.52 | | 0.9.13 | 1.6.8-9.1.2 | Java 6-8 | 1.49-1.52 | | 0.9.14 | 1.6.8-9.1.5 | Java 6-8 | 1.49-1.54 | | 0.9.17 | 1.6.8-9.1.5 | Java 6-8 | 1.50-1.54 | | 0.9.18 | 1.6.8-9.1.7 | Java 6-8 | 1.50-1.55 | NOTE: backwards JRuby compatibility was not handled for versions <= **0.9.6** ## Security JRuby-OpenSSL is an essential part of [JRuby](http://jruby.org), please report security vulnerabilities to `security@jruby.org` as detailed on JRuby's [security page](http://jruby.org/security). Please note that most OpenSSL vulnerabilities do not effect JRuby since its not using any of OpenSSL's C code, only Ruby parts (*.rb) are the same as in MRI's OpenSSL library. ## Testing [![Build Status][0]](http://travis-ci.org/jruby/jruby-openssl) rake jar:all # creates pom.xml and generates jopenssl.jar under lib mvn test will run (junit as well as ruby) tests and a some ruby tests against the default jruby version. to pick a different version and/or modes (1.8, 1.9, 2.0, 2.1) run mvn test -Djruby.versions=1.7.12 -Djruby.modes=1.8 for running integration-tests the gem will be first installed and then the same tests run for each possible bouncy-castle version (see [listing][3]), run with mvn verify -P test-9.0.4.0,test-1.7.22 or pick a bouncy-castle version mvn verify -P test-1.6.8 -Dbc.versions=1.50 or simply be more picky mvn verify -P test-1.7.4 -Dbc.versions=1.49 -Djruby.modes=1.9 NOTE: you can pick any jruby version which is on [central][4] or on [ci.jruby][5] ## License (c) 2009-2017 JRuby distributed under EPL 1.0/GPL 2.0/LGPL 2.1 [0]: https://secure.travis-ci.org/jruby/jruby-openssl.svg [1]: http://xircles.codehaus.org/projects/jruby/lists [2]: https://github.com/jruby/jruby/issues [3]: https://github.com/jruby/jruby-openssl/tree/master/integration [4]: http://central.maven.org/maven2/org/jruby/ [5]: http://ci.jruby.org/snapshots/maven/org.jruby/ jruby-openssl-0.9.21/Rakefile000066400000000000000000000041061313661621600160720ustar00rootroot00000000000000#-*- mode: ruby -*- begin require 'ruby-maven' rescue LoadError warn "ruby-maven not available - some tasks will not work " << "either `gem install ruby-maven' or use mvn instead of rake" desc "Package jopenssl.jar with the compiled classes" task :jar do sh "mvn prepare-package -Dmaven.test.skip=true" end namespace :jar do desc "Package jopenssl.jar file (and dependendent jars)" task :all do sh "mvn package -Dmaven.test.skip=true" end end else #Rake::Task[:jar].clear rescue nil desc "Package jopenssl.jar with the compiled classes" task :jar do RubyMaven.exec( 'prepare-package -Dmaven.test.skip=true' ) end namespace :jar do desc "Package jopenssl.jar file (and dependendent jars)" task :all do RubyMaven.exec( 'package -Dmaven.test.skip=true' ) end end end task :build do RubyMaven.exec('package -Dmaven.test.skip') end task :default => :build file('lib/jopenssl.jar') { Rake::Task['jar'].invoke } require 'rake/testtask' Rake::TestTask.new do |task| task.libs << File.expand_path('src/test/ruby', File.dirname(__FILE__)) test_files = FileList['src/test/ruby/**/test*.rb'].to_a task.test_files = test_files.map { |path| path.sub('src/test/ruby/', '') } task.verbose = true task.loader = :direct task.ruby_opts = [ '-C', 'src/test/ruby', '-rbundler/setup' ] end task :test => 'lib/jopenssl.jar' namespace :integration do it_path = File.expand_path('../src/test/integration', __FILE__) task :install do Dir.chdir(it_path) do ruby "-S bundle install --gemfile '#{it_path}/Gemfile'" end end # desc "Run IT tests" task :test => 'lib/jopenssl.jar' do unless File.exist?(File.join(it_path, 'Gemfile.lock')) raise "bundle not installed, run `rake integration:install'" end loader = "ARGV.each { |f| require f }" ; lib = [ 'lib', it_path ] test_files = FileList['src/test/integration/*_test.rb'].map { |path| path.sub('src/test/integration/', '') } ruby "-I#{lib.join(':')} -C src/test/integration -e \"#{loader}\" #{test_files.map { |f| "\"#{f}\"" }.join(' ')}" end end jruby-openssl-0.9.21/integration/000077500000000000000000000000001313661621600167475ustar00rootroot00000000000000jruby-openssl-0.9.21/integration/1.47/000077500000000000000000000000001313661621600173405ustar00rootroot00000000000000jruby-openssl-0.9.21/integration/1.47/pom.xml000066400000000000000000000010501313661621600206510ustar00rootroot00000000000000 4.0.0 none base 0 bouncy-castle 1.47 ${project.version} jruby-openssl-0.9.21/integration/1.48/000077500000000000000000000000001313661621600173415ustar00rootroot00000000000000jruby-openssl-0.9.21/integration/1.48/pom.xml000066400000000000000000000010501313661621600206520ustar00rootroot00000000000000 4.0.0 none base 0 bouncy-castle 1.48 ${project.version} jruby-openssl-0.9.21/integration/1.49/000077500000000000000000000000001313661621600173425ustar00rootroot00000000000000jruby-openssl-0.9.21/integration/1.49/pom.xml000066400000000000000000000010501313661621600206530ustar00rootroot00000000000000 4.0.0 none base 0 bouncy-castle 1.49 ${project.version} jruby-openssl-0.9.21/integration/1.50/000077500000000000000000000000001313661621600173325ustar00rootroot00000000000000jruby-openssl-0.9.21/integration/1.50/pom.xml000066400000000000000000000010501313661621600206430ustar00rootroot00000000000000 4.0.0 none base 0 bouncy-castle 1.50 ${project.version} jruby-openssl-0.9.21/integration/Mavenfile000066400000000000000000000041331313661621600206010ustar00rootroot00000000000000#-*- mode: ruby -*- id 'none:base:0' packaging :pom snapshot_repository :id => 'jruby', :url => 'http://ci.jruby.org/snapshots/maven' # TODO should be setup whenever a plugin uses gems plugin_repository :id => 'rubygems-releases', :url => 'http://rubygems-proxy.torquebox.org/releases' base_path = File.expand_path('..', File.dirname(__FILE__)) bc_version = File.read("#{base_path}/lib/jopenssl/version.rb")[/BOUNCY_CASTLE_VERSION\s?=\s?'(.*?)'/, 1] properties( 'bc.version' => bc_version, # to satisfy maven 'jruby.openssl.version' => '0.9.7', # to satisfy maven # use the gem-maven-plugin repo for the tests 'gem.home' => '${basedir}/../pkg/rubygems', 'gem.path' => '${basedir}/../pkg/rubygems', 'tesla.dump.pom' => 'pom.xml', 'tesla.dump.readonly' => true, 'jruby.version' => '1.7.19', # for jruby-maven-plugins 'jruby.plugins.version' => '1.0.9' ) jruby_plugin :gem, :gemHomes => { 'gem-maven-plugin' => '${gem.home}' } do execute_goal :initialize gem 'jar-dependencies', '0.1.8' # TODO change after 0.1.15 is out spec = Gem::Specification.load "#{base_path}/jruby-openssl.gemspec" spec.development_dependencies.each do |dev_spec| gem dev_spec.name, *dev_spec.requirements_list end # make sure we have those in the local repo # BUT not be part of the runit-classloader # otherwise jruby-1.7.x and jruby-1.6.x will not use those # required in the test_*.rb files jar 'org.bouncycastle', 'bcpkix-jdk15on', '${bc.version}' jar 'org.bouncycastle', 'bcprov-jdk15on', '${bc.version}' #spec.requirements.each do |req| # req = req.sub('jar', '').split(',').each(&:strip!) # jar req[0], req[1] #end gem 'jruby-openssl', '${jruby.openssl.version}' end jruby_plugin :runit do execute_goal( :test, :env => { 'BC_VERSION' => '${bc.version}' }, :jrubySwitches => '-I../../lib', :runitDirectory => '../../src/test/ruby/**/test_*.rb', :versions => '${jruby.versions}', :modes => '${jruby.modes}' ) end # vim: syntax=Ruby jruby-openssl-0.9.21/integration/pom.xml000066400000000000000000000077631313661621600203010ustar00rootroot00000000000000 4.0.0 none base 0 pom integration 1.7.19 true 0.9.7 ${basedir}/../pkg/rubygems 1.0.9 ${basedir}/../pkg/rubygems 1.50 pom.xml false true jruby http://ci.jruby.org/snapshots/maven rubygems-releases http://rubygems-proxy.torquebox.org/releases de.saumya.mojo gem-maven-plugin ${jruby.plugins.version} initialize rubygems jar-dependencies 0.1.8 gem rubygems jar-dependencies [0.1.0,0.1.99999] gem rubygems mocha [1.1.0,1.1.99999] gem rubygems ruby-maven [0,) gem org.bouncycastle bcpkix-jdk15on ${bc.version} org.bouncycastle bcprov-jdk15on ${bc.version} rubygems jruby-openssl ${jruby.openssl.version} gem ${gem.home} de.saumya.mojo runit-maven-plugin ${jruby.plugins.version} test ${bc.version} -I../../lib ../../src/test/ruby/**/test_*.rb ${jruby.versions} ${jruby.modes} jruby-openssl-0.9.21/jruby-openssl.gemspec000066400000000000000000000027341313661621600206130ustar00rootroot00000000000000#-*- mode: ruby -*- Gem::Specification.new do |s| s.name = 'jruby-openssl' version_rb = File.expand_path('lib/jopenssl/version.rb', File.dirname(__FILE__)) version_rb = File.read(version_rb) s.version = version_rb.match( /.*\sVERSION\s*=\s*['"](.*)['"]/ )[1] s.platform = 'java' s.authors = ['Ola Bini', 'JRuby contributors'] s.email = "ola.bini@gmail.com" s.summary = "JRuby OpenSSL" s.homepage = 'https://github.com/jruby/jruby-openssl' s.description = 'JRuby-OpenSSL is an add-on gem for JRuby that emulates the' << ' Ruby OpenSSL native library.' s.licenses = [ 'EPL-1.0', 'GPL-2.0', 'LGPL-2.1' ] s.require_paths = ['lib'] s.files = `git ls-files`.split("\n"). select { |f| f =~ /^(lib)/ || f =~ /^History|LICENSE|README|Rakefile|Mavenfile|pom.xml/i } + Dir.glob('lib/**/*.jar') # 'lib/jopenssl.jar' and potentially BC jars bc_version = version_rb.match( /.*\sBOUNCY_CASTLE_VERSION\s*=\s*['"](.*)['"]/ )[1] raise 'BOUNCY_CASTLE_VERSION not matched' if (bc_version || '').empty? s.requirements << "jar org.bouncycastle:bcpkix-jdk15on, #{bc_version}" s.requirements << "jar org.bouncycastle:bcprov-jdk15on, #{bc_version}" s.add_development_dependency 'jar-dependencies', '~> 0.1' s.add_development_dependency 'mocha', '~> 1.1.0' s.add_development_dependency 'ruby-maven', '~> 3.0' # NOTE: runit-maven-plugin will use it's own : #s.add_development_dependency 'test-unit', '2.5.5' end # vim: syntax=Rubyjruby-openssl-0.9.21/lib/000077500000000000000000000000001313661621600151725ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl/000077500000000000000000000000001313661621600170275ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl/load.rb000066400000000000000000000023171313661621600202760ustar00rootroot00000000000000warn 'Loading jruby-openssl in a non-JRuby interpreter' unless defined? JRUBY_VERSION require 'java' require 'jopenssl/version' # NOTE: assuming user does pull in BC .jars from somewhere else on the CP unless ENV_JAVA['jruby.openssl.load.jars'].eql?('false') version = Jopenssl::Version::BOUNCY_CASTLE_VERSION bc_jars = nil begin require 'jar-dependencies' # if we have jar-dependencies we let it track the jars require_jar( 'org.bouncycastle', 'bcpkix-jdk15on', version ) require_jar( 'org.bouncycastle', 'bcprov-jdk15on', version ) bc_jars = true rescue LoadError end unless bc_jars load "org/bouncycastle/bcpkix-jdk15on/#{version}/bcpkix-jdk15on-#{version}.jar" load "org/bouncycastle/bcprov-jdk15on/#{version}/bcprov-jdk15on-#{version}.jar" end end require 'jruby' require 'jopenssl.jar' org.jruby.ext.openssl.OpenSSL.load(JRuby.runtime) if RUBY_VERSION > '2.3' load 'jopenssl23/openssl.rb' load 'jopenssl24.rb' if RUBY_VERSION >= '2.4' elsif RUBY_VERSION > '2.2' load 'jopenssl22/openssl.rb' elsif RUBY_VERSION > '2.1' load 'jopenssl21/openssl.rb' elsif RUBY_VERSION > '1.9' load 'jopenssl19/openssl.rb' else load 'jopenssl18/openssl.rb' end require 'openssl/pkcs12' jruby-openssl-0.9.21/lib/jopenssl/version.rb000066400000000000000000000003531313661621600210420ustar00rootroot00000000000000module Jopenssl VERSION = '0.9.21' BOUNCY_CASTLE_VERSION = '1.56' # @deprecated module Version # @private VERSION = Jopenssl::VERSION # @private BOUNCY_CASTLE_VERSION = Jopenssl::BOUNCY_CASTLE_VERSION end end jruby-openssl-0.9.21/lib/jopenssl18/000077500000000000000000000000001313661621600172005ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl18/openssl.rb000066400000000000000000000010521313661621600212060ustar00rootroot00000000000000=begin = $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id: openssl.rb 12496 2007-06-08 15:02:04Z technorama $ =end require 'openssl/bn' require 'openssl/cipher' require 'openssl/config' require 'openssl/digest' require 'openssl/pkcs7' require 'openssl/ssl-internal' require 'openssl/x509-internal' jruby-openssl-0.9.21/lib/jopenssl18/openssl/000077500000000000000000000000001313661621600206635ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl18/openssl/bn.rb000066400000000000000000000006761313661621600216200ustar00rootroot00000000000000=begin = $RCSfile$ -- Ruby-space definitions that completes C-space funcs for BN = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end ## # Add double dispatch to Integer # class Integer def to_bn OpenSSL::BN::new(self.to_s(16), 16) end end # Integer jruby-openssl-0.9.21/lib/jopenssl18/openssl/buffering.rb000066400000000000000000000072571313661621600231720ustar00rootroot00000000000000=begin = $RCSfile$ -- Buffering mix-in module. = Info 'OpenSSL for Ruby 2' project Copyright (C) 2001 GOTOU YUUZOU All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end module OpenSSL module Buffering include Enumerable attr_accessor :sync BLOCK_SIZE = 1024*16 def initialize(*args) @eof = false @rbuffer = "" @sync = @io.sync end # # for reading. # private def fill_rbuff begin @rbuffer << self.sysread(BLOCK_SIZE) rescue Errno::EAGAIN retry rescue EOFError @eof = true end end def consume_rbuff(size=nil) if @rbuffer.empty? nil else size = @rbuffer.size unless size ret = @rbuffer[0, size] @rbuffer[0, size] = "" ret end end public def read(size=nil, buf=nil) if size == 0 if buf buf.clear else buf = "" end return @eof ? nil : buf end until @eof break if size && size <= @rbuffer.size fill_rbuff end ret = consume_rbuff(size) || "" if buf buf.replace(ret) ret = buf end (size && ret.empty?) ? nil : ret end def readpartial(maxlen, buf=nil) if maxlen == 0 if buf buf.clear else buf = "" end return @eof ? nil : buf end if @rbuffer.empty? begin return sysread(maxlen, buf) rescue Errno::EAGAIN retry end end ret = consume_rbuff(maxlen) if buf buf.replace(ret) ret = buf end raise EOFError if ret.empty? ret end def gets(eol=$/) idx = @rbuffer.index(eol) until @eof break if idx fill_rbuff idx = @rbuffer.index(eol) end if eol.is_a?(Regexp) size = idx ? idx+$&.size : nil else size = idx ? idx+eol.size : nil end consume_rbuff(size) end def each(eol=$/) while line = self.gets(eol) yield line end end alias each_line each def readlines(eol=$/) ary = [] while line = self.gets(eol) ary << line end ary end def readline(eol=$/) raise EOFError if eof? gets(eol) end def getc c = read(1) c ? c[0] : nil end def each_byte while c = getc yield(c) end end def readchar raise EOFError if eof? getc end def ungetc(c) @rbuffer[0,0] = c.chr end def eof? fill_rbuff if !@eof && @rbuffer.empty? @eof && @rbuffer.empty? end alias eof eof? # # for writing. # private def do_write(s) @wbuffer = "" unless defined? @wbuffer @wbuffer << s @sync ||= false if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/) remain = idx ? idx + $/.size : @wbuffer.length nwritten = 0 while remain > 0 str = @wbuffer[nwritten,remain] begin nwrote = syswrite(str) rescue Errno::EAGAIN retry end remain -= nwrote nwritten += nwrote end @wbuffer[0,nwritten] = "" end end public def write(s) do_write(s) s.length end def << (s) do_write(s) self end def puts(*args) s = "" if args.empty? s << "\n" end args.each{|arg| s << arg.to_s if $/ && /\n\z/ !~ s s << "\n" end } do_write(s) nil end def print(*args) s = "" args.each{ |arg| s << arg.to_s } do_write(s) nil end def printf(s, *args) do_write(s % args) nil end def flush osync = @sync @sync = true do_write "" @sync = osync end def close flush rescue nil sysclose end end end jruby-openssl-0.9.21/lib/jopenssl18/openssl/cipher.rb000066400000000000000000000011261313661621600224620ustar00rootroot00000000000000=begin = $RCSfile$ -- Ruby-space predefined Cipher subclasses = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end ## # Should we care what if somebody require this file directly? #require 'openssl' module OpenSSL class Cipher # This class is only provided for backwards compatibility. Use OpenSSL::Digest in the future. class Cipher < Cipher # add warning end end # Cipher end # OpenSSLjruby-openssl-0.9.21/lib/jopenssl18/openssl/config.rb000066400000000000000000000165141313661621600224640ustar00rootroot00000000000000=begin = Ruby-space definitions that completes C-space funcs for Config = Info Copyright (C) 2010 Hiroshi Nakamura = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) =end ## # Should we care what if somebody require this file directly? #require 'openssl' require 'stringio' module OpenSSL class Config include Enumerable class << self def parse(str) c = new() parse_config(StringIO.new(str)).each do |section, hash| c[section] = hash end c end alias load new def parse_config(io) begin parse_config_lines(io) rescue ConfigError => e e.message.replace("error in line #{io.lineno}: " + e.message) raise end end def get_key_string(data, section, key) # :nodoc: if v = data[section] && data[section][key] return v elsif section == 'ENV' if v = ENV[key] return v end end if v = data['default'] && data['default'][key] return v end end private def parse_config_lines(io) section = 'default' data = {section => {}} while definition = get_definition(io) definition = clear_comments(definition) next if definition.empty? if definition[0] == ?[ if /\[([^\]]*)\]/ =~ definition section = $1.strip data[section] ||= {} else raise ConfigError, "missing close square bracket" end else if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition if $2 section = $1 key = $2 else key = $1 end value = unescape_value(data, section, $3) (data[section] ||= {})[key] = value.strip else raise ConfigError, "missing equal sign" end end end data end # escape with backslash QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/ # escape with backslash and doubled dq QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/ # escaped char map ESCAPE_MAP = { "r" => "\r", "n" => "\n", "b" => "\b", "t" => "\t", } def unescape_value(data, section, value) scanned = [] while m = value.match(/['"\\$]/) scanned << m.pre_match c = m[0] value = m.post_match case c when "'" if m = value.match(QUOTE_REGEXP_SQ) scanned << m[1].gsub(/\\(.)/, '\\1') value = m.post_match else break end when '"' if m = value.match(QUOTE_REGEXP_DQ) scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1') value = m.post_match else break end when "\\" c = value.slice!(0, 1) scanned << (ESCAPE_MAP[c] || c) when "$" ref, value = extract_reference(value) refsec = section if ref.index('::') refsec, ref = ref.split('::', 2) end if v = get_key_string(data, refsec, ref) scanned << v else raise ConfigError, "variable has no value" end else raise 'must not reaced' end end scanned << value scanned.join end def extract_reference(value) rest = '' if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/) value = m[1] || m[2] rest = m.post_match elsif [?(, ?{].include?(value[0]) raise ConfigError, "no close brace" end if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/) return m[0], m.post_match + rest else raise end end def clear_comments(line) # FCOMMENT if m = line.match(/\A([\t\n\f ]*);.*\z/) return m[1] end # COMMENT scanned = [] while m = line.match(/[#'"\\]/) scanned << m.pre_match c = m[0] line = m.post_match case c when '#' line = nil break when "'", '"' regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ scanned << c if m = line.match(regexp) scanned << m[0] line = m.post_match else scanned << line line = nil break end when "\\" scanned << c scanned << line.slice!(0, 1) else raise 'must not reaced' end end scanned << line scanned.join end def get_definition(io) if line = get_line(io) while /[^\\]\\\z/ =~ line if extra = get_line(io) line += extra else break end end return line.strip end end def get_line(io) if line = io.gets line.gsub(/[\r\n]*/, '') end end end def initialize(filename = nil) @data = {} if filename File.open(filename.to_s) do |file| Config.parse_config(file).each do |section, hash| self[section] = hash end end end end def get_value(section, key) if section.nil? raise TypeError.new('nil not allowed') end section = 'default' if section.empty? get_key_string(section, key) end def value(arg1, arg2 = nil) warn('Config#value is deprecated; use Config#get_value') if arg2.nil? section, key = 'default', arg1 else section, key = arg1, arg2 end section ||= 'default' section = 'default' if section.empty? get_key_string(section, key) end def add_value(section, key, value) check_modify (@data[section] ||= {})[key] = value end def [](section) @data[section] || {} end def section(name) warn('Config#section is deprecated; use Config#[]') @data[name] || {} end def []=(section, pairs) check_modify @data[section] ||= {} pairs.each do |key, value| self.add_value(section, key, value) end end def sections @data.keys end def to_s ary = [] @data.keys.sort.each do |section| ary << "[ #{section} ]\n" @data[section].keys.each do |key| ary << "#{key}=#{@data[section][key]}\n" end ary << "\n" end ary.join end def each @data.each do |section, hash| hash.each do |key, value| yield(section, key, value) end end end def inspect "#<#{self.class.name} sections=#{sections.inspect}>" end protected def data @data end private def initialize_copy(other) @data = other.data.dup end def check_modify raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen? end def get_key_string(section, key) Config.get_key_string(@data, section, key) end end end jruby-openssl-0.9.21/lib/jopenssl18/openssl/digest.rb000066400000000000000000000012251313661621600224670ustar00rootroot00000000000000=begin = $RCSfile$ -- Ruby-space predefined Digest subclasses = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end ## # Should we care what if somebody require this file directly? #require 'openssl' module OpenSSL class Digest # This class is only provided for backwards compatibility. Use OpenSSL::Digest in the future. class Digest < Digest def initialize(*args) # add warning super(*args) end end end # Digest end # OpenSSL jruby-openssl-0.9.21/lib/jopenssl18/openssl/pkcs7.rb000066400000000000000000000010511313661621600222340ustar00rootroot00000000000000=begin = $RCSfile$ -- PKCS7 = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id: digest.rb 12148 2007-04-05 05:59:22Z technorama $ =end module OpenSSL class PKCS7 # This class is only provided for backwards compatibility. Use OpenSSL::PKCS7 in the future. class PKCS7 < PKCS7 def initialize(*args) super(*args) warn("Warning: OpenSSL::PKCS7::PKCS7 is deprecated after Ruby 1.9; use OpenSSL::PKCS7 instead") end end end # PKCS7 end # OpenSSL jruby-openssl-0.9.21/lib/jopenssl18/openssl/ssl-internal.rb000066400000000000000000000054351313661621600236320ustar00rootroot00000000000000=begin = $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL = Info 'OpenSSL for Ruby 2' project Copyright (C) 2001 GOTOU YUUZOU All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end require "openssl/buffering" require 'fcntl' # used by OpenSSL::SSL::Nonblock (if loaded) module OpenSSL module SSL def verify_certificate_identity(cert, hostname) should_verify_common_name = true cert.extensions.each{|ext| next if ext.oid != "subjectAltName" ext.value.split(/,\s+/).each{|general_name| if /\ADNS:(.*)/ =~ general_name should_verify_common_name = false reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+") return true if /\A#{reg}\z/i =~ hostname # NOTE: somehow we need the IP: canonical form # seems there were failures elsewhere when not # not sure how that's possible possible to-do! elsif /\AIP(?: Address)?:(.*)/ =~ general_name #elsif /\AIP Address:(.*)/ =~ general_name should_verify_common_name = false return true if $1 == hostname end } } if should_verify_common_name cert.subject.to_a.each{|oid, value| if oid == "CN" reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") return true if /\A#{reg}\z/i =~ hostname end } end return false end module_function :verify_certificate_identity class SSLSocket include Buffering include SocketForwarder include Nonblock def post_connection_check(hostname) unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) raise SSLError, "hostname was not match with the server certificate" end return true end end class SSLServer include SocketForwarder attr_accessor :start_immediately def initialize(svr, ctx) @svr = svr @ctx = ctx unless ctx.session_id_context session_id = OpenSSL::Digest::MD5.hexdigest($0) @ctx.session_id_context = session_id end @start_immediately = true end def to_io @svr end def listen(backlog=5) @svr.listen(backlog) end def shutdown(how=Socket::SHUT_RDWR) @svr.shutdown(how) end def accept sock = @svr.accept begin ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) ssl.sync_close = true ssl.accept if @start_immediately ssl rescue SSLError => ex sock.close raise ex end end def close @svr.close end end end end jruby-openssl-0.9.21/lib/jopenssl18/openssl/ssl.rb000066400000000000000000000000221313661621600220030ustar00rootroot00000000000000require 'openssl' jruby-openssl-0.9.21/lib/jopenssl18/openssl/x509-internal.rb000066400000000000000000000062421313661621600235330ustar00rootroot00000000000000=begin = $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end module OpenSSL module X509 class Name module RFC2253DN Special = ',=+<>#;' HexChar = /[0-9a-fA-F]/ HexPair = /#{HexChar}#{HexChar}/ HexString = /#{HexPair}+/ Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/ StringChar = /[^#{Special}\\"]/ QuoteChar = /[^\\"]/ AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/ AttributeValue = / (?!["#])((?:#{StringChar}|#{Pair})*)| \#(#{HexString})| "((?:#{QuoteChar}|#{Pair})*)" /x TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/ module_function def expand_pair(str) return nil unless str return str.gsub(Pair){ pair = $& case pair.size when 2 then pair[1,1] when 3 then Integer("0x#{pair[1,2]}").chr else raise OpenSSL::X509::NameError, "invalid pair: #{str}" end } end def expand_hexstring(str) return nil unless str der = str.gsub(HexPair){$&.to_i(16).chr } a1 = OpenSSL::ASN1.decode(der) return a1.value, a1.tag end def expand_value(str1, str2, str3) value = expand_pair(str1) value, tag = expand_hexstring(str2) unless value value = expand_pair(str3) unless value return value, tag end def scan(dn) str = dn ary = [] while true if md = TypeAndValue.match(str) matched = md.to_s remain = md.post_match type = md[1] value, tag = expand_value(md[2], md[3], md[4]) rescue nil if value type_and_value = [type, value] type_and_value.push(tag) if tag ary.unshift(type_and_value) if remain.length > 2 && remain[0] == ?, str = remain[1..-1] next elsif remain.length > 2 && remain[0] == ?+ raise OpenSSL::X509::NameError, "multi-valued RDN is not supported: #{dn}" elsif remain.empty? break end end end msg_dn = dn[0, dn.length - str.length] + " =>" + str raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}" end return ary end end class <= 0 size = [size, limit].min end consume_rbuff(size) end ## # Executes the block for every line in the stream where lines are separated # by +eol+. # # See also #gets def each(eol=$/) while line = self.gets(eol) yield line end end alias each_line each ## # Reads lines from the stream which are separated by +eol+. # # See also #gets def readlines(eol=$/) ary = [] while line = self.gets(eol) ary << line end ary end ## # Reads a line from the stream which is separated by +eol+. # # Raises EOFError if at end of file. def readline(eol=$/) raise EOFError if eof? gets(eol) end ## # Reads one character from the stream. Returns nil if called at end of # file. def getc read(1) end ## # Calls the given block once for each byte in the stream. def each_byte # :yields: byte while c = getc yield(c.ord) end end ## # Reads a one-character string from the stream. Raises an EOFError at end # of file. def readchar raise EOFError if eof? getc end ## # Pushes character +c+ back onto the stream such that a subsequent buffered # character read will return it. # # Unlike IO#getc multiple bytes may be pushed back onto the stream. # # Has no effect on unbuffered reads (such as #sysread). def ungetc(c) @rbuffer[0,0] = c.chr end ## # Returns true if the stream is at file which means there is no more data to # be read. def eof? fill_rbuff if !@eof && @rbuffer.empty? @eof && @rbuffer.empty? end alias eof eof? # # for writing. # private ## # Writes +s+ to the buffer. When the buffer is full or #sync is true the # buffer is flushed to the underlying socket. def do_write(s) @wbuffer = "" unless defined? @wbuffer @wbuffer << s @wbuffer.force_encoding(Encoding::BINARY) @sync ||= false if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/) remain = idx ? idx + $/.size : @wbuffer.length nwritten = 0 while remain > 0 str = @wbuffer[nwritten,remain] begin nwrote = syswrite(str) rescue Errno::EAGAIN retry end remain -= nwrote nwritten += nwrote end @wbuffer[0,nwritten] = "" end end public ## # Writes +s+ to the stream. If the argument is not a string it will be # converted using String#to_s. Returns the number of bytes written. def write(s) do_write(s) s.bytesize end ## # Writes +str+ in the non-blocking manner. # # If there is buffered data, it is flushed first. This may block. # # write_nonblock returns number of bytes written to the SSL connection. # # When no data can be written without blocking it raises # OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable. # # IO::WaitReadable means SSL needs to read internally so write_nonblock # should be called again after the underlying IO is readable. # # IO::WaitWritable means SSL needs to write internally so write_nonblock # should be called again after underlying IO is writable. # # So OpenSSL::Buffering#write_nonblock needs two rescue clause as follows. # # # emulates blocking write. # begin # result = ssl.write_nonblock(str) # rescue IO::WaitReadable # IO.select([io]) # retry # rescue IO::WaitWritable # IO.select(nil, [io]) # retry # end # # Note that one reason that write_nonblock reads from the underlying IO # is when the peer requests a new TLS/SSL handshake. See the openssl FAQ # for more details. http://www.openssl.org/support/faq.html def write_nonblock(s) flush syswrite_nonblock(s) end ## # Writes +s+ to the stream. +s+ will be converted to a String using # String#to_s. def << (s) do_write(s) self end ## # Writes +args+ to the stream along with a record separator. # # See IO#puts for full details. def puts(*args) s = "" if args.empty? s << "\n" end args.each{|arg| s << arg.to_s if $/ && /\n\z/ !~ s s << "\n" end } do_write(s) nil end ## # Writes +args+ to the stream. # # See IO#print for full details. def print(*args) s = "" args.each{ |arg| s << arg.to_s } do_write(s) nil end ## # Formats and writes to the stream converting parameters under control of # the format string. # # See Kernel#sprintf for format string details. def printf(s, *args) do_write(s % args) nil end ## # Flushes buffered data to the SSLSocket. def flush osync = @sync @sync = true do_write "" return self ensure @sync = osync end ## # Closes the SSLSocket and flushes any unwritten data. def close flush rescue nil sysclose end end jruby-openssl-0.9.21/lib/jopenssl19/openssl/cipher.rb000066400000000000000000000010151313661621600224600ustar00rootroot00000000000000#-- # # $RCSfile$ # # = Ruby-space predefined Cipher subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # # = Version # $Id$ # #++ module OpenSSL class Cipher # This class is only provided for backwards compatibility. Use OpenSSL::Cipher in the future. class Cipher < Cipher # add warning end end # Cipher end # OpenSSLjruby-openssl-0.9.21/lib/jopenssl19/openssl/config.rb000066400000000000000000000277031313661621600224670ustar00rootroot00000000000000=begin = Ruby-space definitions that completes C-space funcs for Config = Info Copyright (C) 2010 Hiroshi Nakamura = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) =end require 'stringio' module OpenSSL ## # = OpenSSL::Config # # Configuration for the openssl library. # # Many system's installation of openssl library will depend on your system # configuration. See the value of OpenSSL::Config::DEFAULT_CONFIG_FILE for # the location of the file for your host. # # See also http://www.openssl.org/docs/apps/config.html class Config include Enumerable class << self ## # Parses a given +string+ as a blob that contains configuration for openssl. # # If the source of the IO is a file, then consider using #parse_config. def parse(string) c = new() parse_config(StringIO.new(string)).each do |section, hash| c[section] = hash end c end ## # load is an alias to ::new alias load new ## # Parses the configuration data read from +io+, see also #parse. # # Raises a ConfigError on invalid configuration data. def parse_config(io) begin parse_config_lines(io) rescue ConfigError => e e.message.replace("error in line #{io.lineno}: " + e.message) raise end end def get_key_string(data, section, key) # :nodoc: if v = data[section] && data[section][key] return v elsif section == 'ENV' if v = ENV[key] return v end end if v = data['default'] && data['default'][key] return v end end private def parse_config_lines(io) section = 'default' data = {section => {}} while definition = get_definition(io) definition = clear_comments(definition) next if definition.empty? if definition[0] == ?[ if /\[([^\]]*)\]/ =~ definition section = $1.strip data[section] ||= {} else raise ConfigError, "missing close square bracket" end else if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition if $2 section = $1 key = $2 else key = $1 end value = unescape_value(data, section, $3) (data[section] ||= {})[key] = value.strip else raise ConfigError, "missing equal sign" end end end data end # escape with backslash QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/ # escape with backslash and doubled dq QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/ # escaped char map ESCAPE_MAP = { "r" => "\r", "n" => "\n", "b" => "\b", "t" => "\t", } def unescape_value(data, section, value) scanned = [] while m = value.match(/['"\\$]/) scanned << m.pre_match c = m[0] value = m.post_match case c when "'" if m = value.match(QUOTE_REGEXP_SQ) scanned << m[1].gsub(/\\(.)/, '\\1') value = m.post_match else break end when '"' if m = value.match(QUOTE_REGEXP_DQ) scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1') value = m.post_match else break end when "\\" c = value.slice!(0, 1) scanned << (ESCAPE_MAP[c] || c) when "$" ref, value = extract_reference(value) refsec = section if ref.index('::') refsec, ref = ref.split('::', 2) end if v = get_key_string(data, refsec, ref) scanned << v else raise ConfigError, "variable has no value" end else raise 'must not reaced' end end scanned << value scanned.join end def extract_reference(value) rest = '' if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/) value = m[1] || m[2] rest = m.post_match elsif [?(, ?{].include?(value[0]) raise ConfigError, "no close brace" end if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/) return m[0], m.post_match + rest else raise end end def clear_comments(line) # FCOMMENT if m = line.match(/\A([\t\n\f ]*);.*\z/) return m[1] end # COMMENT scanned = [] while m = line.match(/[#'"\\]/) scanned << m.pre_match c = m[0] line = m.post_match case c when '#' line = nil break when "'", '"' regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ scanned << c if m = line.match(regexp) scanned << m[0] line = m.post_match else scanned << line line = nil break end when "\\" scanned << c scanned << line.slice!(0, 1) else raise 'must not reaced' end end scanned << line scanned.join end def get_definition(io) if line = get_line(io) while /[^\\]\\\z/ =~ line if extra = get_line(io) line += extra else break end end return line.strip end end def get_line(io) if line = io.gets line.gsub(/[\r\n]*/, '') end end end ## # Creates an instance of OpenSSL's configuration class. # # This can be used in contexts like OpenSSL::X509::ExtensionFactory.config= # # If the optional +filename+ parameter is provided, then it is read in and # parsed via #parse_config. # # This can raise IO exceptions based on the access, or availability of the # file. A ConfigError exception may be raised depending on the validity of # the data being configured. # def initialize(filename = nil) @data = {} if filename File.open(filename.to_s) do |file| Config.parse_config(file).each do |section, hash| self[section] = hash end end end end ## # Gets the value of +key+ from the given +section+ # # Given the following configurating file being loaded: # # config = OpenSSL::Config.load('foo.cnf') # #=> # # puts config.to_s # #=> [ default ] # # foo=bar # # You can get a specific value from the config if you know the +section+ # and +key+ like so: # # config.get_value('default','foo') # #=> "bar" # def get_value(section, key) if section.nil? raise TypeError.new('nil not allowed') end section = 'default' if section.empty? get_key_string(section, key) end ## # # *Deprecated* # # Use #get_value instead def value(arg1, arg2 = nil) # :nodoc: warn('Config#value is deprecated; use Config#get_value') if arg2.nil? section, key = 'default', arg1 else section, key = arg1, arg2 end section ||= 'default' section = 'default' if section.empty? get_key_string(section, key) end ## # Set the target +key+ with a given +value+ under a specific +section+. # # Given the following configurating file being loaded: # # config = OpenSSL::Config.load('foo.cnf') # #=> # # puts config.to_s # #=> [ default ] # # foo=bar # # You can set the value of +foo+ under the +default+ section to a new # value: # # config.add_value('default', 'foo', 'buzz') # #=> "buzz" # puts config.to_s # #=> [ default ] # # foo=buzz # def add_value(section, key, value) check_modify (@data[section] ||= {})[key] = value end ## # Get a specific +section+ from the current configuration # # Given the following configurating file being loaded: # # config = OpenSSL::Config.load('foo.cnf') # #=> # # puts config.to_s # #=> [ default ] # # foo=bar # # You can get a hash of the specific section like so: # # config['default'] # #=> {"foo"=>"bar"} # def [](section) @data[section] || {} end ## # Deprecated # # Use #[] instead def section(name) # :nodoc: warn('Config#section is deprecated; use Config#[]') @data[name] || {} end ## # Sets a specific +section+ name with a Hash +pairs+ # # Given the following configuration being created: # # config = OpenSSL::Config.new # #=> # # config['default'] = {"foo"=>"bar","baz"=>"buz"} # #=> {"foo"=>"bar", "baz"=>"buz"} # puts config.to_s # #=> [ default ] # # foo=bar # # baz=buz # # It's important to note that this will essentially merge any of the keys # in +pairs+ with the existing +section+. For example: # # config['default'] # #=> {"foo"=>"bar", "baz"=>"buz"} # config['default'] = {"foo" => "changed"} # #=> {"foo"=>"changed"} # config['default'] # #=> {"foo"=>"changed", "baz"=>"buz"} # def []=(section, pairs) check_modify @data[section] ||= {} pairs.each do |key, value| self.add_value(section, key, value) end end ## # Get the names of all sections in the current configuration def sections @data.keys end ## # Get the parsable form of the current configuration # # Given the following configuration being created: # # config = OpenSSL::Config.new # #=> # # config['default'] = {"foo"=>"bar","baz"=>"buz"} # #=> {"foo"=>"bar", "baz"=>"buz"} # puts config.to_s # #=> [ default ] # # foo=bar # # baz=buz # # You can parse get the serialized configuration using #to_s and then parse # it later: # # serialized_config = config.to_s # # much later... # new_config = OpenSSL::Config.parse(serialized_config) # #=> # # puts new_config # #=> [ default ] # foo=bar # baz=buz # def to_s ary = [] @data.keys.sort.each do |section| ary << "[ #{section} ]\n" @data[section].keys.each do |key| ary << "#{key}=#{@data[section][key]}\n" end ary << "\n" end ary.join end ## # For a block. # # Receive the section and its pairs for the current configuration. # # config.each do |section, key, value| # # ... # end # def each @data.each do |section, hash| hash.each do |key, value| yield [section, key, value] end end end ## # String representation of this configuration object, including the class # name and its sections. def inspect "#<#{self.class.name} sections=#{sections.inspect}>" end protected def data # :nodoc: @data end private def initialize_copy(other) @data = other.data.dup end def check_modify raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen? end def get_key_string(section, key) Config.get_key_string(@data, section, key) end end end jruby-openssl-0.9.21/lib/jopenssl19/openssl/digest.rb000066400000000000000000000011141313661621600224650ustar00rootroot00000000000000#-- # # $RCSfile$ # # = Ruby-space predefined Digest subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # # = Version # $Id$ # #++ module OpenSSL class Digest # This class is only provided for backwards compatibility. Use OpenSSL::Digest in the future. class Digest < Digest def initialize(*args) # add warning super(*args) end end end # Digest end # OpenSSL jruby-openssl-0.9.21/lib/jopenssl19/openssl/ssl-internal.rb000066400000000000000000000062711313661621600236320ustar00rootroot00000000000000=begin = $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL = Info 'OpenSSL for Ruby 2' project Copyright (C) 2001 GOTOU YUUZOU All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end require "openssl/buffering" require 'fcntl' # used by OpenSSL::SSL::Nonblock (if loaded) module OpenSSL module SSL def verify_certificate_identity(cert, hostname) should_verify_common_name = true cert.extensions.each { |ext| next if ext.oid != "subjectAltName" ext.value.split(/,\s+/).each { |general_name| # MRI 1.9.3 (since we parse ASN.1 differently) # when 2 # dNSName in GeneralName (RFC5280) if /\ADNS:(.*)/ =~ general_name should_verify_common_name = false reg = Regexp.escape($1).gsub(/\\\*/, "[^.]+") return true if /\A#{reg}\z/i =~ hostname # MRI 1.9.3 (since we parse ASN.1 differently) # when 7 # iPAddress in GeneralName (RFC5280) elsif /\AIP(?: Address)?:(.*)/ =~ general_name should_verify_common_name = false return true if $1 == hostname # NOTE: bellow logic makes little sense as we read exts differently #value = $1 # follows GENERAL_NAME_print() in x509v3/v3_alt.c #if value.size == 4 # return true if value.unpack('C*').join('.') == hostname #elsif value.size == 16 # return true if value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname #end end } } if should_verify_common_name cert.subject.to_a.each { |oid, value| if oid == "CN" reg = Regexp.escape(value).gsub(/\\\*/, "[^.]+") return true if /\A#{reg}\z/i =~ hostname end } end return false end module_function :verify_certificate_identity class SSLSocket include Buffering include SocketForwarder include Nonblock def post_connection_check(hostname) unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) raise SSLError, "hostname does not match the server certificate" end return true end end class SSLServer include SocketForwarder attr_accessor :start_immediately def initialize(svr, ctx) @svr = svr @ctx = ctx unless ctx.session_id_context session_id = OpenSSL::Digest::MD5.hexdigest($0) @ctx.session_id_context = session_id end @start_immediately = true end def to_io @svr end def listen(backlog=5) @svr.listen(backlog) end def shutdown(how=Socket::SHUT_RDWR) @svr.shutdown(how) end def accept sock = @svr.accept begin ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) ssl.sync_close = true ssl.accept if @start_immediately ssl rescue SSLError => ex sock.close raise ex end end def close @svr.close end end end end jruby-openssl-0.9.21/lib/jopenssl19/openssl/ssl.rb000066400000000000000000000001401313661621600220050ustar00rootroot00000000000000warn 'deprecated openssl/ssl use: require "openssl" instead of "openssl/ssl"' require 'openssl' jruby-openssl-0.9.21/lib/jopenssl19/openssl/x509-internal.rb000066400000000000000000000064621313661621600235400ustar00rootroot00000000000000=begin = $RCSfile$ -- Ruby-space definitions that completes C-space funcs for X509 and subclasses = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end module OpenSSL module X509 class Name module RFC2253DN Special = ',=+<>#;' HexChar = /[0-9a-fA-F]/ HexPair = /#{HexChar}#{HexChar}/ HexString = /#{HexPair}+/ Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/ StringChar = /[^#{Special}\\"]/ QuoteChar = /[^\\"]/ AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/ AttributeValue = / (?!["#])((?:#{StringChar}|#{Pair})*)| \#(#{HexString})| "((?:#{QuoteChar}|#{Pair})*)" /x TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/ module_function def expand_pair(str) return nil unless str return str.gsub(Pair){ pair = $& case pair.size when 2 then pair[1,1] when 3 then Integer("0x#{pair[1,2]}").chr else raise OpenSSL::X509::NameError, "invalid pair: #{str}" end } end def expand_hexstring(str) return nil unless str der = str.gsub(HexPair){$&.to_i(16).chr } a1 = OpenSSL::ASN1.decode(der) return a1.value, a1.tag end def expand_value(str1, str2, str3) value = expand_pair(str1) value, tag = expand_hexstring(str2) unless value value = expand_pair(str3) unless value return value, tag end def scan(dn) str = dn ary = [] while true if md = TypeAndValue.match(str) remain = md.post_match type = md[1] value, tag = expand_value(md[2], md[3], md[4]) rescue nil if value type_and_value = [type, value] type_and_value.push(tag) if tag ary.unshift(type_and_value) if remain.length > 2 && remain[0] == ?, str = remain[1..-1] next elsif remain.length > 2 && remain[0] == ?+ raise OpenSSL::X509::NameError, "multi-valued RDN is not supported: #{dn}" elsif remain.empty? break end end end msg_dn = dn[0, dn.length - str.length] + " =>" + str raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}" end return ary end end class << self def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE) ary = OpenSSL::X509::Name::RFC2253DN.scan(str) self.new(ary, template) end def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE) ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) } self.new(ary, template) end alias parse parse_openssl end end class StoreContext def cleanup warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE end end end end jruby-openssl-0.9.21/lib/jopenssl19/openssl/x509.rb000066400000000000000000000001421313661621600217130ustar00rootroot00000000000000warn 'deprecated openssl/x509 use: require "openssl" instead of "openssl/x509"' require 'openssl' jruby-openssl-0.9.21/lib/jopenssl21/000077500000000000000000000000001313661621600171725ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl21/openssl.rb000066400000000000000000000007151313661621600212050ustar00rootroot00000000000000=begin = $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end require 'openssl/bn' require 'openssl/cipher' require 'openssl/config' require 'openssl/digest' require 'openssl/x509' require 'openssl/ssl' jruby-openssl-0.9.21/lib/jopenssl21/openssl/000077500000000000000000000000001313661621600206555ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl21/openssl/bn.rb000066400000000000000000000006741313661621600216100ustar00rootroot00000000000000#-- # # $RCSfile$ # # = Ruby-space definitions that completes C-space funcs for BN # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # # = Version # $Id$ # #++ ## # Add double dispatch to Integer # class Integer def to_bn OpenSSL::BN::new(self) end end # Integer jruby-openssl-0.9.21/lib/jopenssl21/openssl/buffering.rb000066400000000000000000000000461313661621600231510ustar00rootroot00000000000000load 'jopenssl22/openssl/buffering.rb'jruby-openssl-0.9.21/lib/jopenssl21/openssl/cipher.rb000066400000000000000000000000431313661621600224510ustar00rootroot00000000000000load 'jopenssl22/openssl/cipher.rb'jruby-openssl-0.9.21/lib/jopenssl21/openssl/config.rb000066400000000000000000000000431313661621600224440ustar00rootroot00000000000000load 'jopenssl22/openssl/config.rb'jruby-openssl-0.9.21/lib/jopenssl21/openssl/digest.rb000066400000000000000000000000431313661621600224560ustar00rootroot00000000000000load 'jopenssl22/openssl/digest.rb'jruby-openssl-0.9.21/lib/jopenssl21/openssl/ssl.rb000066400000000000000000000000401313661621600217750ustar00rootroot00000000000000load 'jopenssl22/openssl/ssl.rb'jruby-openssl-0.9.21/lib/jopenssl21/openssl/x509.rb000066400000000000000000000064761313661621600217240ustar00rootroot00000000000000#-- # # $RCSfile$ # # = Ruby-space definitions that completes C-space funcs for X509 and subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # # = Version # $Id$ # #++ module OpenSSL module X509 class Name module RFC2253DN Special = ',=+<>#;' HexChar = /[0-9a-fA-F]/ HexPair = /#{HexChar}#{HexChar}/ HexString = /#{HexPair}+/ Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/ StringChar = /[^#{Special}\\"]/ QuoteChar = /[^\\"]/ AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/ AttributeValue = / (?!["#])((?:#{StringChar}|#{Pair})*)| \#(#{HexString})| "((?:#{QuoteChar}|#{Pair})*)" /x TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/ module_function def expand_pair(str) return nil unless str return str.gsub(Pair){ pair = $& case pair.size when 2 then pair[1,1] when 3 then Integer("0x#{pair[1,2]}").chr else raise OpenSSL::X509::NameError, "invalid pair: #{str}" end } end def expand_hexstring(str) return nil unless str der = str.gsub(HexPair){$&.to_i(16).chr } a1 = OpenSSL::ASN1.decode(der) return a1.value, a1.tag end def expand_value(str1, str2, str3) value = expand_pair(str1) value, tag = expand_hexstring(str2) unless value value = expand_pair(str3) unless value return value, tag end def scan(dn) str = dn ary = [] while true if md = TypeAndValue.match(str) remain = md.post_match type = md[1] value, tag = expand_value(md[2], md[3], md[4]) rescue nil if value type_and_value = [type, value] type_and_value.push(tag) if tag ary.unshift(type_and_value) if remain.length > 2 && remain[0] == ?, str = remain[1..-1] next elsif remain.length > 2 && remain[0] == ?+ raise OpenSSL::X509::NameError, "multi-valued RDN is not supported: #{dn}" elsif remain.empty? break end end end msg_dn = dn[0, dn.length - str.length] + " =>" + str raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}" end return ary end end class << self def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE) ary = OpenSSL::X509::Name::RFC2253DN.scan(str) self.new(ary, template) end def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE) ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) } self.new(ary, template) end alias parse parse_openssl end end class StoreContext def cleanup warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE end end end end jruby-openssl-0.9.21/lib/jopenssl22/000077500000000000000000000000001313661621600171735ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl22/openssl.rb000066400000000000000000000007151313661621600212060ustar00rootroot00000000000000=begin = $RCSfile$ -- Loader for all OpenSSL C-space and Ruby-space definitions = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end require 'openssl/bn' require 'openssl/cipher' require 'openssl/config' require 'openssl/digest' require 'openssl/x509' require 'openssl/ssl' jruby-openssl-0.9.21/lib/jopenssl22/openssl/000077500000000000000000000000001313661621600206565ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl22/openssl/bn.rb000066400000000000000000000011411313661621600215770ustar00rootroot00000000000000#-- # # $RCSfile$ # # = Ruby-space definitions that completes C-space funcs for BN # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # # = Version # $Id$ # #++ module OpenSSL class BN def pretty_print(q) q.object_group(self) { q.text ' ' q.text to_i.to_s } end end # BN end # OpenSSL ## # Add double dispatch to Integer # class Integer def to_bn OpenSSL::BN::new(self) end end # Integer jruby-openssl-0.9.21/lib/jopenssl22/openssl/buffering.rb000066400000000000000000000226401313661621600231560ustar00rootroot00000000000000# coding: binary #-- #= $RCSfile$ -- Buffering mix-in module. # #= Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2001 GOTOU YUUZOU # All rights reserved. # #= Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # #= Version # $Id$ #++ ## # OpenSSL IO buffering mix-in module. # # This module allows an OpenSSL::SSL::SSLSocket to behave like an IO. # # You typically won't use this module directly, you can see it implemented in # OpenSSL::SSL::SSLSocket. module OpenSSL::Buffering include Enumerable ## # The "sync mode" of the SSLSocket. # # See IO#sync for full details. attr_accessor :sync ## # Default size to read from or write to the SSLSocket for buffer operations. BLOCK_SIZE = 1024*16 ## # Creates an instance of OpenSSL's buffering IO module. def initialize(*) @eof = false @rbuffer = "" @sync = @io.sync end # # for reading. # private ## # Fills the buffer from the underlying SSLSocket def fill_rbuff begin @rbuffer << self.sysread(BLOCK_SIZE) rescue Errno::EAGAIN retry rescue EOFError @eof = true end end ## # Consumes +size+ bytes from the buffer def consume_rbuff(size=nil) if @rbuffer.empty? nil else size = @rbuffer.size unless size ret = @rbuffer[0, size] @rbuffer[0, size] = "" ret end end public ## # Reads +size+ bytes from the stream. If +buf+ is provided it must # reference a string which will receive the data. # # See IO#read for full details. def read(size=nil, buf=nil) if size == 0 if buf buf.clear return buf else return "" end end until @eof break if size && size <= @rbuffer.size fill_rbuff end ret = consume_rbuff(size) || "" if buf buf.replace(ret) ret = buf end (size && ret.empty?) ? nil : ret end ## # Reads at most +maxlen+ bytes from the stream. If +buf+ is provided it # must reference a string which will receive the data. # # See IO#readpartial for full details. def readpartial(maxlen, buf=nil) if maxlen == 0 if buf buf.clear return buf else return "" end end if @rbuffer.empty? begin return sysread(maxlen, buf) rescue Errno::EAGAIN retry end end ret = consume_rbuff(maxlen) if buf buf.replace(ret) ret = buf end raise EOFError if ret.empty? ret end ## # Reads at most +maxlen+ bytes in the non-blocking manner. # # When no data can be read without blocking it raises # OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable. # # IO::WaitReadable means SSL needs to read internally so read_nonblock # should be called again when the underlying IO is readable. # # IO::WaitWritable means SSL needs to write internally so read_nonblock # should be called again after the underlying IO is writable. # # OpenSSL::Buffering#read_nonblock needs two rescue clause as follows: # # # emulates blocking read (readpartial). # begin # result = ssl.read_nonblock(maxlen) # rescue IO::WaitReadable # IO.select([io]) # retry # rescue IO::WaitWritable # IO.select(nil, [io]) # retry # end # # Note that one reason that read_nonblock writes to the underlying IO is # when the peer requests a new TLS/SSL handshake. See openssl the FAQ for # more details. http://www.openssl.org/support/faq.html def read_nonblock(maxlen, buf=nil, exception: true) if maxlen == 0 if buf buf.clear return buf else return "" end end if @rbuffer.empty? return sysread_nonblock(maxlen, buf, exception: exception) end ret = consume_rbuff(maxlen) if buf buf.replace(ret) ret = buf end raise EOFError if ret.empty? ret end ## # Reads the next "line+ from the stream. Lines are separated by +eol+. If # +limit+ is provided the result will not be longer than the given number of # bytes. # # +eol+ may be a String or Regexp. # # Unlike IO#gets the line read will not be assigned to +$_+. # # Unlike IO#gets the separator must be provided if a limit is provided. def gets(eol=$/, limit=nil) idx = @rbuffer.index(eol) until @eof break if idx fill_rbuff idx = @rbuffer.index(eol) end if eol.is_a?(Regexp) size = idx ? idx+$&.size : nil else size = idx ? idx+eol.size : nil end if limit and limit >= 0 size = [size, limit].min end consume_rbuff(size) end ## # Executes the block for every line in the stream where lines are separated # by +eol+. # # See also #gets def each(eol=$/) while line = self.gets(eol) yield line end end alias each_line each ## # Reads lines from the stream which are separated by +eol+. # # See also #gets def readlines(eol=$/) ary = [] while line = self.gets(eol) ary << line end ary end ## # Reads a line from the stream which is separated by +eol+. # # Raises EOFError if at end of file. def readline(eol=$/) raise EOFError if eof? gets(eol) end ## # Reads one character from the stream. Returns nil if called at end of # file. def getc read(1) end ## # Calls the given block once for each byte in the stream. def each_byte # :yields: byte while c = getc yield(c.ord) end end ## # Reads a one-character string from the stream. Raises an EOFError at end # of file. def readchar raise EOFError if eof? getc end ## # Pushes character +c+ back onto the stream such that a subsequent buffered # character read will return it. # # Unlike IO#getc multiple bytes may be pushed back onto the stream. # # Has no effect on unbuffered reads (such as #sysread). def ungetc(c) @rbuffer[0,0] = c.chr end ## # Returns true if the stream is at file which means there is no more data to # be read. def eof? fill_rbuff if !@eof && @rbuffer.empty? @eof && @rbuffer.empty? end alias eof eof? # # for writing. # private ## # Writes +s+ to the buffer. When the buffer is full or #sync is true the # buffer is flushed to the underlying socket. def do_write(s) @wbuffer = "" unless defined? @wbuffer @wbuffer << s @wbuffer.force_encoding(Encoding::BINARY) @sync ||= false if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/) remain = idx ? idx + $/.size : @wbuffer.length nwritten = 0 while remain > 0 str = @wbuffer[nwritten,remain] begin nwrote = syswrite(str) rescue Errno::EAGAIN retry end remain -= nwrote nwritten += nwrote end @wbuffer[0,nwritten] = "" end end public ## # Writes +s+ to the stream. If the argument is not a string it will be # converted using String#to_s. Returns the number of bytes written. def write(s) do_write(s) s.bytesize end ## # Writes +str+ in the non-blocking manner. # # If there is buffered data, it is flushed first. This may block. # # write_nonblock returns number of bytes written to the SSL connection. # # When no data can be written without blocking it raises # OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable. # # IO::WaitReadable means SSL needs to read internally so write_nonblock # should be called again after the underlying IO is readable. # # IO::WaitWritable means SSL needs to write internally so write_nonblock # should be called again after underlying IO is writable. # # So OpenSSL::Buffering#write_nonblock needs two rescue clause as follows. # # # emulates blocking write. # begin # result = ssl.write_nonblock(str) # rescue IO::WaitReadable # IO.select([io]) # retry # rescue IO::WaitWritable # IO.select(nil, [io]) # retry # end # # Note that one reason that write_nonblock reads from the underlying IO # is when the peer requests a new TLS/SSL handshake. See the openssl FAQ # for more details. http://www.openssl.org/support/faq.html def write_nonblock(s, exception: true) flush syswrite_nonblock(s, exception: exception) end ## # Writes +s+ to the stream. +s+ will be converted to a String using # String#to_s. def << (s) do_write(s) self end ## # Writes +args+ to the stream along with a record separator. # # See IO#puts for full details. def puts(*args) s = "" if args.empty? s << "\n" end args.each{|arg| s << arg.to_s if $/ && /\n\z/ !~ s s << "\n" end } do_write(s) nil end ## # Writes +args+ to the stream. # # See IO#print for full details. def print(*args) s = "" args.each{ |arg| s << arg.to_s } do_write(s) nil end ## # Formats and writes to the stream converting parameters under control of # the format string. # # See Kernel#sprintf for format string details. def printf(s, *args) do_write(s % args) nil end ## # Flushes buffered data to the SSLSocket. def flush osync = @sync @sync = true do_write "" return self ensure @sync = osync end ## # Closes the SSLSocket and flushes any unwritten data. def close flush rescue nil sysclose end end jruby-openssl-0.9.21/lib/jopenssl22/openssl/cipher.rb000066400000000000000000000010151313661621600224520ustar00rootroot00000000000000#-- # # $RCSfile$ # # = Ruby-space predefined Cipher subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # # = Version # $Id$ # #++ module OpenSSL class Cipher # This class is only provided for backwards compatibility. Use OpenSSL::Cipher in the future. class Cipher < Cipher # add warning end end # Cipher end # OpenSSLjruby-openssl-0.9.21/lib/jopenssl22/openssl/config.rb000066400000000000000000000163711313661621600224600ustar00rootroot00000000000000=begin = Ruby-space definitions that completes C-space funcs for Config = Info Copyright (C) 2010 Hiroshi Nakamura = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) =end require 'stringio' module OpenSSL class Config include Enumerable class << self def parse(str) c = new() parse_config(StringIO.new(str)).each do |section, hash| c[section] = hash end c end alias load new def parse_config(io) begin parse_config_lines(io) rescue ConfigError => e e.message.replace("error in line #{io.lineno}: " + e.message) raise end end def get_key_string(data, section, key) # :nodoc: if v = data[section] && data[section][key] return v elsif section == 'ENV' if v = ENV[key] return v end end if v = data['default'] && data['default'][key] return v end end private def parse_config_lines(io) section = 'default' data = {section => {}} while definition = get_definition(io) definition = clear_comments(definition) next if definition.empty? if definition[0] == ?[ if /\[([^\]]*)\]/ =~ definition section = $1.strip data[section] ||= {} else raise ConfigError, "missing close square bracket" end else if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition if $2 section = $1 key = $2 else key = $1 end value = unescape_value(data, section, $3) (data[section] ||= {})[key] = value.strip else raise ConfigError, "missing equal sign" end end end data end # escape with backslash QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/ # escape with backslash and doubled dq QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/ # escaped char map ESCAPE_MAP = { "r" => "\r", "n" => "\n", "b" => "\b", "t" => "\t", } def unescape_value(data, section, value) scanned = [] while m = value.match(/['"\\$]/) scanned << m.pre_match c = m[0] value = m.post_match case c when "'" if m = value.match(QUOTE_REGEXP_SQ) scanned << m[1].gsub(/\\(.)/, '\\1') value = m.post_match else break end when '"' if m = value.match(QUOTE_REGEXP_DQ) scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1') value = m.post_match else break end when "\\" c = value.slice!(0, 1) scanned << (ESCAPE_MAP[c] || c) when "$" ref, value = extract_reference(value) refsec = section if ref.index('::') refsec, ref = ref.split('::', 2) end if v = get_key_string(data, refsec, ref) scanned << v else raise ConfigError, "variable has no value" end else raise 'must not reaced' end end scanned << value scanned.join end def extract_reference(value) rest = '' if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/) value = m[1] || m[2] rest = m.post_match elsif [?(, ?{].include?(value[0]) raise ConfigError, "no close brace" end if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/) return m[0], m.post_match + rest else raise end end def clear_comments(line) # FCOMMENT if m = line.match(/\A([\t\n\f ]*);.*\z/) return m[1] end # COMMENT scanned = [] while m = line.match(/[#'"\\]/) scanned << m.pre_match c = m[0] line = m.post_match case c when '#' line = nil break when "'", '"' regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ scanned << c if m = line.match(regexp) scanned << m[0] line = m.post_match else scanned << line line = nil break end when "\\" scanned << c scanned << line.slice!(0, 1) else raise 'must not reaced' end end scanned << line scanned.join end def get_definition(io) if line = get_line(io) while /[^\\]\\\z/ =~ line if extra = get_line(io) line += extra else break end end return line.strip end end def get_line(io) if line = io.gets line.gsub(/[\r\n]*/, '') end end end def initialize(filename = nil) @data = {} if filename File.open(filename.to_s) do |file| Config.parse_config(file).each do |section, hash| self[section] = hash end end end end def get_value(section, key) if section.nil? raise TypeError.new('nil not allowed') end section = 'default' if section.empty? get_key_string(section, key) end def value(arg1, arg2 = nil) warn('Config#value is deprecated; use Config#get_value') if arg2.nil? section, key = 'default', arg1 else section, key = arg1, arg2 end section ||= 'default' section = 'default' if section.empty? get_key_string(section, key) end def add_value(section, key, value) check_modify (@data[section] ||= {})[key] = value end def [](section) @data[section] || {} end def section(name) warn('Config#section is deprecated; use Config#[]') @data[name] || {} end def []=(section, pairs) check_modify @data[section] ||= {} pairs.each do |key, value| self.add_value(section, key, value) end end def sections @data.keys end def to_s ary = [] @data.keys.sort.each do |section| ary << "[ #{section} ]\n" @data[section].keys.each do |key| ary << "#{key}=#{@data[section][key]}\n" end ary << "\n" end ary.join end def each @data.each do |section, hash| hash.each do |key, value| yield [section, key, value] end end end def inspect "#<#{self.class.name} sections=#{sections.inspect}>" end protected def data @data end private def initialize_copy(other) @data = other.data.dup end def check_modify raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen? end def get_key_string(section, key) Config.get_key_string(@data, section, key) end end end jruby-openssl-0.9.21/lib/jopenssl22/openssl/digest.rb000066400000000000000000000017201313661621600224620ustar00rootroot00000000000000#-- # # $RCSfile$ # # = Ruby-space predefined Digest subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # # = Version # $Id$ # #++ module OpenSSL class Digest # Deprecated. # # This class is only provided for backwards compatibility. class Digest < Digest # :nodoc: # Deprecated. # # See OpenSSL::Digest.new def initialize(*args) warn('Digest::Digest is deprecated; use Digest') super(*args) end end end # Digest # Returns a Digest subclass by +name+. # # require 'openssl' # # OpenSSL::Digest("MD5") # # => OpenSSL::Digest::MD5 # # Digest("Foo") # # => NameError: wrong constant name Foo def Digest(name) OpenSSL::Digest.const_get(name) end module_function :Digest end # OpenSSL jruby-openssl-0.9.21/lib/jopenssl22/openssl/ssl.rb000066400000000000000000000247141313661621600220140ustar00rootroot00000000000000=begin = $RCSfile$ -- Ruby-space definitions that completes C-space funcs for SSL = Info 'OpenSSL for Ruby 2' project Copyright (C) 2001 GOTOU YUUZOU All rights reserved. = Licence This program is licenced under the same licence as Ruby. (See the file 'LICENCE'.) = Version $Id$ =end require "openssl/buffering" require "fcntl" module OpenSSL module SSL class SSLContext DEFAULT_PARAMS = { :ssl_version => "SSLv23", :verify_mode => OpenSSL::SSL::VERIFY_PEER, :ciphers => %w{ ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-DSS-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-DSS-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-DSS-AES128-SHA256 DHE-DSS-AES256-SHA256 DHE-DSS-AES128-SHA DHE-DSS-AES256-SHA AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-SHA256 AES256-SHA256 AES128-SHA AES256-SHA ECDHE-ECDSA-RC4-SHA ECDHE-RSA-RC4-SHA RC4-SHA }.join(":"), :options => -> { opts = OpenSSL::SSL::OP_ALL opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS) opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION) opts |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2) opts |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3) opts }.call } unless const_defined? :DEFAULT_PARAMS # JRuby does it in Java unless const_defined? :DEFAULT_CERT_STORE # JRuby specific DEFAULT_CERT_STORE = OpenSSL::X509::Store.new DEFAULT_CERT_STORE.set_default_paths if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL) DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL end end ## # Sets the parameters for this SSL context to the values in +params+. # The keys in +params+ must be assignment methods on SSLContext. # # If the verify_mode is not VERIFY_NONE and ca_file, ca_path and # cert_store are not set then the system default certificate store is # used. def set_params(params={}) params = DEFAULT_PARAMS.merge(params) params.each{|name, value| self.__send__("#{name}=", value) } if self.verify_mode != OpenSSL::SSL::VERIFY_NONE unless self.ca_file or self.ca_path or self.cert_store self.cert_store = DEFAULT_CERT_STORE end end return params end unless method_defined? :set_params # JRuby: hooked up in "native" Java end module SocketForwarder def addr to_io.addr end def peeraddr to_io.peeraddr end def setsockopt(level, optname, optval) to_io.setsockopt(level, optname, optval) end def getsockopt(level, optname) to_io.getsockopt(level, optname) end def fcntl(*args) to_io.fcntl(*args) end def closed? to_io.closed? end def do_not_reverse_lookup=(flag) to_io.do_not_reverse_lookup = flag end end unless const_defined? :SocketForwarder # JRuby: hooked up in "native" Java module Nonblock def initialize(*args) flag = File::NONBLOCK flag |= @io.fcntl(Fcntl::F_GETFL) if defined?(Fcntl::F_GETFL) @io.fcntl(Fcntl::F_SETFL, flag) super end end unless const_defined? :Nonblock # JRuby: hooked up in "native" Java def verify_certificate_identity(cert, hostname) should_verify_common_name = true cert.extensions.each { |ext| next if ext.oid != "subjectAltName" ext.value.split(/,\s+/).each { |general_name| #case san.tag # MRI 2.2.3 (JRuby parses ASN.1 differently) #when 2 # dNSName in GeneralName (RFC5280) if /\ADNS:(.*)/ =~ general_name should_verify_common_name = false return true if verify_hostname(hostname, $1) # MRI 2.2.3 (JRuby parses ASN.1 differently) #when 7 # iPAddress in GeneralName (RFC5280) elsif /\AIP(?: Address)?:(.*)/ =~ general_name should_verify_common_name = false return true if $1 == hostname # NOTE: bellow logic makes little sense JRuby reads exts differently # follows GENERAL_NAME_print() in x509v3/v3_alt.c #if san.value.size == 4 # return true if san.value.unpack('C*').join('.') == hostname #elsif san.value.size == 16 # return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname #end end } } if should_verify_common_name cert.subject.to_a.each{|oid, value| if oid == "CN" return true if verify_hostname(hostname, value) end } end return false end module_function :verify_certificate_identity def verify_hostname(hostname, san) # :nodoc: # RFC 5280, IA5String is limited to the set of ASCII characters return false unless san.ascii_only? return false unless hostname.ascii_only? # See RFC 6125, section 6.4.1 # Matching is case-insensitive. san_parts = san.downcase.split(".") # TODO: this behavior should probably be more strict return san == hostname if san_parts.size < 2 # Matching is case-insensitive. host_parts = hostname.downcase.split(".") # RFC 6125, section 6.4.3, subitem 2. # If the wildcard character is the only character of the left-most # label in the presented identifier, the client SHOULD NOT compare # against anything but the left-most label of the reference # identifier (e.g., *.example.com would match foo.example.com but # not bar.foo.example.com or example.com). return false unless san_parts.size == host_parts.size # RFC 6125, section 6.4.3, subitem 1. # The client SHOULD NOT attempt to match a presented identifier in # which the wildcard character comprises a label other than the # left-most label (e.g., do not match bar.*.example.net). return false unless verify_wildcard(host_parts.shift, san_parts.shift) san_parts.join(".") == host_parts.join(".") end module_function :verify_hostname def verify_wildcard(domain_component, san_component) # :nodoc: parts = san_component.split("*", -1) return false if parts.size > 2 return san_component == domain_component if parts.size == 1 # RFC 6125, section 6.4.3, subitem 3. # The client SHOULD NOT attempt to match a presented identifier # where the wildcard character is embedded within an A-label or # U-label of an internationalized domain name. return false if domain_component.start_with?("xn--") && san_component != "*" parts[0].length + parts[1].length < domain_component.length && domain_component.start_with?(parts[0]) && domain_component.end_with?(parts[1]) end module_function :verify_wildcard class SSLSocket include Buffering include SocketForwarder include Nonblock ## # Perform hostname verification after an SSL connection is established # # This method MUST be called after calling #connect to ensure that the # hostname of a remote peer has been verified. def post_connection_check(hostname) if peer_cert.nil? msg = "Peer verification enabled, but no certificate received." if using_anon_cipher? msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification." end raise SSLError, msg end unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) raise SSLError, "hostname \"#{hostname}\" does not match the server certificate" end return true end #def session # SSL::Session.new(self) #rescue SSL::Session::SessionError # nil #end private def using_anon_cipher? ctx = OpenSSL::SSL::SSLContext.new ctx.ciphers = "aNULL" ctx.ciphers.include?(cipher) end end ## # SSLServer represents a TCP/IP server socket with Secure Sockets Layer. class SSLServer include SocketForwarder # When true then #accept works exactly the same as TCPServer#accept attr_accessor :start_immediately # Creates a new instance of SSLServer. # * +srv+ is an instance of TCPServer. # * +ctx+ is an instance of OpenSSL::SSL::SSLContext. def initialize(svr, ctx) @svr = svr @ctx = ctx unless ctx.session_id_context # see #6137 - session id may not exceed 32 bytes prng = ::Random.new($0.hash) session_id = prng.bytes(16).unpack('H*')[0] @ctx.session_id_context = session_id end @start_immediately = true end # Returns the TCPServer passed to the SSLServer when initialized. def to_io @svr end # See TCPServer#listen for details. def listen(backlog=5) @svr.listen(backlog) end # See BasicSocket#shutdown for details. def shutdown(how=Socket::SHUT_RDWR) @svr.shutdown(how) end # Works similar to TCPServer#accept. def accept # Socket#accept returns [socket, addrinfo]. # TCPServer#accept returns a socket. # The following comma strips addrinfo. sock, = @svr.accept begin ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) ssl.sync_close = true ssl.accept if @start_immediately ssl rescue Exception => ex if ssl ssl.close else sock.close end raise ex end end # See IO#close for details. def close @svr.close end end end end jruby-openssl-0.9.21/lib/jopenssl22/openssl/x509.rb000066400000000000000000000076541313661621600217240ustar00rootroot00000000000000#-- # # $RCSfile$ # # = Ruby-space definitions that completes C-space funcs for X509 and subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licenced under the same licence as Ruby. # (See the file 'LICENCE'.) # # = Version # $Id$ # #++ module OpenSSL module X509 class Name module RFC2253DN Special = ',=+<>#;' HexChar = /[0-9a-fA-F]/ HexPair = /#{HexChar}#{HexChar}/ HexString = /#{HexPair}+/ Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/ StringChar = /[^\\"#{Special}]/ QuoteChar = /[^\\"]/ AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/ AttributeValue = / (?!["#])((?:#{StringChar}|#{Pair})*)| \#(#{HexString})| "((?:#{QuoteChar}|#{Pair})*)" /x TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/ module_function def expand_pair(str) return nil unless str return str.gsub(Pair){ pair = $& case pair.size when 2 then pair[1,1] when 3 then Integer("0x#{pair[1,2]}").chr else raise OpenSSL::X509::NameError, "invalid pair: #{str}" end } end def expand_hexstring(str) return nil unless str der = str.gsub(HexPair){$&.to_i(16).chr } a1 = OpenSSL::ASN1.decode(der) return a1.value, a1.tag end def expand_value(str1, str2, str3) value = expand_pair(str1) value, tag = expand_hexstring(str2) unless value value = expand_pair(str3) unless value return value, tag end def scan(dn) str = dn ary = [] while true if md = TypeAndValue.match(str) remain = md.post_match type = md[1] value, tag = expand_value(md[2], md[3], md[4]) rescue nil if value type_and_value = [type, value] type_and_value.push(tag) if tag ary.unshift(type_and_value) if remain.length > 2 && remain[0] == ?, str = remain[1..-1] next elsif remain.length > 2 && remain[0] == ?+ raise OpenSSL::X509::NameError, "multi-valued RDN is not supported: #{dn}" elsif remain.empty? break end end end msg_dn = dn[0, dn.length - str.length] + " =>" + str raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}" end return ary end end class << self def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE) ary = OpenSSL::X509::Name::RFC2253DN.scan(str) self.new(ary, template) end def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE) ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) } self.new(ary, template) end alias parse parse_openssl end def pretty_print(q) q.object_group(self) { q.text ' ' q.text to_s(OpenSSL::X509::Name::RFC2253) } end end class StoreContext def cleanup warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE end end class Certificate def pretty_print(q) q.object_group(self) { q.breakable q.text 'subject='; q.pp self.subject; q.text ','; q.breakable q.text 'issuer='; q.pp self.issuer; q.text ','; q.breakable q.text 'serial='; q.pp self.serial; q.text ','; q.breakable q.text 'not_before='; q.pp self.not_before; q.text ','; q.breakable q.text 'not_after='; q.pp self.not_after } end end end end jruby-openssl-0.9.21/lib/jopenssl23/000077500000000000000000000000001313661621600171745ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl23/openssl.rb000066400000000000000000000006471313661621600212130ustar00rootroot00000000000000# frozen_string_literal: false =begin = Info 'OpenSSL for Ruby 2' project Copyright (C) 2002 Michal Rokos All rights reserved. = Licence This program is licensed under the same licence as Ruby. (See the file 'LICENCE'.) =end require 'openssl/bn' require 'openssl/pkey' require 'openssl/cipher' require 'openssl/config' require 'openssl/digest' require 'openssl/x509' require 'openssl/ssl' jruby-openssl-0.9.21/lib/jopenssl23/openssl/000077500000000000000000000000001313661621600206575ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/jopenssl23/openssl/bn.rb000066400000000000000000000012461313661621600216060ustar00rootroot00000000000000# frozen_string_literal: false #-- # # = Ruby-space definitions that completes C-space funcs for BN # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licensed under the same licence as Ruby. # (See the file 'LICENCE'.) #++ module OpenSSL class BN def pretty_print(q) q.object_group(self) { q.text ' ' q.text to_i.to_s } end end # BN end # OpenSSL ## # Add double dispatch to Integer # class Integer # Casts an Integer as an OpenSSL::BN # # See `man bn` for more info. def to_bn OpenSSL::BN::new(self) end end # Integer jruby-openssl-0.9.21/lib/jopenssl23/openssl/buffering.rb000066400000000000000000000225201313661621600231540ustar00rootroot00000000000000# coding: binary # frozen_string_literal: false #-- #= Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2001 GOTOU YUUZOU # All rights reserved. # #= Licence # This program is licensed under the same licence as Ruby. # (See the file 'LICENCE'.) #++ ## # OpenSSL IO buffering mix-in module. # # This module allows an OpenSSL::SSL::SSLSocket to behave like an IO. # # You typically won't use this module directly, you can see it implemented in # OpenSSL::SSL::SSLSocket. module OpenSSL::Buffering include Enumerable ## # The "sync mode" of the SSLSocket. # # See IO#sync for full details. attr_accessor :sync ## # Default size to read from or write to the SSLSocket for buffer operations. BLOCK_SIZE = 1024*16 ## # Creates an instance of OpenSSL's buffering IO module. def initialize(*) # super @eof = false @rbuffer = "" @sync = @io.sync end # # for reading. # private ## # Fills the buffer from the underlying SSLSocket def fill_rbuff begin @rbuffer << self.sysread(BLOCK_SIZE) rescue Errno::EAGAIN retry rescue EOFError @eof = true end end ## # Consumes +size+ bytes from the buffer def consume_rbuff(size=nil) if @rbuffer.empty? nil else size = @rbuffer.size unless size ret = @rbuffer[0, size] @rbuffer[0, size] = "" ret end end public ## # Reads +size+ bytes from the stream. If +buf+ is provided it must # reference a string which will receive the data. # # See IO#read for full details. def read(size=nil, buf=nil) if size == 0 if buf buf.clear return buf else return "" end end until @eof break if size && size <= @rbuffer.size fill_rbuff end ret = consume_rbuff(size) || "" if buf buf.replace(ret) ret = buf end (size && ret.empty?) ? nil : ret end ## # Reads at most +maxlen+ bytes from the stream. If +buf+ is provided it # must reference a string which will receive the data. # # See IO#readpartial for full details. def readpartial(maxlen, buf=nil) if maxlen == 0 if buf buf.clear return buf else return "" end end if @rbuffer.empty? begin return sysread(maxlen, buf) rescue Errno::EAGAIN retry end end ret = consume_rbuff(maxlen) if buf buf.replace(ret) ret = buf end ret end ## # Reads at most +maxlen+ bytes in the non-blocking manner. # # When no data can be read without blocking it raises # OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable. # # IO::WaitReadable means SSL needs to read internally so read_nonblock # should be called again when the underlying IO is readable. # # IO::WaitWritable means SSL needs to write internally so read_nonblock # should be called again after the underlying IO is writable. # # OpenSSL::Buffering#read_nonblock needs two rescue clause as follows: # # # emulates blocking read (readpartial). # begin # result = ssl.read_nonblock(maxlen) # rescue IO::WaitReadable # IO.select([io]) # retry # rescue IO::WaitWritable # IO.select(nil, [io]) # retry # end # # Note that one reason that read_nonblock writes to the underlying IO is # when the peer requests a new TLS/SSL handshake. See openssl the FAQ for # more details. http://www.openssl.org/support/faq.html def read_nonblock(maxlen, buf=nil, exception: true) if maxlen == 0 if buf buf.clear return buf else return "" end end if @rbuffer.empty? return sysread_nonblock(maxlen, buf, exception: exception) end ret = consume_rbuff(maxlen) if buf buf.replace(ret) ret = buf end ret end ## # Reads the next "line+ from the stream. Lines are separated by +eol+. If # +limit+ is provided the result will not be longer than the given number of # bytes. # # +eol+ may be a String or Regexp. # # Unlike IO#gets the line read will not be assigned to +$_+. # # Unlike IO#gets the separator must be provided if a limit is provided. def gets(eol=$/, limit=nil) idx = @rbuffer.index(eol) until @eof break if idx fill_rbuff idx = @rbuffer.index(eol) end if eol.is_a?(Regexp) size = idx ? idx+$&.size : nil else size = idx ? idx+eol.size : nil end if size && limit && limit >= 0 size = [size, limit].min end consume_rbuff(size) end ## # Executes the block for every line in the stream where lines are separated # by +eol+. # # See also #gets def each(eol=$/) while line = self.gets(eol) yield line end end alias each_line each ## # Reads lines from the stream which are separated by +eol+. # # See also #gets def readlines(eol=$/) ary = [] while line = self.gets(eol) ary << line end ary end ## # Reads a line from the stream which is separated by +eol+. # # Raises EOFError if at end of file. def readline(eol=$/) raise EOFError if eof? gets(eol) end ## # Reads one character from the stream. Returns nil if called at end of # file. def getc read(1) end ## # Calls the given block once for each byte in the stream. def each_byte # :yields: byte while c = getc yield(c.ord) end end ## # Reads a one-character string from the stream. Raises an EOFError at end # of file. def readchar raise EOFError if eof? getc end ## # Pushes character +c+ back onto the stream such that a subsequent buffered # character read will return it. # # Unlike IO#getc multiple bytes may be pushed back onto the stream. # # Has no effect on unbuffered reads (such as #sysread). def ungetc(c) @rbuffer[0,0] = c.chr end ## # Returns true if the stream is at file which means there is no more data to # be read. def eof? fill_rbuff if !@eof && @rbuffer.empty? @eof && @rbuffer.empty? end alias eof eof? # # for writing. # private ## # Writes +s+ to the buffer. When the buffer is full or #sync is true the # buffer is flushed to the underlying socket. def do_write(s) @wbuffer = "" unless defined? @wbuffer @wbuffer << s @wbuffer.force_encoding(Encoding::BINARY) @sync ||= false if @sync or @wbuffer.size > BLOCK_SIZE or idx = @wbuffer.rindex($/) remain = idx ? idx + $/.size : @wbuffer.length nwritten = 0 while remain > 0 str = @wbuffer[nwritten,remain] begin nwrote = syswrite(str) rescue Errno::EAGAIN retry end remain -= nwrote nwritten += nwrote end @wbuffer[0,nwritten] = "" end end public ## # Writes +s+ to the stream. If the argument is not a string it will be # converted using String#to_s. Returns the number of bytes written. def write(s) do_write(s) s.bytesize end ## # Writes +str+ in the non-blocking manner. # # If there is buffered data, it is flushed first. This may block. # # write_nonblock returns number of bytes written to the SSL connection. # # When no data can be written without blocking it raises # OpenSSL::SSL::SSLError extended by IO::WaitReadable or IO::WaitWritable. # # IO::WaitReadable means SSL needs to read internally so write_nonblock # should be called again after the underlying IO is readable. # # IO::WaitWritable means SSL needs to write internally so write_nonblock # should be called again after underlying IO is writable. # # So OpenSSL::Buffering#write_nonblock needs two rescue clause as follows. # # # emulates blocking write. # begin # result = ssl.write_nonblock(str) # rescue IO::WaitReadable # IO.select([io]) # retry # rescue IO::WaitWritable # IO.select(nil, [io]) # retry # end # # Note that one reason that write_nonblock reads from the underlying IO # is when the peer requests a new TLS/SSL handshake. See the openssl FAQ # for more details. http://www.openssl.org/support/faq.html def write_nonblock(s, exception: true) flush syswrite_nonblock(s, exception: exception) end ## # Writes +s+ to the stream. +s+ will be converted to a String using # String#to_s. def << (s) do_write(s) self end ## # Writes +args+ to the stream along with a record separator. # # See IO#puts for full details. def puts(*args) s = "" if args.empty? s << "\n" end args.each{|arg| s << arg.to_s if $/ && /\n\z/ !~ s s << "\n" end } do_write(s) nil end ## # Writes +args+ to the stream. # # See IO#print for full details. def print(*args) s = "" args.each{ |arg| s << arg.to_s } do_write(s) nil end ## # Formats and writes to the stream converting parameters under control of # the format string. # # See Kernel#sprintf for format string details. def printf(s, *args) do_write(s % args) nil end ## # Flushes buffered data to the SSLSocket. def flush osync = @sync @sync = true do_write "" return self ensure @sync = osync end ## # Closes the SSLSocket and flushes any unwritten data. def close flush rescue nil sysclose end end jruby-openssl-0.9.21/lib/jopenssl23/openssl/cipher.rb000066400000000000000000000010361313661621600224560ustar00rootroot00000000000000# frozen_string_literal: false #-- # = Ruby-space predefined Cipher subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licensed under the same licence as Ruby. # (See the file 'LICENCE'.) #++ module OpenSSL class Cipher # Deprecated. # # This class is only provided for backwards compatibility. # Use OpenSSL::Cipher. class Cipher < Cipher; end deprecate_constant :Cipher end # Cipher end # OpenSSL jruby-openssl-0.9.21/lib/jopenssl23/openssl/config.rb000066400000000000000000000277421313661621600224650ustar00rootroot00000000000000# frozen_string_literal: false =begin = Ruby-space definitions that completes C-space funcs for Config = Info Copyright (C) 2010 Hiroshi Nakamura = Licence This program is licensed under the same licence as Ruby. (See the file 'LICENCE'.) =end require 'stringio' module OpenSSL ## # = OpenSSL::Config # # Configuration for the openssl library. # # Many system's installation of openssl library will depend on your system # configuration. See the value of OpenSSL::Config::DEFAULT_CONFIG_FILE for # the location of the file for your host. # # See also http://www.openssl.org/docs/apps/config.html class Config include Enumerable class << self ## # Parses a given +string+ as a blob that contains configuration for openssl. # # If the source of the IO is a file, then consider using #parse_config. def parse(string) c = new() parse_config(StringIO.new(string)).each do |section, hash| c[section] = hash end c end ## # load is an alias to ::new alias load new ## # Parses the configuration data read from +io+, see also #parse. # # Raises a ConfigError on invalid configuration data. def parse_config(io) begin parse_config_lines(io) rescue ConfigError => e e.message.replace("error in line #{io.lineno}: " + e.message) raise end end def get_key_string(data, section, key) # :nodoc: if v = data[section] && data[section][key] return v elsif section == 'ENV' if v = ENV[key] return v end end if v = data['default'] && data['default'][key] return v end end private def parse_config_lines(io) section = 'default' data = {section => {}} while definition = get_definition(io) definition = clear_comments(definition) next if definition.empty? if definition[0] == ?[ if /\[([^\]]*)\]/ =~ definition section = $1.strip data[section] ||= {} else raise ConfigError, "missing close square bracket" end else if /\A([^:\s]*)(?:::([^:\s]*))?\s*=(.*)\z/ =~ definition if $2 section = $1 key = $2 else key = $1 end value = unescape_value(data, section, $3) (data[section] ||= {})[key] = value.strip else raise ConfigError, "missing equal sign" end end end data end # escape with backslash QUOTE_REGEXP_SQ = /\A([^'\\]*(?:\\.[^'\\]*)*)'/ # escape with backslash and doubled dq QUOTE_REGEXP_DQ = /\A([^"\\]*(?:""[^"\\]*|\\.[^"\\]*)*)"/ # escaped char map ESCAPE_MAP = { "r" => "\r", "n" => "\n", "b" => "\b", "t" => "\t", } def unescape_value(data, section, value) scanned = [] while m = value.match(/['"\\$]/) scanned << m.pre_match c = m[0] value = m.post_match case c when "'" if m = value.match(QUOTE_REGEXP_SQ) scanned << m[1].gsub(/\\(.)/, '\\1') value = m.post_match else break end when '"' if m = value.match(QUOTE_REGEXP_DQ) scanned << m[1].gsub(/""/, '').gsub(/\\(.)/, '\\1') value = m.post_match else break end when "\\" c = value.slice!(0, 1) scanned << (ESCAPE_MAP[c] || c) when "$" ref, value = extract_reference(value) refsec = section if ref.index('::') refsec, ref = ref.split('::', 2) end if v = get_key_string(data, refsec, ref) scanned << v else raise ConfigError, "variable has no value" end else raise 'must not reaced' end end scanned << value scanned.join end def extract_reference(value) rest = '' if m = value.match(/\(([^)]*)\)|\{([^}]*)\}/) value = m[1] || m[2] rest = m.post_match elsif [?(, ?{].include?(value[0]) raise ConfigError, "no close brace" end if m = value.match(/[a-zA-Z0-9_]*(?:::[a-zA-Z0-9_]*)?/) return m[0], m.post_match + rest else raise end end def clear_comments(line) # FCOMMENT if m = line.match(/\A([\t\n\f ]*);.*\z/) return m[1] end # COMMENT scanned = [] while m = line.match(/[#'"\\]/) scanned << m.pre_match c = m[0] line = m.post_match case c when '#' line = nil break when "'", '"' regexp = (c == "'") ? QUOTE_REGEXP_SQ : QUOTE_REGEXP_DQ scanned << c if m = line.match(regexp) scanned << m[0] line = m.post_match else scanned << line line = nil break end when "\\" scanned << c scanned << line.slice!(0, 1) else raise 'must not reaced' end end scanned << line scanned.join end def get_definition(io) if line = get_line(io) while /[^\\]\\\z/ =~ line if extra = get_line(io) line += extra else break end end return line.strip end end def get_line(io) if line = io.gets line.gsub(/[\r\n]*/, '') end end end ## # Creates an instance of OpenSSL's configuration class. # # This can be used in contexts like OpenSSL::X509::ExtensionFactory.config= # # If the optional +filename+ parameter is provided, then it is read in and # parsed via #parse_config. # # This can raise IO exceptions based on the access, or availability of the # file. A ConfigError exception may be raised depending on the validity of # the data being configured. # def initialize(filename = nil) @data = {} if filename File.open(filename.to_s) do |file| Config.parse_config(file).each do |section, hash| self[section] = hash end end end end ## # Gets the value of +key+ from the given +section+ # # Given the following configurating file being loaded: # # config = OpenSSL::Config.load('foo.cnf') # #=> # # puts config.to_s # #=> [ default ] # # foo=bar # # You can get a specific value from the config if you know the +section+ # and +key+ like so: # # config.get_value('default','foo') # #=> "bar" # def get_value(section, key) if section.nil? raise TypeError.new('nil not allowed') end section = 'default' if section.empty? get_key_string(section, key) end ## # # *Deprecated* # # Use #get_value instead def value(arg1, arg2 = nil) # :nodoc: warn('Config#value is deprecated; use Config#get_value') if arg2.nil? section, key = 'default', arg1 else section, key = arg1, arg2 end section ||= 'default' section = 'default' if section.empty? get_key_string(section, key) end ## # Set the target +key+ with a given +value+ under a specific +section+. # # Given the following configurating file being loaded: # # config = OpenSSL::Config.load('foo.cnf') # #=> # # puts config.to_s # #=> [ default ] # # foo=bar # # You can set the value of +foo+ under the +default+ section to a new # value: # # config.add_value('default', 'foo', 'buzz') # #=> "buzz" # puts config.to_s # #=> [ default ] # # foo=buzz # def add_value(section, key, value) check_modify (@data[section] ||= {})[key] = value end ## # Get a specific +section+ from the current configuration # # Given the following configurating file being loaded: # # config = OpenSSL::Config.load('foo.cnf') # #=> # # puts config.to_s # #=> [ default ] # # foo=bar # # You can get a hash of the specific section like so: # # config['default'] # #=> {"foo"=>"bar"} # def [](section) @data[section] || {} end ## # Deprecated # # Use #[] instead def section(name) # :nodoc: warn('Config#section is deprecated; use Config#[]') @data[name] || {} end ## # Sets a specific +section+ name with a Hash +pairs+ # # Given the following configuration being created: # # config = OpenSSL::Config.new # #=> # # config['default'] = {"foo"=>"bar","baz"=>"buz"} # #=> {"foo"=>"bar", "baz"=>"buz"} # puts config.to_s # #=> [ default ] # # foo=bar # # baz=buz # # It's important to note that this will essentially merge any of the keys # in +pairs+ with the existing +section+. For example: # # config['default'] # #=> {"foo"=>"bar", "baz"=>"buz"} # config['default'] = {"foo" => "changed"} # #=> {"foo"=>"changed"} # config['default'] # #=> {"foo"=>"changed", "baz"=>"buz"} # def []=(section, pairs) check_modify @data[section] ||= {} pairs.each do |key, value| self.add_value(section, key, value) end end ## # Get the names of all sections in the current configuration def sections @data.keys end ## # Get the parsable form of the current configuration # # Given the following configuration being created: # # config = OpenSSL::Config.new # #=> # # config['default'] = {"foo"=>"bar","baz"=>"buz"} # #=> {"foo"=>"bar", "baz"=>"buz"} # puts config.to_s # #=> [ default ] # # foo=bar # # baz=buz # # You can parse get the serialized configuration using #to_s and then parse # it later: # # serialized_config = config.to_s # # much later... # new_config = OpenSSL::Config.parse(serialized_config) # #=> # # puts new_config # #=> [ default ] # foo=bar # baz=buz # def to_s ary = [] @data.keys.sort.each do |section| ary << "[ #{section} ]\n" @data[section].keys.each do |key| ary << "#{key}=#{@data[section][key]}\n" end ary << "\n" end ary.join end ## # For a block. # # Receive the section and its pairs for the current configuration. # # config.each do |section, key, value| # # ... # end # def each @data.each do |section, hash| hash.each do |key, value| yield [section, key, value] end end end ## # String representation of this configuration object, including the class # name and its sections. def inspect "#<#{self.class.name} sections=#{sections.inspect}>" end protected def data # :nodoc: @data end private def initialize_copy(other) @data = other.data.dup end def check_modify raise TypeError.new("Insecure: can't modify OpenSSL config") if frozen? end def get_key_string(section, key) Config.get_key_string(@data, section, key) end end end jruby-openssl-0.9.21/lib/jopenssl23/openssl/digest.rb000066400000000000000000000015301313661621600224620ustar00rootroot00000000000000# frozen_string_literal: false #-- # = Ruby-space predefined Digest subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licensed under the same licence as Ruby. # (See the file 'LICENCE'.) #++ module OpenSSL class Digest # Deprecated. # # This class is only provided for backwards compatibility. # Use OpenSSL::Digest instead. class Digest < Digest; end # :nodoc: deprecate_constant :Digest end # Digest # Returns a Digest subclass by +name+. # # require 'openssl' # # OpenSSL::Digest("MD5") # # => OpenSSL::Digest::MD5 # # Digest("Foo") # # => NameError: wrong constant name Foo def Digest(name) OpenSSL::Digest.const_get(name) end module_function :Digest end # OpenSSL jruby-openssl-0.9.21/lib/jopenssl23/openssl/pkey.rb000066400000000000000000000017261313661621600221620ustar00rootroot00000000000000# frozen_string_literal: false module OpenSSL module PKey if defined?(OpenSSL::PKey::DH) class DH DEFAULT_512 = new <<-_end_of_pem_ -----BEGIN DH PARAMETERS----- MEYCQQD0zXHljRg/mJ9PYLACLv58Cd8VxBxxY7oEuCeURMiTqEhMym16rhhKgZG2 zk2O9uUIBIxSj+NKMURHGaFKyIvLAgEC -----END DH PARAMETERS----- _end_of_pem_ DEFAULT_1024 = new <<-_end_of_pem_ -----BEGIN DH PARAMETERS----- MIGHAoGBAJ0lOVy0VIr/JebWn0zDwY2h+rqITFOpdNr6ugsgvkDXuucdcChhYExJ AV/ZD2AWPbrTqV76mGRgJg4EddgT1zG0jq3rnFdMj2XzkBYx3BVvfR0Arnby0RHR T4h7KZ/2zmjvV+eF8kBUHBJAojUlzxKj4QeO2x20FP9X5xmNUXeDAgEC -----END DH PARAMETERS----- _end_of_pem_ end DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| warn "using default DH parameters." if $VERBOSE case keylen when 512 then OpenSSL::PKey::DH::DEFAULT_512 when 1024 then OpenSSL::PKey::DH::DEFAULT_1024 else nil end } else DEFAULT_TMP_DH_CALLBACK = nil end end endjruby-openssl-0.9.21/lib/jopenssl23/openssl/ssl.rb000066400000000000000000000332061313661621600220110ustar00rootroot00000000000000# frozen_string_literal: false =begin = Info 'OpenSSL for Ruby 2' project Copyright (C) 2001 GOTOU YUUZOU All rights reserved. = Licence This program is licensed under the same licence as Ruby. (See the file 'LICENCE'.) =end require "openssl/buffering" require "io/nonblock" module OpenSSL module SSL class SSLContext DEFAULT_PARAMS = { :ssl_version => "SSLv23", :verify_mode => OpenSSL::SSL::VERIFY_PEER, :ciphers => %w{ ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES128-GCM-SHA256 DHE-DSS-AES128-GCM-SHA256 DHE-RSA-AES256-GCM-SHA384 DHE-DSS-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES128-SHA ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-AES128-SHA256 DHE-RSA-AES256-SHA256 DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DHE-DSS-AES128-SHA256 DHE-DSS-AES256-SHA256 DHE-DSS-AES128-SHA DHE-DSS-AES256-SHA AES128-GCM-SHA256 AES256-GCM-SHA384 AES128-SHA256 AES256-SHA256 AES128-SHA AES256-SHA ECDHE-ECDSA-RC4-SHA ECDHE-RSA-RC4-SHA RC4-SHA }.join(":"), :options => -> { opts = OpenSSL::SSL::OP_ALL opts &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS) opts |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION) opts |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2) opts |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3) opts }.call } unless const_defined? :DEFAULT_PARAMS # JRuby does it in Java unless const_defined? :DEFAULT_CERT_STORE # JRuby specific DEFAULT_CERT_STORE = OpenSSL::X509::Store.new DEFAULT_CERT_STORE.set_default_paths if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL) DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL end end INIT_VARS = ["cert", "key", "client_ca", "ca_file", "ca_path", "timeout", "verify_mode", "verify_depth", "renegotiation_cb", "verify_callback", "cert_store", "extra_chain_cert", "client_cert_cb", "session_id_context", "tmp_dh_callback", "session_get_cb", "session_new_cb", "session_remove_cb", "tmp_ecdh_callback", "servername_cb", "npn_protocols", "alpn_protocols", "alpn_select_cb", "npn_select_cb"].map { |x| "@#{x}" } # A callback invoked when DH parameters are required. # # The callback is invoked with the Session for the key exchange, an # flag indicating the use of an export cipher and the keylength # required. # # The callback must return an OpenSSL::PKey::DH instance of the correct # key length. attr_accessor :tmp_dh_callback #if ExtConfig::HAVE_TLSEXT_HOST_NAME # A callback invoked at connect time to distinguish between multiple # server names. # # The callback is invoked with an SSLSocket and a server name. The # callback must return an SSLContext for the server name or nil. attr_accessor :servername_cb #end # call-seq: # SSLContext.new => ctx # SSLContext.new(:TLSv1) => ctx # SSLContext.new("SSLv23_client") => ctx # # You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS def initialize(version = nil) self.options |= OpenSSL::SSL::OP_ALL self.ssl_version = version if version end unless defined? JRUBY_VERSION # JRuby: handled in "native" Java ## # Sets the parameters for this SSL context to the values in +params+. # The keys in +params+ must be assignment methods on SSLContext. # # If the verify_mode is not VERIFY_NONE and ca_file, ca_path and # cert_store are not set then the system default certificate store is # used. def set_params(params={}) params = DEFAULT_PARAMS.merge(params) params.each{|name, value| self.__send__("#{name}=", value) } if self.verify_mode != OpenSSL::SSL::VERIFY_NONE unless self.ca_file or self.ca_path or self.cert_store self.cert_store = DEFAULT_CERT_STORE end end return params end unless method_defined? :set_params # JRuby: hooked up in "native" Java end module SocketForwarder def addr to_io.addr end def peeraddr to_io.peeraddr end def setsockopt(level, optname, optval) to_io.setsockopt(level, optname, optval) end def getsockopt(level, optname) to_io.getsockopt(level, optname) end def fcntl(*args) to_io.fcntl(*args) end def closed? to_io.closed? end def do_not_reverse_lookup=(flag) to_io.do_not_reverse_lookup = flag end end unless const_defined? :SocketForwarder # JRuby: hooked up in "native" Java def verify_certificate_identity(cert, hostname) should_verify_common_name = true cert.extensions.each{|ext| next if ext.oid != "subjectAltName" ext.value.split(/,\s+/).each { |general_name| #case san.tag # MRI 2.2.3 (JRuby parses ASN.1 differently) #when 2 # dNSName in GeneralName (RFC5280) if /\ADNS:(.*)/ =~ general_name should_verify_common_name = false return true if verify_hostname(hostname, $1) # MRI 2.2.3 (JRuby parses ASN.1 differently) #when 7 # iPAddress in GeneralName (RFC5280) elsif /\AIP(?: Address)?:(.*)/ =~ general_name should_verify_common_name = false return true if $1 == hostname # NOTE: bellow logic makes little sense JRuby reads exts differently # follows GENERAL_NAME_print() in x509v3/v3_alt.c #if san.value.size == 4 # return true if san.value.unpack('C*').join('.') == hostname #elsif san.value.size == 16 # return true if san.value.unpack('n*').map { |e| sprintf("%X", e) }.join(':') == hostname #end end } } if should_verify_common_name cert.subject.to_a.each{|oid, value| if oid == "CN" return true if verify_hostname(hostname, value) end } end return false end module_function :verify_certificate_identity def verify_hostname(hostname, san) # :nodoc: # RFC 5280, IA5String is limited to the set of ASCII characters return false unless san.ascii_only? return false unless hostname.ascii_only? # See RFC 6125, section 6.4.1 # Matching is case-insensitive. san_parts = san.downcase.split(".") # TODO: this behavior should probably be more strict return san == hostname if san_parts.size < 2 # Matching is case-insensitive. host_parts = hostname.downcase.split(".") # RFC 6125, section 6.4.3, subitem 2. # If the wildcard character is the only character of the left-most # label in the presented identifier, the client SHOULD NOT compare # against anything but the left-most label of the reference # identifier (e.g., *.example.com would match foo.example.com but # not bar.foo.example.com or example.com). return false unless san_parts.size == host_parts.size # RFC 6125, section 6.4.3, subitem 1. # The client SHOULD NOT attempt to match a presented identifier in # which the wildcard character comprises a label other than the # left-most label (e.g., do not match bar.*.example.net). return false unless verify_wildcard(host_parts.shift, san_parts.shift) san_parts.join(".") == host_parts.join(".") end module_function :verify_hostname def verify_wildcard(domain_component, san_component) # :nodoc: parts = san_component.split("*", -1) return false if parts.size > 2 return san_component == domain_component if parts.size == 1 # RFC 6125, section 6.4.3, subitem 3. # The client SHOULD NOT attempt to match a presented identifier # where the wildcard character is embedded within an A-label or # U-label of an internationalized domain name. return false if domain_component.start_with?("xn--") && san_component != "*" parts[0].length + parts[1].length < domain_component.length && domain_component.start_with?(parts[0]) && domain_component.end_with?(parts[1]) end module_function :verify_wildcard class SSLSocket include Buffering include SocketForwarder if ExtConfig::OPENSSL_NO_SOCK def initialize(io, ctx = nil); raise NotImplementedError; end else if ExtConfig::HAVE_TLSEXT_HOST_NAME attr_accessor :hostname end attr_reader :io, :context attr_accessor :sync_close alias :to_io :io # call-seq: # SSLSocket.new(io) => aSSLSocket # SSLSocket.new(io, ctx) => aSSLSocket # # Creates a new SSL socket from +io+ which must be a real ruby object (not an # IO-like object that responds to read/write). # # If +ctx+ is provided the SSL Sockets initial params will be taken from # the context. # # The OpenSSL::Buffering module provides additional IO methods. # # This method will freeze the SSLContext if one is provided; # however, session management is still allowed in the frozen SSLContext. def initialize(io, context = OpenSSL::SSL::SSLContext.new) @io = io @context = context @sync_close = false @hostname = nil @io.nonblock = true if @io.respond_to?(:nonblock=) context.setup super() end end unless defined? JRUBY_VERSION # JRuby: handled in "native" Java # call-seq: # ssl.sysclose => nil # # Shuts down the SSL connection and prepares it for another connection. def sysclose return if closed? stop io.close if sync_close end unless defined? JRUBY_VERSION # JRuby: handled in "native" Java ## # Perform hostname verification after an SSL connection is established # # This method MUST be called after calling #connect to ensure that the # hostname of a remote peer has been verified. def post_connection_check(hostname) if peer_cert.nil? msg = "Peer verification enabled, but no certificate received." if using_anon_cipher? msg += " Anonymous cipher suite #{cipher[0]} was negotiated. Anonymous suites must be disabled to use peer verification." end raise SSLError, msg end unless OpenSSL::SSL.verify_certificate_identity(peer_cert, hostname) raise SSLError, "hostname \"#{hostname}\" does not match the server certificate" end return true end #def session # SSL::Session.new(self) #rescue SSL::Session::SessionError # nil #end private def using_anon_cipher? ctx = OpenSSL::SSL::SSLContext.new ctx.ciphers = "aNULL" ctx.ciphers.include?(cipher) end def client_cert_cb @context.client_cert_cb end def tmp_dh_callback @context.tmp_dh_callback || OpenSSL::PKey::DEFAULT_TMP_DH_CALLBACK end def tmp_ecdh_callback @context.tmp_ecdh_callback end def session_new_cb @context.session_new_cb end def session_get_cb @context.session_get_cb end end ## # SSLServer represents a TCP/IP server socket with Secure Sockets Layer. class SSLServer include SocketForwarder # When true then #accept works exactly the same as TCPServer#accept attr_accessor :start_immediately # Creates a new instance of SSLServer. # * +srv+ is an instance of TCPServer. # * +ctx+ is an instance of OpenSSL::SSL::SSLContext. def initialize(svr, ctx) @svr = svr @ctx = ctx unless ctx.session_id_context # see #6137 - session id may not exceed 32 bytes prng = ::Random.new($0.hash) session_id = prng.bytes(16).unpack('H*')[0] @ctx.session_id_context = session_id end @start_immediately = true end # Returns the TCPServer passed to the SSLServer when initialized. def to_io @svr end # See TCPServer#listen for details. def listen(backlog=5) @svr.listen(backlog) end # See BasicSocket#shutdown for details. def shutdown(how=Socket::SHUT_RDWR) @svr.shutdown(how) end # Works similar to TCPServer#accept. def accept # Socket#accept returns [socket, addrinfo]. # TCPServer#accept returns a socket. # The following comma strips addrinfo. sock, = @svr.accept begin ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx) ssl.sync_close = true ssl.accept if @start_immediately ssl rescue Exception => ex if ssl ssl.close else sock.close end raise ex end end # See IO#close for details. def close @svr.close end end end end jruby-openssl-0.9.21/lib/jopenssl23/openssl/x509.rb000066400000000000000000000076441313661621600217240ustar00rootroot00000000000000# frozen_string_literal: false #-- # = Ruby-space definitions that completes C-space funcs for X509 and subclasses # # = Info # 'OpenSSL for Ruby 2' project # Copyright (C) 2002 Michal Rokos # All rights reserved. # # = Licence # This program is licensed under the same licence as Ruby. # (See the file 'LICENCE'.) #++ module OpenSSL module X509 class Name module RFC2253DN Special = ',=+<>#;' HexChar = /[0-9a-fA-F]/ HexPair = /#{HexChar}#{HexChar}/ HexString = /#{HexPair}+/ Pair = /\\(?:[#{Special}]|\\|"|#{HexPair})/ StringChar = /[^\\"#{Special}]/ QuoteChar = /[^\\"]/ AttributeType = /[a-zA-Z][0-9a-zA-Z]*|[0-9]+(?:\.[0-9]+)*/ AttributeValue = / (?!["#])((?:#{StringChar}|#{Pair})*)| \#(#{HexString})| "((?:#{QuoteChar}|#{Pair})*)" /x TypeAndValue = /\A(#{AttributeType})=#{AttributeValue}/ module_function def expand_pair(str) return nil unless str return str.gsub(Pair){ pair = $& case pair.size when 2 then pair[1,1] when 3 then Integer("0x#{pair[1,2]}").chr else raise OpenSSL::X509::NameError, "invalid pair: #{str}" end } end def expand_hexstring(str) return nil unless str der = str.gsub(HexPair){$&.to_i(16).chr } a1 = OpenSSL::ASN1.decode(der) return a1.value, a1.tag end def expand_value(str1, str2, str3) value = expand_pair(str1) value, tag = expand_hexstring(str2) unless value value = expand_pair(str3) unless value return value, tag end def scan(dn) str = dn ary = [] while true if md = TypeAndValue.match(str) remain = md.post_match type = md[1] value, tag = expand_value(md[2], md[3], md[4]) rescue nil if value type_and_value = [type, value] type_and_value.push(tag) if tag ary.unshift(type_and_value) if remain.length > 2 && remain[0] == ?, str = remain[1..-1] next elsif remain.length > 2 && remain[0] == ?+ raise OpenSSL::X509::NameError, "multi-valued RDN is not supported: #{dn}" elsif remain.empty? break end end end msg_dn = dn[0, dn.length - str.length] + " =>" + str raise OpenSSL::X509::NameError, "malformed RDN: #{msg_dn}" end return ary end end class << self def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE) ary = OpenSSL::X509::Name::RFC2253DN.scan(str) self.new(ary, template) end def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE) ary = str.scan(/\s*([^\/,]+)\s*/).collect{|i| i[0].split("=", 2) } self.new(ary, template) end alias parse parse_openssl end def pretty_print(q) q.object_group(self) { q.text ' ' q.text to_s(OpenSSL::X509::Name::RFC2253) } end end class StoreContext def cleanup warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE end end class Certificate def pretty_print(q) q.object_group(self) { q.breakable q.text 'subject='; q.pp self.subject; q.text ','; q.breakable q.text 'issuer='; q.pp self.issuer; q.text ','; q.breakable q.text 'serial='; q.pp self.serial; q.text ','; q.breakable q.text 'not_before='; q.pp self.not_before; q.text ','; q.breakable q.text 'not_after='; q.pp self.not_after } end end end end jruby-openssl-0.9.21/lib/jopenssl24.rb000066400000000000000000000045251313661621600175300ustar00rootroot00000000000000# frozen_string_literal: false # Ruby 2.4 preliminary compatibility script, loaded after all (2.3) jruby-openssl files module OpenSSL module SSL class SSLContext # OpenSSL 1.1.0 introduced "security level" def security_level; 0 end def security_level=(level); raise NotImplementedError end end end module PKey class DH def set_key(pub_key, priv_key) self.public_key = pub_key self.priv_key = priv_key self end def set_pqg(p, q, g) self.p = p # TODO self.q = q if respond_to?(:q) self.q = q else OpenSSL.warn "JRuby-OpenSSL does not support setting q param on #{inspect}" if q end self.g = g self end end class DSA def set_key(pub_key, priv_key) self.public_key = pub_key self.priv_key = priv_key self end def set_pqg(p, q, g) self.p = p self.q = q self.g = g self end end class RSA def set_key(n, e, d) self.n = n self.e = e self.d = d self end def set_factors(p, q) self.p = p self.q = q self end def set_crt_params(dmp1, dmq1, iqmp) self.dmp1 = dmp1 self.dmq1 = dmq1 self.iqmp = iqmp self end end # openssl/lib/openssl/pkey.rb : class DH remove_const :DEFAULT_512 if const_defined?(:DEFAULT_512) DEFAULT_2048 = new <<-_end_of_pem_ -----BEGIN DH PARAMETERS----- MIIBCAKCAQEA7E6kBrYiyvmKAMzQ7i8WvwVk9Y/+f8S7sCTN712KkK3cqd1jhJDY JbrYeNV3kUIKhPxWHhObHKpD1R84UpL+s2b55+iMd6GmL7OYmNIT/FccKhTcveab VBmZT86BZKYyf45hUF9FOuUM9xPzuK3Vd8oJQvfYMCd7LPC0taAEljQLR4Edf8E6 YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 1bNveX5wInh5GDx1FGhKBZ+s1H+aedudCm7sCgRwv8lKWYGiHzObSma8A86KG+MD 7Lo5JquQ3DlBodj3IDyPrxIv96lvRPFtAwIBAg== -----END DH PARAMETERS----- _end_of_pem_ end remove_const :DEFAULT_TMP_DH_CALLBACK if const_defined?(:DEFAULT_TMP_DH_CALLBACK) DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| warn "using default DH parameters." if $VERBOSE case keylen when 1024 then OpenSSL::PKey::DH::DEFAULT_1024 when 2048 then OpenSSL::PKey::DH::DEFAULT_2048 else nil end } end end jruby-openssl-0.9.21/lib/jruby-openssl.rb000066400000000000000000000003611313661621600203330ustar00rootroot00000000000000# This file allows older version of JRuby (prior to 1.7.5) to explicitly load # the gem version of jruby-openssl rather than the stdlib version. JRuby 1.7.5 # and higher use the "default gems" capability of RubyGems. require 'jopenssl/load'jruby-openssl-0.9.21/lib/openssl.rb000066400000000000000000000000271313661621600172010ustar00rootroot00000000000000require 'jopenssl/load'jruby-openssl-0.9.21/lib/openssl/000077500000000000000000000000001313661621600166555ustar00rootroot00000000000000jruby-openssl-0.9.21/lib/openssl/bn.rb000066400000000000000000000006041313661621600176010ustar00rootroot00000000000000if RUBY_VERSION > '2.3' load "jopenssl23/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.2' load "jopenssl22/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.1' load "jopenssl21/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/lib/openssl/buffering.rb000066400000000000000000000006041313661621600211510ustar00rootroot00000000000000if RUBY_VERSION > '2.3' load "jopenssl23/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.2' load "jopenssl22/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.1' load "jopenssl21/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/lib/openssl/cipher.rb000066400000000000000000000006041313661621600204540ustar00rootroot00000000000000if RUBY_VERSION > '2.3' load "jopenssl23/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.2' load "jopenssl22/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.1' load "jopenssl21/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/lib/openssl/config.rb000066400000000000000000000006041313661621600204470ustar00rootroot00000000000000if RUBY_VERSION > '2.3' load "jopenssl23/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.2' load "jopenssl22/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.1' load "jopenssl21/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/lib/openssl/digest.rb000066400000000000000000000006041313661621600204610ustar00rootroot00000000000000if RUBY_VERSION > '2.3' load "jopenssl23/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.2' load "jopenssl22/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.1' load "jopenssl21/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/lib/openssl/pkcs12.rb000066400000000000000000000062461313661621600203150ustar00rootroot00000000000000require 'java' module OpenSSL class PKCS12 class PKCS12Error < OpenSSLError end java_import 'org.jruby.ext.openssl.PEMUtils' java_import 'org.jruby.ext.openssl.SecurityHelper' def self.create(pass, name, key, cert, ca = nil) pkcs12 = self.new pkcs12.generate(pass, name, key, cert, ca) pkcs12 end attr_reader :key, :certificate, :ca_certs def initialize(str = nil, password = '') return @der = nil unless str if str.is_a?(File) file = File.open(str.path, "rb") @der = file.read file.close else str.force_encoding(Encoding::ASCII_8BIT) if str.respond_to?(:force_encoding) @der = str end p12_input_stream = java.io.StringBufferInputStream.new(@der) store = SecurityHelper.getKeyStore("PKCS12") store.load(p12_input_stream, password.to_java.to_char_array) aliases = store.aliases aliases.each do |alias_name| if store.is_key_entry(alias_name) if java_certificate = store.get_certificate(alias_name) der = String.from_java_bytes(java_certificate.get_encoded) @certificate = OpenSSL::X509::Certificate.new(der) end java_key = store.get_key(alias_name, password.to_java.to_char_array) if java_key der = String.from_java_bytes(java_key.get_encoded) algorithm = java_key.get_algorithm if algorithm == "RSA" @key = OpenSSL::PKey::RSA.new(der) elsif algorithm == "DSA" @key = OpenSSL::PKey::DSA.new(der) elsif algorithm == "DH" @key = OpenSSL::PKey::DH.new(der) elsif algorithm == "EC" @key = OpenSSL::PKey::EC.new(der) else raise PKCS12Error, "Unknown key algorithm #{algorithm}" end end @ca_certs = Array.new java_ca_certs = store.get_certificate_chain(alias_name) if java_ca_certs java_ca_certs.each do |java_ca_cert| der = String.from_java_bytes(java_ca_cert.get_encoded) ruby_cert = OpenSSL::X509::Certificate.new(der) if (ruby_cert.to_pem != @certificate.to_pem) @ca_certs << ruby_cert end end end break end end rescue java.lang.Exception => e raise PKCS12Error, e.inspect end def generate(pass, alias_name, key, cert, ca = nil) @key, @certificate, @ca_certs = key, cert, ca certificates = cert.to_pem ca.each { |ca_cert| certificates << ca_cert.to_pem } if ca begin der_bytes = PEMUtils.generatePKCS12( java.io.StringReader.new(key.to_pem), certificates.to_java_bytes, alias_name, ( pass.nil? ? "" : pass ).to_java.to_char_array ) rescue java.security.KeyStoreException, java.security.cert.CertificateException => e raise PKCS12Error, e.message rescue java.security.GeneralSecurityException, java.io.IOException => e raise PKCS12Error, e.inspect end @der = String.from_java_bytes(der_bytes) end def to_der @der end end end jruby-openssl-0.9.21/lib/openssl/pkcs7.rb000066400000000000000000000002141313661621600202260ustar00rootroot00000000000000if RUBY_VERSION > '1.9' raise LoadError, "no such library in #{RUBY_VERSION}: openssl/pkcs7" else load "jopenssl18/openssl/pkcs7.rb" endjruby-openssl-0.9.21/lib/openssl/pkey.rb000066400000000000000000000002211313661621600201450ustar00rootroot00000000000000if RUBY_VERSION > '2.3' load "jopenssl23/openssl/#{File.basename(__FILE__)}" else raise LoadError, "no such file to load -- openssl/pkey" endjruby-openssl-0.9.21/lib/openssl/ssl-internal.rb000066400000000000000000000003721313661621600216170ustar00rootroot00000000000000if RUBY_VERSION > '2.1' raise LoadError, "no such library in #{RUBY_VERSION}: openssl/ssl-internal.rb" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/lib/openssl/ssl.rb000066400000000000000000000006041313661621600200030ustar00rootroot00000000000000if RUBY_VERSION > '2.3' load "jopenssl23/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.2' load "jopenssl22/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.1' load "jopenssl21/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/lib/openssl/x509-internal.rb000066400000000000000000000003731313661621600215240ustar00rootroot00000000000000if RUBY_VERSION > '2.1' raise LoadError, "no such library in #{RUBY_VERSION}: openssl/x509-internal.rb" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/lib/openssl/x509.rb000066400000000000000000000006041313661621600177070ustar00rootroot00000000000000if RUBY_VERSION > '2.3' load "jopenssl23/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.2' load "jopenssl22/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '2.1' load "jopenssl21/openssl/#{File.basename(__FILE__)}" elsif RUBY_VERSION > '1.9' load "jopenssl19/openssl/#{File.basename(__FILE__)}" else load "jopenssl18/openssl/#{File.basename(__FILE__)}" endjruby-openssl-0.9.21/pom.xml000066400000000000000000001137271313661621600157540ustar00rootroot00000000000000 4.0.0 rubygems jruby-openssl 0.9.21 gem JRuby OpenSSL JRuby-OpenSSL is an add-on gem for JRuby that emulates the Ruby OpenSSL native library. https://github.com/jruby/jruby-openssl EPL-1.0 http://opensource.org/licenses/EPL-1.0 Eclipse Public License 1.0 GPL-2.0 http://opensource.org/licenses/GPL-2.0 GNU General Public License version 2.0 LGPL-2.1 http://opensource.org/licenses/LGPL-2.1 GNU Library or "Lesser" General Public License version 2.1 Ola Bini ola.bini@gmail.com JRuby contributors https://github.com/jruby/jruby-openssl.git https://github.com/jruby/jruby-openssl ossrh https://oss.sonatype.org/service/local/staging/deploy/maven2/ ossrh https://oss.sonatype.org/content/repositories/snapshots 0.2.0 1.0.10 ${maven.test.skip} 1.7.18 src/test/ruby/**/test_*.rb 1.7.18 true pom.xml pom.xml true ${bc.versions} rubygems jar-dependencies [0.1,0.99999] gem test rubygems mocha [1.1.0,1.1.99999] gem test rubygems ruby-maven [3.0,3.99999] gem test org.bouncycastle bcpkix-jdk15on 1.56 org.bouncycastle bcprov-jdk15on 1.56 org.jruby jruby-core 1.7.17 provided junit junit 4.11 test mavengems mavengem:https://rubygems.org false true sonatype https://oss.sonatype.org/content/repositories/snapshots/ org.torquebox.mojo mavengem-wagon ${mavengem.wagon.version} de.saumya.mojo gem-with-jar-extension ${jruby.plugins.version} ${basedir}/pkg maven-jar-plugin 2.4 prepare-package jar lib jopenssl maven-clean-plugin 2.4 lib jopenssl.jar */**/*.jar maven-dependency-plugin generate-test-resources copy-dependencies lib true de.saumya.mojo gem-maven-plugin ${jruby.plugins.version} default-initialize false something-which-does-not-exists default-push true jruby-openssl.gemspec true true org.codehaus.mojo exec-maven-plugin 1.3.2 invoker-generator process-classes exec java compile -Djruby.bytecode.version=1.6 -classpath org.jruby.anno.InvokerGenerator ${basedir}/target/generated-sources/annotated_classes.txt ${project.build.outputDirectory} org.codehaus.mojo build-helper-maven-plugin 1.9 process-classes add-source ${basedir}/target/generated-sources maven-compiler-plugin 3.1 compile-populators process-classes compile org/jruby/gen/**/*.java true -XDignore.symbol.file=true 1.6 1.6 UTF-8 true true true ${basedir}/target/generated-sources org.jruby.anno.AnnotationBinder -XDignore.symbol.file=true maven-clean-plugin default-clean clean clean lib jopenssl.jar lib/org target * false maven-deploy-plugin 2.8.1 deploy false maven-dependency-plugin generate-test-resources copy-dependencies ${basedir}/lib true org.bouncycastle de.saumya.mojo runit-maven-plugin ${jruby.plugins.version} test ${runit.dir} test-1.6.8 maven-invoker-plugin 1.8 tests-with-different-bc-versions install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9 1.6.8 test-1.7.4 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9 1.7.4 test-1.7.13 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.13 test-1.7.15 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.15 test-1.7.16 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.16 test-1.7.18 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.18 test-1.7.20 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.20 test-1.7.22 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.22 test-1.7.23 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.23 test-1.7.24 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.24 test-1.7.25 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.25 test-1.7.26 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.26 test-1.7.27 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 1.8,1.9,2.0 1.7.27 test-9.0.1.0 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 9.0.1.0 9.0.1.0 test-9.0.5.0 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 9.0.5.0 9.0.5.0 test-9.1.2.0 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 9.1.2.0 9.1.2.0 test-9.1.5.0 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 9.1.5.0 9.1.5.0 test-9.1.8.0 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 9.1.8.0 9.1.8.0 test-9.1.12.0 maven-invoker-plugin 1.8 install run integration */pom.xml true ${jruby.versions} ${jruby.modes} ${project.version} ${bc.versions} ${runit.dir} 1.51,1.52,1.53,1.54 9.1.12.0 9.1.12.0 release maven-gpg-plugin 1.5 verify sign jruby-openssl-0.9.21/src/000077500000000000000000000000001313661621600152135ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/000077500000000000000000000000001313661621600161375ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/000077500000000000000000000000001313661621600170605ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/000077500000000000000000000000001313661621600176475ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/jruby/000077500000000000000000000000001313661621600210025ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/jruby/ext/000077500000000000000000000000001313661621600216025ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/000077500000000000000000000000001313661621600232655ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/ASN1.java000066400000000000000000002743171313661621600246500ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigInteger; import java.text.ParseException; import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.WeakHashMap; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Enumerated; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Null; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.ASN1UTCTime; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.BEROctetString; import org.bouncycastle.asn1.BERSequenceGenerator; import org.bouncycastle.asn1.BERSet; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERApplicationSpecific; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DEREnumerated; import org.bouncycastle.asn1.DERGeneralString; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERNumericString; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERT61String; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DERUniversalString; import org.bouncycastle.asn1.DERVisibleString; import org.bouncycastle.asn1.DLSet; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBignum; import org.jruby.RubyClass; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.RubySymbol; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Block; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.ext.openssl.impl.ASN1Registry; import static org.jruby.ext.openssl.OpenSSL.*; import org.jruby.ext.openssl.util.ByteArrayOutputStream; /** * @author Ola Bini */ public class ASN1 { private static Map> SYM_TO_OID = new WeakHashMap>(8); private static Map> OID_TO_SYM = new WeakHashMap>(8); private static Map> OID_TO_NID = new WeakHashMap>(8); private static Map> NID_TO_OID = new WeakHashMap>(8); private static Map> NID_TO_SN = new WeakHashMap>(8); private static Map> NID_TO_LN = new WeakHashMap>(8); @SuppressWarnings("unchecked") private static synchronized void initMaps(final Ruby runtime) { final int size = 200; final float fact = 1.0f; SYM_TO_OID.put(runtime, new HashMap(size, fact)); OID_TO_SYM.put(runtime, new HashMap(size, fact)); OID_TO_NID.put(runtime, new HashMap(size, fact)); NID_TO_OID.put(runtime, new HashMap(size, fact)); NID_TO_SN.put(runtime, new HashMap(size, fact)); NID_TO_LN.put(runtime, new HashMap(size, fact)); defaultObjects(runtime); } private static void defaultObjects(final Ruby runtime) { addObject(runtime, 0, null, null,"1.2.840.113549.1.12.1"); addObject(runtime, 1, null, "rsadsi","1.2.840.113549"); addObject(runtime, 2, null, "pkcs","1.2.840.113549.1"); addObject(runtime, 3, "MD2", "md2","1.2.840.113549.2.2"); addObject(runtime, 4, "MD5", "md5","1.2.840.113549.2.5"); addObject(runtime, 5, "RC4", "rc4","1.2.840.113549.3.4"); addObject(runtime, 6, null, "rsaEncryption","1.2.840.113549.1.1.1"); addObject(runtime, 7, "RSA-MD2", "md2WithRSAEncryption","1.2.840.113549.1.1.2"); addObject(runtime, 8, "RSA-MD5", "md5WithRSAEncryption","1.2.840.113549.1.1.4"); addObject(runtime, 9, "PBE-MD2-DES", "pbeWithMD2AndDES-CBC","1.2.840.113549.1.5.1"); addObject(runtime, 10, "PBE-MD5-DES", "pbeWithMD5AndDES-CBC","1.2.840.113549.1.5.3"); addObject(runtime, 11, null, "X500","2.5"); addObject(runtime, 12, null, "X509","2.5.4"); addObject(runtime, 13, "CN", "commonName","2.5.4.3"); addObject(runtime, 14, "C", "countryName","2.5.4.6"); addObject(runtime, 15, "L", "localityName","2.5.4.7"); addObject(runtime, 16, "ST", "stateOrProvinceName","2.5.4.8"); addObject(runtime, 17, "O", "organizationName","2.5.4.10"); addObject(runtime, 18, "OU", "organizationalUnitName","2.5.4.11"); addObject(runtime, 19, "RSA", "rsa","2.5.8.1.1"); addObject(runtime, 20, null, "pkcs7","1.2.840.113549.1.7"); addObject(runtime, 21, null, "pkcs7-data","1.2.840.113549.1.7.1"); addObject(runtime, 22, null, "pkcs7-signedData","1.2.840.113549.1.7.2"); addObject(runtime, 23, null, "pkcs7-envelopedData","1.2.840.113549.1.7.3"); addObject(runtime, 24, null, "pkcs7-signedAndEnvelopedData","1.2.840.113549.1.7.4"); addObject(runtime, 25, null, "pkcs7-digestData","1.2.840.113549.1.7.5"); addObject(runtime, 26, null, "pkcs7-encryptedData","1.2.840.113549.1.7.6"); addObject(runtime, 27, null, "pkcs3","1.2.840.113549.1.3"); addObject(runtime, 28, null, "dhKeyAgreement","1.2.840.113549.1.3.1"); addObject(runtime, 29, "DES-ECB", "des-ecb","1.3.14.3.2.6"); addObject(runtime, 30, "DES-CFB", "des-cfb","1.3.14.3.2.9"); addObject(runtime, 31, "DES-CBC", "des-cbc","1.3.14.3.2.7"); addObject(runtime, 32, "DES-EDE", "des-ede","1.3.14.3.2.17"); addObject(runtime, 33, "DES-EDE3", "des-ede3",null); addObject(runtime, 34, "IDEA-CBC", "idea-cbc","1.3.6.1.4.1.188.7.1.1.2"); addObject(runtime, 35, "IDEA-CFB", "idea-cfb",null); addObject(runtime, 36, "IDEA-ECB", "idea-ecb",null); addObject(runtime, 37, "RC2-CBC", "rc2-cbc","1.2.840.113549.3.2"); addObject(runtime, 38, "RC2-ECB", "rc2-ecb",null); addObject(runtime, 39, "RC2-CFB", "rc2-cfb",null); addObject(runtime, 40, "RC2-OFB", "rc2-ofb",null); addObject(runtime, 41, "SHA", "sha","1.3.14.3.2.18"); addObject(runtime, 42, "RSA-SHA", "shaWithRSAEncryption","1.3.14.3.2.15"); addObject(runtime, 43, "DES-EDE-CBC", "des-ede-cbc",null); addObject(runtime, 44, "DES-EDE3-CBC", "des-ede3-cbc","1.2.840.113549.3.7"); addObject(runtime, 45, "DES-OFB", "des-ofb","1.3.14.3.2.8"); addObject(runtime, 46, "IDEA-OFB", "idea-ofb",null); addObject(runtime, 47, null, "pkcs9","1.2.840.113549.1.9"); addObject(runtime, 48, null, "emailAddress","1.2.840.113549.1.9.1"); addObject(runtime, 49, null, "unstructuredName","1.2.840.113549.1.9.2"); addObject(runtime, 50, null, "contentType","1.2.840.113549.1.9.3"); addObject(runtime, 51, null, "messageDigest","1.2.840.113549.1.9.4"); addObject(runtime, 52, null, "signingTime","1.2.840.113549.1.9.5"); addObject(runtime, 53, null, "countersignature","1.2.840.113549.1.9.6"); addObject(runtime, 54, null, "challengePassword","1.2.840.113549.1.9.7"); addObject(runtime, 55, null, "unstructuredAddress","1.2.840.113549.1.9.8"); addObject(runtime, 56, null, "extendedCertificateAttributes","1.2.840.113549.1.9.9"); addObject(runtime, 57, "Netscape", "Netscape Communications Corp.","2.16.840.1.113730"); addObject(runtime, 58, "nsCertExt", "Netscape Certificate Extension","2.16.840.1.113730.1"); addObject(runtime, 59, "nsDataType", "Netscape Data Type","2.16.840.1.113730.2"); addObject(runtime, 60, "DES-EDE-CFB", "des-ede-cfb",null); addObject(runtime, 61, "DES-EDE3-CFB", "des-ede3-cfb",null); addObject(runtime, 62, "DES-EDE-OFB", "des-ede-ofb",null); addObject(runtime, 63, "DES-EDE3-OFB", "des-ede3-ofb",null); addObject(runtime, 64, "SHA1", "sha1","1.3.14.3.2.26"); addObject(runtime, 65, "RSA-SHA1", "sha1WithRSAEncryption","1.2.840.113549.1.1.5"); addObject(runtime, 66, "DSA-SHA", "dsaWithSHA","1.3.14.3.2.13"); addObject(runtime, 67, "DSA-old", "dsaEncryption-old","1.3.14.3.2.12"); addObject(runtime, 68, "PBE-SHA1-RC2-64", "pbeWithSHA1AndRC2-CBC","1.2.840.113549.1.5.11"); addObject(runtime, 69, null, "PBKDF2","1.2.840.113549.1.5.12"); addObject(runtime, 70, "DSA-SHA1-old", "dsaWithSHA1-old","1.3.14.3.2.27"); addObject(runtime, 71, "nsCertType", "Netscape Cert Type","2.16.840.1.113730.1.1"); addObject(runtime, 72, "nsBaseUrl", "Netscape Base Url","2.16.840.1.113730.1.2"); addObject(runtime, 73, "nsRevocationUrl", "Netscape Revocation Url","2.16.840.1.113730.1.3"); addObject(runtime, 74, "nsCaRevocationUrl", "Netscape CA Revocation Url","2.16.840.1.113730.1.4"); addObject(runtime, 75, "nsRenewalUrl", "Netscape Renewal Url","2.16.840.1.113730.1.7"); addObject(runtime, 76, "nsCaPolicyUrl", "Netscape CA Policy Url","2.16.840.1.113730.1.8"); addObject(runtime, 77, "nsSslServerName", "Netscape SSL Server Name","2.16.840.1.113730.1.12"); addObject(runtime, 78, "nsComment", "Netscape Comment","2.16.840.1.113730.1.13"); addObject(runtime, 79, "nsCertSequence", "Netscape Certificate Sequence","2.16.840.1.113730.2.5"); addObject(runtime, 80, "DESX-CBC", "desx-cbc",null); addObject(runtime, 81, "id-ce", null,"2.5.29"); addObject(runtime, 82, "subjectKeyIdentifier", "X509v3 Subject Key Identifier","2.5.29.14"); addObject(runtime, 83, "keyUsage", "X509v3 Key Usage","2.5.29.15"); addObject(runtime, 84, "privateKeyUsagePeriod", "X509v3 Private Key Usage Period","2.5.29.16"); addObject(runtime, 85, "subjectAltName", "X509v3 Subject Alternative Name","2.5.29.17"); addObject(runtime, 86, "issuerAltName", "X509v3 Issuer Alternative Name","2.5.29.18"); addObject(runtime, 87, "basicConstraints", "X509v3 Basic Constraints","2.5.29.19"); addObject(runtime, 88, "crlNumber", "X509v3 CRL Number","2.5.29.20"); addObject(runtime, 89, "certificatePolicies", "X509v3 Certificate Policies","2.5.29.32"); addObject(runtime, 90, "authorityKeyIdentifier", "X509v3 Authority Key Identifier","2.5.29.35"); addObject(runtime, 91, "BF-CBC", "bf-cbc","1.3.6.1.4.1.3029.1.2"); addObject(runtime, 92, "BF-ECB", "bf-ecb",null); addObject(runtime, 93, "BF-CFB", "bf-cfb",null); addObject(runtime, 94, "BF-OFB", "bf-ofb",null); addObject(runtime, 95, "MDC2", "mdc2","2.5.8.3.101"); addObject(runtime, 96, "RSA-MDC2", "mdc2withRSA","2.5.8.3.100"); addObject(runtime, 97, "RC4-40", "rc4-40",null); addObject(runtime, 98, "RC2-40-CBC", "rc2-40-cbc",null); addObject(runtime, 99, "G", "givenName","2.5.4.42"); addObject(runtime, 100, "S", "surname","2.5.4.4"); addObject(runtime, 101, "I", "initials","2.5.4.43"); addObject(runtime, 102, "UID", "uniqueIdentifier","2.5.4.45"); // BC prefers UID to map to userId ?! addObject(runtime, 103, "crlDistributionPoints", "X509v3 CRL Distribution Points","2.5.29.31"); addObject(runtime, 104, "RSA-NP-MD5", "md5WithRSA","1.3.14.3.2.3"); addObject(runtime, 105, null, "serialNumber","2.5.4.5"); addObject(runtime, 106, "T", "title","2.5.4.12"); addObject(runtime, 107, "D", "description","2.5.4.13"); addObject(runtime, 108, "CAST5-CBC", "cast5-cbc","1.2.840.113533.7.66.10"); addObject(runtime, 109, "CAST5-ECB", "cast5-ecb",null); addObject(runtime, 110, "CAST5-CFB", "cast5-cfb",null); addObject(runtime, 111, "CAST5-OFB", "cast5-ofb",null); addObject(runtime, 112, null, "pbeWithMD5AndCast5CBC","1.2.840.113533.7.66.12"); addObject(runtime, 113, "DSA-SHA1", "dsaWithSHA1","1.2.840.10040.4.3"); addObject(runtime, 114, "MD5-SHA1", "md5-sha1",null); addObject(runtime, 115, "RSA-SHA1-2", "sha1WithRSA","1.3.14.3.2.29"); addObject(runtime, 116, "DSA", "dsaEncryption","1.2.840.10040.4.1"); addObject(runtime, 117, "RIPEMD160", "ripemd160","1.3.36.3.2.1"); addObject(runtime, 118, "RSA-RIPEMD160", "ripemd160WithRSA","1.3.36.3.3.1.2"); addObject(runtime, 119, "RC5-CBC", "rc5-cbc","1.2.840.113549.3.8"); addObject(runtime, 120, "RC5-ECB", "rc5-ecb",null); addObject(runtime, 121, "RC5-CFB", "rc5-cfb",null); addObject(runtime, 122, "RC5-OFB", "rc5-ofb",null); addObject(runtime, 123, "RLE", "run length compression","1.1.1.1.666.1"); addObject(runtime, 124, "ZLIB", "zlib compression","1.1.1.1.666.2"); addObject(runtime, 125, "extendedKeyUsage", "X509v3 Extended Key Usage","2.5.29.37"); addObject(runtime, 126, "PKIX", null,"1.3.6.1.5.5.7"); addObject(runtime, 127, "id-kp", null,"1.3.6.1.5.5.7.3"); addObject(runtime, 128, "serverAuth", "TLS Web Server Authentication","1.3.6.1.5.5.7.3.1"); addObject(runtime, 129, "clientAuth", "TLS Web Client Authentication","1.3.6.1.5.5.7.3.2"); addObject(runtime, 130, "codeSigning", "Code Signing","1.3.6.1.5.5.7.3.3"); addObject(runtime, 131, "emailProtection", "E-mail Protection","1.3.6.1.5.5.7.3.4"); addObject(runtime, 132, "timeStamping", "Time Stamping","1.3.6.1.5.5.7.3.8"); addObject(runtime, 133, "msCodeInd", "Microsoft Individual Code Signing","1.3.6.1.4.1.311.2.1.21"); addObject(runtime, 134, "msCodeCom", "Microsoft Commercial Code Signing","1.3.6.1.4.1.311.2.1.22"); addObject(runtime, 135, "msCTLSign", "Microsoft Trust List Signing","1.3.6.1.4.1.311.10.3.1"); addObject(runtime, 136, "msSGC", "Microsoft Server Gated Crypto","1.3.6.1.4.1.311.10.3.3"); addObject(runtime, 137, "msEFS", "Microsoft Encrypted File System","1.3.6.1.4.1.311.10.3.4"); addObject(runtime, 138, "nsSGC", "Netscape Server Gated Crypto","2.16.840.1.113730.4.1"); addObject(runtime, 139, "deltaCRL", "X509v3 Delta CRL Indicator","2.5.29.27"); addObject(runtime, 140, "CRLReason", "CRL Reason Code","2.5.29.21"); addObject(runtime, 141, "invalidityDate", "Invalidity Date","2.5.29.24"); addObject(runtime, 142, "SXNetID", "Strong Extranet ID","1.3.101.1.4.1"); addObject(runtime, 143, "PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4","1.2.840.113549.1.12.1.1"); addObject(runtime, 144, "PBE-SHA1-RC4-40", "pbeWithSHA1And40BitRC4","1.2.840.113549.1.12.1.2"); addObject(runtime, 145, "PBE-SHA1-3DES", "pbeWithSHA1And3-KeyTripleDES-CBC","1.2.840.113549.1.12.1.3"); addObject(runtime, 146, "PBE-SHA1-2DES", "pbeWithSHA1And2-KeyTripleDES-CBC","1.2.840.113549.1.12.1.4"); addObject(runtime, 147, "PBE-SHA1-RC2-128", "pbeWithSHA1And128BitRC2-CBC","1.2.840.113549.1.12.1.5"); addObject(runtime, 148, "PBE-SHA1-RC2-40", "pbeWithSHA1And40BitRC2-CBC","1.2.840.113549.1.12.1.6"); addObject(runtime, 149, null, "keyBag","1.2.840.113549.1.12.10.1.1"); addObject(runtime, 150, null, "pkcs8ShroudedKeyBag","1.2.840.113549.1.12.10.1.2"); addObject(runtime, 151, null, "certBag","1.2.840.113549.1.12.10.1.3"); addObject(runtime, 152, null, "crlBag","1.2.840.113549.1.12.10.1.4"); addObject(runtime, 153, null, "secretBag","1.2.840.113549.1.12.10.1.5"); addObject(runtime, 154, null, "safeContentsBag","1.2.840.113549.1.12.10.1.6"); addObject(runtime, 155, null, "PBES2","1.2.840.113549.1.5.13"); addObject(runtime, 156, null, "PBMAC1","1.2.840.113549.1.5.14"); addObject(runtime, 157, null, "hmacWithSHA1","1.2.840.113549.2.7"); addObject(runtime, 158, "id-qt-cps", "Policy Qualifier CPS","1.3.6.1.5.5.7.2.1"); addObject(runtime, 159, "id-qt-unotice", "Policy Qualifier User Notice","1.3.6.1.5.5.7.2.2"); addObject(runtime, 160, "RC2-64-CBC", "rc2-64-cbc",null); addObject(runtime, 161, "SMIME-CAPS", "S/MIME Capabilities","1.2.840.113549.1.9.15"); addObject(runtime, 162, "PBE-MD2-RC2-64", "pbeWithMD2AndRC2-CBC","1.2.840.113549.1.5.4"); addObject(runtime, 163, "PBE-MD5-RC2-64", "pbeWithMD5AndRC2-CBC","1.2.840.113549.1.5.6"); addObject(runtime, 164, "PBE-SHA1-DES", "pbeWithSHA1AndDES-CBC","1.2.840.113549.1.5.10"); addObject(runtime, 165, "msExtReq", "Microsoft Extension Request","1.3.6.1.4.1.311.2.1.14"); addObject(runtime, 166, "extReq", "Extension Request","1.2.840.113549.1.9.14"); addObject(runtime, 167, "name", "name","2.5.4.41"); addObject(runtime, 168, "dnQualifier", "dnQualifier","2.5.4.46"); addObject(runtime, 169, "id-pe", null,"1.3.6.1.5.5.7.1"); addObject(runtime, 170, "id-ad", null,"1.3.6.1.5.5.7.48"); addObject(runtime, 171, "authorityInfoAccess", "Authority Information Access","1.3.6.1.5.5.7.1.1"); addObject(runtime, 172, "OCSP", "OCSP","1.3.6.1.5.5.7.48.1"); addObject(runtime, 173, "caIssuers", "CA Issuers","1.3.6.1.5.5.7.48.2"); addObject(runtime, 174, "OCSPSigning", "OCSP Signing","1.3.6.1.5.5.7.3.9"); addObject(runtime, 175, "AES-128-EBC", "aes-128-ebc","2.16.840.1.101.3.4.1.1"); addObject(runtime, 176, "AES-128-CBC", "aes-128-cbc","2.16.840.1.101.3.4.1.2"); addObject(runtime, 177, "AES-128-OFB", "aes-128-ofb","2.16.840.1.101.3.4.1.3"); addObject(runtime, 178, "AES-128-CFB", "aes-128-cfb","2.16.840.1.101.3.4.1.4"); addObject(runtime, 179, "AES-192-EBC", "aes-192-ebc","2.16.840.1.101.3.4.1.21"); addObject(runtime, 180, "AES-192-CBC", "aes-192-cbc","2.16.840.1.101.3.4.1.22"); addObject(runtime, 181, "AES-192-OFB", "aes-192-ofb","2.16.840.1.101.3.4.1.23"); addObject(runtime, 182, "AES-192-CFB", "aes-192-cfb","2.16.840.1.101.3.4.1.24"); addObject(runtime, 183, "AES-256-EBC", "aes-256-ebc","2.16.840.1.101.3.4.1.41"); addObject(runtime, 184, "AES-256-CBC", "aes-256-cbc","2.16.840.1.101.3.4.1.42"); addObject(runtime, 185, "AES-256-OFB", "aes-256-ofb","2.16.840.1.101.3.4.1.43"); addObject(runtime, 186, "AES-256-CFB", "aes-256-cfb","2.16.840.1.101.3.4.1.44"); addObject(runtime, 672, "SHA256", "sha256", "2.16.840.1.101.3.4.2.1"); addObject(runtime, 660, "street", "streetAddress", "2.5.4.9"); addObject(runtime, 391, "DC", "domainComponent", "0.9.2342.19200300.100.1.25"); //addObject(runtime, 509, null, "generationQualifier", "2.5.4.44"); //addObject(runtime, 510, null, "pseudonym", "2.5.4.65"); //addObject(runtime, 661, null, "postalCode", "2.5.4.17"); //addObject(runtime, 861, null, "postalAddress", "2.5.4.16"); // NOTE: left-overs from BC's org.bouncycastle.asn1.x509.X509Name /* DefaultLookUp.put("uid", UID); DefaultLookUp.put("dn", DN_QUALIFIER); DefaultLookUp.put("nameofbirth", NAME_AT_BIRTH); DefaultLookUp.put("placeofbirth", PLACE_OF_BIRTH); DefaultLookUp.put("dateofbirth", DATE_OF_BIRTH);gen DefaultLookUp.put("countryofcitizenship", COUNTRY_OF_CITIZENSHIP); DefaultLookUp.put("countryofresidence", COUNTRY_OF_RESIDENCE); DefaultLookUp.put("gender", GENDER); DefaultLookUp.put("businesscategory", BUSINESS_CATEGORY); DefaultLookUp.put("telephonenumber", TELEPHONE_NUMBER); */ } private static void addObject(final Ruby runtime, final int nid, final String sn, final String ln, final String oid) { if ( oid != null && ( sn != null || ln != null ) ) { ASN1ObjectIdentifier objectId = new ASN1ObjectIdentifier(oid); if ( sn != null ) { symToOid(runtime).put(sn.toLowerCase(), objectId); } if ( ln != null ) { symToOid(runtime).put(ln.toLowerCase(), objectId); } oidToSym(runtime).put(objectId, sn == null ? ln : sn); oidToNid(runtime).put(objectId, nid); nidToOid(runtime).put(nid, objectId); nidToSn(runtime).put(nid, sn); nidToLn(runtime).put(nid, ln); } } private static Map symToOid(final Ruby runtime) { Map map = SYM_TO_OID.get(runtime); if ( map == null ) { synchronized(ASN1.class) { map = SYM_TO_OID.get(runtime); if ( map == null ) { initMaps(runtime); map = SYM_TO_OID.get(runtime); } } } return map; } private static Map oidToSym(final Ruby runtime) { Map map = OID_TO_SYM.get(runtime); if ( map == null ) { synchronized(ASN1.class) { map = OID_TO_SYM.get(runtime); if ( map == null ) { initMaps(runtime); map = OID_TO_SYM.get(runtime); } } } return map; } private static Map nidToOid(final Ruby runtime) { Map map = NID_TO_OID.get(runtime); if ( map == null ) { synchronized(ASN1.class) { map = NID_TO_OID.get(runtime); if ( map == null ) { initMaps(runtime); map = NID_TO_OID.get(runtime); } } } return map; } private static Map oidToNid(final Ruby runtime) { Map map = OID_TO_NID.get(runtime); if ( map == null ) { synchronized(ASN1.class) { map = OID_TO_NID.get(runtime); if ( map == null ) { initMaps(runtime); map = OID_TO_NID.get(runtime); } } } return map; } private static Map nidToSn(final Ruby runtime) { Map map = NID_TO_SN.get(runtime); if ( map == null ) { synchronized(ASN1.class) { map = NID_TO_SN.get(runtime); if ( map == null ) { initMaps(runtime); map = NID_TO_SN.get(runtime); } } } return map; } private static Map nidToLn(final Ruby runtime) { Map map = NID_TO_LN.get(runtime); if ( map == null ) { synchronized(ASN1.class) { map = NID_TO_LN.get(runtime); if ( map == null ) { initMaps(runtime); map = NID_TO_LN.get(runtime); } } } return map; } static String ln2oid(final Ruby runtime, final String ln) { Map map = symToOid(runtime); final ASN1ObjectIdentifier val = map.get(ln); if ( val == null ) { throw new NullPointerException("oid not found for ln = '" + ln + "' (" + runtime + ")"); } return val.getId(); } static Integer oid2nid(final Ruby runtime, final ASN1ObjectIdentifier oid) { return oidToNid(runtime).get(oid); } static String o2a(final Ruby runtime, final ASN1ObjectIdentifier oid) { return o2a(runtime, oid, false); } static String o2a(final Ruby runtime, final ASN1ObjectIdentifier oid, final boolean silent) { Integer nid = oidToNid(runtime).get(oid); if ( nid != null ) { final String name = nid2ln(runtime, nid, false); return name == null ? nid2sn(runtime, nid, false) : name; } nid = ASN1Registry.oid2nid(oid); if ( nid == null ) { if ( silent ) return null; throw new NullPointerException("nid not found for oid = '" + oid + "' (" + runtime + ")"); } final String name = nid2ln(runtime, nid, false); if ( name != null ) return name; return nid2sn(runtime, nid, true); } static String oid2name(final Ruby runtime, final ASN1ObjectIdentifier oid, final boolean silent) { Integer nid = oidToNid(runtime).get(oid); if ( nid != null ) { final String name = nid2sn(runtime, nid, false); return name == null ? nid2ln(runtime, nid, false) : name; } nid = ASN1Registry.oid2nid(oid); if ( nid == null ) { if ( silent ) return null; throw new NullPointerException("nid not found for oid = '" + oid + "' (" + runtime + ")"); } final String name = nid2sn(runtime, nid, false); if ( name != null ) return name; return nid2ln(runtime, nid, true); /* if ( nid == null ) nid = ASN1Registry.oid2nid(oid); if ( nid == null ) { if ( silent ) return null; throw new NullPointerException("nid not found for oid = '" + oid + "' (" + runtime + ")"); } final String name = nid2sn(runtime, nid, true); if ( name != null ) return name; return nid2ln(runtime, nid, true); */ } static String oid2name(final Ruby runtime, final String oid) { return oid2name(runtime, new ASN1ObjectIdentifier(oid), false); } static String nid2sn(final Ruby runtime, final Integer nid) { return nid2sn(runtime, nid, true); } private static String nid2sn(final Ruby runtime, final Integer nid, boolean fallback) { final String ln = nidToSn(runtime).get(nid); if ( ln == null && fallback ) return ASN1Registry.nid2sn(nid); return ln; } static String nid2ln(final Ruby runtime, final Integer nid) { return nid2ln(runtime, nid, true); } private static String nid2ln(final Ruby runtime, final Integer nid, boolean fallback) { final String ln = nidToLn(runtime).get(nid); if ( ln == null && fallback ) return ASN1Registry.nid2ln(nid); return ln; } static String oid2Sym(final Ruby runtime, final ASN1ObjectIdentifier oid) { return oid2Sym(runtime, oid, false); } static String oid2Sym(final Ruby runtime, final ASN1ObjectIdentifier oid, final boolean fallback) { final String sym = getSymLookup(runtime).get(oid); return ( sym == null && fallback ) ? ASN1Registry.oid2sym(oid) : sym; } static ASN1ObjectIdentifier sym2Oid(final Ruby runtime, final String name) { return getOIDLookup(runtime).get(name); } private static Map getOIDLookup(final Ruby runtime) { return symToOid(runtime); } private static Map getSymLookup(final Ruby runtime) { return oidToSym(runtime); } private final static Object[][] ASN1_INFO = { { "EOC", null, "EndOfContent" }, // OpenSSL::ASN1::EOC (0) { "BOOLEAN", org.bouncycastle.asn1.DERBoolean.class, "Boolean" }, { "INTEGER", org.bouncycastle.asn1.DERInteger.class, "Integer" }, { "BIT_STRING", org.bouncycastle.asn1.DERBitString.class, "BitString" }, { "OCTET_STRING", org.bouncycastle.asn1.DEROctetString.class, "OctetString" }, { "NULL", org.bouncycastle.asn1.DERNull.class, "Null" }, // OpenSSL::ASN1::OBJECT (6) : { "OBJECT", org.bouncycastle.asn1.DERObjectIdentifier.class, "ObjectId" }, { "OBJECT_DESCRIPTOR", null, null }, { "EXTERNAL", null, null }, { "REAL", null, null }, // OpenSSL::ASN1::ENUMERATED (10) : { "ENUMERATED", org.bouncycastle.asn1.DEREnumerated.class, "Enumerated" }, { "EMBEDDED_PDV", null, null }, // OpenSSL::ASN1::UTF8STRING (12) : { "UTF8STRING", org.bouncycastle.asn1.DERUTF8String.class, "UTF8String" }, { "RELATIVE_OID", null, null }, { "[UNIVERSAL 14]", null, null }, { "[UNIVERSAL 15]", null, null }, // OpenSSL::ASN1::SEQUENCE (16) : // NOTE: org.bouncycastle.asn1.DERSequence does not have a getInstance //{ "SEQUENCE", org.bouncycastle.asn1.ASN1Sequence.class, "Sequence" }, { "SEQUENCE", org.bouncycastle.asn1.DERSequence.class, "Sequence" }, // OpenSSL::ASN1::SET (17) : // NOTE: org.bouncycastle.asn1.DERSet does not have a getInstance //{ "SET", org.bouncycastle.asn1.ASN1Set.class, "Set" }, { "SET", org.bouncycastle.asn1.DERSet.class, "Set" }, { "NUMERICSTRING", org.bouncycastle.asn1.DERNumericString.class, "NumericString" }, { "PRINTABLESTRING", org.bouncycastle.asn1.DERPrintableString.class, "PrintableString" }, { "T61STRING", org.bouncycastle.asn1.DERT61String.class, "T61String" }, { "VIDEOTEXSTRING", null, "VideotexString" }, { "IA5STRING", org.bouncycastle.asn1.DERIA5String.class, "IA5String" }, { "UTCTIME", org.bouncycastle.asn1.DERUTCTime.class, "UTCTime" }, { "GENERALIZEDTIME", org.bouncycastle.asn1.DERGeneralizedTime.class, "GeneralizedTime" }, { "GRAPHICSTRING", null, "GraphicString" }, { "ISO64STRING", null, "ISO64String" }, { "GENERALSTRING", org.bouncycastle.asn1.DERGeneralString.class, "GeneralString" }, // OpenSSL::ASN1::UNIVERSALSTRING (28) : { "UNIVERSALSTRING", org.bouncycastle.asn1.DERUniversalString.class, "UniversalString" }, { "CHARACTER_STRING", null, null }, // OpenSSL::ASN1::BMPSTRING (30) : { "BMPSTRING", org.bouncycastle.asn1.DERBMPString.class, "BMPString" }}; private final static Map, Integer> JCLASS_TO_ID = new HashMap, Integer>(24, 1); private final static Map RCLASS_TO_ID = new HashMap(28, 1); static { for ( int i = 0; i < ASN1_INFO.length; i++ ) { final Object[] info = ASN1_INFO[i]; if ( info[1] != null ) { JCLASS_TO_ID.put((Class) info[1], Integer.valueOf(i)); } if ( info[2] != null ) { RCLASS_TO_ID.put((String) info[2], Integer.valueOf(i)); } } } private final static int EOC = 0; // OpenSSL::ASN1::EOC (0) //private final static int BOOLEAN = 1; // OpenSSL::ASN1::BOOLEAN (1) //private final static int INTEGER = 2; // OpenSSL::ASN1::INTEGER (2) private final static int BIT_STRING = 3; // OpenSSL::ASN1::BIT_STRING (3) private final static int OCTET_STRING = 4; // OpenSSL::ASN1::OCTET_STRING (4) //private final static int NULL = 5; // OpenSSL::ASN1::NULL (5) //private final static int OBJECT = 6; // OpenSSL::ASN1::OBJECT (6) //private final static int ENUMARATED = 10; // OpenSSL::ASN1::ENUMERATED (10) //private final static int UTFSTRING = 12; // OpenSSL::ASN1::UTF8STRING (12) private final static int SEQUENCE = 16; // OpenSSL::ASN1::SEQUENCE (16) private final static int SET = 17; // OpenSSL::ASN1::SET (17) //private final static int NUMERICSTRING = 18; // OpenSSL::ASN1::NUMERICSTRING (18) // OpenSSL::ASN1::PRINTABLESTRING (19) // OpenSSL::ASN1::T61STRING (20) // OpenSSL::ASN1::VIDEOTEXSTRING (21) // OpenSSL::ASN1::IA5STRING (22) // OpenSSL::ASN1::UTCTIME (23) // OpenSSL::ASN1::GENERALIZEDTIME (24) // OpenSSL::ASN1::GRAPHICSTRING (25) // OpenSSL::ASN1::ISO64STRING (26) // OpenSSL::ASN1::GENERALSTRING (27) // OpenSSL::ASN1::UNIVERSALSTRING (28) // OpenSSL::ASN1::BMPSTRING (30) private static Integer typeId(Class type) { Integer id = null; while ( type != Object.class && id == null ) { id = JCLASS_TO_ID.get(type); if ( id == null ) type = type.getSuperclass(); } return id; //return v == null ? -1 : v.intValue(); } static Integer typeId(final ASN1Encodable obj) { return typeId( obj.getClass() ); } private static Integer typeId(final RubyClass metaClass) { final String name = metaClass.getRealClass().getBaseName(); final Integer id = RCLASS_TO_ID.get(name); return id == null ? null : id; } @SuppressWarnings("unchecked") static Class typeClass(final RubyClass metaClass) { final Integer tag = typeId( metaClass ); if ( tag == null ) return null; return (Class) ASN1_INFO[tag][1]; } @SuppressWarnings("unchecked") static Class typeClass(final int typeId) { return (Class) ASN1_INFO[typeId][1]; } static ASN1Encodable typeInstance(Class type, Object value) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Method getInstance = null; try { getInstance = type.getMethod("getInstance", Object.class); } catch (NoSuchMethodException e) { Class superType = type.getSuperclass(); try { if ( superType != Object.class ) { getInstance = type.getSuperclass().getMethod("getInstance", Object.class); } } catch (NoSuchMethodException e2) { } if ( getInstance == null ) throw e; } return (ASN1Encodable) getInstance.invoke(null, value); } public static void createASN1(final Ruby runtime, final RubyModule OpenSSL) { final RubyModule ASN1 = OpenSSL.defineModuleUnder("ASN1"); final RubyClass OpenSSLError = OpenSSL.getClass("OpenSSLError"); ASN1.defineClassUnder("ASN1Error", OpenSSLError, OpenSSLError.getAllocator()); ASN1.defineAnnotatedMethods(ASN1.class); final RubyArray UNIVERSAL_TAG_NAME = runtime.newArray(ASN1_INFO.length); for ( int i = 0; i < ASN1_INFO.length; i++ ) { final String name = (String) ASN1_INFO[i][0]; if ( name.charAt(0) != '[' ) { UNIVERSAL_TAG_NAME.append( runtime.newString(name) ); ASN1.setConstant( name, runtime.newFixnum(i) ); } else { UNIVERSAL_TAG_NAME.append( runtime.getNil() ); } } ASN1.setConstant("UNIVERSAL_TAG_NAME", UNIVERSAL_TAG_NAME); final ThreadContext context = runtime.getCurrentContext(); final ObjectAllocator asn1DataAllocator = ASN1Data.ALLOCATOR; RubyClass _ASN1Data = ASN1.defineClassUnder("ASN1Data", runtime.getObject(), asn1DataAllocator); _ASN1Data.addReadWriteAttribute(context, "value"); _ASN1Data.addReadWriteAttribute(context, "tag"); _ASN1Data.addReadWriteAttribute(context, "tag_class"); _ASN1Data.defineAnnotatedMethods(ASN1Data.class); final ObjectAllocator primitiveAllocator = Primitive.ALLOCATOR; RubyClass Primitive = ASN1.defineClassUnder("Primitive", _ASN1Data, primitiveAllocator); Primitive.addReadWriteAttribute(context, "tagging"); Primitive.addReadAttribute(context, "infinite_length"); Primitive.defineAnnotatedMethods(Primitive.class); final ObjectAllocator constructiveAllocator = Constructive.ALLOCATOR; RubyClass Constructive = ASN1.defineClassUnder("Constructive", _ASN1Data, constructiveAllocator); Constructive.includeModule( runtime.getModule("Enumerable") ); Constructive.addReadWriteAttribute(context, "tagging"); Constructive.addReadWriteAttribute(context, "infinite_length"); Constructive.defineAnnotatedMethods(Constructive.class); ASN1.defineClassUnder("Boolean", Primitive, primitiveAllocator); // OpenSSL::ASN1::Boolean <=> value is a Boolean ASN1.defineClassUnder("Integer", Primitive, primitiveAllocator); // OpenSSL::ASN1::Integer <=> value is a Number ASN1.defineClassUnder("Null", Primitive, primitiveAllocator); // OpenSSL::ASN1::Null <=> value is always nil ASN1.defineClassUnder("Object", Primitive, primitiveAllocator); // OpenSSL::ASN1::Object <=> value is a String ASN1.defineClassUnder("Enumerated", Primitive, primitiveAllocator); // OpenSSL::ASN1::Enumerated <=> value is a Number RubyClass BitString = ASN1.defineClassUnder("BitString", Primitive, primitiveAllocator); BitString.addReadWriteAttribute(context, "unused_bits"); ASN1.defineClassUnder("OctetString", Primitive, primitiveAllocator); ASN1.defineClassUnder("UTF8String", Primitive, primitiveAllocator); ASN1.defineClassUnder("NumericString", Primitive, primitiveAllocator); ASN1.defineClassUnder("PrintableString", Primitive, primitiveAllocator); ASN1.defineClassUnder("T61String", Primitive, primitiveAllocator); ASN1.defineClassUnder("VideotexString", Primitive, primitiveAllocator); ASN1.defineClassUnder("IA5String", Primitive, primitiveAllocator); ASN1.defineClassUnder("GraphicString", Primitive, primitiveAllocator); ASN1.defineClassUnder("ISO64String", Primitive, primitiveAllocator); ASN1.defineClassUnder("GeneralString", Primitive, primitiveAllocator); ASN1.defineClassUnder("UniversalString", Primitive, primitiveAllocator); ASN1.defineClassUnder("BMPString", Primitive, primitiveAllocator); ASN1.defineClassUnder("UTCTime", Primitive, primitiveAllocator); // OpenSSL::ASN1::UTCTime <=> value is a Time ASN1.defineClassUnder("GeneralizedTime", Primitive, primitiveAllocator); // OpenSSL::ASN1::GeneralizedTime <=> value is a Time ASN1.defineClassUnder("EndOfContent", Primitive, primitiveAllocator); // OpenSSL::ASN1::EndOfContent <=> value is always nil RubyClass ObjectId = ASN1.defineClassUnder("ObjectId", Primitive, primitiveAllocator); ObjectId.defineAnnotatedMethods(ObjectId.class); ASN1.defineClassUnder("Sequence", Constructive, Constructive.getAllocator()); ASN1.defineClassUnder("Set", Constructive, Constructive.getAllocator()); } static ASN1ObjectIdentifier getObjectID(final Ruby runtime, final String nameOrOid) throws IllegalArgumentException { final String name = nameOrOid.toLowerCase(); ASN1ObjectIdentifier objectId = getOIDLookup(runtime).get( name ); if ( objectId != null ) return objectId; final String objectIdStr = ASN1Registry.getOIDLookup().get( name ); if ( objectIdStr != null ) return toObjectID(objectIdStr, false); return new ASN1ObjectIdentifier( nameOrOid ); } static ASN1ObjectIdentifier toObjectID(final String oid, final boolean silent) throws IllegalArgumentException { try { return new ASN1ObjectIdentifier(oid); } catch (IllegalArgumentException e) { if ( silent ) return null; throw e; } } @JRubyMethod(name="Boolean", module=true, rest=true) public static IRubyObject fact_Boolean(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "Boolean", args); } @JRubyMethod(name="Integer", module=true, rest=true) public static IRubyObject fact_Integer(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "Integer", args); } @JRubyMethod(name="Enumerated", module=true, rest=true) public static IRubyObject fact_Enumerated(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "Enumerated", args); } @JRubyMethod(name="BitString", module=true, rest=true) public static IRubyObject fact_BitString(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "BitString", args); } @JRubyMethod(name="OctetString", module=true, rest=true) public static IRubyObject fact_OctetString(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "OctetString", args); } @JRubyMethod(name="UTF8String", module=true, rest=true) public static IRubyObject fact_UTF8String(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "UTF8String", args); } @JRubyMethod(name="NumericString", module=true, rest=true) public static IRubyObject fact_NumericString(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "NumericString", args); } @JRubyMethod(name="PrintableString", module=true, rest=true) public static IRubyObject fact_PrintableString(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "PrintableString", args); } @JRubyMethod(name="T61String", module=true, rest=true) public static IRubyObject fact_T61String(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "T61String", args); } @JRubyMethod(name="VideotexString", module=true, rest=true) public static IRubyObject fact_VideotexString(IRubyObject recv, IRubyObject[] args) { return ((RubyModule)recv).getClass("VideotexString").callMethod(recv.getRuntime().getCurrentContext(),"new",args); } @JRubyMethod(name="IA5String", module=true, rest=true) public static IRubyObject fact_IA5String(IRubyObject recv, IRubyObject[] args) { return ((RubyModule)recv).getClass("IA5String").callMethod(recv.getRuntime().getCurrentContext(),"new",args); } @JRubyMethod(name="GraphicString", module=true, rest=true) public static IRubyObject fact_GraphicString(IRubyObject recv, IRubyObject[] args) { return ((RubyModule)recv).getClass("GraphicString").callMethod(recv.getRuntime().getCurrentContext(),"new",args); } @JRubyMethod(name="ISO64String", module=true, rest=true) public static IRubyObject fact_ISO64String(IRubyObject recv, IRubyObject[] args) { return ((RubyModule)recv).getClass("ISO64String").callMethod(recv.getRuntime().getCurrentContext(),"new",args); } @JRubyMethod(name="GeneralString", module=true, rest=true) public static IRubyObject fact_GeneralString(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "GeneralString", args); } @JRubyMethod(name="UniversalString", module=true, rest=true) public static IRubyObject fact_UniversalString(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "UniversalString", args); } @JRubyMethod(name="BMPString", module=true, rest=true) public static IRubyObject fact_BMPString(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "BMPString", args); } @JRubyMethod(name="Nul", module=true, rest=true) public static IRubyObject fact_Null(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "Null", args); } @JRubyMethod(name="ObjectId", module=true, rest=true) public static IRubyObject fact_ObjectId(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "ObjectId", args); } @JRubyMethod(name="UTCTime", module=true, rest=true) public static IRubyObject fact_UTCTime(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "UTCTime", args); } @JRubyMethod(name="GeneralizedTime", module=true, rest=true) public static IRubyObject fact_GeneralizedTime(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "GeneralizedTime", args); } @JRubyMethod(name="Sequence", module=true, rest=true) public static IRubyObject fact_Sequence(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "Sequence", args); } @JRubyMethod(name="Set", module=true, rest=true) public static IRubyObject fact_Set(IRubyObject self, IRubyObject[] args) { return callClassNew(self, "Set", args); } private static IRubyObject callClassNew(final IRubyObject self, final String className, final IRubyObject[] args) { return ((RubyModule) self).getClass(className).callMethod(self.getRuntime().getCurrentContext(), "new", args); } public static class ObjectId { @JRubyMethod(meta = true, rest = true) public static IRubyObject register(final IRubyObject self, final IRubyObject[] args) { final Ruby runtime = self.getRuntime(); final ASN1ObjectIdentifier derOid = new ASN1ObjectIdentifier( args[0].toString() ); final String a1 = args[1].toString(); final String a2 = args[2].toString(); synchronized(ASN1.class) { Map sym2oid = getOIDLookup(runtime); sym2oid.put( a1.toLowerCase(), derOid ); sym2oid.put( a2.toLowerCase(), derOid ); getSymLookup(runtime).put( derOid, a1 ); } return runtime.getTrue(); } @JRubyMethod(name = { "sn", "short_name" }) public static RubyString sn(final ThreadContext context, final IRubyObject self) { return name(context, self.callMethod(context, "value"), false); } @JRubyMethod(name = { "ln", "long_name" }) public static RubyString ln(final ThreadContext context, final IRubyObject self) { return name(context, self.callMethod(context, "value"), true); } @JRubyMethod public static RubyString oid(final ThreadContext context, final IRubyObject self) { final Ruby runtime = context.runtime; return runtime.newString( getObjectID(runtime, self.callMethod(context, "value").toString()).getId() ); } private static RubyString name(final ThreadContext context, IRubyObject value, final boolean longName) { final Ruby runtime = context.runtime; final String oid = value.toString(); // name or oid Integer nid = null; try { nid = ASN1.oid2nid(runtime, ASN1.getObjectID(runtime, oid)); } catch (IllegalArgumentException e) { /* ignored */ } // not an oid if ( nid != null ) { String val = longName ? nid2ln(runtime, nid) : nid2sn(runtime, nid); if ( val != null ) return runtime.newString(val); } return value.asString(); } } // ObjectId static IRubyObject decodeObject(final ThreadContext context, final RubyModule ASN1, final org.bouncycastle.asn1.ASN1Encodable obj) throws IOException, IllegalArgumentException { final Ruby runtime = context.runtime; if ( obj instanceof ASN1Integer ) { final BN val = BN.newBN(runtime, ((ASN1Integer) obj).getValue()); return ASN1.getClass("Integer").callMethod(context, "new", val); } if ( obj instanceof DERInteger ) { final BN val = BN.newBN(runtime, ((DERInteger) obj).getValue()); return ASN1.getClass("Integer").callMethod(context, "new", val); } if ( obj instanceof DERBitString ) { final DERBitString derObj = (DERBitString) obj; RubyString str = runtime.newString( new ByteList(derObj.getBytes(), false) ); IRubyObject bitString = ASN1.getClass("BitString").callMethod(context, "new", str); bitString.callMethod(context, "unused_bits=", runtime.newFixnum( derObj.getPadBits() )); return bitString; } if ( obj instanceof ASN1String ) { final Integer typeId = typeId( obj.getClass() ); String type = typeId == null ? null : (String) ( ASN1_INFO[typeId][2] ); final ByteList bytes; if ( obj instanceof DERUTF8String ) { if ( type == null ) type = "UTF8String"; bytes = new ByteList(((DERUTF8String) obj).getString().getBytes("UTF-8"), false); } else { if ( type == null ) { if ( obj instanceof DERNumericString ) { type = "NumericString"; } else if ( obj instanceof DERPrintableString ) { type = "PrintableString"; } else if ( obj instanceof DERIA5String ) { type = "IA5String"; } else if ( obj instanceof DERT61String ) { type = "T61String"; } else if ( obj instanceof DERGeneralString ) { type = "GeneralString"; } else if ( obj instanceof DERUniversalString ) { type = "UniversalString"; } else if ( obj instanceof DERBMPString ) { type = "BMPString"; } else { // NOTE "VideotexString", "GraphicString", "ISO64String" not-handled in BC ! throw new IllegalArgumentException("could not handle ASN1 string type: " + obj + " (" + obj.getClass().getName() + ")"); } } bytes = ByteList.create(((ASN1String) obj).getString()); } return ASN1.getClass(type).callMethod(context, "new", runtime.newString(bytes)); } //if ( obj instanceof DEROctetString ) { // byte[] octets = ((ASN1OctetString) obj).getOctets(); // if ( (octets[0] & 0xFF) == 0xD1 ) Thread.dumpStack(); //} if ( obj instanceof ASN1OctetString ) { final ByteList octets = new ByteList(((ASN1OctetString) obj).getOctets(), false); // NOTE: sometimes MRI does include the tag but it really should not ;( ! //final ByteList octets = new ByteList(((ASN1OctetString) obj).getEncoded(ASN1Encoding.DER), false); return ASN1.getClass("OctetString").callMethod(context, "new", runtime.newString(octets)); } if ( obj instanceof ASN1Null ) { return ASN1.getClass("Null").callMethod(context,"new", runtime.getNil()); } if ( obj instanceof ASN1Boolean ) { final boolean val = ((ASN1Boolean) obj).isTrue(); return ASN1.getClass("Boolean").callMethod(context, "new", runtime.newBoolean(val)); } // DERBoolean extends ASN1Boolean only since 1.51 (<= 1.50 the other way around) if ( obj instanceof DERBoolean ) { final boolean val = ((DERBoolean) obj).isTrue(); return ASN1.getClass("Boolean").callMethod(context, "new", runtime.newBoolean(val)); } if ( obj instanceof ASN1UTCTime ) { final Date adjustedTime; try { adjustedTime = ((ASN1UTCTime) obj).getAdjustedDate(); } catch (ParseException e) { throw new IOException(e); } final RubyTime time = RubyTime.newTime(runtime, adjustedTime.getTime()); return ASN1.getClass("UTCTime").callMethod(context,"new", time); } // NOTE: keep for BC versions compatibility ... extends ASN1UTCTime (since BC 1.51) if ( obj instanceof DERUTCTime ) { final Date adjustedTime; try { adjustedTime = ((DERUTCTime) obj).getAdjustedDate(); } catch (ParseException e) { throw new IOException(e); } final RubyTime time = RubyTime.newTime(runtime, adjustedTime.getTime()); return ASN1.getClass("UTCTime").callMethod(context,"new", time); } if ( obj instanceof ASN1GeneralizedTime ) { final Date generalTime; try { generalTime = ((ASN1GeneralizedTime) obj).getDate(); } catch (ParseException e) { throw new IOException(e); } final RubyTime time = RubyTime.newTime(runtime, generalTime.getTime()); return ASN1.getClass("GeneralizedTime").callMethod(context,"new", time); } // NOTE: keep for BC versions compatibility ... extends ASN1GeneralizedTime (since BC 1.51) if ( obj instanceof DERGeneralizedTime ) { final Date generalTime; try { generalTime = ((DERGeneralizedTime) obj).getDate(); } catch (ParseException e) { throw new IOException(e); } final RubyTime time = RubyTime.newTime(runtime, generalTime.getTime()); return ASN1.getClass("GeneralizedTime").callMethod(context,"new", time); } if ( obj instanceof ASN1ObjectIdentifier ) { final String objId = ((ASN1ObjectIdentifier) obj).getId(); return ASN1.getClass("ObjectId").callMethod(context, "new", runtime.newString(objId)); } // ASN1ObjectIdentifier extends DERObjectIdentifier < 1.51 // DERObjectIdentifier extends ASN1ObjectIdentifier = 1.51 if ( obj instanceof DERObjectIdentifier ) { final String objId = ((DERObjectIdentifier) obj).getId(); return ASN1.getClass("ObjectId").callMethod(context, "new", runtime.newString(objId)); } if ( obj instanceof ASN1TaggedObject ) { final ASN1TaggedObject taggedObj = (ASN1TaggedObject) obj; IRubyObject val = decodeObject(context, ASN1, taggedObj.getObject()); IRubyObject tag = runtime.newFixnum( taggedObj.getTagNo() ); IRubyObject tag_class = runtime.newSymbol("CONTEXT_SPECIFIC"); final RubyArray valArr = runtime.newArray(val); return ASN1.getClass("ASN1Data").callMethod(context, "new", new IRubyObject[] { valArr, tag, tag_class } ); } if ( obj instanceof DERApplicationSpecific ) { final DERApplicationSpecific appSpecific = (DERApplicationSpecific) obj; IRubyObject tag = runtime.newFixnum( appSpecific.getApplicationTag() ); IRubyObject tag_class = runtime.newSymbol("APPLICATION"); final ASN1Sequence sequence = (ASN1Sequence) appSpecific.getObject(SEQUENCE); @SuppressWarnings("unchecked") final RubyArray valArr = decodeObjects(context, ASN1, sequence.getObjects()); return ASN1.getClass("ASN1Data").callMethod(context, "new", new IRubyObject[] { valArr, tag, tag_class } ); } if ( obj instanceof ASN1Sequence ) { @SuppressWarnings("unchecked") RubyArray arr = decodeObjects(context, ASN1, ((ASN1Sequence) obj).getObjects()); return ASN1.getClass("Sequence").callMethod(context, "new", arr); } if ( obj instanceof ASN1Set ) { @SuppressWarnings("unchecked") RubyArray arr = decodeObjects(context, ASN1, ((ASN1Set) obj).getObjects()); return ASN1.getClass("Set").callMethod(context, "new", arr); } if ( obj instanceof ASN1Enumerated ) { final RubyInteger value = RubyBignum.bignorm(runtime, ((ASN1Enumerated) obj).getValue()); return ASN1.getClass("Enumerated").callMethod(context, "new", value); } throw new IllegalArgumentException("unable to decode object: " + obj + " (" + ( obj == null ? "" : obj.getClass().getName() ) + ")"); } private static RubyArray decodeObjects(final ThreadContext context, final RubyModule ASN1, final Enumeration e) throws IOException { final RubyArray arr = context.runtime.newArray(); while ( e.hasMoreElements() ) { arr.append( decodeObject(context, ASN1, e.nextElement()) ); } return arr; } @JRubyMethod(meta = true) public static IRubyObject decode(final ThreadContext context, final IRubyObject self, final IRubyObject obj) { try { return decodeImpl(context, (RubyModule) self, obj); } catch (IOException e) { //throw context.runtime.newIOErrorFromException(e); throw newASN1Error(context.runtime, e.getMessage()); } catch (IllegalArgumentException e) { debugStackTrace(context.runtime, e); throw context.runtime.newArgumentError(e.getMessage()); } //catch (RuntimeException e) { // final Ruby runtime = context.runtime; // debugStackTrace(runtime, e); // throw Utils.newRuntimeError(context.runtime, e); //} } static IRubyObject decodeImpl(final ThreadContext context, IRubyObject obj) throws IOException, IllegalArgumentException { return decodeImpl(context, _ASN1(context.runtime), obj); } static IRubyObject decodeImpl(final ThreadContext context, final RubyModule ASN1, IRubyObject obj) throws IOException, IllegalArgumentException { obj = to_der_if_possible(context, obj); BytesInputStream in = new BytesInputStream( obj.asString().getByteList() ); final IRubyObject decoded = decodeImpl(context, ASN1, in); if ( in.available() > 0 ) { final int read = in.readCount(); throw new IOException("Type mismatch. Total bytes read: "+ read + " Bytes available: " + in.available()); } return decoded; } private static class BytesInputStream extends ByteArrayInputStream { private BytesInputStream(final ByteList bytes) { super(bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize()); } final byte[] bytes() { return buf; } final int readCount() { return pos - mark; } // since last mark final int position() { return pos; } final int offset() { return mark; } } private static IRubyObject decodeImpl(final ThreadContext context, final RubyModule ASN1, final BytesInputStream in) throws IOException, IllegalArgumentException { // NOTE: need to handle OpenSSL::ASN1::Constructive wrapping by hand : final Integer tag = getConstructiveTag(in.bytes(), in.offset()); IRubyObject decoded = decodeObject(context, ASN1, readObject( in )); if ( tag != null ) { // OpenSSL::ASN1::Constructive.new( arg ) : final String type; List value = null; if ( tag.intValue() == SEQUENCE ) { //type = "Sequence"; // got a OpenSSL::ASN1::Sequence already : return Constructive.setInfiniteLength(context, decoded); } else if ( tag.intValue() == SET ) { //type = "Set"; // got a OpenSSL::ASN1::Set already : return Constructive.setInfiniteLength(context, decoded); } else { type = "Constructive"; } if ( value == null ) value = Collections.singletonList(decoded); return Constructive.newInfiniteConstructive(context, type, value, tag); } return decoded; } @JRubyMethod(meta = true, required = 1) public static IRubyObject decode_all(final ThreadContext context, final IRubyObject self, IRubyObject obj) { obj = to_der_if_possible(context, obj); BytesInputStream in = new BytesInputStream( obj.asString().getByteList() ); final RubyModule ASN1 = _ASN1(context.runtime); final RubyArray arr = context.runtime.newArray(); while ( in.available() > 0 ) { try { in.mark(0); // set offset() before each object is read arr.append( decodeImpl(context, ASN1, in) ); } catch (IOException e) { //throw context.runtime.newIOErrorFromException(e); throw newASN1Error(context.runtime, e.getMessage()); } catch (IllegalArgumentException e) { debugStackTrace(context.runtime, e); throw context.runtime.newArgumentError(e.getMessage()); } } return arr; } @JRubyMethod(meta = true, required = 1) public static IRubyObject traverse(final ThreadContext context, final IRubyObject self, IRubyObject arg) { warn(context, "WARNING: unimplemented method called: ASN1#traverse"); return context.runtime.getNil(); } public static RaiseException newASN1Error(Ruby runtime, String message) { return Utils.newError(runtime, _ASN1(runtime).getClass("ASN1Error"), message, false); } static RubyModule _ASN1(final Ruby runtime) { return (RubyModule) runtime.getModule("OpenSSL").getConstant("ASN1"); } static org.bouncycastle.asn1.ASN1Primitive readObject(final byte[] bytes) throws IOException { return new ASN1InputStream(new ByteArrayInputStream(bytes)).readObject(); } private static org.bouncycastle.asn1.ASN1Primitive readObject(final InputStream bytes) throws IOException { return new ASN1InputStream(bytes).readObject(); } // NOTE: BC's ASNInputStream internals "reinvented" a bit : private static Integer getConstructiveTag(final byte[] asn1, int offset) { final int tag = asn1[ offset ] & 0xFF; if ( ( tag & BERTags.CONSTRUCTED ) != 0 ) { // isConstructed // // calculate tag number // // readTagNumber(asn1, ++offset, tag) : int tagNo = tag & 0x1f; // // with tagged object tag number is bottom 5 bits, or stored at the start of the content // if (tagNo == 0x1f) { tagNo = 0; int b = asn1[ ++offset ]; //s.read(); // X.690-0207 8.1.2.4.2 // "c) bits 7 to 1 of the first subsequent octet shall not all be zero." if ((b & 0x7f) == 0) // Note: -1 will pass { return null; //throw new IOException("corrupted stream - invalid high tag number found"); } while ((b >= 0) && ((b & 0x80) != 0)) { tagNo |= (b & 0x7f); tagNo <<= 7; b = asn1[ ++offset ]; //s.read(); } if (b < 0) { return null; //throw new EOFException("EOF found inside tag value."); } tagNo |= (b & 0x7f); } // // calculate length // final int length = asn1[ ++offset ] & 0xFF; if ( length == 0x80 ) { // return -1; // indefinite-length encoding } else { return null; } if ((tag & BERTags.APPLICATION) != 0) { //return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject(); } if ((tag & BERTags.TAGGED) != 0) { //return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject(); } //System.out.println(" tagNo = 0x" + Integer.toHexString(tagNo)); // TODO There are other tags that may be constructed (e.g. BIT_STRING) switch (tagNo) { case BERTags.SEQUENCE : //return new BERSequenceParser(sp).getLoadedObject(); return Integer.valueOf( SEQUENCE ); //return "Sequence"; case BERTags.SET : //return new BERSetParser(sp).getLoadedObject(); return Integer.valueOf( SET ); //return "Set"; case BERTags.OCTET_STRING : return Integer.valueOf( OCTET_STRING ); //return new BEROctetStringParser(sp).getLoadedObject(); case BERTags.EXTERNAL : //return new DERExternalParser(sp).getLoadedObject(); default: return Integer.valueOf( 0 ); //return "Constructive"; //throw new IOException("unknown BER object encountered"); } } return null; } public static class ASN1Data extends RubyObject { private static final long serialVersionUID = 6117598347932209839L; static ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new ASN1Data(runtime, klass); } }; static final int MAX_TAG_VALUE = ASN1_INFO.length; public ASN1Data(Ruby runtime, RubyClass type) { super(runtime,type); } @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject value, final IRubyObject tag, final IRubyObject tag_class) { checkTag(context.runtime, tag, tag_class, "UNIVERSAL"); this.callMethod(context, "tag=", tag); this.callMethod(context, "value=", value); this.callMethod(context, "tag_class=", tag_class); return this; } private void checkTag(final Ruby runtime, final IRubyObject tag, final IRubyObject tagClass, final String expected) { if ( ! (tagClass instanceof RubySymbol) ) { throw newASN1Error(runtime, "invalid tag class"); } if ( tagClass.toString().equals(expected) && RubyNumeric.fix2int(tag) > MAX_TAG_VALUE ) { throw newASN1Error(runtime, "tag number for :" + expected + " too large"); } } boolean isEOC() { return false; } boolean isExplicitTagging() { return ! isImplicitTagging(); } boolean isImplicitTagging() { return true; } int getTag(final ThreadContext context) { return RubyNumeric.fix2int(callMethod(context, "tag")); } ASN1Encodable toASN1(final ThreadContext context) { return toASN1TaggedObject(context); } final ASN1TaggedObject toASN1TaggedObject(final ThreadContext context) { final int tag = getTag(context); final IRubyObject val = callMethod(context, "value"); if ( val instanceof RubyArray ) { final RubyArray arr = (RubyArray) val; if ( arr.size() > 1 ) { ASN1EncodableVector vec = new ASN1EncodableVector(); for ( final IRubyObject obj : arr.toJavaArray() ) { ASN1Encodable data = ((ASN1Data) obj).toASN1(context); if ( data == null ) break; vec.add( data ); } return new DERTaggedObject(isExplicitTagging(), tag, new DERSequence(vec)); } else if ( arr.size() == 1 ) { ASN1Encodable data = ((ASN1Data) arr.entry(0)).toASN1(context); return new DERTaggedObject(isExplicitTagging(), tag, data); } else { throw new IllegalStateException("empty array detected"); } } return new DERTaggedObject(isExplicitTagging(), tag, ((ASN1Data) val).toASN1(context)); } @JRubyMethod public IRubyObject to_der(final ThreadContext context) { try { final byte[] encoded = toDER(context); return context.runtime.newString(new ByteList(encoded, false)); } catch (IOException e) { throw newASN1Error(context.runtime, e.getMessage()); } } byte[] toDER(final ThreadContext context) throws IOException { return toASN1(context).toASN1Primitive().getEncoded(ASN1Encoding.DER); } protected IRubyObject defaultTag() { final Integer id = typeId( getMetaClass() ); if ( id == null ) return getRuntime().getNil(); return getRuntime().newFixnum( id.intValue() ); } final IRubyObject value() { return value(getRuntime().getCurrentContext()); } IRubyObject value(final ThreadContext context) { return callMethod(context, "value"); } final String getClassBaseName() { return getMetaClass().getBaseName(); } @Override public String toString() { return value().toString(); } protected final void print() { print(0); } protected void print(int indent) { final PrintStream out = getRuntime().getOut(); printIndent(out, indent); final IRubyObject value = value(); out.println("ASN1Data: "); if ( value instanceof RubyArray ) { printArray(out, indent, (RubyArray) value); } else { ((ASN1Data) value).print(indent + 1); } } static void printIndent(final PrintStream out, final int indent) { for ( int i = 0; i < indent; i++) out.print(" "); } static void printArray(final PrintStream out, final int indent, final RubyArray array) { for ( int i = 0; i < array.size(); i++ ) { ((ASN1Data) array.entry(i)).print(indent + 1); } } static RaiseException createNativeRaiseException(final ThreadContext context, final Throwable e) { Throwable cause = e.getCause(); if ( cause == null ) cause = e; return RaiseException.createNativeRaiseException(context.runtime, cause); } } public static class Primitive extends ASN1Data { private static final long serialVersionUID = 8489625559339190259L; static ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new Primitive(runtime, klass); } }; public Primitive(Ruby runtime, RubyClass type) { super(runtime,type); } @Override @JRubyMethod public IRubyObject to_der(final ThreadContext context) { if ( value(context).isNil() ) { // MRI compatibility but avoids Java exceptions as well e.g. // Java::JavaLang::NumberFormatException // java.math.BigInteger.(BigInteger.java:296) // java.math.BigInteger.(BigInteger.java:476) // org.jruby.ext.openssl.ASN1$ASN1Primitive.toASN1(ASN1.java:1287) // org.jruby.ext.openssl.ASN1$ASN1Data.to_der(ASN1.java:1129) // org.jruby.ext.openssl.ASN1$ASN1Primitive.to_der(ASN1.java:1202) throw context.runtime.newTypeError("nil value"); } return super.to_der(context); } @JRubyMethod(required = 0, optional = 4, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { initializeImpl(context, this, args); return this; } // shared initialize logic between Primitive and Constructive static void initializeImpl(final ThreadContext context, final ASN1Data self, final IRubyObject[] args) { final Ruby runtime = context.runtime; final int len = args.length; IRubyObject value = len == 0 ? runtime.getNil() : args[0]; final IRubyObject tag; IRubyObject tagging = runtime.getNil(); IRubyObject tag_class = runtime.getNil(); if ( len > 1 ) { tag = args[1]; if ( len > 2 ) { tagging = args[2]; if ( len > 3 ) tag_class = args[3]; } if ( tag.isNil() ) throw newASN1Error(runtime, "must specify tag number"); if ( tagging.isNil() ) tagging = runtime.newSymbol("EXPLICIT"); if ( ! (tagging instanceof RubySymbol) ) { throw newASN1Error(runtime, "invalid tag default"); } if ( tag_class.isNil() ) tag_class = runtime.newSymbol("CONTEXT_SPECIFIC"); if ( ! (tag_class instanceof RubySymbol) ) { throw newASN1Error(runtime, "invalid tag class"); } if ( tagging.toString().equals("IMPLICIT") && RubyNumeric.fix2int(tag) > MAX_TAG_VALUE ) { throw newASN1Error(runtime, "tag number for Universal too large"); } } else { tag = self.defaultTag(); tag_class = runtime.newSymbol("UNIVERSAL"); } // NOTE: Primitive only final String baseName = self.getMetaClass().getRealClass().getBaseName(); if ( "ObjectId".equals( baseName ) ) { final String name; try { name = oid2Sym( runtime, getObjectID(runtime, value.toString()), true ); } catch (IllegalArgumentException e) { // e.g. in case of nil "string not an OID" throw runtime.newTypeError(e.getMessage()); } if ( name != null ) value = runtime.newString(name); } self.setInstanceVariable("@tag", tag); self.setInstanceVariable("@value", value); self.setInstanceVariable("@tag_class", tag_class); self.setInstanceVariable("@tagging", tagging); self.setInstanceVariable("@infinite_length", runtime.getFalse()); } @Override boolean isExplicitTagging() { return "EXPLICIT".equals( getInstanceVariable("@tagging").toString() ); } @Override boolean isImplicitTagging() { IRubyObject tagging = getInstanceVariable("@tagging"); if ( tagging.isNil() ) return true; return "IMPLICIT".equals( tagging.toString() ); } @Override boolean isEOC() { return "EndOfContent".equals( getClassBaseName() ); } @Override byte[] toDER(final ThreadContext context) throws IOException { if ( isEOC() ) return new byte[] { 0x00, 0x00 }; return toASN1(context).toASN1Primitive().getEncoded(ASN1Encoding.DER); } static Primitive newInstance(final ThreadContext context, final String type, final IRubyObject value) { RubyClass klass = _ASN1(context.runtime).getClass(type); final Primitive self = new Primitive(context.runtime, klass); if ( value != null ) self.setInstanceVariable("@value", value); return self; } static Primitive newEndOfContent(final ThreadContext context) { return newInstance(context, "EndOfContent", null); } /* private static final Class DERBooleanClass; static { Class klass; try { klass = Class.forName("org.bouncycastle.asn1.DERBoolean"); } catch(ClassNotFoundException e) { klass = null; } DERBooleanClass = klass; } */ @Override ASN1Encodable toASN1(final ThreadContext context) { Class type = typeClass( getMetaClass() ); if ( type == null ) { final int tag = getTag(context); if ( tag == 0 ) return null; // TODO pass EOC to BC ? if ( isExplicitTagging() ) type = typeClass( tag ); if ( type == null ) { throw new IllegalArgumentException( "no type for: " + getMetaClass() + " or tag: " + getTag(context) ); } } final IRubyObject val = callMethod(context, "value"); if ( type == ASN1ObjectIdentifier.class || type == DERObjectIdentifier.class ) { return getObjectID(context.runtime, val.toString()); } if ( type == DERNull.class || type == ASN1Null.class ) { return DERNull.INSTANCE; } if ( ASN1Boolean.class.isAssignableFrom( type ) ) { return ASN1Boolean.getInstance(val.isTrue()); } if ( type == DERBoolean.class ) { return DERBoolean.getInstance(val.isTrue()); } if ( type == DERUTCTime.class ) { if ( val instanceof RubyTime ) { return new DERUTCTime(((RubyTime) val).getJavaDate()); } return DERUTCTime.getInstance( val.asString().getBytes() ); } if ( type == DERGeneralizedTime.class ) { if ( val instanceof RubyTime ) { return new DERGeneralizedTime(((RubyTime) val).getJavaDate()); } return DERGeneralizedTime.getInstance( val.asString().getBytes() ); } if ( type == DERInteger.class ) { return new DERInteger( bigIntegerValue(val) ); } if ( ASN1Integer.class.isAssignableFrom( type ) ) { return new ASN1Integer( bigIntegerValue(val) ); } if ( type == DEREnumerated.class ) { return new DEREnumerated( bigIntegerValue(val) ); } if ( type == ASN1Enumerated.class ) { return new ASN1Enumerated( bigIntegerValue(val) ); } //if ( type == DEROctetString.class ) { if ( ASN1OctetString.class.isAssignableFrom( type ) ) { return new DEROctetString( val.asString().getBytes() ); } if ( type == DERBitString.class ) { final byte[] bs = val.asString().getBytes(); int unused = 0; for ( int i = (bs.length - 1); i > -1; i-- ) { if (bs[i] == 0) unused += 8; else { byte v2 = bs[i]; int x = 8; while ( v2 != 0 ) { v2 <<= 1; x--; } unused += x; break; } } return new DERBitString(bs, unused); } if ( type == DERIA5String.class ) { return new DERIA5String( val.asString().toString() ); } if ( type == DERUTF8String.class ) { return new DERUTF8String( val.asString().toString() ); } if ( type == DERBMPString.class ) { return new DERBMPString( val.asString().toString() ); } if ( type == DERUniversalString.class ) { return new DERUniversalString( val.asString().getBytes() ); } if ( type == DERGeneralString.class ) { return DERGeneralString.getInstance( val.asString().getBytes() ); } if ( type == DERVisibleString.class ) { return DERVisibleString.getInstance( val.asString().getBytes() ); } if ( type == DERNumericString.class ) { return DERNumericString.getInstance( val.asString().getBytes() ); } if ( val instanceof RubyString ) { try { return typeInstance(type, ( (RubyString) val ).getBytes()); } catch (Exception e) { // TODO exception handling debugStackTrace(context.runtime, e); throw createNativeRaiseException(context, e); } } // TODO throw an exception here too? if ( isDebug(context.runtime) ) { debug(this + " toASN1() could not handle class " + getMetaClass() + " and value " + val.inspect() + " (" + val.getClass().getName() + ")"); } warn(context, "WARNING: unimplemented method called: ASN1Data#toASN1 (" + type + ")"); return null; } private static BigInteger bigIntegerValue(final IRubyObject val) { if ( val instanceof RubyInteger ) { // RubyBignum return ((RubyInteger) val).getBigIntegerValue(); } if ( val instanceof BN ) ((BN) val).getValue(); return new BigInteger( val.asString().getBytes() ); } @Override protected void print(int indent) { final PrintStream out = getRuntime().getOut(); printIndent(out, indent); out.print(getMetaClass().getRealClass().getBaseName()); out.print(": "); out.println(value().callMethod(getRuntime().getCurrentContext(), "inspect").toString()); } } public static class Constructive extends ASN1Data { // implements ASN1Encodable { private static final long serialVersionUID = -7166662655104776828L; static ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new Constructive(runtime, klass); } }; public Constructive(Ruby runtime, RubyClass type) { super(runtime, type); } @JRubyMethod(required = 1, optional = 3, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { Primitive.initializeImpl(context, this, args); return this; } static Constructive newInfiniteConstructive(final ThreadContext context, final String type, final List value, final int defaultTag) { final Ruby runtime = context.runtime; final RubyClass klass = _ASN1(context.runtime).getClass(type); final Constructive self = new Constructive(runtime, klass); final RubyArray values = runtime.newArray(value.size()); for ( final IRubyObject val : value ) values.append(val); // values.append( Primitive.newEndOfContent(context) ); self.setInstanceVariable("@tag", runtime.newFixnum(defaultTag)); self.setInstanceVariable("@value", values); self.setInstanceVariable("@tag_class", runtime.newSymbol("UNIVERSAL")); self.setInstanceVariable("@tagging", context.nil); return setInfiniteLength(context, self); } static Constructive setInfiniteLength(final ThreadContext context, final IRubyObject constructive) { final Constructive instance = ((Constructive) constructive); final IRubyObject eoc = Primitive.newEndOfContent(context); final IRubyObject value = instance.value(context); if ( value instanceof RubyArray ) ((RubyArray) value).append(eoc); else value.callMethod(context, "<<", eoc); instance.setInstanceVariable("@infinite_length", context.runtime.getTrue()); return instance; } private boolean rawConstructive() { return "Constructive".equals( getClassBaseName() ); } private boolean isSequence() { return "Sequence".equals( getClassBaseName() ); } private boolean isSet() { return "Set".equals( getClassBaseName() ); } private boolean isInfiniteLength() { return getInstanceVariable("@infinite_length").isTrue(); } @Override boolean isExplicitTagging() { IRubyObject tagging = getInstanceVariable("@tagging"); if ( tagging.isNil() ) return true; return "EXPLICIT".equals( tagging.toString() ); } @Override boolean isImplicitTagging() { return "IMPLICIT".equals( getInstanceVariable("@tagging").toString() ); } @Override ASN1Encodable toASN1(final ThreadContext context) { if ( isInfiniteLength() ) return super.toASN1(context); if ( isSequence() ) { return new DERSequence( toASN1EncodableVector(context) ); } if ( isSet() ) { return new DLSet( toASN1EncodableVector(context) ); // return new BERSet(values); //return ASN1Set.getInstance(toASN1TaggedObject(context), isExplicitTagging()); } switch ( getTag(context) ) { // "raw" Constructive ?!? case OCTET_STRING: final ASN1EncodableVector values = toASN1EncodableVector(context); ASN1OctetString[] octets = new ASN1OctetString[ values.size() ]; for ( int i = 0; i < values.size(); i++ ) { octets[i] = (ASN1OctetString) values.get(i).toASN1Primitive(); } return new BEROctetString(octets); case SEQUENCE: return new DERSequence( toASN1EncodableVector(context) ); case SET: return new DLSet( toASN1EncodableVector(context) ); // return new BERSet(values); //return ASN1Set.getInstance(toASN1TaggedObject(context), isExplicitTagging()); } throw new UnsupportedOperationException( this.inspect().toString() ); } @Override @JRubyMethod public IRubyObject to_der(final ThreadContext context) { if ( rawConstructive() ) { // MRI compatibility if ( ! isInfiniteLength() && ! super.value(context).isNil() ) { final Ruby runtime = context.runtime; throw newASN1Error(runtime, "Constructive shall only be used" + " with infinite length"); } } return super.to_der(context); } @Override byte[] toDER(final ThreadContext context) throws IOException { if ( isInfiniteLength() ) { if ( isSequence() ) { return sequenceToDER(context); } else if ( isSet() ) { return setToDER(context); } else { // "raw" Constructive switch ( getTag(context) ) { case OCTET_STRING: return octetStringToDER(context); case BIT_STRING: return bitStringToDER(context); case SEQUENCE: return sequenceToDER(context); case SET: return setToDER(context); } throw new UnsupportedOperationException( this.inspect().toString() ); } } return super.toDER(context); } private byte[] bitStringToDER(final ThreadContext context) throws IOException { final ASN1EncodableVector values = toASN1EncodableVector(context); final ByteArrayOutputStream out = new ByteArrayOutputStream(); out.write(BERTags.CONSTRUCTED | BERTags.BIT_STRING); out.write(0x80); // infinite-length for ( int i = 0; i < values.size(); i++ ) { out.write( values.get(i).toASN1Primitive().getEncoded() ); } out.write(0x00); out.write(0x00); // writeBEREnd return out.toByteArray(); } private byte[] octetStringToDER(final ThreadContext context) throws IOException { final ASN1EncodableVector values = toASN1EncodableVector(context); ASN1OctetString[] octets = new ASN1OctetString[ values.size() ]; for ( int i = 0; i < values.size(); i++ ) { octets[i] = (ASN1OctetString) values.get(i).toASN1Primitive(); } return new BEROctetString(octets).getEncoded(); } private byte[] sequenceToDER(final ThreadContext context) throws IOException { final ASN1EncodableVector values = toASN1EncodableVector(context); final ByteArrayOutputStream out = new ByteArrayOutputStream(64); BERSequenceGenerator sequenceGenerator = new BERSequenceGenerator(out); for ( int i = 0; i < values.size(); i++ ) { final ASN1Encodable value = values.get(i); if ( value instanceof InternalEncodable ) { // HACK byte[] nested = ((InternalEncodable) value).entry.toDER(context); out.write(nested, 0, nested.length); continue; } sequenceGenerator.addObject( values.get(i) ); } sequenceGenerator.close(); return out.toByteArray(); } private byte[] setToDER(final ThreadContext context) throws IOException { final ASN1EncodableVector values = toASN1EncodableVector(context); return new BERSet(values).toASN1Primitive().getEncoded(); } private ASN1EncodableVector toASN1EncodableVector(final ThreadContext context) { final ASN1EncodableVector vec = new ASN1EncodableVector(); final IRubyObject value = value(context); if ( value instanceof RubyArray ) { final RubyArray val = (RubyArray) value; for ( int i = 0; i < val.size(); i++ ) { if ( addEntry(context, vec, val.entry(i)) ) break; } } else { final int size = RubyInteger.num2int(value.callMethod(context, "size")); for ( int i = 0; i < size; i++ ) { final RubyInteger idx = context.runtime.newFixnum(i); IRubyObject entry = value.callMethod(context, "[]", idx); if ( addEntry(context, vec, entry) ) break; } } return vec; } public ASN1Primitive toASN1Primitive() { throw new UnsupportedOperationException(); } private static class InternalEncodable implements ASN1Encodable { final Constructive entry; InternalEncodable(Constructive entry) { this.entry = entry; } @Override public ASN1Primitive toASN1Primitive() { throw new UnsupportedOperationException(); } } private static boolean addEntry(final ThreadContext context, final ASN1EncodableVector vec, final IRubyObject entry) { try { if ( entry instanceof Constructive ) { final Constructive constructive = (Constructive) entry; if ( constructive.isInfiniteLength() || constructive.rawConstructive() ) { vec.add( new InternalEncodable( (Constructive) entry) ); } else { vec.add( constructive.toASN1(context) ); } } else if ( entry instanceof ASN1Data ) { final ASN1Data data = ( (ASN1Data) entry ); if ( data.isEOC() ) return true; vec.add( data.toASN1(context) ); } else { vec.add( ( (ASN1Data) decodeImpl(context, entry) ).toASN1(context) ); } return false; } catch (IOException e) { throw Utils.newIOError(context.runtime, e); } } @JRubyMethod public IRubyObject each(final ThreadContext context, final Block block) { final IRubyObject value = value(context); if ( value instanceof RubyArray ) { final RubyArray val = (RubyArray) value; for ( int i = 0; i < val.size(); i++ ) { block.yield(context, val.entry(i)); } } else { value.callMethod(context, "each", NULL_ARRAY, block); //final int size = RubyInteger.num2int(value.callMethod(context, "size")); //for ( int i = 0; i < size; i++ ) { // final RubyInteger idx = context.runtime.newFixnum(i); // block.yield(context, value.callMethod(context, "[]", idx)); //} } return context.runtime.getNil(); } @JRubyMethod public IRubyObject size(final ThreadContext context) { final IRubyObject value = value(context); if ( value instanceof RubyArray ) { final RubyArray val = (RubyArray) value; return context.runtime.newFixnum(val.size()); } else { return value.callMethod(context, "size"); } } @Override protected void print(int indent) { final PrintStream out = getRuntime().getOut(); printIndent(out, indent); out.print(getMetaClass().getRealClass().getBaseName()); out.println(": "); printArray( out, indent, (RubyArray) value( getRuntime().getCurrentContext() ) ); } } }// ASN1 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/BN.java000066400000000000000000001013521313661621600244310ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2007 William N Dortch * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Collections; import java.util.Random; import org.jruby.Ruby; import org.jruby.RubyBignum; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.runtime.Visibility; /** * OpenSSL::BN implementation. Wraps java.math.BigInteger, which provides * most functionality directly; the rest is easily derived. * * Beware that BN's are mutable -- I don't agree with this approach, but * must conform for compatibility with MRI's implementation. The offending methods * are set_bit!, clear_bit!, mask_bits! and copy.

* * I've included a few operations (& | ^ ~) that aren't defined by MRI/OpenSSL. * These are non-portable (i.e., won't work in C-Ruby), so use at your own risk.

* * @author Bill Dortch */ @JRubyClass(name = "OpenSSL::BN", include = "Comparable") public class BN extends RubyObject { private static final long serialVersionUID = -5660938062191525498L; private static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE); static final BigInteger TWO = BigInteger.valueOf(2); private static final BigInteger MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE); private static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE); private static final int DEFAULT_CERTAINTY = 100; private static final ObjectAllocator BN_ALLOCATOR = new ObjectAllocator() { public BN allocate(Ruby runtime, RubyClass klass) { return new BN(runtime, klass); } }; public static BN newBN(Ruby runtime, BigInteger value) { return newInstance(runtime, value); } static BN newInstance(final Ruby runtime, BigInteger value) { return new BN(runtime, value != null ? value : BigInteger.ZERO); } //static BN newInstance(final Ruby runtime, long value) { // return new BN(runtime, BigInteger.valueOf(value)); //} public static void createBN(final Ruby runtime, final RubyModule OpenSSL) { final RubyClass OpenSSLError = OpenSSL.getClass("OpenSSLError"); OpenSSL.defineClassUnder("BNError", OpenSSLError, OpenSSLError.getAllocator()); RubyClass BN = OpenSSL.defineClassUnder("BN", runtime.getObject(), BN_ALLOCATOR); BN.includeModule( runtime.getModule("Comparable") ); BN.defineAnnotatedMethods(BN.class); } private volatile BigInteger value; private BN(Ruby runtime, RubyClass clazz) { super(runtime, clazz); this.value = BigInteger.ZERO; } protected BN(Ruby runtime, BigInteger value) { super(runtime, runtime.getModule("OpenSSL").getClass("BN")); this.value = value; } public final BigInteger getValue() { return value; } @JRubyMethod(name="initialize", required=1, optional=1, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; if (this.value != BigInteger.ZERO) { // already initialized throw newBNError(runtime, "illegal initialization"); } int argc = Arity.checkArgumentCount(runtime, args, 1, 2); int base = argc == 2 ? RubyNumeric.num2int(args[1]) : 10; final RubyString str = args[0].asString(); switch (base) { case 0: final byte[] bytes = str.getBytes(); final int signum; if ( ( bytes[0] & 0x80 ) != 0 ) { bytes[0] &= 0x7f; signum = -1; } else { signum = 1; } this.value = new BigInteger(signum, bytes); break; case 2: // this seems wrong to me, but is the behavior of the // MRI implementation. rather than interpreting the string // as ASCII-encoded binary digits, the raw binary value of // the string is used instead. the value is always interpreted // as positive, hence the use of the signum version of the BI // constructor here: this.value = new BigInteger(1, str.getBytes()); break; case 10: case 16: // here, the ASCII-encoded decimal or hex string is used try { this.value = new BigInteger(str.toString(), base); break; } catch (NumberFormatException e) { throw runtime.newArgumentError("value " + str + " is not legal for radix " + base); } default: throw runtime.newArgumentError("illegal radix: " + base); } return this; } @Override public synchronized IRubyObject initialize_copy(final IRubyObject that) { super.initialize_copy(that); if ( this != that ) this.value = ((BN) that).value; return this; } @JRubyMethod(name = "copy") public IRubyObject copy(IRubyObject other) { if (this != other) { this.value = asBigInteger(other); } return this; } @JRubyMethod(name = "to_s", rest = true, optional = 1) public RubyString to_s(IRubyObject[] args) { int argc = Arity.checkArgumentCount(getRuntime(), args, 0, 1); return to_s( argc == 1 ? RubyNumeric.num2int(args[0]) : 10 ); } // 1.6.8 can not handle - this way : @Override //@JRubyMethod(name = "to_s") public RubyString to_s() { return to_s(10); } //@JRubyMethod(name = "to_s") //public RubyString to_s(IRubyObject base) { // return to_s( RubyNumeric.num2int(base) ); //} private RubyString to_s(final int base) { final Ruby runtime = getRuntime(); byte[] bytes; switch (base) { case 0: bytes = this.value.abs().toByteArray(); int offset = 0; if (bytes[0] == 0) { offset = 1; } int length = bytes.length - offset; boolean negative = BigInteger.ZERO.compareTo(this.value) > 0; // for positive values with most significant bit in first byte, // add leading '\0' boolean need0 = !negative && (bytes[offset] & 0x80) != 0; if (negative) { // for negative values, set most significant bit in first byte bytes[offset] |= 0x80; } else if (need0) { length++; } byte[] data = new byte[5 + length]; data[0] = (byte)(0xff & (length >> 24)); data[1] = (byte)(0xff & (length >> 16)); data[2] = (byte)(0xff & (length >> 8)); data[3] = (byte)(0xff & (length >> 0)); if (need0) { data[4] = 0; System.arraycopy(bytes, offset, data, 5, length - 1); } else { System.arraycopy(bytes, offset, data, 4, length); } return runtime.newString(new ByteList(data, 0, 4 + length, false)); case 2: // again, following MRI implementation, wherein base 2 deals // with strings as byte arrays rather than ASCII-encoded binary // digits. note that negative values are returned as though positive: bytes = this.value.abs().toByteArray(); // suppress leading 0 byte to conform to MRI behavior if (bytes[0] == 0) { return runtime.newString(new ByteList(bytes, 1, bytes.length - 1, false)); } return runtime.newString(new ByteList(bytes, false)); case 10: return runtime.newString(value.toString(10)); case 16: final String hex = value.toString(16); final int len = hex.length(); final ByteList val = new ByteList(len + 1); if ( value.signum() == 1 && len % 2 != 0 ) val.append('0'); for ( int i = 0; i < len ; i++ ) { val.append( Character.toUpperCase(hex.charAt(i)) ); } return runtime.newString(val); default: throw runtime.newArgumentError("illegal radix: " + base); } } @Override public String toString() { return to_s().toString(); } public String toString(int base) { return to_s(base).toString(); } @Override @SuppressWarnings("unchecked") @JRubyMethod public IRubyObject inspect() { return ObjectSupport.inspect(this, Collections.EMPTY_LIST); } @Override public boolean equals(Object other) { return (other instanceof BN) ? this.value.equals(((BN) other).value) : false; } @Override public int hashCode() { return 997 * value.hashCode(); } @JRubyMethod(name = "hash") public RubyInteger hash(final ThreadContext context) { return context.runtime.newFixnum(hashCode()); } @JRubyMethod(name = "to_i") public RubyInteger to_i() { if ( value.compareTo( MAX_LONG ) > 0 || value.compareTo( MIN_LONG ) < 0 ) { return RubyBignum.newBignum(getRuntime(), value); } return RubyFixnum.newFixnum(getRuntime(), value.longValue()); } @JRubyMethod(name = "to_bn") public BN to_bn() { return this; } @JRubyMethod(name="coerce") // FIXME: is this right? don't see how it would be useful... public IRubyObject coerce(IRubyObject other) { final Ruby runtime = getRuntime(); IRubyObject self; if ( other instanceof RubyString ) { self = runtime.newString(value.toString()); } else if ( other instanceof RubyInteger ) { self = to_i(); } else if ( other instanceof BN ) { self = this; } else { throw runtime.newTypeError("don't know how to coerce to " + other.getMetaClass().getName()); } return runtime.newArray(other, self); } @JRubyMethod(name="zero?") public RubyBoolean zero_p(final ThreadContext context) { return context.runtime.newBoolean( value.equals(BigInteger.ZERO) ); } @JRubyMethod(name="one?") public RubyBoolean one_p(final ThreadContext context) { return context.runtime.newBoolean( value.equals(BigInteger.ONE) ); } @JRubyMethod(name="odd?") public RubyBoolean odd_p(final ThreadContext context) { return context.runtime.newBoolean( value.testBit(0) ); } @JRubyMethod(name={"cmp", "<=>"}) public IRubyObject cmp(final ThreadContext context, IRubyObject other) { return context.runtime.newFixnum( value.compareTo( asBigInteger(other) ) ); } @JRubyMethod(name="ucmp") public IRubyObject ucmp(final ThreadContext context, IRubyObject other) { return context.runtime.newFixnum( value.abs().compareTo( asBigInteger(other).abs() ) ); } @JRubyMethod(name={"eql?", "==", "==="}) public RubyBoolean eql_p(final ThreadContext context, IRubyObject other) { return context.runtime.newBoolean( value.equals( asBigInteger(other) ) ); } @JRubyMethod(name="sqr") public BN sqr(final ThreadContext context) { // TODO: check whether mult n * n is faster return newBN(context.runtime, value.pow(2)); } @JRubyMethod(name="~") public BN not(final ThreadContext context) { return newBN(context.runtime, value.not()); } @JRubyMethod(name="+") public BN add(final ThreadContext context, IRubyObject other) { return newBN(context.runtime, value.add(asBigInteger(other))); } @JRubyMethod(name="-") public BN sub(final ThreadContext context, IRubyObject other) { return newBN(context.runtime, value.subtract(asBigInteger(other))); } @JRubyMethod(name="*") public BN mul(final ThreadContext context, IRubyObject other) { return newBN(context.runtime, value.multiply(asBigInteger(other))); } @JRubyMethod(name="%") public BN mod(final ThreadContext context, IRubyObject other) { try { return newBN(context.runtime, value.mod(asBigInteger(other))); } catch (ArithmeticException e) { throw context.runtime.newZeroDivisionError(); } } @JRubyMethod(name="/") public IRubyObject div(final ThreadContext context, IRubyObject other) { final Ruby runtime = context.runtime; try { BigInteger[] result = value.divideAndRemainder(asBigInteger(other)); return runtime.newArray(newBN(runtime, result[0]), newBN(runtime, result[1])); } catch (ArithmeticException e) { throw runtime.newZeroDivisionError(); } } @JRubyMethod(name="&") public BN and(final ThreadContext context, IRubyObject other) { return newBN(context.runtime, value.and(asBigInteger(other))); } @JRubyMethod(name="|") public BN or(final ThreadContext context, IRubyObject other) { return newBN(context.runtime, value.or(asBigInteger(other))); } @JRubyMethod(name="^") public BN xor(final ThreadContext context, IRubyObject other) { return newBN(context.runtime, value.xor(asBigInteger(other))); } @JRubyMethod(name="**") public BN exp(final ThreadContext context, IRubyObject other) { // somewhat strangely, BigInteger takes int rather than BigInteger // as the argument to pow. so we'll have to narrow the value, and // raise an exception if data would be lost. (on the other hand, an // exponent even approaching Integer.MAX_VALUE would be silly big, and // the value would take a very, very long time to calculate.) // we'll check for values < 0 (illegal) while we're at it int exp = -1; if ( other instanceof RubyInteger ) { long val = ((RubyInteger) other).getLongValue(); if ( val >= 0 && val <= Integer.MAX_VALUE ) { exp = (int) val; } else if ( other instanceof RubyBignum ) { // inherently too big throw newBNError(context.runtime, "invalid exponent"); } } if ( exp == -1 ) { if ( ! (other instanceof BN) ) { throw context.runtime.newTypeError("Cannot convert into " + other.getMetaClass().getName()); } BigInteger val = ((BN) other).value; if (val.compareTo(BigInteger.ZERO) < 0 || val.compareTo(MAX_INT) > 0) { throw newBNError(context.runtime, "invalid exponent"); } exp = val.intValue(); } try { return newBN(context.runtime, value.pow(exp)); } catch (ArithmeticException e) { // shouldn't happen, we've already checked for < 0 throw newBNError(context.runtime, "invalid exponent"); } } @JRubyMethod(name="gcd") public BN gcd(final ThreadContext context, IRubyObject other) { return newBN(context.runtime, value.gcd(asBigInteger(other))); } @JRubyMethod(name="mod_sqr") public BN mod_sqr(final ThreadContext context, IRubyObject other) { try { return newBN(context.runtime, value.modPow(TWO, asBigInteger(other))); } catch (ArithmeticException e) { throw context.runtime.newZeroDivisionError(); } } @JRubyMethod(name="mod_inverse") public BN mod_inverse(final ThreadContext context, IRubyObject other) { try { return newBN(context.runtime, value.modInverse(asBigInteger(other))); } catch (ArithmeticException e) { throw context.runtime.newZeroDivisionError(); } } @JRubyMethod(name="mod_add") public BN mod_add(final ThreadContext context, IRubyObject other, IRubyObject mod) { try { return newBN(context.runtime, value.add(asBigInteger(other)).mod(asBigInteger(mod))); } catch (ArithmeticException e) { throw context.runtime.newZeroDivisionError(); } } @JRubyMethod(name="mod_sub") public BN mod_sub(final ThreadContext context, IRubyObject other, IRubyObject mod) { try { return newBN(context.runtime, value.subtract(asBigInteger(other)).mod(asBigInteger(mod))); } catch (ArithmeticException e) { throw context.runtime.newZeroDivisionError(); } } @JRubyMethod(name="mod_mul") public BN mod_mul(final ThreadContext context, IRubyObject other, IRubyObject mod) { try { return newBN(context.runtime, value.multiply(asBigInteger(other)).mod(asBigInteger(mod))); } catch (ArithmeticException e) { throw context.runtime.newZeroDivisionError(); } } @JRubyMethod(name="mod_exp") public BN mod_exp(final ThreadContext context, IRubyObject other, IRubyObject mod) { try { return newBN(context.runtime, value.modPow(asBigInteger(other), asBigInteger(mod))); } catch (ArithmeticException e) { throw context.runtime.newZeroDivisionError(); } } @JRubyMethod(name="set_bit!") public synchronized IRubyObject set_bit(IRubyObject n) { // evil mutable BN int pos = RubyNumeric.num2int(n); BigInteger oldValue = this.value; // FIXME? in MRI/OSSL-BIGNUM, the original sign of a BN is remembered, so if // you set the value of an (originally) negative number to zero (through some // combination of clear_bit! and/or mask_bits! calls), and later call set_bit!, // the resulting value will be negative. this seems unintuitive and, frankly, // wrong, not to mention expensive to carry the extra sign field. // I'm not duplicating this behavior here at this time. -BD try { if (oldValue.signum() >= 0) { this.value = oldValue.setBit(pos); } else { this.value = oldValue.abs().setBit(pos).negate(); } } catch (ArithmeticException e) { throw newBNError(getRuntime(), "invalid pos"); } return this; } @JRubyMethod(name="clear_bit!") public synchronized IRubyObject clear_bit(IRubyObject n) { // evil mutable BN int pos = RubyNumeric.num2int(n); BigInteger oldValue = this.value; try { if (oldValue.signum() >= 0) { this.value = oldValue.clearBit(pos); } else { this.value = oldValue.abs().clearBit(pos).negate(); } } catch (ArithmeticException e) { throw newBNError(getRuntime(), "invalid pos"); } return this; } /** * Truncates value to n bits */ @JRubyMethod(name="mask_bits!") public synchronized IRubyObject mask_bits(IRubyObject n) { // evil mutable BN int pos = RubyNumeric.num2int(n); if (pos < 0) throw newBNError(getRuntime(), "invalid pos"); BigInteger oldValue = this.value; // TODO: cache 2 ** n values? if (oldValue.signum() >= 0) { if (oldValue.bitLength() < pos) throw newBNError(getRuntime(), "invalid pos"); this.value = oldValue.mod(TWO.pow(pos)); } else { BigInteger absValue = oldValue.abs(); if (absValue.bitLength() < pos) throw newBNError(getRuntime(), "invalid pos"); this.value = absValue.mod(TWO.pow(pos)).negate(); } return this; } @JRubyMethod(name="bit_set?") public RubyBoolean bit_set_p(final ThreadContext context, IRubyObject n) { int pos = RubyNumeric.num2int(n); BigInteger val = this.value; try { if (val.signum() >= 0) { return context.runtime.newBoolean(val.testBit(pos)); } return context.runtime.newBoolean(val.abs().testBit(pos)); } catch (ArithmeticException e) { throw newBNError(context.runtime, "invalid pos"); } } @JRubyMethod(name="<<") public BN lshift(final ThreadContext context, IRubyObject n) { int nbits = RubyNumeric.num2int(n); BigInteger val = this.value; if (val.signum() >= 0) { return newBN(context.runtime, val.shiftLeft(nbits)); } return newBN(context.runtime, val.abs().shiftLeft(nbits).negate()); } @JRubyMethod(name=">>") public BN rshift(final ThreadContext context, IRubyObject n) { int nbits = RubyNumeric.num2int(n); BigInteger val = this.value; if (val.signum() >= 0) { return newBN(context.runtime, val.shiftRight(nbits)); } return newBN(context.runtime, val.abs().shiftRight(nbits).negate()); } @JRubyMethod(name="num_bits") public RubyFixnum num_bits(final ThreadContext context) { return context.runtime.newFixnum( this.value.abs().bitLength() ); } @JRubyMethod(name="num_bytes") public RubyFixnum num_bytes(final ThreadContext context) { return context.runtime.newFixnum( (this.value.abs().bitLength() + 7) / 8 ); } @JRubyMethod(name="num_bits_set") public RubyFixnum num_bits_set(final ThreadContext context) { return context.runtime.newFixnum( this.value.abs().bitCount() ); } // note that there is a bug in the MRI version, in argument handling, // so apparently no one ever calls this... @JRubyMethod(name = "prime?", rest = true) public IRubyObject prime_p(IRubyObject[] args) { final Ruby runtime = getRuntime(); int argc = Arity.checkArgumentCount(runtime, args, 0, 1); // negative numbers are always considered non-prime if (this.value.signum() < 0) return runtime.getFalse(); int certainty = argc == 0 ? DEFAULT_CERTAINTY : RubyNumeric.fix2int(args[0]); // BigInteger#isProbablePrime will actually limit checks to a maximum of 50, // depending on bit count. return runtime.newBoolean(this.value.isProbablePrime(certainty)); } // NOTE: BigInteger doesn't supply this, so right now this is // ... (essentially) the same as prime? @JRubyMethod(name = "prime_fasttest?", rest = true) public IRubyObject prime_fasttest_p(IRubyObject[] args) { final Ruby runtime = getRuntime(); int argc = Arity.checkArgumentCount(runtime, args, 0, 2); // negative numbers are always considered non-prime if (this.value.signum() < 0) return runtime.getFalse(); int certainty = argc == 0 ? DEFAULT_CERTAINTY : RubyNumeric.fix2int(args[0]); // BigInteger#isProbablePrime will actually limit checks to a maximum of 50, // depending on bit count. return runtime.newBoolean(this.value.isProbablePrime(certainty)); } @JRubyMethod(name = "generate_prime", meta = true, rest = true) public static IRubyObject generate_prime(IRubyObject recv, IRubyObject[] args) { Ruby runtime = recv.getRuntime(); int argc = Arity.checkArgumentCount(runtime, args, 1, 4); int bits = RubyNumeric.num2int(args[0]); boolean safe = argc > 1 ? args[1] != runtime.getFalse() : true; BigInteger add = argc > 2 ? asBigInteger(args[2]) : null; BigInteger rem = argc > 3 ? asBigInteger(args[3]) : null; if (bits < 3) { if (safe) throw runtime.newArgumentError("bits < 3"); if (bits < 2) throw runtime.newArgumentError("bits < 2"); } return newBN(runtime, generatePrime(bits, safe, add, rem)); } public static BigInteger generatePrime(int bits, boolean safe, BigInteger add, BigInteger rem) { // From OpenSSL man page BN_generate_prime(3): // // "If add is not NULL, the prime will fulfill the condition p % add == rem // (p % add == 1 if rem == NULL) in order to suit a given generator." // // "If safe is true, it will be a safe prime (i.e. a prime p so that // (p-1)/2 is also prime)." // // see [ossl]/crypto/bn/bn_prime.c #BN_generate_prime_ex // if (add != null && rem == null) { rem = BigInteger.ONE; } // borrowing technique from org.bouncycastle.crypto.generators.DHParametersHelper // (unfortunately the code has package visibility), wherein for safe primes, // we'll use the lowest useful certainty (2) for generation of q, then if // p ( = 2q + 1) is prime to our required certainty (100), we'll verify that q // is as well. // // for typical bit lengths ( >= 1024), this should speed things up by reducing // initial Miller-Rabin iterations from 2 to 1 for candidate values of q. // // it's still painfully slow... // BigInteger p, q; int qbits = bits - 1; SecureRandom secureRandom = getSecureRandom(); do { if (safe) { do { q = new BigInteger(qbits, 2, secureRandom); p = q.shiftLeft(1).setBit(0); } while (!(p.isProbablePrime(DEFAULT_CERTAINTY) && q.isProbablePrime(DEFAULT_CERTAINTY))); } else { p = BigInteger.probablePrime(bits, secureRandom); } } while (add != null && !p.mod(add).equals(rem)); return p; } public static BigInteger generatePrime(int bits, boolean safe) { return generatePrime(bits, safe, null, null); } @JRubyMethod(name = "rand", meta = true, rest = true) public static IRubyObject rand(IRubyObject recv, IRubyObject[] args) { return getRandomBN(recv.getRuntime(), args, getSecureRandom()); } @JRubyMethod(name = "pseudo_rand", meta = true, rest = true) public static IRubyObject pseudo_rand(IRubyObject recv, IRubyObject[] args) { return getRandomBN(recv.getRuntime(), args, getRandom()); } public static BN getRandomBN(Ruby runtime, IRubyObject[] args, Random random) { int argc = Arity.checkArgumentCount(runtime, args, 1, 3); int bits = RubyNumeric.num2int(args[0]); int top; boolean bottom; if (argc > 1) { top = RubyNumeric.fix2int(args[1]); bottom = argc == 3 ? args[2].isTrue() : false; } else { top = 0; bottom = false; } BigInteger value; try { value = getRandomBI(bits, top, bottom, random); } catch (IllegalArgumentException e) { throw runtime.newArgumentError(e.getMessage()); } return newBN(runtime, value); } public static BigInteger getRandomBI(int bits, int top, boolean bottom, Random random) { // From OpenSSL man page BN_rand(3): // // "If top is -1, the most significant bit of the random number can be zero. // If top is 0, it is set to 1, and if top is 1, the two most significant bits // of the number will be set to 1, so that the product of two such random numbers // will always have 2*bits length." // // "If bottom is true, the number will be odd." // if (bits <= 0) { if (bits == 0) return BigInteger.ZERO; throw new IllegalArgumentException("Illegal bit length"); } if (top < -1 || top > 1) { throw new IllegalArgumentException("Illegal top value"); } // top/bottom handling adapted from OpenSSL's crypto/bn/bn_rand.c int bytes = (bits + 7) / 8; int bit = (bits - 1) % 8; int mask = 0xff << (bit + 1); byte[] buf; random.nextBytes(buf = new byte[bytes]); if (top >= 0) { if (top == 0) { buf[0] |= (1 << bit); } else { if (bit == 0) { buf[0] = 1; buf[1] |= 0x80; } else { buf[0] |= (3 << (bit - 1)); } } } buf[0] &= ~mask; if (bottom) { buf[bytes-1] |= 1; } // treating result as unsigned return new BigInteger(1, buf); } @JRubyMethod(name = "rand_range", meta = true) public static IRubyObject rand_range(IRubyObject recv, IRubyObject arg) { return randomValueInRange(recv.getRuntime(), asBigInteger(arg), getSecureRandom()); } @JRubyMethod(name = "pseudo_rand_range", meta = true) public static IRubyObject pseudo_rand_range(IRubyObject recv, IRubyObject arg) { return randomValueInRange(recv.getRuntime(), asBigInteger(arg), getRandom()); } private static BN randomValueInRange(Ruby runtime, BigInteger limit, Random random) { BigInteger value; try { value = randomIntegerInRange(limit, random); } catch (IllegalArgumentException e) { throw newBNError(runtime, e.getMessage()); } return newInstance(runtime, value); } public static BigInteger randomIntegerInRange(BigInteger limit, Random random) { if (limit.signum() < 0) { throw new IllegalArgumentException("illegal range: " + limit); } int bits = limit.bitLength(); BigInteger value; do { value = new BigInteger(bits, random); } while (value.compareTo(limit) >= 0); return value; } private static Random random; private static Random getRandom() { final Random rnd; if ( ( rnd = BN.random ) != null ) { return rnd; } return BN.random = new Random(); } private static SecureRandom secureRandom; private static SecureRandom getSecureRandom() { final SecureRandom rnd; if ( ( rnd = BN.secureRandom ) != null ) { return rnd; } // NOTE: will use (default) Sun's even if BC provider is set return BN.secureRandom = new SecureRandom(); } public static RaiseException newBNError(Ruby runtime, String message) { return new RaiseException(runtime, runtime.getModule("OpenSSL").getClass("BNError"), message, true); } public static BigInteger asBigInteger(final IRubyObject arg) { if ( arg.isNil() ) return null; if ( arg instanceof RubyInteger ) { return ((RubyInteger) arg).getBigIntegerValue(); } if ( arg instanceof BN ) return ((BN) arg).value; throw arg.getRuntime().newTypeError("Cannot convert into OpenSSL::BN"); } public static BigInteger asBigInteger(final BN arg) { return arg.isNil() ? null : arg.value; } @Deprecated public static BigInteger getBigInteger(final IRubyObject arg) { return asBigInteger(arg); } @Override public Object toJava(Class target) { if ( target.isAssignableFrom(BigInteger.class) || target == Number.class ) return value; if ( target == Long.class || target == Long.TYPE ) return value.longValue(); if ( target == Integer.class || target == Integer.TYPE ) return value.intValue(); if ( target == Double.class || target == Double.TYPE ) return value.doubleValue(); if ( target == Float.class || target == Float.TYPE ) return value.floatValue(); return super.toJava(target); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/BouncyCastlePEMHandler.java000066400000000000000000000067611313661621600303750ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.Reader; import java.io.Writer; import java.lang.reflect.Method; import java.security.SecureRandom; //import org.bouncycastle.openssl.PEMReader; // uses Security API directly import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.openssl.PasswordFinder; /** * @author Ola Bini */ @Deprecated public class BouncyCastlePEMHandler implements PEMHandler { @SuppressWarnings("unchecked") public Object readPEM(Reader read, String password) throws Exception { // NOTE: class not longer available since BC 1.50 : // return new PEMReader(read, new BasicPasswordFinder(password)).readObject(); Class PEMReader = Class.forName("org.bouncycastle.openssl.PEMReader"); Object pemReader = PEMReader.getConstructor(java.io.Reader.class, PasswordFinder.class). newInstance(read, new BasicPasswordFinder(password)); return PEMReader.getMethod("readObject").invoke(pemReader); } public void writePEM(Writer writer, Object obj, String algorithm, char[] password) throws Exception { final PEMWriter pemWriter = new PEMWriter(writer); // NOTE: method parameters changed since BC 1.50 : // pemWriter.writeObject(obj, algorithm, password, null); Method writeObject = PEMWriter.class.getMethod("writeObject", Object.class, String.class, char[].class, SecureRandom.class); writeObject.invoke(pemWriter, obj, algorithm, password, null); pemWriter.flush(); } public void writePEM(Writer writer, Object obj) throws Exception { PEMWriter pemWriter = new PEMWriter(writer); pemWriter.writeObject(obj); pemWriter.flush(); } private static class BasicPasswordFinder implements PasswordFinder { private char[] pwd; BasicPasswordFinder(final String pwd) { if ( pwd != null ) this.pwd = pwd.toCharArray(); } public char[] getPassword() { return this.pwd; } } }// BouncyCastlePEMHandler jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/Cipher.java000066400000000000000000001654541313661621600253610ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.PrintStream; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.spec.AlgorithmParameterSpec; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static javax.crypto.Cipher.DECRYPT_MODE; import static javax.crypto.Cipher.ENCRYPT_MODE; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.common.IRubyWarnings.ID; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import org.jruby.util.ByteList; import static org.jruby.ext.openssl.OpenSSL.*; /** * @author Ola Bini */ public class Cipher extends RubyObject { private static final long serialVersionUID = -5390983669951165103L; private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public Cipher allocate(Ruby runtime, RubyClass klass) { return new Cipher(runtime, klass); } }; public static void createCipher(final Ruby runtime, final RubyModule OpenSSL) { final RubyClass Cipher = OpenSSL.defineClassUnder("Cipher", runtime.getObject(), ALLOCATOR); Cipher.defineAnnotatedMethods(Cipher.class); final RubyClass OpenSSLError = OpenSSL.getClass("OpenSSLError"); Cipher.defineClassUnder("CipherError", OpenSSLError, OpenSSLError.getAllocator()); String cipherName; cipherName = "AES"; // OpenSSL::Cipher::AES Cipher.defineClassUnder(cipherName, Cipher, new NamedCipherAllocator(cipherName)) .defineAnnotatedMethods(Named.class); cipherName = "CAST5"; // OpenSSL::Cipher::CAST5 Cipher.defineClassUnder(cipherName, Cipher, new NamedCipherAllocator(cipherName)) .defineAnnotatedMethods(Named.class); cipherName = "BF"; // OpenSSL::Cipher::BF Cipher.defineClassUnder(cipherName, Cipher, new NamedCipherAllocator(cipherName)) .defineAnnotatedMethods(Named.class); cipherName = "DES"; // OpenSSL::Cipher::DES Cipher.defineClassUnder(cipherName, Cipher, new NamedCipherAllocator(cipherName)) .defineAnnotatedMethods(Named.class); cipherName = "IDEA"; // OpenSSL::Cipher::IDEA Cipher.defineClassUnder(cipherName, Cipher, new NamedCipherAllocator(cipherName)) .defineAnnotatedMethods(Named.class); cipherName = "RC2"; // OpenSSL::Cipher::RC2 Cipher.defineClassUnder(cipherName, Cipher, new NamedCipherAllocator(cipherName)) .defineAnnotatedMethods(Named.class); cipherName = "RC4"; // OpenSSL::Cipher::RC4 Cipher.defineClassUnder(cipherName, Cipher, new NamedCipherAllocator(cipherName)) .defineAnnotatedMethods(Named.class); cipherName = "RC5"; // OpenSSL::Cipher::RC5 Cipher.defineClassUnder(cipherName, Cipher, new NamedCipherAllocator(cipherName)) .defineAnnotatedMethods(Named.class); String keyLength; keyLength = "128"; // OpenSSL::Cipher::AES128 Cipher.defineClassUnder("AES" + keyLength, Cipher, new AESCipherAllocator(keyLength)) .defineAnnotatedMethods(AES.class); keyLength = "192"; // OpenSSL::Cipher::AES192 Cipher.defineClassUnder("AES" + keyLength, Cipher, new AESCipherAllocator(keyLength)) .defineAnnotatedMethods(AES.class); keyLength = "256"; // OpenSSL::Cipher::AES256 Cipher.defineClassUnder("AES" + keyLength, Cipher, new AESCipherAllocator(keyLength)) .defineAnnotatedMethods(AES.class); } static RubyClass _Cipher(final Ruby runtime) { return (RubyClass) runtime.getModule("OpenSSL").getConstantAt("Cipher"); } @JRubyMethod(meta = true) public static IRubyObject ciphers(final ThreadContext context, final IRubyObject self) { final Ruby runtime = context.runtime; final Collection ciphers = Algorithm.allSupportedCiphers().keySet(); final RubyArray result = runtime.newArray( ciphers.size() * 2 ); for ( final String cipher : ciphers ) { result.append( runtime.newString(cipher) ); // upper-case } for ( final String cipher : ciphers ) { // than lower-case OpenSSL compatibility result.append( runtime.newString(cipher.toLowerCase()) ); } return result; } public static boolean isSupportedCipher(final String name) { final String osslName = name.toUpperCase(); // if ( Algorithm.allSupportedCiphers().get( osslName ) != null ) { return true; } // final Algorithm alg = Algorithm.osslToJava(osslName); if ( isDebug() ) debug("isSupportedCipher( "+ name +" ) try new cipher = " + alg.getRealName()); try { return getCipherInstance(alg.getRealName(), true) != null; } catch (GeneralSecurityException e) { return false; } } private static String[] cipherModes(final String alg) { final String[] modes = providerCipherModes(alg); return modes == null ? registeredCipherModes(alg) : modes; } private static String[] providerCipherModes(final String alg) { final Provider.Service service = providerCipherService(alg); if ( service != null ) { final String supportedModes = service.getAttribute("SupportedModes"); if ( supportedModes == null ) return Algorithm.OPENSSL_BLOCK_MODES; return StringHelper.split(supportedModes, '|'); } return null; } private static Provider.Service providerCipherService(final String alg) { if ( SecurityHelper.securityProvider != null ) { return SecurityHelper.securityProvider.getService("Cipher", alg); } return null; } private static String[] registeredCipherModes(final String alg) { // e.g. "AES" /* if ( SecurityHelper.securityProvider != null && ! SecurityHelper.isProviderRegistered() ) { final Provider provider = SecurityHelper.securityProvider; for ( Provider.Service service : provider.getServices() ) { if ( "Cipher".equals( service.getType() ) ) { services.add(service); } } } */ boolean serviceFound = false; final Provider[] providers = java.security.Security.getProviders(); for ( int i = 0; i < providers.length; i++ ) { final Provider provider = providers[i]; final String name = provider.getName() == null ? "" : provider.getName(); // skip those that are known to provide no Cipher engines : if ( name.contains("JGSS") ) continue; // SunJGSS if ( name.contains("SASL") ) continue; // SunSASL if ( name.contains("XMLD") ) continue; // XMLDSig if ( name.contains("PCSC") ) continue; // SunPCSC if ( name.contains("JSSE") ) continue; // SunJSSE final Provider.Service service = provider.getService("Cipher", alg); if ( service != null ) { serviceFound = true; final String supportedModes = service.getAttribute("SupportedModes"); if ( supportedModes != null ) return StringHelper.split(supportedModes, '|'); } } // if a service is found but has no SupportedModes configuration included // e.g. BC provider does not provide those - assume all modes that OpenSSL // supports (and are mappable to JSE) work with the cipher algorithm : return serviceFound ? Algorithm.OPENSSL_BLOCK_MODES : null; } public static final class Algorithm { final String base; // e.g. DES, AES final String version; // e.g. EDE3, 256 final String mode; // CBC (default) private String padding; // PKCS5Padding (default) private String realName; private boolean realNameNeedsPadding; private int keyLength = -1, ivLength = -1; Algorithm(String cryptoBase, String cryptoVersion, String cryptoMode) { this.base = cryptoBase; this.version = cryptoVersion; this.mode = cryptoMode; //this.padding = padding; } private static final Set KNOWN_BLOCK_MODES; // NOTE: CFB1 does not work as (OpenSSL) expects with BC (@see GH-35) private static final String[] OPENSSL_BLOCK_MODES = { "CBC", "CFB", /* "CFB1", */ "CFB8", "ECB", "OFB" // that Java supports }; static { KNOWN_BLOCK_MODES = new HashSet(); for ( String mode : OPENSSL_BLOCK_MODES ) KNOWN_BLOCK_MODES.add(mode); KNOWN_BLOCK_MODES.add("CTR"); KNOWN_BLOCK_MODES.add("CTS"); // not supported by OpenSSL KNOWN_BLOCK_MODES.add("PCBC"); // not supported by OpenSSL KNOWN_BLOCK_MODES.add("NONE"); // valid to pass into JCE } // Ruby to Java name String (or FALSE) static final HashMap supportedCiphers = new LinkedHashMap(120, 1); // we're _marking_ unsupported keys with a Boolean.FALSE mapping // all cipher mappings are resolved on `OpenSSL::Cipher.ciphers` // ... probably a slightly _rare_ case to be going for up front static boolean supportedCiphersAll; static Map allSupportedCiphers() { if ( supportedCiphersAll ) return supportedCiphers; synchronized ( supportedCiphers ) { if ( supportedCiphersAll ) return supportedCiphers; // cleanup all FALSE keys : //for ( String key: supportedCiphers.keySet() ) { //if ( supportedCiphers.get(key) == Boolean.FALSE ) supportedCiphers.remove(key); //} // OpenSSL: all the block ciphers normally use PKCS#5 padding String[] modes; modes = cipherModes("AES"); // null if not supported if ( modes != null ) { for ( final String mode : modes ) { final String realName = "AES/" + mode; // + "/PKCS5Padding" supportedCiphers.put( "AES-128-" + mode, new String[] { "AES", mode, "128", realName } ); supportedCiphers.put( "AES-192-" + mode, new String[] { "AES", mode, "192", realName } ); supportedCiphers.put( "AES-256-" + mode, new String[] { "AES", mode, "256", realName } ); } final String realName = "AES/CBC"; supportedCiphers.put( "AES128", new String[] { "AES", "CBC", "128", realName } ); supportedCiphers.put( "AES192", new String[] { "AES", "CBC", "192", realName } ); supportedCiphers.put( "AES256", new String[] { "AES", "CBC", "256", realName } ); } modes = cipherModes("Blowfish"); if ( modes != null ) { supportedCiphers.put( "BF", new String[] { "BF", "CBC", null, "Blowfish/CBC" }); for ( final String mode : modes ) { supportedCiphers.put( "BF-" + mode, new String[] { "BF", mode, null, "Blowfish/" + mode } ); } } modes = cipherModes("Camellia"); if ( modes != null ) { for ( final String mode : modes ) { final String realName = "Camellia/" + mode; supportedCiphers.put( "CAMELLIA-128-" + mode, new String[] { "CAMELLIA", mode, "128", realName } ); supportedCiphers.put( "CAMELLIA-192-" + mode, new String[] { "CAMELLIA", mode, "192", realName } ); supportedCiphers.put( "CAMELLIA-256-" + mode, new String[] { "CAMELLIA", mode, "256", realName } ); } final String realName = "Camellia/CBC"; supportedCiphers.put( "CAMELLIA128", new String[] { "CAMELLIA", "CBC", "128", realName } ); supportedCiphers.put( "CAMELLIA192", new String[] { "CAMELLIA", "CBC", "192", realName } ); supportedCiphers.put( "CAMELLIA256", new String[] { "CAMELLIA", "CBC", "256", realName } ); } modes = cipherModes("CAST5"); if ( modes != null ) { supportedCiphers.put( "CAST", new String[] { "CAST", "CBC", null, "CAST5/CBC" } ); supportedCiphers.put( "CAST-CBC", supportedCiphers.get("CAST") ); for ( final String mode : modes ) { supportedCiphers.put( "CAST5-" + mode, new String[] { "CAST", mode, null, "CAST5/" + mode }); } } modes = cipherModes("CAST6"); if ( modes != null ) { for ( final String mode : modes ) { supportedCiphers.put( "CAST6-" + mode, new String[] { "CAST6", mode, null, "CAST6/" + mode }); } } modes = cipherModes("DES"); if ( modes != null ) { supportedCiphers.put( "DES", new String[] { "DES", "CBC", null, "DES/CBC" } ); for ( final String mode : modes ) { supportedCiphers.put( "DES-" + mode, new String[] { "DES", mode, null, "DES/" + mode }); } } modes = cipherModes("DESede"); if ( modes != null ) { supportedCiphers.put( "DES-EDE", new String[] { "DES", "ECB", "EDE", "DESede/ECB" } ); supportedCiphers.put( "DES-EDE-CBC", new String[] { "DES", "CBC", "EDE", "DESede/CBC" } ); supportedCiphers.put( "DES-EDE-CFB", new String[] { "DES", "CBC", "EDE", "DESede/CFB" } ); supportedCiphers.put( "DES-EDE-OFB", new String[] { "DES", "CBC", "EDE", "DESede/OFB" } ); supportedCiphers.put( "DES-EDE3", new String[] { "DES", "ECB", "EDE3", "DESede/ECB" }); for ( final String mode : modes ) { supportedCiphers.put( "DES-EDE3-" + mode, new String[] { "DES", mode, "EDE3", "DESede/" + mode }); } supportedCiphers.put( "DES3", new String[] { "DES", "CBC", "EDE3", "DESede/CBC" } ); } modes = cipherModes("RC2"); if ( modes != null ) { supportedCiphers.put( "RC2", new String[] { "RC2", "CBC", null, "RC2/CBC" } ); for ( final String mode : modes ) { supportedCiphers.put( "RC2-" + mode, new String[] { "RC2", mode, null, "RC2/" + mode } ); } supportedCiphers.put( "RC2-40-CBC", new String[] { "RC2", "CBC", "40", "RC2/CBC" } ); supportedCiphers.put( "RC2-64-CBC", new String[] { "RC2", "CBC", "64", "RC2/CBC" } ); } modes = cipherModes("RC4"); // NOTE: stream cipher (BC supported) if ( modes != null ) { supportedCiphers.put( "RC4", new String[] { "RC4", null, null, "RC4" } ); supportedCiphers.put( "RC4-40", new String[] { "RC4", null, "40", "RC4" } ); //supportedCiphers.put( "RC2-HMAC-MD5", new String[] { "RC4", null, null, "RC4" }); } modes = cipherModes("SEED"); if ( modes != null ) { supportedCiphers.put( "SEED", new String[] { "SEED", "CBC", null, "SEED/CBC" } ); for ( final String mode : modes ) { supportedCiphers.put( "SEED-" + mode, new String[] { "SEED", mode, null, "SEED/" + mode }); } } supportedCiphersAll = true; return supportedCiphers; } } @Deprecated public static String jsseToOssl(final String cipherName, final int keyLength) { return javaToOssl(cipherName, keyLength); } public static String javaToOssl(final String cipherName, final int keyLength) { String cryptoBase; String cryptoVersion = null; String cryptoMode = null; final List parts = StringHelper.split((CharSequence) cipherName, '/'); final int partsLength = parts.size(); if ( partsLength != 1 && partsLength != 3 ) return null; if ( partsLength > 2 ) { cryptoMode = (String) parts.get(1); // padding: parts[2] not used } cryptoBase = (String) parts.get(0); if ( ! KNOWN_BLOCK_MODES.contains(cryptoMode) ) { cryptoVersion = cryptoMode; cryptoMode = "CBC"; } if (cryptoMode == null) { cryptoMode = "CBC"; } if ( "DESede".equals(cryptoBase) ) { cryptoBase = "DES"; cryptoVersion = "EDE3"; } else if ( "Blowfish".equals(cryptoBase) ) { cryptoBase = "BF"; } if (cryptoVersion == null) { cryptoVersion = String.valueOf(keyLength); } return cryptoBase + '-' + cryptoVersion + '-' + cryptoMode; } static Algorithm osslToJava(final String osslName) { return osslToJava(osslName, null); // assume PKCS5Padding } private static Algorithm osslToJava(final String osslName, final String padding) { final String[] algVals = supportedCiphers.get(osslName); if ( algVals != null ) { final String cryptoMode = algVals[1]; Algorithm alg = new Algorithm(algVals[0], algVals[2], cryptoMode); alg.realName = algVals[3]; alg.realNameNeedsPadding = true; alg.padding = getPaddingType(padding, cryptoMode); return alg; } String cryptoBase, cryptoVersion = null, cryptoMode, realName; String paddingType = null; // EXPERIMENTAL: if there's '/' assume it's a "real" JCE name : if ( osslName.indexOf('/') != -1 ) { // e.g. "DESedeWrap/CBC/NOPADDING" final List names = StringHelper.split((CharSequence) osslName, '/'); cryptoBase = (String) names.get(0); cryptoMode = names.size() > 1 ? (String) names.get(1) : "CBC"; paddingType = getPaddingType(padding, cryptoMode); if ( names.size() > 2 ) paddingType = (String) names.get(2); Algorithm alg = new Algorithm(cryptoBase, null, cryptoMode); alg.realName = osslName; alg.padding = paddingType; return alg; } int s = osslName.indexOf('-'); int i = 0; if (s == -1) { cryptoBase = osslName; cryptoMode = null; } else { cryptoBase = osslName.substring(i, s); s = osslName.indexOf('-', i = s + 1); if (s == -1) cryptoMode = osslName.substring(i); // "base-mode" else { // two separators : "base-version-mode" cryptoVersion = osslName.substring(i, s); s = osslName.indexOf('-', i = s + 1); if (s == -1) { cryptoMode = osslName.substring(i); } else { cryptoMode = osslName.substring(i, s); } } } cryptoBase = cryptoBase.toUpperCase(); // allways upper e.g. "AES" if ( cryptoMode != null ) cryptoMode = cryptoMode.toUpperCase(); boolean realNameSet = false; boolean setDefaultCryptoMode = true; if ( "BF".equals(cryptoBase) ) realName = "Blowfish"; else if ( "CAST".equals(cryptoBase) ) realName = "CAST5"; else if ( cryptoBase.startsWith("DES") ) { if ( "DES3".equals(cryptoBase) ) { cryptoBase = "DES"; realName = "DESede"; cryptoVersion = "EDE3"; // cryptoMode = "CBC"; } else if ( "EDE3".equalsIgnoreCase(cryptoVersion) || "EDE".equalsIgnoreCase(cryptoVersion) ) { realName = "DESede"; if ( cryptoMode == null ) cryptoMode = "ECB"; } else if ( "EDE3".equalsIgnoreCase(cryptoMode) || "EDE".equalsIgnoreCase(cryptoMode) ) { realName = "DESede"; cryptoVersion = cryptoMode; cryptoMode = "ECB"; } else realName = "DES"; } else if ( cryptoBase.length() > 3 && cryptoBase.startsWith("AES") ) { try { // try parsing e.g. "AES256" final String version = cryptoBase.substring(3); Integer.parseInt( version ); realName = cryptoBase = "AES"; cryptoVersion = version; } catch (NumberFormatException e) { realName = cryptoBase; } } else if ( cryptoBase.length() > 8 && cryptoBase.startsWith("CAMELLIA") ) { try { // try parsing e.g. "CAMELLIA192" final String version = cryptoBase.substring(8); Integer.parseInt( version ); realName = cryptoBase = "CAMELLIA"; cryptoVersion = version; } catch (NumberFormatException e) { realName = cryptoBase; } } else { realName = cryptoBase; // streaming ciphers - no padding/mode to be used ... // e.g. only SecurityHelper.getCipherInstance("RC4") will work if ( "RC4".equals(cryptoBase) ) { if ( ! KNOWN_BLOCK_MODES.contains(cryptoMode) ) { cryptoVersion = cryptoMode; } cryptoMode = null; // padding = null; setDefaultCryptoMode = false; // cryptoMode = "NONE"; paddingType = "NoPadding"; realNameSet = true; } } if ( cryptoMode == null && setDefaultCryptoMode ) cryptoMode = "CBC"; if ( paddingType == null ) paddingType = getPaddingType(padding, cryptoMode); if ( cryptoMode != null ) { //if ( ! KNOWN_BLOCK_MODES.contains(cryptoMode) ) { // if ( ! "XTS".equals(cryptoMode) ) { // // valid but likely not supported by JCE/provider // //cryptoVersion = cryptoMode; cryptoMode = "CBC"; // } //} if ( ! realNameSet ) { realName = realName + '/' + cryptoMode + '/' + paddingType; } } else if ( ! realNameSet ) { if ( padding != null ) { realName = realName + '/' + "NONE" + '/' + paddingType; } //else paddingType = null; // else realName is cryptoBase } Algorithm alg = new Algorithm(cryptoBase, cryptoVersion, cryptoMode); alg.realName = realName; alg.padding = paddingType; return alg; } String getPadding() { if ( mode == null ) return null; // if ( "RC4".equals(base) ) return null; return padding; } private static String getPaddingType(final String padding, final String cryptoMode) { //if ( "ECB".equals(cryptoMode) ) return "NoPadding"; // TODO check cryptoMode CFB/OFB final String defaultPadding = "PKCS5Padding"; if ( padding == null ) { if ( "GCM".equalsIgnoreCase(cryptoMode) ) { return "NoPadding"; } return defaultPadding; } if ( padding.equalsIgnoreCase("PKCS5Padding") ) { return "PKCS5Padding"; } if ( padding.equals("0") || padding.equalsIgnoreCase("NoPadding") ) { return "NoPadding"; } if ( padding.equalsIgnoreCase("ISO10126Padding") ) { return "ISO10126Padding"; } if ( padding.equalsIgnoreCase("PKCS1Padding") ) { return "PKCS1Padding"; } if ( padding.equalsIgnoreCase("SSL3Padding") ) { return "SSL3Padding"; } if (padding.equalsIgnoreCase("OAEPPadding")) { return "OAEPPadding"; } return defaultPadding; // "PKCS5Padding"; // default } String getRealName() { if ( realName != null ) { if ( realNameNeedsPadding ) { final String padding = getPadding(); if ( padding != null ) { realName = realName + '/' + padding; } realNameNeedsPadding = false; } return realName; } return realName = base + '/' + (mode == null ? "NONE" : mode) + '/' + padding; } public static String getAlgorithmBase(javax.crypto.Cipher cipher) { final String algorithm = cipher.getAlgorithm(); final int idx = algorithm.indexOf('/'); if ( idx != -1 ) return algorithm.substring(0, idx); return algorithm; } public static String getRealName(final String osslName) { return osslToJava(osslName).getRealName(); } public int getIvLength() { if ( ivLength != -1 ) return ivLength; getKeyLength(); if ( ivLength == -1 ) { if ( "AES".equals(base) ) { ivLength = 16; // OpenSSL defaults to 12 // NOTE: we can NOT handle 12 for non GCM mode if ( "GCM".equals(mode) || "CCM".equals(mode) ) ivLength = 12; } //else if ( "DES".equals(base) ) { // ivLength = 8; //} //else if ( "RC4".equals(base) ) { // ivLength = 8; //} else if ( "ECB".equals(mode) ) { ivLength = 0; } else { ivLength = 8; } } return ivLength; } public int getKeyLength() { if ( keyLength != -1 ) return keyLength; int keyLen = -1; if ( version != null ) { try { keyLen = Integer.parseInt(version) / 8; } catch (NumberFormatException e) { keyLen = -1; } } if ( keyLen == -1 ) { if ( "DES".equals(base) ) { if ( "EDE".equalsIgnoreCase(version) ) keyLen = 16; else if ( "EDE3".equalsIgnoreCase(version) ) keyLen = 24; else keyLen = 8; } else if ( "RC4".equals(base) ) { keyLen = 16; } else { keyLen = 16; try { final String name = getRealName(); int maxLen = javax.crypto.Cipher.getMaxAllowedKeyLength(name) / 8; if (maxLen < keyLen) keyLen = maxLen; } catch (NoSuchAlgorithmException e) { } } } return keyLength = keyLen; } @Deprecated public static int[] osslKeyIvLength(final String cipherName) { final Algorithm alg = Algorithm.osslToJava(cipherName); return new int[] { alg.getKeyLength(), alg.getIvLength() }; } @Override public String toString() { return getClass().getSimpleName() + '@' + Integer.toHexString(hashCode()) + ""; } } private static javax.crypto.Cipher getCipherInstance(final String transformation, boolean silent) throws NoSuchAlgorithmException, NoSuchPaddingException { try { return SecurityHelper.getCipher(transformation); // tries BC if it's available } catch (NoSuchAlgorithmException e) { if ( silent ) return null; throw e; } catch (NoSuchPaddingException e) { if ( silent ) return null; throw e; } } public Cipher(Ruby runtime, RubyClass type) { super(runtime, type); } private javax.crypto.Cipher cipher; // the "real" (Java) Cipher object private String name; private String cryptoBase; private String cryptoVersion; private String cryptoMode; private String paddingType; private String realName; // Cipher's "real" (Java) name - used to instantiate private int keyLength = -1; private int generateKeyLength = -1; private int ivLength = -1; private boolean encryptMode = true; //private IRubyObject[] modeParams; private boolean cipherInited = false; private byte[] key; private byte[] realIV; private byte[] orgIV; private String padding; private void dumpVars(final PrintStream out, final String header) { out.println(this.toString() + ' ' + header + "\n" + " name = " + name + " cryptoBase = " + cryptoBase + " cryptoVersion = " + cryptoVersion + " cryptoMode = " + cryptoMode + " padding_type = " + paddingType + " realName = " + realName + " keyLength = " + keyLength + " ivLength = " + ivLength + "\n" + " cipher.alg = " + (cipher == null ? null : cipher.getAlgorithm()) + " cipher.blockSize = " + (cipher == null ? null : cipher.getBlockSize()) + " encryptMode = " + encryptMode + " cipherInited = " + cipherInited + " key.length = " + (key == null ? 0 : key.length) + " iv.length = " + (realIV == null ? 0 : realIV.length) + " padding = " + padding); } @JRubyMethod(required = 1, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject name) { initializeImpl(context.runtime, name.toString()); return this; } final void initializeImpl(final Ruby runtime, final String name) { //if ( ! isSupportedCipher(name) ) { // throw newCipherError(runtime, "unsupported cipher algorithm ("+ name +")"); //} if ( cipher != null ) { throw runtime.newRuntimeError("Cipher already inititalized!"); } updateCipher(name, padding); } @Override @JRubyMethod(required = 1, visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(final IRubyObject obj) { if ( this == obj ) return this; checkFrozen(); final Cipher other = (Cipher) obj; cryptoBase = other.cryptoBase; cryptoVersion = other.cryptoVersion; cryptoMode = other.cryptoMode; paddingType = other.paddingType; realName = other.realName; name = other.name; keyLength = other.keyLength; ivLength = other.ivLength; encryptMode = other.encryptMode; cipherInited = false; if ( other.key != null ) { key = Arrays.copyOf(other.key, other.key.length); } else { key = null; } if (other.realIV != null) { realIV = Arrays.copyOf(other.realIV, other.realIV.length); } else { realIV = null; } this.orgIV = this.realIV; padding = other.padding; cipher = getCipherInstance(); return this; } @JRubyMethod public final RubyString name() { return getRuntime().newString(name); } @JRubyMethod public final RubyInteger key_len() { return getRuntime().newFixnum(keyLength); } @JRubyMethod public final RubyInteger iv_len() { return getRuntime().newFixnum(ivLength); } @JRubyMethod(name = "key_len=", required = 1) public final IRubyObject set_key_len(IRubyObject len) { this.keyLength = RubyNumeric.fix2int(len); return len; } @JRubyMethod(name = "key=", required = 1) public IRubyObject set_key(final ThreadContext context, final IRubyObject key) { final ByteList keyBytes; try { keyBytes = key.asString().getByteList(); } catch (Exception e) { final Ruby runtime = context.runtime; debugStackTrace(runtime, e); throw newCipherError(runtime, e); } if ( keyBytes.length() < keyLength ) { throw newCipherError(context.runtime, "key length too short"); } final byte[] k = new byte[keyLength]; System.arraycopy(keyBytes.unsafeBytes(), keyBytes.getBegin(), k, 0, keyLength); this.key = k; return key; } @JRubyMethod(name = "iv=", required = 1) public IRubyObject set_iv(final ThreadContext context, final IRubyObject iv) { final ByteList ivBytes; try { ivBytes = iv.asString().getByteList(); } catch (Exception e) { final Ruby runtime = context.runtime; debugStackTrace(runtime, e); throw newCipherError(runtime, e); } if ( ivBytes.length() < ivLength ) { throw newCipherError(context.runtime, "iv length too short"); } // EVP_CipherInit_ex uses leading IV length of given sequence. final byte[] i = new byte[ivLength]; System.arraycopy(ivBytes.unsafeBytes(), ivBytes.getBegin(), i, 0, ivLength); this.realIV = i; this.orgIV = this.realIV; if ( ! isStreamCipher() ) cipherInited = false; return iv; } @JRubyMethod public IRubyObject block_size(final ThreadContext context) { final Ruby runtime = context.runtime; checkCipherNotNull(runtime); if ( isStreamCipher() ) { // getBlockSize() returns 0 for stream cipher in JCE // OpenSSL returns 1 for RC4. return runtime.newFixnum(1); } return runtime.newFixnum(cipher.getBlockSize()); } private void init(final ThreadContext context, final IRubyObject[] args, final boolean encrypt) { final Ruby runtime = context.runtime; Arity.checkArgumentCount(runtime, args, 0, 2); encryptMode = encrypt; cipherInited = false; if ( args.length > 0 ) { /* * oops. this code mistakes salt for IV. * We deprecated the arguments for this method, but we decided * keeping this behaviour for backward compatibility. */ byte[] pass = args[0].asString().getBytes(); byte[] iv = null; try { iv = "OpenSSL for Ruby rulez!".getBytes("ISO8859-1"); byte[] iv2 = new byte[this.ivLength]; System.arraycopy(iv, 0, iv2, 0, this.ivLength); iv = iv2; } catch (Exception e) { } if ( args.length > 1 && ! args[1].isNil() ) { runtime.getWarnings().warning(ID.MISCELLANEOUS, "key derivation by " + getMetaClass().getRealClass().getName() + "#encrypt is deprecated; use " + getMetaClass().getRealClass().getName() + "::pkcs5_keyivgen instead"); iv = args[1].asString().getBytes(); if (iv.length > this.ivLength) { byte[] iv2 = new byte[this.ivLength]; System.arraycopy(iv, 0, iv2, 0, this.ivLength); iv = iv2; } } final MessageDigest digest = Digest.getDigest(runtime, "MD5"); KeyAndIv result = evpBytesToKey(keyLength, ivLength, digest, iv, pass, 2048); this.key = result.key; this.realIV = iv; this.orgIV = this.realIV; } } @JRubyMethod(optional = 2) public IRubyObject encrypt(final ThreadContext context, IRubyObject[] args) { this.realIV = orgIV; init(context, args, true); return this; } @JRubyMethod(optional = 2) public IRubyObject decrypt(final ThreadContext context, IRubyObject[] args) { this.realIV = orgIV; init(context, args, false); return this; } @JRubyMethod public IRubyObject reset(final ThreadContext context) { final Ruby runtime = context.runtime; checkCipherNotNull(runtime); if ( ! isStreamCipher() ) { this.realIV = orgIV; doInitCipher(runtime); } return this; } private void updateCipher(final String name, final String padding) { // given 'rc4' must be 'RC4' here. OpenSSL checks it as a LN of object // ID and set SN. We don't check 'name' is allowed as a LN in ASN.1 for // the possibility of JCE specific algorithm so just do upperCase here // for OpenSSL compatibility. this.name = name.toUpperCase(); this.padding = padding; final Algorithm alg = Algorithm.osslToJava(this.name, this.padding); cryptoBase = alg.base; cryptoVersion = alg.version; cryptoMode = alg.mode; realName = alg.getRealName(); paddingType = alg.getPadding(); keyLength = alg.getKeyLength(); ivLength = alg.getIvLength(); if ( "DES".equalsIgnoreCase(cryptoBase) ) { generateKeyLength = keyLength / 8 * 7; } cipher = getCipherInstance(); } final javax.crypto.Cipher getCipherInstance() { try { return getCipherInstance(realName, false); } catch (NoSuchAlgorithmException e) { throw newCipherError(getRuntime(), "unsupported cipher algorithm (" + realName + ")"); } catch (NoSuchPaddingException e) { throw newCipherError(getRuntime(), "unsupported cipher padding (" + realName + ")"); } } @JRubyMethod(required = 1, optional = 3) public IRubyObject pkcs5_keyivgen(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; Arity.checkArgumentCount(runtime, args, 1, 4); byte[] pass = args[0].asString().getBytes(); byte[] salt = null; int iter = 2048; IRubyObject vdigest = runtime.getNil(); if ( args.length > 1 ) { if ( ! args[1].isNil() ) { salt = args[1].asString().getBytes(); } if ( args.length > 2 ) { if ( ! args[2].isNil() ) { iter = RubyNumeric.fix2int(args[2]); } if ( args.length > 3 ) { vdigest = args[3]; } } } if ( salt != null && salt.length != 8 ) { throw newCipherError(runtime, "salt must be an 8-octet string"); } final String algorithm; if ( vdigest.isNil() ) algorithm = "MD5"; else { algorithm = (vdigest instanceof Digest) ? ((Digest) vdigest).getAlgorithm() : vdigest.asJavaString(); } final MessageDigest digest = Digest.getDigest(runtime, algorithm); KeyAndIv result = evpBytesToKey(keyLength, ivLength, digest, salt, pass, iter); this.key = result.key; this.realIV = result.iv; this.orgIV = this.realIV; doInitCipher(runtime); return runtime.getNil(); } private void doInitCipher(final Ruby runtime) { if ( isDebug(runtime) ) { dumpVars( runtime.getOut(), "doInitCipher()" ); } checkCipherNotNull(runtime); if ( key == null ) { //key = emptyKey(keyLength); throw newCipherError(runtime, "key not specified"); } try { // ECB mode is the only mode that does not require an IV if ( "ECB".equalsIgnoreCase(cryptoMode) ) { cipher.init(encryptMode ? ENCRYPT_MODE : DECRYPT_MODE, new SimpleSecretKey(getCipherAlgorithm(), this.key) ); } else { // if no IV yet, start out with all \0s if ( realIV == null ) realIV = new byte[ivLength]; if ( "RC2".equalsIgnoreCase(cryptoBase) ) { cipher.init(encryptMode ? ENCRYPT_MODE : DECRYPT_MODE, new SimpleSecretKey("RC2", this.key), new RC2ParameterSpec(this.key.length * 8, this.realIV) ); } else if ( "RC4".equalsIgnoreCase(cryptoBase) ) { cipher.init(encryptMode ? ENCRYPT_MODE : DECRYPT_MODE, new SimpleSecretKey("RC4", this.key) ); } else { final AlgorithmParameterSpec ivSpec; if ( "GCM".equalsIgnoreCase(cryptoMode) ) { // e.g. 'aes-128-gcm' ivSpec = new GCMParameterSpec(getAuthTagLength() * 8, this.realIV); } else { ivSpec = new IvParameterSpec(this.realIV); } cipher.init(encryptMode ? ENCRYPT_MODE : DECRYPT_MODE, new SimpleSecretKey(getCipherAlgorithm(), this.key), ivSpec ); } } } catch (InvalidKeyException e) { throw newCipherError(runtime, e + "\n possibly you need to install Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for your JRE"); } catch (Exception e) { debugStackTrace(runtime, e); throw newCipherError(runtime, e); } cipherInited = true; processedDataBytes = 0; //outBuffer = new ByteList(keyLength); } private String getCipherAlgorithm() { final int idx = realName.indexOf('/'); return idx <= 0 ? realName : realName.substring(0, idx); } private int processedDataBytes = 0; //private volatile ByteList outBuffer; private byte[] lastIV; @JRubyMethod public IRubyObject update(final ThreadContext context, final IRubyObject arg) { final Ruby runtime = context.runtime; if ( isDebug(runtime) ) dumpVars( runtime.getOut(), "update()" ); checkCipherNotNull(runtime); checkAuthTag(runtime); final ByteList data = arg.asString().getByteList(); final int length = data.length(); if ( length == 0 ) { throw runtime.newArgumentError("data must not be empty"); } if ( ! cipherInited ) doInitCipher(runtime); final ByteList str; try { updateAuthData(runtime); // if any final byte[] in = data.getUnsafeBytes(); final int offset = data.begin(); final byte[] out = cipher.update(in, offset, length); if ( out != null ) { str = new ByteList(out, false); if ( realIV != null ) { if ( encryptMode ) setLastIVIfNeeded( out ); else setLastIVIfNeeded( in, offset, length ); } processedDataBytes += length; } else { str = new ByteList(ByteList.NULL_ARRAY); } } catch (Exception e) { debugStackTrace( runtime, e ); throw newCipherError(runtime, e); } return RubyString.newString(runtime, str); } @JRubyMethod(name = "<<") public IRubyObject update_deprecated(final ThreadContext context, final IRubyObject data) { context.runtime.getWarnings().warn(ID.DEPRECATED_METHOD, getMetaClass().getRealClass().getName() + "#<< is deprecated; use #update instead"); return update(context, data); } @JRubyMethod(name = "final") public IRubyObject do_final(final ThreadContext context) { final Ruby runtime = context.runtime; checkCipherNotNull(runtime); checkAuthTag(runtime); if ( ! cipherInited ) doInitCipher(runtime); // trying to allow update after final like cruby-openssl. Bad idea. if ( "RC4".equalsIgnoreCase(cryptoBase) ) return runtime.newString(""); final ByteList str; try { if ( isAuthDataMode() ) { str = do_final_with_auth(runtime); } else { final byte[] out = cipher.doFinal(); if ( out != null ) { // TODO: Modifying this line appears to fix the issue, but I do // not have a good reason for why. Best I can tell, lastIv needs // to be set regardless of encryptMode, so we'll go with this // for now. JRUBY-3335. //if ( realIV != null && encryptMode ) ... str = new ByteList(out, false); if ( realIV != null ) setLastIVIfNeeded(out); } else { str = new ByteList(ByteList.NULL_ARRAY); } } //if ( ! isStreamCipher() ) { //if ( str.length() > processedDataBytes && processedDataBytes > 0 ) { // MRI compatibility only trailing bytes : //str.setRealSize(processedDataBytes); //} //} if (realIV != null) { realIV = lastIV; doInitCipher(runtime); } } catch (GeneralSecurityException e) { // cipher.doFinal debugStackTrace(runtime, e); throw newCipherError(runtime, e); } catch (RuntimeException e) { debugStackTrace(runtime, e); throw newCipherError(runtime, e); } return RubyString.newString(runtime, str); } private ByteList do_final_with_auth(final Ruby runtime) throws GeneralSecurityException { updateAuthData(runtime); // if any final ByteList str; // if GCM/CCM is being used, the authentication tag is appended // in the case of encryption, or verified in the case of decryption. // The result is stored in a new buffer. if ( encryptMode ) { final byte[] out = cipher.doFinal(); final int len = getAuthTagLength(); int strLen; if ( ( strLen = out.length - len ) > 0 ) { str = new ByteList(out, 0, strLen, false); } else { str = new ByteList(ByteList.NULL_ARRAY); strLen = 0; } auth_tag = new ByteList(out, strLen, out.length - strLen); return str; } else { final byte[] out; if ( auth_tag != null ) { final byte[] tag = auth_tag.getUnsafeBytes(); out = cipher.doFinal(tag, auth_tag.begin(), auth_tag.length()); } else { out = cipher.doFinal(); } return new ByteList(out, false); } } private void checkAuthTag(final Ruby runtime) { if ( auth_tag != null && encryptMode ) { throw newCipherError(runtime, "authentication tag already generated by cipher"); } } private void setLastIVIfNeeded(final byte[] tmpIV) { setLastIVIfNeeded(tmpIV, 0, tmpIV.length); } private void setLastIVIfNeeded(final byte[] tmpIV, final int offset, final int length) { final int ivLen = this.ivLength; if ( lastIV == null ) lastIV = new byte[ivLen]; if ( length >= ivLen ) { System.arraycopy(tmpIV, offset + (length - ivLen), lastIV, 0, ivLen); } } @JRubyMethod(name = "padding=") public IRubyObject set_padding(IRubyObject padding) { updateCipher(name, padding.toString()); return padding; } private transient ByteList auth_tag; @JRubyMethod(name = "auth_tag") public IRubyObject auth_tag(final ThreadContext context) { if ( auth_tag != null ) { return RubyString.newString(context.runtime, auth_tag); } if ( ! isAuthDataMode() ) { throw newCipherError(context.runtime, "authentication tag not supported by this cipher"); } return context.nil; } @JRubyMethod(name = "auth_tag=") public IRubyObject set_auth_tag(final ThreadContext context, final IRubyObject tag) { if ( ! isAuthDataMode() ) { throw newCipherError(context.runtime, "authentication tag not supported by this cipher"); } final RubyString auth_tag = tag.asString(); this.auth_tag = StringHelper.setByteListShared(auth_tag); return auth_tag; } private boolean isAuthDataMode() { // Authenticated Encryption with Associated Data (AEAD) return "GCM".equalsIgnoreCase(cryptoMode) || "CCM".equalsIgnoreCase(cryptoMode); } private static final int MAX_AUTH_TAG_LENGTH = 16; private int getAuthTagLength() { return Math.min(MAX_AUTH_TAG_LENGTH, this.key.length); // in bytes } private transient ByteList auth_data; @JRubyMethod(name = "auth_data=") public IRubyObject set_auth_data(final ThreadContext context, final IRubyObject data) { if ( ! isAuthDataMode() ) { throw newCipherError(context.runtime, "authentication data not supported by this cipher"); } final RubyString auth_data = data.asString(); this.auth_data = StringHelper.setByteListShared(auth_data); return auth_data; } private boolean updateAuthData(final Ruby runtime) { if ( auth_data == null ) return false; // only to be set if auth-mode //try { final byte[] data = auth_data.getUnsafeBytes(); cipher.updateAAD(data, auth_data.begin(), auth_data.length()); //} //catch (RuntimeException e) { // debugStackTrace( runtime, e ); // throw newCipherError(runtime, e); //} auth_data = null; return true; } @JRubyMethod(name = "authenticated?") public RubyBoolean authenticated_p(final ThreadContext context) { return context.runtime.newBoolean( isAuthDataMode() ); } @JRubyMethod public IRubyObject random_key(final ThreadContext context) { // str = OpenSSL::Random.random_bytes(self.key_len) // self.key = str // return str RubyString str = Random.random_bytes(context, this.keyLength); this.set_key(context, str); return str; } @JRubyMethod public IRubyObject random_iv(final ThreadContext context) { // str = OpenSSL::Random.random_bytes(self.iv_len) // self.iv = str // return str RubyString str = Random.random_bytes(context, this.ivLength); this.set_iv(context, str); return str; } //String getAlgorithm() { // return this.cipher.getAlgorithm(); //} final String getName() { return this.name; } //String getCryptoBase() { // return this.cryptoBase; //} //String getCryptoMode() { // return this.cryptoMode; //} final int getKeyLength() { return keyLength; } final int getGenerateKeyLength() { return (generateKeyLength == -1) ? keyLength : generateKeyLength; } private void checkCipherNotNull(final Ruby runtime) { if ( cipher == null ) { throw runtime.newRuntimeError("Cipher not inititalized!"); } } private boolean isStreamCipher() { return cipher.getBlockSize() == 0; } private static RaiseException newCipherError(Ruby runtime, Exception e) { return Utils.newError(runtime, _Cipher(runtime).getClass("CipherError"), e); } private static RaiseException newCipherError(Ruby runtime, String message) { return Utils.newError(runtime, _Cipher(runtime).getClass("CipherError"), message); } private static class KeyAndIv { final byte[] key; final byte[] iv; KeyAndIv(byte[] key, byte[] iv) { this.key = key; this.iv = iv; } } private static KeyAndIv evpBytesToKey( final int key_len, final int iv_len, final MessageDigest md, final byte[] salt, final byte[] data, final int count) { final byte[] key = new byte[key_len]; final byte[] iv = new byte[iv_len]; if ( data == null ) return new KeyAndIv(key, iv); int key_ix = 0; int iv_ix = 0; byte[] md_buf = null; int nkey = key_len; int niv = iv_len; int i; int addmd = 0; for(;;) { md.reset(); if ( addmd++ > 0 ) md.update(md_buf); md.update(data); if ( salt != null ) md.update(salt, 0, 8); md_buf = md.digest(); for ( i = 1; i < count; i++ ) { md.reset(); md.update(md_buf); md_buf = md.digest(); } i = 0; if ( nkey > 0 ) { for(;;) { if ( nkey == 0) break; if ( i == md_buf.length ) break; key[ key_ix++ ] = md_buf[i]; nkey--; i++; } } if ( niv > 0 && i != md_buf.length ) { for(;;) { if ( niv == 0 ) break; if ( i == md_buf.length ) break; iv[ iv_ix++ ] = md_buf[i]; niv--; i++; } } if ( nkey == 0 && niv == 0 ) break; } return new KeyAndIv(key,iv); } private static class NamedCipherAllocator implements ObjectAllocator { private final String cipherBase; NamedCipherAllocator(final String cipherBase) { this.cipherBase = cipherBase; } public Named allocate(Ruby runtime, RubyClass klass) { return new Named(runtime, klass, cipherBase); } }; public static class Named extends Cipher { private static final long serialVersionUID = 5599069534014317221L; final String cipherBase; Named(Ruby runtime, RubyClass type, String cipherBase) { super(runtime, type); this.cipherBase = cipherBase; // e.g. "AES" } /* AES = Class.new(Cipher) do define_method(:initialize) do |*args| cipher_name = args.inject('AES'){|n, arg| "#{n}-#{arg}" } super(cipher_name) end end */ @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final StringBuilder name = new StringBuilder(); name.append(cipherBase); if ( args != null ) { for ( int i = 0; i < args.length; i++ ) { name.append('-').append( args[i].asString() ); } } initializeImpl(context.runtime, name.toString()); return this; } } private static class AESCipherAllocator implements ObjectAllocator { private final String keyLength; AESCipherAllocator(final String keyLength) { this.keyLength = keyLength; } public AES allocate(Ruby runtime, RubyClass klass) { return new AES(runtime, klass, keyLength); } }; public static class AES extends Cipher { private static final long serialVersionUID = -3627749495034257750L; final String keyLength; AES(Ruby runtime, RubyClass type, String keyLength) { super(runtime, type); this.keyLength = keyLength; // e.g. "256" } /* AES256 = Class.new(Cipher) do define_method(:initialize) do |mode| mode ||= "CBC" cipher_name = "AES-256-#{mode}" super(cipher_name) end end */ @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final String mode; if ( args != null && args.length > 0 ) { mode = args[0].toString(); } else { mode = "CBC"; } initializeImpl(context.runtime, "AES-" + keyLength + '-' + mode); return this; } } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/CipherStrings.java000066400000000000000000002771031313661621600267260ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; /** * * @author Ola Bini */ public class CipherStrings { public final static String SSL2_TXT_DES_64_CFB64_WITH_MD5_1 = "DES-CFB-M1"; public final static String SSL2_TXT_NULL_WITH_MD5 = "NULL-MD5"; public final static String SSL2_TXT_RC4_128_WITH_MD5 = "RC4-MD5"; public final static String SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 = "EXP-RC4-MD5"; public final static String SSL2_TXT_RC2_128_CBC_WITH_MD5 = "RC2-CBC-MD5"; public final static String SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 = "EXP-RC2-CBC-MD5"; public final static String SSL2_TXT_IDEA_128_CBC_WITH_MD5 = "IDEA-CBC-MD5"; public final static String SSL2_TXT_DES_64_CBC_WITH_MD5 = "DES-CBC-MD5"; public final static String SSL2_TXT_DES_64_CBC_WITH_SHA = "DES-CBC-SHA"; public final static String SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 = "DES-CBC3-MD5"; public final static String SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA = "DES-CBC3-SHA"; public final static String SSL2_TXT_RC4_64_WITH_MD5 = "RC4-64-MD5"; public final static String SSL2_TXT_NULL = "NULL"; public final static String SSL3_TXT_RSA_NULL_MD5 = "NULL-MD5"; public final static String SSL3_TXT_RSA_NULL_SHA = "NULL-SHA"; public final static String SSL3_TXT_RSA_RC4_40_MD5 = "EXP-RC4-MD5"; public final static String SSL3_TXT_RSA_RC4_128_MD5 = "RC4-MD5"; public final static String SSL3_TXT_RSA_RC4_128_SHA = "RC4-SHA"; public final static String SSL3_TXT_RSA_RC2_40_MD5 = "EXP-RC2-CBC-MD5"; public final static String SSL3_TXT_RSA_IDEA_128_SHA = "IDEA-CBC-SHA"; public final static String SSL3_TXT_RSA_DES_40_CBC_SHA = "EXP-DES-CBC-SHA"; public final static String SSL3_TXT_RSA_DES_64_CBC_SHA = "DES-CBC-SHA"; public final static String SSL3_TXT_RSA_DES_192_CBC3_SHA = "DES-CBC3-SHA"; public final static String SSL3_TXT_DH_DSS_DES_40_CBC_SHA = "EXP-DH-DSS-DES-CBC-SHA"; public final static String SSL3_TXT_DH_DSS_DES_64_CBC_SHA = "DH-DSS-DES-CBC-SHA"; public final static String SSL3_TXT_DH_DSS_DES_192_CBC3_SHA = "DH-DSS-DES-CBC3-SHA"; public final static String SSL3_TXT_DH_RSA_DES_40_CBC_SHA = "EXP-DH-RSA-DES-CBC-SHA"; public final static String SSL3_TXT_DH_RSA_DES_64_CBC_SHA = "DH-RSA-DES-CBC-SHA"; public final static String SSL3_TXT_DH_RSA_DES_192_CBC3_SHA = "DH-RSA-DES-CBC3-SHA"; public final static String SSL3_TXT_EDH_DSS_DES_40_CBC_SHA = "EXP-EDH-DSS-DES-CBC-SHA"; public final static String SSL3_TXT_EDH_DSS_DES_64_CBC_SHA = "EDH-DSS-DES-CBC-SHA"; public final static String SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA = "EDH-DSS-DES-CBC3-SHA"; public final static String SSL3_TXT_EDH_RSA_DES_40_CBC_SHA = "EXP-EDH-RSA-DES-CBC-SHA"; public final static String SSL3_TXT_EDH_RSA_DES_64_CBC_SHA = "EDH-RSA-DES-CBC-SHA"; public final static String SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA = "EDH-RSA-DES-CBC3-SHA"; public final static String SSL3_TXT_ADH_RC4_40_MD5 = "EXP-ADH-RC4-MD5"; public final static String SSL3_TXT_ADH_RC4_128_MD5 = "ADH-RC4-MD5"; public final static String SSL3_TXT_ADH_DES_40_CBC_SHA = "EXP-ADH-DES-CBC-SHA"; public final static String SSL3_TXT_ADH_DES_64_CBC_SHA = "ADH-DES-CBC-SHA"; public final static String SSL3_TXT_ADH_DES_192_CBC_SHA = "ADH-DES-CBC3-SHA"; public final static String SSL3_TXT_FZA_DMS_NULL_SHA = "FZA-NULL-SHA"; public final static String SSL3_TXT_FZA_DMS_FZA_SHA = "FZA-FZA-CBC-SHA"; public final static String SSL3_TXT_FZA_DMS_RC4_SHA = "FZA-RC4-SHA"; public final static String SSL3_TXT_KRB5_DES_64_CBC_SHA = "KRB5-DES-CBC-SHA"; public final static String SSL3_TXT_KRB5_DES_192_CBC3_SHA = "KRB5-DES-CBC3-SHA"; public final static String SSL3_TXT_KRB5_RC4_128_SHA = "KRB5-RC4-SHA"; public final static String SSL3_TXT_KRB5_IDEA_128_CBC_SHA = "KRB5-IDEA-CBC-SHA"; public final static String SSL3_TXT_KRB5_DES_64_CBC_MD5 = "KRB5-DES-CBC-MD5"; public final static String SSL3_TXT_KRB5_DES_192_CBC3_MD5 = "KRB5-DES-CBC3-MD5"; public final static String SSL3_TXT_KRB5_RC4_128_MD5 = "KRB5-RC4-MD5"; public final static String SSL3_TXT_KRB5_IDEA_128_CBC_MD5 = "KRB5-IDEA-CBC-MD5"; public final static String SSL3_TXT_KRB5_DES_40_CBC_SHA = "EXP-KRB5-DES-CBC-SHA"; public final static String SSL3_TXT_KRB5_RC2_40_CBC_SHA = "EXP-KRB5-RC2-CBC-SHA"; public final static String SSL3_TXT_KRB5_RC4_40_SHA = "EXP-KRB5-RC4-SHA"; public final static String SSL3_TXT_KRB5_DES_40_CBC_MD5 = "EXP-KRB5-DES-CBC-MD5"; public final static String SSL3_TXT_KRB5_RC2_40_CBC_MD5 = "EXP-KRB5-RC2-CBC-MD5"; public final static String SSL3_TXT_KRB5_RC4_40_MD5 = "EXP-KRB5-RC4-MD5"; public final static String SSL_TXT_NULL_WITH_MD5 = SSL2_TXT_NULL_WITH_MD5; public final static String SSL_TXT_RC4_128_WITH_MD5 = SSL2_TXT_RC4_128_WITH_MD5; public final static String SSL_TXT_RC4_128_EXPORT40_WITH_MD5 = SSL2_TXT_RC4_128_EXPORT40_WITH_MD5; public final static String SSL_TXT_RC2_128_CBC_WITH_MD5 = SSL2_TXT_RC2_128_CBC_WITH_MD5; public final static String SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 = SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5; public final static String SSL_TXT_IDEA_128_CBC_WITH_MD5 = SSL2_TXT_IDEA_128_CBC_WITH_MD5; public final static String SSL_TXT_DES_64_CBC_WITH_MD5 = SSL2_TXT_DES_64_CBC_WITH_MD5; public final static String SSL_TXT_DES_64_CBC_WITH_SHA = SSL2_TXT_DES_64_CBC_WITH_SHA; public final static String SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 = SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5; public final static String SSL_TXT_DES_192_EDE3_CBC_WITH_SHA = SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA; public final static String SSL_TXT_KRB5_DES_64_CBC_SHA = SSL3_TXT_KRB5_DES_64_CBC_SHA; public final static String SSL_TXT_KRB5_DES_192_CBC3_SHA = SSL3_TXT_KRB5_DES_192_CBC3_SHA; public final static String SSL_TXT_KRB5_RC4_128_SHA = SSL3_TXT_KRB5_RC4_128_SHA; public final static String SSL_TXT_KRB5_IDEA_128_CBC_SHA = SSL3_TXT_KRB5_IDEA_128_CBC_SHA; public final static String SSL_TXT_KRB5_DES_64_CBC_MD5 = SSL3_TXT_KRB5_DES_64_CBC_MD5; public final static String SSL_TXT_KRB5_DES_192_CBC3_MD5 = SSL3_TXT_KRB5_DES_192_CBC3_MD5; public final static String SSL_TXT_KRB5_RC4_128_MD5 = SSL3_TXT_KRB5_RC4_128_MD5; public final static String SSL_TXT_KRB5_IDEA_128_CBC_MD5 = SSL3_TXT_KRB5_IDEA_128_CBC_MD5; public final static String SSL_TXT_KRB5_DES_40_CBC_SHA = SSL3_TXT_KRB5_DES_40_CBC_SHA; public final static String SSL_TXT_KRB5_RC2_40_CBC_SHA = SSL3_TXT_KRB5_RC2_40_CBC_SHA; public final static String SSL_TXT_KRB5_RC4_40_SHA = SSL3_TXT_KRB5_RC4_40_SHA; public final static String SSL_TXT_KRB5_DES_40_CBC_MD5 = SSL3_TXT_KRB5_DES_40_CBC_MD5; public final static String SSL_TXT_KRB5_RC2_40_CBC_MD5 = SSL3_TXT_KRB5_RC2_40_CBC_MD5; public final static String SSL_TXT_KRB5_RC4_40_MD5 = SSL3_TXT_KRB5_RC4_40_MD5; public final static String SSL_TXT_LOW = "LOW"; public final static String SSL_TXT_MEDIUM = "MEDIUM"; public final static String SSL_TXT_HIGH = "HIGH"; public final static String SSL_TXT_kFZA = "kFZA"; public final static String SSL_TXT_aFZA = "aFZA"; public final static String SSL_TXT_eFZA = "eFZA"; public final static String SSL_TXT_FZA = "FZA"; public final static String SSL_TXT_aNULL = "aNULL"; public final static String SSL_TXT_eNULL = "eNULL"; public final static String SSL_TXT_NULL = "NULL"; public final static String SSL_TXT_kKRB5 = "kKRB5"; public final static String SSL_TXT_aKRB5 = "aKRB5"; public final static String SSL_TXT_KRB5 = "KRB5"; public final static String SSL_TXT_kRSA = "kRSA"; public final static String SSL_TXT_kDHr = "kDHr"; public final static String SSL_TXT_kDHd = "kDHd"; public final static String SSL_TXT_kEDH = "kEDH"; public final static String SSL_TXT_aRSA = "aRSA"; public final static String SSL_TXT_aDSS = "aDSS"; public final static String SSL_TXT_aDH = "aDH"; public final static String SSL_TXT_DSS = "DSS"; public final static String SSL_TXT_DH = "DH"; public final static String SSL_TXT_EDH = "EDH"; public final static String SSL_TXT_ADH = "ADH"; public final static String SSL_TXT_RSA = "RSA"; public final static String SSL_TXT_DES = "DES"; public final static String SSL_TXT_3DES = "3DES"; public final static String SSL_TXT_RC4 = "RC4"; public final static String SSL_TXT_RC2 = "RC2"; public final static String SSL_TXT_IDEA = "IDEA"; public final static String SSL_TXT_AES = "AES"; public final static String SSL_TXT_MD5 = "MD5"; public final static String SSL_TXT_SHA1 = "SHA1"; public final static String SSL_TXT_SHA = "SHA"; public final static String SSL_TXT_EXP = "EXP"; public final static String SSL_TXT_EXPORT = "EXPORT"; public final static String SSL_TXT_EXP40 = "EXPORT40"; public final static String SSL_TXT_EXP56 = "EXPORT56"; public final static String SSL_TXT_SSLV2 = "SSLv2"; public final static String SSL_TXT_SSLV3 = "SSLv3"; public final static String SSL_TXT_TLSV1 = "TLSv1"; public final static String SSL_TXT_ALL = "ALL"; public final static String SSL_TXT_ECC = "ECCdraft"; public final static String SSL_TXT_CMPALL = "COMPLEMENTOFALL"; public final static String SSL_TXT_CMPDEF = "COMPLEMENTOFDEFAULT"; // "ALL:!aNULL:!eNULL:!SSLv2" is for OpenSSL 1.0.0 GA public final static String SSL_DEFAULT_CIPHER_LIST = "AES:ALL:!aNULL:!eNULL:+RC4:@STRENGTH"; public final static long SSL_MKEY_MASK = 0x000000FFL; public final static long SSL_kRSA = 0x00000001L; public final static long SSL_kDHr = 0x00000002L; public final static long SSL_kDHd = 0x00000004L; public final static long SSL_kFZA = 0x00000008L; public final static long SSL_kEDH = 0x00000010L; public final static long SSL_kKRB5 = 0x00000020L; public final static long SSL_kECDH = 0x00000040L; public final static long SSL_kECDHE = 0x00000080L; public final static long SSL_aNULL = 0x00000800L; public final static long SSL_AUTH_MASK = 0x00007F00L; public final static long SSL_EDH = (SSL_kEDH|(SSL_AUTH_MASK^SSL_aNULL)); public final static long SSL_aRSA = 0x00000100L; public final static long SSL_aDSS = 0x00000200L; public final static long SSL_DSS = SSL_aDSS; public final static long SSL_aFZA = 0x00000400L; public final static long SSL_aDH = 0x00001000L; public final static long SSL_aKRB5 = 0x00002000L; public final static long SSL_aECDSA = 0x00004000L; public final static long SSL_eNULL = 0x00200000L; public final static long SSL_eFZA = 0x00100000L; public final static long SSL_NULL = (SSL_eNULL); public final static long SSL_ADH = (SSL_kEDH|SSL_aNULL); public final static long SSL_RSA = (SSL_kRSA|SSL_aRSA); public final static long SSL_DH = (SSL_kDHr|SSL_kDHd|SSL_kEDH); public final static long SSL_ECDH = (SSL_kECDH|SSL_kECDHE); public final static long SSL_FZA = (SSL_aFZA|SSL_kFZA|SSL_eFZA); public final static long SSL_KRB5 = (SSL_kKRB5|SSL_aKRB5); public final static long SSL_ENC_MASK = 0x043F8000L; public final static long SSL_DES = 0x00008000L; public final static long SSL_3DES = 0x00010000L; public final static long SSL_RC4 = 0x00020000L; public final static long SSL_RC2 = 0x00040000L; public final static long SSL_IDEA = 0x00080000L; public final static long SSL_AES = 0x04000000L; public final static long SSL_MAC_MASK = 0x00c00000L; public final static long SSL_MD5 = 0x00400000L; public final static long SSL_SHA1 = 0x00800000L; public final static long SSL_SHA = (SSL_SHA1); public final static long SSL_SSL_MASK = 0x03000000L; public final static long SSL_SSLV2 = 0x01000000L; public final static long SSL_SSLV3 = 0x02000000L; public final static long SSL_TLSV1 = SSL_SSLV3; public final static long SSL_EXP_MASK = 0x00000003L; public final static long SSL_NOT_EXP = 0x00000001L; public final static long SSL_EXPORT = 0x00000002L; public final static long SSL_STRONG_MASK = 0x000000fcL; public final static long SSL_STRONG_NONE = 0x00000004L; public final static long SSL_EXP40 = 0x00000008L; public final static long SSL_MICRO = (SSL_EXP40); public final static long SSL_EXP56 = 0x00000010L; public final static long SSL_MINI = (SSL_EXP56); public final static long SSL_LOW = 0x00000020L; public final static long SSL_MEDIUM = 0x00000040L; public final static long SSL_HIGH = 0x00000080L; public final static long SSL_ALL = 0xffffffffL; public final static long SSL_ALL_CIPHERS = (SSL_MKEY_MASK|SSL_AUTH_MASK|SSL_ENC_MASK|SSL_MAC_MASK); public final static long SSL_ALL_STRENGTHS = (SSL_EXP_MASK|SSL_STRONG_MASK); public final static long SSL_PKEY_RSA_ENC = 0; public final static long SSL_PKEY_RSA_SIGN = 1; public final static long SSL_PKEY_DSA_SIGN = 2; public final static long SSL_PKEY_DH_RSA = 3; public final static long SSL_PKEY_DH_DSA = 4; public final static long SSL_PKEY_ECC = 5; public final static long SSL_PKEY_NUM = 6; public final static long SSL3_CK_RSA_NULL_MD5 = 0x03000001; public final static long SSL3_CK_RSA_NULL_SHA = 0x03000002; public final static long SSL3_CK_RSA_RC4_40_MD5 = 0x03000003; public final static long SSL3_CK_RSA_RC4_128_MD5 = 0x03000004; public final static long SSL3_CK_RSA_RC4_128_SHA = 0x03000005; public final static long SSL3_CK_RSA_RC2_40_MD5 = 0x03000006; public final static long SSL3_CK_RSA_IDEA_128_SHA = 0x03000007; public final static long SSL3_CK_RSA_DES_40_CBC_SHA = 0x03000008; public final static long SSL3_CK_RSA_DES_64_CBC_SHA = 0x03000009; public final static long SSL3_CK_RSA_DES_192_CBC3_SHA = 0x0300000A; public final static long SSL3_CK_DH_DSS_DES_40_CBC_SHA = 0x0300000B; public final static long SSL3_CK_DH_DSS_DES_64_CBC_SHA = 0x0300000C; public final static long SSL3_CK_DH_DSS_DES_192_CBC3_SHA = 0x0300000D; public final static long SSL3_CK_DH_RSA_DES_40_CBC_SHA = 0x0300000E; public final static long SSL3_CK_DH_RSA_DES_64_CBC_SHA = 0x0300000F; public final static long SSL3_CK_DH_RSA_DES_192_CBC3_SHA = 0x03000010; public final static long SSL3_CK_EDH_DSS_DES_40_CBC_SHA = 0x03000011; public final static long SSL3_CK_EDH_DSS_DES_64_CBC_SHA = 0x03000012; public final static long SSL3_CK_EDH_DSS_DES_192_CBC3_SHA = 0x03000013; public final static long SSL3_CK_EDH_RSA_DES_40_CBC_SHA = 0x03000014; public final static long SSL3_CK_EDH_RSA_DES_64_CBC_SHA = 0x03000015; public final static long SSL3_CK_EDH_RSA_DES_192_CBC3_SHA = 0x03000016; public final static long SSL3_CK_ADH_RC4_40_MD5 = 0x03000017; public final static long SSL3_CK_ADH_RC4_128_MD5 = 0x03000018; public final static long SSL3_CK_ADH_DES_40_CBC_SHA = 0x03000019; public final static long SSL3_CK_ADH_DES_64_CBC_SHA = 0x0300001A; public final static long SSL3_CK_ADH_DES_192_CBC_SHA = 0x0300001B; public final static long SSL3_CK_FZA_DMS_NULL_SHA = 0x0300001C; public final static long SSL3_CK_FZA_DMS_FZA_SHA = 0x0300001D; public final static long SSL3_CK_KRB5_DES_64_CBC_SHA = 0x0300001E; public final static long SSL3_CK_KRB5_DES_192_CBC3_SHA = 0x0300001F; public final static long SSL3_CK_KRB5_RC4_128_SHA = 0x03000020; public final static long SSL3_CK_KRB5_IDEA_128_CBC_SHA = 0x03000021; public final static long SSL3_CK_KRB5_DES_64_CBC_MD5 = 0x03000022; public final static long SSL3_CK_KRB5_DES_192_CBC3_MD5 = 0x03000023; public final static long SSL3_CK_KRB5_RC4_128_MD5 = 0x03000024; public final static long SSL3_CK_KRB5_IDEA_128_CBC_MD5 = 0x03000025; public final static long SSL3_CK_KRB5_DES_40_CBC_SHA = 0x03000026; public final static long SSL3_CK_KRB5_RC2_40_CBC_SHA = 0x03000027; public final static long SSL3_CK_KRB5_RC4_40_SHA = 0x03000028; public final static long SSL3_CK_KRB5_DES_40_CBC_MD5 = 0x03000029; public final static long SSL3_CK_KRB5_RC2_40_CBC_MD5 = 0x0300002A; public final static long SSL3_CK_KRB5_RC4_40_MD5 = 0x0300002B; public final static long TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 = 0x03000060; public final static long TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 = 0x03000061; public final static long TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA = 0x03000062; public final static long TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA = 0x03000063; public final static long TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA = 0x03000064; public final static long TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA = 0x03000065; public final static long TLS1_CK_DHE_DSS_WITH_RC4_128_SHA = 0x03000066; public final static long TLS1_CK_RSA_WITH_AES_128_SHA = 0x0300002F; public final static long TLS1_CK_DH_DSS_WITH_AES_128_SHA = 0x03000030; public final static long TLS1_CK_DH_RSA_WITH_AES_128_SHA = 0x03000031; public final static long TLS1_CK_DHE_DSS_WITH_AES_128_SHA = 0x03000032; public final static long TLS1_CK_DHE_RSA_WITH_AES_128_SHA = 0x03000033; public final static long TLS1_CK_ADH_WITH_AES_128_SHA = 0x03000034; public final static long TLS1_CK_RSA_WITH_AES_256_SHA = 0x03000035; public final static long TLS1_CK_DH_DSS_WITH_AES_256_SHA = 0x03000036; public final static long TLS1_CK_DH_RSA_WITH_AES_256_SHA = 0x03000037; public final static long TLS1_CK_DHE_DSS_WITH_AES_256_SHA = 0x03000038; public final static long TLS1_CK_DHE_RSA_WITH_AES_256_SHA = 0x03000039; public final static long TLS1_CK_ADH_WITH_AES_256_SHA = 0x0300003A; public final static long TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA = 0x0300C001; public final static long TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA = 0x0300C002; public final static long TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA = 0x0300C003; public final static long TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0x0300C004; public final static long TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0x0300C005; public final static long TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA = 0x0300C006; public final static long TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA = 0x0300C007; public final static long TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA = 0x0300C008; final static long TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0x0300C009; final static long TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0x0300C00A; public final static long TLS1_CK_ECDH_RSA_WITH_NULL_SHA = 0x0300C00B; public final static long TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA = 0x0300C00C; public final static long TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA = 0x0300C00D; final static long TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0x0300C00E; final static long TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0x0300C00F; public final static long TLS1_CK_ECDHE_RSA_WITH_NULL_SHA = 0x0300C010; public final static long TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA = 0x0300C011; public final static long TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA = 0x0300C012; final static long TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0x0300C013; final static long TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0x0300C014; public final static long TLS1_CK_ECDH_anon_WITH_NULL_SHA = 0x0300C015; final static long TLS_ECDH_anon_WITH_RC4_128_SHA = 0x0300C016; final static long TLS_ECDH_anon_WITH_DES_192_CBC3_SHA = 0x0300C017; final static long TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0x0300C018; final static long TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0x0300C019; public final static String TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 = "EXP1024-RC4-MD5"; public final static String TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 = "EXP1024-RC2-CBC-MD5"; public final static String TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA = "EXP1024-DES-CBC-SHA"; public final static String TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA = "EXP1024-DHE-DSS-DES-CBC-SHA"; public final static String TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA = "EXP1024-RC4-SHA"; public final static String TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA = "EXP1024-DHE-DSS-RC4-SHA"; public final static String TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA = "DHE-DSS-RC4-SHA"; public final static String TLS1_TXT_RSA_WITH_AES_128_SHA = "AES128-SHA"; public final static String TLS1_TXT_DH_DSS_WITH_AES_128_SHA = "DH-DSS-AES128-SHA"; public final static String TLS1_TXT_DH_RSA_WITH_AES_128_SHA = "DH-RSA-AES128-SHA"; public final static String TLS1_TXT_DHE_DSS_WITH_AES_128_SHA = "DHE-DSS-AES128-SHA"; public final static String TLS1_TXT_DHE_RSA_WITH_AES_128_SHA = "DHE-RSA-AES128-SHA"; public final static String TLS1_TXT_ADH_WITH_AES_128_SHA = "ADH-AES128-SHA"; public final static String TLS1_TXT_RSA_WITH_AES_256_SHA = "AES256-SHA"; public final static String TLS1_TXT_DH_DSS_WITH_AES_256_SHA = "DH-DSS-AES256-SHA"; public final static String TLS1_TXT_DH_RSA_WITH_AES_256_SHA = "DH-RSA-AES256-SHA"; public final static String TLS1_TXT_DHE_DSS_WITH_AES_256_SHA = "DHE-DSS-AES256-SHA"; public final static String TLS1_TXT_DHE_RSA_WITH_AES_256_SHA = "DHE-RSA-AES256-SHA"; public final static String TLS1_TXT_ADH_WITH_AES_256_SHA = "ADH-AES256-SHA"; public final static String TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA = "ECDH-ECDSA-NULL-SHA"; public final static String TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA = "ECDH-ECDSA-RC4-SHA"; public final static String TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA = "ECDH-ECDSA-DES-CBC3-SHA"; public final static String TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA = "ECDHE-ECDSA-NULL-SHA"; public final static String TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA = "ECDHE-ECDSA-RC4-SHA"; public final static String TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA = "ECDHE-ECDSA-DES-CBC3-SHA"; public final static String TLS1_TXT_ECDH_RSA_WITH_NULL_SHA = "ECDH-RSA-NULL-SHA"; public final static String TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA = "ECDH-RSA-RC4-SHA"; public final static String TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA = "ECDH-RSA-DES-CBC3-SHA"; public final static String TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA = "ECDHE-RSA-NULL-SHA"; public final static String TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA = "ECDHE-RSA-RC4-SHA"; public final static String TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA = "ECDHE-RSA-DES-CBC3-SHA"; public final static String TLS1_TXT_ECDH_anon_WITH_NULL_SHA = "AECDH-NULL-SHA"; static final class Def implements Comparable, Cloneable { //private final byte valid; final String name; //private final long id; final long algorithms; private final long algStrength; //final long algorithm2; final int algStrengthBits; final int algBits; private final long mask; private final long algStrengthMask; private volatile String cipherSuite; Def(int valid, String name, long id, long algorithms, long algo_strength, long algorithm2, int strength_bits, int alg_bits, long mask, long maskStrength) { //this.valid = (byte) valid; this.name = name; //this.id = id; this.algorithms = algorithms; this.algStrength = algo_strength; //this.algorithm2 = algorithm2; this.algStrengthBits = strength_bits; this.algBits = alg_bits; this.mask = mask; this.algStrengthMask = maskStrength; } Def(String name, long algorithms, long algo_strength, int strength_bits, int alg_bits, long mask, long maskStrength) { this.name = name; this.algorithms = algorithms; this.algStrength = algo_strength; this.algStrengthBits = strength_bits; this.algBits = alg_bits; this.mask = mask; this.algStrengthMask = maskStrength; } public String getCipherSuite() { return cipherSuite; } Def setCipherSuite(final String suite) { if ( this.cipherSuite == null ) { synchronized (this) { if ( this.cipherSuite == null ) { this.cipherSuite = suite; return this; } } } if ( suite.equals(this.cipherSuite) ) return this; try { Def clone = (Def) super.clone(); clone.cipherSuite = suite; return clone; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); // won't happen } } @Override public int hashCode() { return name.hashCode(); } @Override public boolean equals(Object other) { if ( this == other ) return true; if ( other instanceof Def ) { return this.name.equals(((Def) other).name); } return false; } @Override public int compareTo(final Def that) { return this.algStrengthBits - that.algStrengthBits; } @Override public String toString() { return getClass().getSimpleName() + '@' + Integer.toHexString(System.identityHashCode(this)) + '<' + name + '>'; } // from ssl_cipher_apply_rule public boolean matches(Def current) { // ma = mask & cp->algorithms; // ma_s = mask_strength & cp->algo_strength; // // // Select: if none of the mask bit was met from the // // cipher or not all of the bits were met, the // // selection does not apply. // if (((ma == 0) && (ma_s == 0)) || // ((ma & algorithms) != ma) || // ((ma_s & algo_strength) != ma_s)) // continue; // does not apply // } final long ma = this.mask & current.algorithms; final long ma_s = this.algStrengthMask & current.algStrength; if ( ( ma == 0 && ma_s == 0 ) || ( (ma & this.algorithms) != ma ) || ( (ma_s & this.algStrength) != ma_s) ) { return false; } return true; } } static Collection matchingCiphers(final String cipherString, final String[] all, final boolean setSuite) { final List matchedList = new LinkedList(); Set removed = null; /* * If the rule_string begins with DEFAULT, apply the default rule * before using the (possibly available) additional rules. * (Matching OpenSSL behaviour) */ int offset = 0; final String[] parts = cipherString.split("[:, ]+"); if ( parts.length >= 1 && "DEFAULT".equals(parts[0]) ) { final Collection matching = matchingCiphers(SSL_DEFAULT_CIPHER_LIST, all, setSuite); matchedList.addAll(matching); offset = offset + 1; } for ( int i = offset; i < parts.length; i++ ) { final String part = parts[i]; if ( part.equals("@STRENGTH") ) { Collections.sort(matchedList); continue; } int index = 0; switch ( part.charAt(0) ) { case '!': case '+': case '-': index++; break; } final Collection matching; final String[] defs = part.substring(index).split("[+]"); if ( defs.length == 1 ) { matching = matchingExact(defs[0], all, setSuite); } else { matching = matching(defs, all, setSuite); } if ( matching != null ) { if ( index > 0 ) { switch ( part.charAt(0) ) { case '!': matchedList.removeAll(matching); if ( removed == null ) removed = new HashSet(); removed.addAll(matching); break; case '+': // '+' is for moving entry in the list for ( final Def def : matching ) { if ( removed == null || ! removed.contains(def) ) { if ( matchedList.remove(def) ) matchedList.add(def); } } break; case '-': matchedList.removeAll(matching); break; } } else { for ( final Def def : matching ) { if ( removed == null || ! removed.contains(def) ) { if ( ! matchedList.contains(def) ) matchedList.add(def); } } } } } return matchedList; } private static Collection matchingExact(final String name, final String[] all, final boolean setSuite) { final Def pattern = Definitions.get(name); if ( pattern != null ) { return matchingPattern(pattern, all, true, setSuite); } return null; // Collections.emptyList(); } private static Collection matching(final String[] defs, final String[] all, final boolean setSuite) { Collection matching = null; for ( final String name : defs ) { final Def pattern = Definitions.get(name); if ( pattern != null ) { if ( matching == null ) { matching = matchingPattern(pattern, all, true, setSuite); } else { matching.retainAll( matchingPattern(pattern, all, false, setSuite) ); } } } return matching; } private static Collection matchingPattern( final Def pattern, final String[] all, final boolean useSet, final boolean setSuite) { final Collection matching; if ( useSet ) matching = new LinkedHashSet(); else matching = new ArrayList(all.length); for ( final String entry : all ) { final String ossl = SuiteToOSSL.get(entry); if ( ossl != null ) { final Def def = CipherNames.get(ossl); if ( def != null && pattern.matches(def) ) { if ( setSuite ) { matching.add( def.setCipherSuite(entry) ); } else { matching.add( def ); } } } } return matching; } private final static Map Definitions; //private final static ArrayList Ciphers; private final static Map CipherNames; private final static Map SuiteToOSSL; static { Definitions = new HashMap( 48, 1 ); // TODO review base on OpenSSL's static const SSL_CIPHER cipher_aliases[] ?! Definitions.put(SSL_TXT_ALL,new Def(0,SSL_TXT_ALL, 0,SSL_ALL & ~SSL_eNULL, SSL_ALL ,0,0,0,SSL_ALL,SSL_ALL)); Definitions.put(SSL_TXT_CMPALL,new Def(0,SSL_TXT_CMPALL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_CMPDEF,new Def(0,SSL_TXT_CMPDEF,0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_kKRB5,new Def(0,SSL_TXT_kKRB5,0,SSL_kKRB5,0,0,0,0,SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_kRSA,new Def(0,SSL_TXT_kRSA,0,SSL_kRSA, 0,0,0,0,SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_kDHr,new Def(0,SSL_TXT_kDHr,0,SSL_kDHr, 0,0,0,0,SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_kDHd,new Def(0,SSL_TXT_kDHd,0,SSL_kDHd, 0,0,0,0,SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_kEDH,new Def(0,SSL_TXT_kEDH,0,SSL_kEDH, 0,0,0,0,SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_kFZA,new Def(0,SSL_TXT_kFZA,0,SSL_kFZA, 0,0,0,0,SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_DH,new Def(0,SSL_TXT_DH, 0,SSL_DH, 0,0,0,0,SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_ECC,new Def(0,SSL_TXT_ECC, 0,(SSL_kECDH|SSL_kECDHE), 0,0,0,0,SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_EDH,new Def(0,SSL_TXT_EDH, 0,SSL_EDH, 0,0,0,0,SSL_MKEY_MASK|SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_aKRB5,new Def(0,SSL_TXT_aKRB5,0,SSL_aKRB5,0,0,0,0,SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_aRSA,new Def(0,SSL_TXT_aRSA,0,SSL_aRSA, 0,0,0,0,SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_aDSS,new Def(0,SSL_TXT_aDSS,0,SSL_aDSS, 0,0,0,0,SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_aFZA,new Def(0,SSL_TXT_aFZA,0,SSL_aFZA, 0,0,0,0,SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_aNULL,new Def(0,SSL_TXT_aNULL,0,SSL_aNULL,0,0,0,0,SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_aDH,new Def(0,SSL_TXT_aDH, 0,SSL_aDH, 0,0,0,0,SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_DSS,new Def(0,SSL_TXT_DSS, 0,SSL_DSS, 0,0,0,0,SSL_AUTH_MASK,0)); Definitions.put(SSL_TXT_DES,new Def(0,SSL_TXT_DES, 0,SSL_DES, 0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_3DES,new Def(0,SSL_TXT_3DES,0,SSL_3DES, 0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_RC4,new Def(0,SSL_TXT_RC4, 0,SSL_RC4, 0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_RC2,new Def(0,SSL_TXT_RC2, 0,SSL_RC2, 0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_IDEA,new Def(0,SSL_TXT_IDEA,0,SSL_IDEA, 0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_eNULL,new Def(0,SSL_TXT_eNULL,0,SSL_eNULL,0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_eFZA,new Def(0,SSL_TXT_eFZA,0,SSL_eFZA, 0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_AES,new Def(0,SSL_TXT_AES, 0,SSL_AES, 0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_MD5,new Def(0,SSL_TXT_MD5, 0,SSL_MD5, 0,0,0,0,SSL_MAC_MASK,0)); Definitions.put(SSL_TXT_SHA1,new Def(0,SSL_TXT_SHA1,0,SSL_SHA1, 0,0,0,0,SSL_MAC_MASK,0)); Definitions.put(SSL_TXT_SHA,new Def(0,SSL_TXT_SHA, 0,SSL_SHA, 0,0,0,0,SSL_MAC_MASK,0)); Definitions.put(SSL_TXT_NULL,new Def(0,SSL_TXT_NULL,0,SSL_NULL, 0,0,0,0,SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_KRB5,new Def(0,SSL_TXT_KRB5,0,SSL_KRB5, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_RSA,new Def(0,SSL_TXT_RSA, 0,SSL_RSA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_ADH,new Def(0,SSL_TXT_ADH, 0,SSL_ADH, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK,0)); Definitions.put(SSL_TXT_FZA,new Def(0,SSL_TXT_FZA, 0,SSL_FZA, 0,0,0,0,SSL_AUTH_MASK|SSL_MKEY_MASK|SSL_ENC_MASK,0)); Definitions.put(SSL_TXT_SSLV2,new Def(0,SSL_TXT_SSLV2, 0,SSL_SSLV2, 0,0,0,0,SSL_SSL_MASK,0)); Definitions.put(SSL_TXT_SSLV3,new Def(0,SSL_TXT_SSLV3, 0,SSL_SSLV3, 0,0,0,0,SSL_SSL_MASK,0)); Definitions.put(SSL_TXT_TLSV1,new Def(0,SSL_TXT_TLSV1, 0,SSL_TLSV1, 0,0,0,0,SSL_SSL_MASK,0)); Definitions.put(SSL_TXT_EXP,new Def(0,SSL_TXT_EXP ,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK)); Definitions.put(SSL_TXT_EXPORT,new Def(0,SSL_TXT_EXPORT,0, 0,SSL_EXPORT, 0,0,0,0,SSL_EXP_MASK)); Definitions.put(SSL_TXT_EXP40,new Def(0,SSL_TXT_EXP40, 0, 0, SSL_EXP40, 0,0,0,0,SSL_STRONG_MASK)); Definitions.put(SSL_TXT_EXP56,new Def(0,SSL_TXT_EXP56, 0, 0, SSL_EXP56, 0,0,0,0,SSL_STRONG_MASK)); Definitions.put(SSL_TXT_LOW,new Def(0,SSL_TXT_LOW, 0, 0, SSL_LOW, 0,0,0,0,SSL_STRONG_MASK)); Definitions.put(SSL_TXT_MEDIUM,new Def(0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK)); Definitions.put(SSL_TXT_HIGH,new Def(0,SSL_TXT_HIGH, 0, 0, SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK)); final ArrayList Ciphers = new ArrayList( 96 ); /* Cipher 01 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_NULL_MD5, SSL3_CK_RSA_NULL_MD5, SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_MD5|SSL_SSLV3, SSL_NOT_EXP|SSL_STRONG_NONE, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 02 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_NULL_SHA, SSL3_CK_RSA_NULL_SHA, SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_STRONG_NONE, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 03 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_RC4_40_MD5, SSL3_CK_RSA_RC4_40_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4 |SSL_MD5 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 04 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4 |SSL_MD5|SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 05 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_RC4_128_SHA, SSL3_CK_RSA_RC4_128_SHA, SSL_kRSA|SSL_aRSA|SSL_RC4 |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 06 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_RC2_40_MD5, SSL3_CK_RSA_RC2_40_MD5, SSL_kRSA|SSL_aRSA|SSL_RC2 |SSL_MD5 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 07 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_IDEA_128_SHA, SSL3_CK_RSA_IDEA_128_SHA, SSL_kRSA|SSL_aRSA|SSL_IDEA |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 08 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_DES_40_CBC_SHA, SSL3_CK_RSA_DES_40_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA1|SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 09 */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_DES_64_CBC_SHA, SSL3_CK_RSA_DES_64_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 0A */ Ciphers.add(new Def( 1, SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, SSL_kRSA|SSL_aRSA|SSL_3DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* The DH ciphers */ /* Cipher 0B */ Ciphers.add(new Def( 0, SSL3_TXT_DH_DSS_DES_40_CBC_SHA, SSL3_CK_DH_DSS_DES_40_CBC_SHA, SSL_kDHd |SSL_aDH|SSL_DES|SSL_SHA1|SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 0C */ Ciphers.add(new Def( 0, SSL3_TXT_DH_DSS_DES_64_CBC_SHA, SSL3_CK_DH_DSS_DES_64_CBC_SHA, SSL_kDHd |SSL_aDH|SSL_DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 0D */ Ciphers.add(new Def( 0, SSL3_TXT_DH_DSS_DES_192_CBC3_SHA, SSL3_CK_DH_DSS_DES_192_CBC3_SHA, SSL_kDHd |SSL_aDH|SSL_3DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 0E */ Ciphers.add(new Def( 0, SSL3_TXT_DH_RSA_DES_40_CBC_SHA, SSL3_CK_DH_RSA_DES_40_CBC_SHA, SSL_kDHr |SSL_aDH|SSL_DES|SSL_SHA1|SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 0F */ Ciphers.add(new Def( 0, SSL3_TXT_DH_RSA_DES_64_CBC_SHA, SSL3_CK_DH_RSA_DES_64_CBC_SHA, SSL_kDHr |SSL_aDH|SSL_DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 10 */ Ciphers.add(new Def( 0, SSL3_TXT_DH_RSA_DES_192_CBC3_SHA, SSL3_CK_DH_RSA_DES_192_CBC3_SHA, SSL_kDHr |SSL_aDH|SSL_3DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* The Ephemeral DH ciphers */ /* Cipher 11 */ Ciphers.add(new Def( 1, SSL3_TXT_EDH_DSS_DES_40_CBC_SHA, SSL3_CK_EDH_DSS_DES_40_CBC_SHA, SSL_kEDH|SSL_aDSS|SSL_DES|SSL_SHA1|SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 12 */ Ciphers.add(new Def( 1, SSL3_TXT_EDH_DSS_DES_64_CBC_SHA, SSL3_CK_EDH_DSS_DES_64_CBC_SHA, SSL_kEDH|SSL_aDSS|SSL_DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 13 */ Ciphers.add(new Def( 1, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, SSL3_CK_EDH_DSS_DES_192_CBC3_SHA, SSL_kEDH|SSL_aDSS|SSL_3DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 14 */ Ciphers.add(new Def( 1, SSL3_TXT_EDH_RSA_DES_40_CBC_SHA, SSL3_CK_EDH_RSA_DES_40_CBC_SHA, SSL_kEDH|SSL_aRSA|SSL_DES|SSL_SHA1|SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 15 */ Ciphers.add(new Def( 1, SSL3_TXT_EDH_RSA_DES_64_CBC_SHA, SSL3_CK_EDH_RSA_DES_64_CBC_SHA, SSL_kEDH|SSL_aRSA|SSL_DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 16 */ Ciphers.add(new Def( 1, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, SSL_kEDH|SSL_aRSA|SSL_3DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 17 */ Ciphers.add(new Def( 1, SSL3_TXT_ADH_RC4_40_MD5, SSL3_CK_ADH_RC4_40_MD5, SSL_kEDH |SSL_aNULL|SSL_RC4 |SSL_MD5 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 18 */ Ciphers.add(new Def( 1, SSL3_TXT_ADH_RC4_128_MD5, SSL3_CK_ADH_RC4_128_MD5, SSL_kEDH |SSL_aNULL|SSL_RC4 |SSL_MD5 |SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 19 */ Ciphers.add(new Def( 1, SSL3_TXT_ADH_DES_40_CBC_SHA, SSL3_CK_ADH_DES_40_CBC_SHA, SSL_kEDH |SSL_aNULL|SSL_DES|SSL_SHA1|SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 1A */ Ciphers.add(new Def( 1, SSL3_TXT_ADH_DES_64_CBC_SHA, SSL3_CK_ADH_DES_64_CBC_SHA, SSL_kEDH |SSL_aNULL|SSL_DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 1B */ Ciphers.add(new Def( 1, SSL3_TXT_ADH_DES_192_CBC_SHA, SSL3_CK_ADH_DES_192_CBC_SHA, SSL_kEDH |SSL_aNULL|SSL_3DES |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Fortezza */ /* Cipher 1C */ Ciphers.add(new Def( 0, SSL3_TXT_FZA_DMS_NULL_SHA, SSL3_CK_FZA_DMS_NULL_SHA, SSL_kFZA|SSL_aFZA |SSL_eNULL |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_STRONG_NONE, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 1D */ Ciphers.add(new Def( 0, SSL3_TXT_FZA_DMS_FZA_SHA, SSL3_CK_FZA_DMS_FZA_SHA, SSL_kFZA|SSL_aFZA |SSL_eFZA |SSL_SHA1|SSL_SSLV3, SSL_NOT_EXP|SSL_STRONG_NONE, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 1E VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_DES_64_CBC_SHA, SSL3_CK_KRB5_DES_64_CBC_SHA, SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_SHA1 |SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 1F VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_DES_192_CBC3_SHA, SSL3_CK_KRB5_DES_192_CBC3_SHA, SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_SHA1 |SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 112, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 20 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_RC4_128_SHA, SSL3_CK_KRB5_RC4_128_SHA, SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_SHA1 |SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 21 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_IDEA_128_CBC_SHA, SSL3_CK_KRB5_IDEA_128_CBC_SHA, SSL_kKRB5|SSL_aKRB5| SSL_IDEA|SSL_SHA1 |SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 22 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_DES_64_CBC_MD5, SSL3_CK_KRB5_DES_64_CBC_MD5, SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_MD5 |SSL_SSLV3, SSL_NOT_EXP|SSL_LOW, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 23 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_DES_192_CBC3_MD5, SSL3_CK_KRB5_DES_192_CBC3_MD5, SSL_kKRB5|SSL_aKRB5| SSL_3DES|SSL_MD5 |SSL_SSLV3, SSL_NOT_EXP|SSL_HIGH, 0, 112, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 24 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_RC4_128_MD5, SSL3_CK_KRB5_RC4_128_MD5, SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_MD5 |SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 25 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_IDEA_128_CBC_MD5, SSL3_CK_KRB5_IDEA_128_CBC_MD5, SSL_kKRB5|SSL_aKRB5| SSL_IDEA|SSL_MD5 |SSL_SSLV3, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 26 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_DES_40_CBC_SHA, SSL3_CK_KRB5_DES_40_CBC_SHA, SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_SHA1 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 27 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_RC2_40_CBC_SHA, SSL3_CK_KRB5_RC2_40_CBC_SHA, SSL_kKRB5|SSL_aKRB5| SSL_RC2|SSL_SHA1 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 28 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_RC4_40_SHA, SSL3_CK_KRB5_RC4_40_SHA, SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_SHA1 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 29 VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_DES_40_CBC_MD5, SSL3_CK_KRB5_DES_40_CBC_MD5, SSL_kKRB5|SSL_aKRB5| SSL_DES|SSL_MD5 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 2A VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_RC2_40_CBC_MD5, SSL3_CK_KRB5_RC2_40_CBC_MD5, SSL_kKRB5|SSL_aKRB5| SSL_RC2|SSL_MD5 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 40, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 2B VRS */ Ciphers.add(new Def( 1, SSL3_TXT_KRB5_RC4_40_MD5, SSL3_CK_KRB5_RC4_40_MD5, SSL_kKRB5|SSL_aKRB5| SSL_RC4|SSL_MD5 |SSL_SSLV3, SSL_EXPORT|SSL_EXP40, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 2F */ Ciphers.add(new Def( 1, TLS1_TXT_RSA_WITH_AES_128_SHA, TLS1_CK_RSA_WITH_AES_128_SHA, SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 30 */ Ciphers.add(new Def( 0, TLS1_TXT_DH_DSS_WITH_AES_128_SHA, TLS1_CK_DH_DSS_WITH_AES_128_SHA, SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 31 */ Ciphers.add(new Def( 0, TLS1_TXT_DH_RSA_WITH_AES_128_SHA, TLS1_CK_DH_RSA_WITH_AES_128_SHA, SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 32 */ Ciphers.add(new Def( 1, TLS1_TXT_DHE_DSS_WITH_AES_128_SHA, TLS1_CK_DHE_DSS_WITH_AES_128_SHA, SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 33 */ Ciphers.add(new Def( 1, TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, TLS1_CK_DHE_RSA_WITH_AES_128_SHA, SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 34 */ Ciphers.add(new Def( 1, TLS1_TXT_ADH_WITH_AES_128_SHA, TLS1_CK_ADH_WITH_AES_128_SHA, SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 35 */ Ciphers.add(new Def( 1, TLS1_TXT_RSA_WITH_AES_256_SHA, TLS1_CK_RSA_WITH_AES_256_SHA, SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 36 */ Ciphers.add(new Def( 0, TLS1_TXT_DH_DSS_WITH_AES_256_SHA, TLS1_CK_DH_DSS_WITH_AES_256_SHA, SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 37 */ Ciphers.add(new Def( 0, TLS1_TXT_DH_RSA_WITH_AES_256_SHA, TLS1_CK_DH_RSA_WITH_AES_256_SHA, SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 38 */ Ciphers.add(new Def( 1, TLS1_TXT_DHE_DSS_WITH_AES_256_SHA, TLS1_CK_DHE_DSS_WITH_AES_256_SHA, SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 39 */ Ciphers.add(new Def( 1, TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, TLS1_CK_DHE_RSA_WITH_AES_256_SHA, SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 3A */ Ciphers.add(new Def( 1, TLS1_TXT_ADH_WITH_AES_256_SHA, TLS1_CK_ADH_WITH_AES_256_SHA, SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* New TLS Export CipherSuites */ /* Cipher 60 */ Ciphers.add(new Def( 1, TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5, TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_MD5|SSL_TLSV1, SSL_EXPORT|SSL_EXP56, 0, 56, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 61 */ Ciphers.add(new Def( 1, TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, SSL_kRSA|SSL_aRSA|SSL_RC2|SSL_MD5|SSL_TLSV1, SSL_EXPORT|SSL_EXP56, 0, 56, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 62 */ Ciphers.add(new Def( 1, TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA, TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA, SSL_kRSA|SSL_aRSA|SSL_DES|SSL_SHA|SSL_TLSV1, SSL_EXPORT|SSL_EXP56, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 63 */ Ciphers.add(new Def( 1, TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, SSL_kEDH|SSL_aDSS|SSL_DES|SSL_SHA|SSL_TLSV1, SSL_EXPORT|SSL_EXP56, 0, 56, 56, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 64 */ Ciphers.add(new Def( 1, TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA, TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_kRSA|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1, SSL_EXPORT|SSL_EXP56, 0, 56, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 65 */ Ciphers.add(new Def( 1, TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, SSL_kEDH|SSL_aDSS|SSL_RC4|SSL_SHA|SSL_TLSV1, SSL_EXPORT|SSL_EXP56, 0, 56, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher 66 */ Ciphers.add(new Def( 1, TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA, TLS1_CK_DHE_DSS_WITH_RC4_128_SHA, SSL_kEDH|SSL_aDSS|SSL_RC4|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_MEDIUM, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C001 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA, TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA, SSL_kECDH|SSL_aECDSA|SSL_eNULL|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C002 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA, TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_kECDH|SSL_aECDSA|SSL_RC4|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C003 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, SSL_kECDH|SSL_aECDSA|SSL_3DES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C006 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, SSL_kECDHE|SSL_aECDSA|SSL_eNULL|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C007 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_kECDHE|SSL_aECDSA|SSL_RC4|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C008 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, SSL_kECDHE|SSL_aECDSA|SSL_3DES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C00B */ Ciphers.add(new Def( 1, TLS1_TXT_ECDH_RSA_WITH_NULL_SHA, TLS1_CK_ECDH_RSA_WITH_NULL_SHA, SSL_kECDH|SSL_aRSA|SSL_eNULL|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C00C */ Ciphers.add(new Def( 1, TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA, TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA, SSL_kECDH|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C00D */ Ciphers.add(new Def( 1, TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA, TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA, SSL_kECDH|SSL_aRSA|SSL_3DES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C010 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, SSL_kECDHE|SSL_aRSA|SSL_eNULL|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C011 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, SSL_kECDHE|SSL_aRSA|SSL_RC4|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C012 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, SSL_kECDHE|SSL_aRSA|SSL_3DES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 0, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); /* Cipher C015 */ Ciphers.add(new Def( 1, TLS1_TXT_ECDH_anon_WITH_NULL_SHA, TLS1_CK_ECDH_anon_WITH_NULL_SHA, SSL_kECDHE|SSL_aNULL|SSL_eNULL|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 0, 0, 0, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); String name; CipherNames = new HashMap(Ciphers.size() + 24, 1); SuiteToOSSL = new HashMap( 120, 1 ); SuiteToOSSL.put("SSL_RSA_WITH_NULL_MD5", "NULL-MD5"); SuiteToOSSL.put("SSL_RSA_WITH_NULL_SHA", "NULL-SHA"); SuiteToOSSL.put("SSL_RSA_EXPORT_WITH_RC4_40_MD5", "EXP-RC4-MD5"); SuiteToOSSL.put("SSL_RSA_WITH_RC4_128_MD5", "RC4-MD5"); SuiteToOSSL.put("SSL_RSA_WITH_RC4_128_SHA", "RC4-SHA"); SuiteToOSSL.put("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5","EXP-RC2-CBC-MD5"); SuiteToOSSL.put("SSL_RSA_WITH_IDEA_CBC_SHA","IDEA-CBC-SHA"); SuiteToOSSL.put("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-DES-CBC-SHA"); SuiteToOSSL.put("SSL_RSA_WITH_DES_CBC_SHA", "DES-CBC-SHA"); SuiteToOSSL.put("SSL_RSA_WITH_3DES_EDE_CBC_SHA", "DES-CBC3-SHA"); SuiteToOSSL.put("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-DSS-DES-CBC-SHA"); SuiteToOSSL.put("SSL_DHE_DSS_WITH_DES_CBC_SHA", "EDH-DSS-CBC-SHA"); SuiteToOSSL.put("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "EDH-DSS-DES-CBC3-SHA"); SuiteToOSSL.put("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "EXP-EDH-RSA-DES-CBC-SHA"); SuiteToOSSL.put("SSL_DHE_RSA_WITH_DES_CBC_SHA", "EDH-RSA-DES-CBC-SHA"); SuiteToOSSL.put("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "EDH-RSA-DES-CBC3-SHA"); SuiteToOSSL.put("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", "EXP-ADH-RC4-MD5"); SuiteToOSSL.put("SSL_DH_anon_WITH_RC4_128_MD5", "ADH-RC4-MD5"); SuiteToOSSL.put("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", "EXP-ADH-DES-CBC-SHA"); SuiteToOSSL.put("SSL_DH_anon_WITH_DES_CBC_SHA", "ADH-DES-CBC-SHA"); SuiteToOSSL.put("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", "ADH-DES-CBC3-SHA"); SuiteToOSSL.put("TLS_RSA_WITH_NULL_MD5","NULL-MD5"); SuiteToOSSL.put("TLS_RSA_WITH_NULL_SHA","NULL-SHA"); SuiteToOSSL.put("TLS_RSA_WITH_NULL_SHA256", "NULL-SHA256"); SuiteToOSSL.put("TLS_RSA_EXPORT_WITH_RC4_40_MD5","EXP-RC4-MD5"); SuiteToOSSL.put("TLS_RSA_WITH_RC4_128_MD5","RC4-MD5"); SuiteToOSSL.put("TLS_RSA_WITH_RC4_128_SHA","RC4-SHA"); SuiteToOSSL.put("TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5","EXP-RC2-CBC-MD5"); SuiteToOSSL.put("TLS_RSA_WITH_IDEA_CBC_SHA","IDEA-CBC-SHA"); SuiteToOSSL.put("TLS_RSA_EXPORT_WITH_DES40_CBC_SHA","EXP-DES-CBC-SHA"); SuiteToOSSL.put("TLS_RSA_WITH_DES_CBC_SHA","DES-CBC-SHA"); SuiteToOSSL.put("TLS_RSA_WITH_3DES_EDE_CBC_SHA","DES-CBC3-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA","EXP-EDH-DSS-DES-CBC-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_WITH_DES_CBC_SHA","EDH-DSS-CBC-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA","EDH-DSS-DES-CBC3-SHA"); SuiteToOSSL.put("TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA","EXP-EDH-RSA-DES-CBC-SHA"); SuiteToOSSL.put("TLS_DHE_RSA_WITH_DES_CBC_SHA","EDH-RSA-DES-CBC-SHA"); SuiteToOSSL.put("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA","EDH-RSA-DES-CBC3-SHA"); SuiteToOSSL.put("TLS_DH_anon_EXPORT_WITH_RC4_40_MD5","EXP-ADH-RC4-MD5"); SuiteToOSSL.put("TLS_DH_anon_WITH_RC4_128_MD5","ADH-RC4-MD5"); SuiteToOSSL.put("TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA","EXP-ADH-DES-CBC-SHA"); SuiteToOSSL.put("TLS_DH_anon_WITH_DES_CBC_SHA","ADH-DES-CBC-SHA"); SuiteToOSSL.put("TLS_DH_anon_WITH_3DES_EDE_CBC_SHA","ADH-DES-CBC3-SHA"); SuiteToOSSL.put("TLS_RSA_WITH_AES_128_CBC_SHA", "AES128-SHA"); SuiteToOSSL.put("TLS_RSA_WITH_AES_256_CBC_SHA", "AES256-SHA"); SuiteToOSSL.put("TLS_RSA_WITH_AES_128_CBC_SHA256", "AES128-SHA256"); SuiteToOSSL.put("TLS_RSA_WITH_AES_256_CBC_SHA256", "AES256-SHA256"); SuiteToOSSL.put("TLS_DH_DSS_WITH_AES_128_CBC_SHA","DH-DSS-AES128-SHA"); SuiteToOSSL.put("TLS_DH_DSS_WITH_AES_256_CBC_SHA","DH-DSS-AES256-SHA"); SuiteToOSSL.put("TLS_DH_RSA_WITH_AES_128_CBC_SHA","DH-RSA-AES128-SHA"); SuiteToOSSL.put("TLS_DH_RSA_WITH_AES_256_CBC_SHA","DH-RSA-AES256-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "DHE-DSS-AES128-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_WITH_AES_256_CBC_SHA","DHE-DSS-AES256-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "DHE-DSS-AES128-SHA256"); SuiteToOSSL.put("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "DHE-DSS-AES256-SHA256"); SuiteToOSSL.put("TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "DHE-RSA-AES128-SHA"); SuiteToOSSL.put("TLS_DHE_RSA_WITH_AES_256_CBC_SHA","DHE-RSA-AES256-SHA"); SuiteToOSSL.put("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "DHE-RSA-AES128-SHA256"); SuiteToOSSL.put("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "DHE-RSA-AES256-SHA256"); SuiteToOSSL.put("TLS_DH_anon_WITH_AES_128_CBC_SHA","ADH-AES128-SHA"); SuiteToOSSL.put("TLS_DH_anon_WITH_AES_256_CBC_SHA","ADH-AES256-SHA"); SuiteToOSSL.put("TLS_DH_anon_WITH_AES_128_CBC_SHA256", "ADH-AES128-SHA256"); SuiteToOSSL.put("TLS_DH_anon_WITH_AES_256_CBC_SHA256", "ADH-AES256-SHA256"); SuiteToOSSL.put("TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA","EXP1024-DES-CBC-SHA"); SuiteToOSSL.put("TLS_RSA_EXPORT1024_WITH_RC4_56_SHA","EXP1024-RC4-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA","EXP1024-DHE-DSS-DES-CBC-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA","EXP1024-DHE-DSS-RC4-SHA"); SuiteToOSSL.put("TLS_DHE_DSS_WITH_RC4_128_SHA","DHE-DSS-RC4-SHA"); SuiteToOSSL.put("SSL_CK_RC4_128_WITH_MD5","RC4-MD5"); SuiteToOSSL.put("SSL_CK_RC4_128_EXPORT40_WITH_MD5","EXP-RC4-MD5"); SuiteToOSSL.put("SSL_CK_RC2_128_CBC_WITH_MD5","RC2-MD5"); SuiteToOSSL.put("SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5","EXP-RC2-MD5"); SuiteToOSSL.put("SSL_CK_IDEA_128_CBC_WITH_MD5","IDEA-CBC-MD5"); SuiteToOSSL.put("SSL_CK_DES_64_CBC_WITH_MD5","DES-CBC-MD5"); SuiteToOSSL.put("SSL_CK_DES_192_EDE3_CBC_WITH_MD5","DES-CBC3-MD5"); SuiteToOSSL.put("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", name = "ECDHE-ECDSA-AES128-SHA"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", name = "ECDHE-ECDSA-AES256-SHA"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", name = "ECDHE-ECDSA-AES128-SHA256"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", name = "ECDHE-ECDSA-AES256-SHA384"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 384, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", name = "ECDHE-RSA-AES128-SHA"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", name = "ECDHE-RSA-AES256-SHA"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", name = "ECDHE-RSA-AES128-SHA256"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", name = "ECDHE-RSA-AES256-SHA384"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 384, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", name = "ECDH-ECDSA-AES128-SHA"); CipherNames.put(name, new Def(name, SSL_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", name = "ECDH-ECDSA-AES256-SHA"); CipherNames.put(name, new Def(name, SSL_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", name = "ECDH-ECDSA-AES128-SHA256"); CipherNames.put(name, new Def(name, SSL_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", name = "ECDH-ECDSA-AES256-SHA384"); CipherNames.put(name, new Def(name, SSL_kECDH|SSL_aECDSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 384, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", name = "ECDH-RSA-AES128-SHA"); CipherNames.put(name, new Def(name, SSL_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", name = "ECDH-RSA-AES256-SHA"); CipherNames.put(name, new Def(name, SSL_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", name = "ECDH-RSA-AES128-SHA256"); CipherNames.put(name, new Def(name, SSL_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", name = "ECDH-RSA-AES256-SHA384"); CipherNames.put(name, new Def(name, SSL_kECDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 384, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-ECDSA-DES-CBC3-SHA"); SuiteToOSSL.put("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "ECDH-ECDSA-DES-CBC3-SHA"); SuiteToOSSL.put("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "ECDHE-RSA-DES-CBC3-SHA"); SuiteToOSSL.put("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "ECDH-RSA-DES-CBC3-SHA"); SuiteToOSSL.put("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "ECDHE-ECDSA-RC4-SHA"); SuiteToOSSL.put("TLS_ECDHE_RSA_WITH_RC4_128_SHA", "ECDHE-RSA-RC4-SHA"); SuiteToOSSL.put("TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "ECDH-ECDSA-RC4-SHA"); SuiteToOSSL.put("TLS_ECDH_RSA_WITH_RC4_128_SHA", "ECDH-RSA-RC4-SHA"); SuiteToOSSL.put("TLS_ECDH_anon_WITH_AES_128_CBC_SHA", name = "AECDH-AES128-SHA"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_anon_WITH_AES_256_CBC_SHA", name = "AECDH-AES256-SHA"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 256, 256, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", name = "AECDH-DES-CBC3-SHA"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aNULL|SSL_3DES|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP|SSL_HIGH, 168, 168, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDH_anon_WITH_RC4_128_SHA", name = "AECDH-RC4-SHA"); CipherNames.put(name, new Def(name, SSL_kECDHE|SSL_aNULL|SSL_RC4|SSL_SHA|SSL_TLSV1, SSL_NOT_EXP, 128, 128, SSL_ALL_CIPHERS, SSL_ALL_STRENGTHS )); SuiteToOSSL.put("TLS_ECDHE_ECDSA_WITH_NULL_SHA", "ECDHE-ECDSA-NULL-SHA"); SuiteToOSSL.put("TLS_ECDHE_RSA_WITH_NULL_SHA", "ECDHE-RSA-NULL-SHA"); SuiteToOSSL.put("TLS_ECDH_ECDSA_WITH_NULL_SHA", "ECDH-ECDSA-NULL-SHA"); SuiteToOSSL.put("TLS_ECDH_RSA_WITH_NULL_SHA", "ECDH-RSA-NULL-SHA"); SuiteToOSSL.put("TLS_ECDH_anon_WITH_NULL_SHA", "AECDH-NULL-SHA"); /* For IBM JRE: suite names start with "SSL_". On Oracle JRE, the suite names start with "TLS_" */ SuiteToOSSL.put("SSL_DH_anon_WITH_AES_128_CBC_SHA", "ADH-AES128-SHA"); SuiteToOSSL.put("SSL_DH_anon_WITH_AES_128_CBC_SHA256", "ADH-AES128-SHA256"); SuiteToOSSL.put("SSL_DH_anon_WITH_AES_128_GCM_SHA256", "ADH-AES128-GCM-SHA256"); SuiteToOSSL.put("SSL_DH_anon_WITH_AES_256_CBC_SHA", "ADH-AES256-SHA"); SuiteToOSSL.put("SSL_DH_anon_WITH_AES_256_CBC_SHA256", "ADH-AES256-SHA256"); SuiteToOSSL.put("SSL_DH_anon_WITH_AES_256_GCM_SHA384", "ADH-AES256-GCM-SHA384"); SuiteToOSSL.put("SSL_DHE_DSS_WITH_AES_128_CBC_SHA", "DHE-DSS-AES128-SHA"); SuiteToOSSL.put("SSL_DHE_DSS_WITH_AES_128_CBC_SHA256", "DHE-DSS-AES128-SHA256"); SuiteToOSSL.put("SSL_DHE_DSS_WITH_AES_128_GCM_SHA256", "DHE-DSS-AES128-GCM-SHA256"); SuiteToOSSL.put("SSL_DHE_DSS_WITH_AES_256_CBC_SHA", "DHE-DSS-AES256-SHA"); SuiteToOSSL.put("SSL_DHE_DSS_WITH_AES_256_CBC_SHA256", "DHE-DSS-AES256-SHA256"); SuiteToOSSL.put("SSL_DHE_DSS_WITH_AES_256_GCM_SHA384", "DHE-DSS-AES256-GCM-SHA384"); SuiteToOSSL.put("SSL_DHE_RSA_WITH_AES_128_CBC_SHA", "DHE-RSA-AES128-SHA"); SuiteToOSSL.put("SSL_DHE_RSA_WITH_AES_128_CBC_SHA256", "DHE-RSA-AES128-SHA256"); SuiteToOSSL.put("SSL_DHE_RSA_WITH_AES_128_GCM_SHA256", "DHE-RSA-AES128-GCM-SHA256"); SuiteToOSSL.put("SSL_DHE_RSA_WITH_AES_256_CBC_SHA", "DHE-RSA-AES256-SHA"); SuiteToOSSL.put("SSL_DHE_RSA_WITH_AES_256_CBC_SHA256", "DHE-RSA-AES256-SHA256"); SuiteToOSSL.put("SSL_DHE_RSA_WITH_AES_256_GCM_SHA384", "DHE-RSA-AES256-GCM-SHA384"); SuiteToOSSL.put("SSL_ECDH_anon_WITH_AES_128_CBC_SHA", "AECDH-AES128-SHA"); SuiteToOSSL.put("SSL_ECDH_anon_WITH_AES_256_CBC_SHA", "AECDH-AES256-SHA"); SuiteToOSSL.put("SSL_ECDH_anon_WITH_NULL_SHA", "AECDH-NULL-SHA"); SuiteToOSSL.put("SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "ECDH-ECDSA-AES128-SHA"); SuiteToOSSL.put("SSL_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "ECDH-ECDSA-AES128-SHA256"); SuiteToOSSL.put("SSL_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "ECDH-ECDSA-AES128-GCM-SHA256"); SuiteToOSSL.put("SSL_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "ECDH-ECDSA-AES256-SHA"); SuiteToOSSL.put("SSL_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "ECDH-ECDSA-AES256-SHA384"); SuiteToOSSL.put("SSL_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "ECDH-ECDSA-AES256-GCM-SHA384"); SuiteToOSSL.put("SSL_ECDH_ECDSA_WITH_NULL_SHA", "ECDH-ECDSA-NULL-SHA"); SuiteToOSSL.put("SSL_ECDH_RSA_WITH_AES_128_CBC_SHA", "ECDH-RSA-AES128-SHA"); SuiteToOSSL.put("SSL_ECDH_RSA_WITH_AES_128_CBC_SHA256", "ECDH-RSA-AES128-SHA256"); SuiteToOSSL.put("SSL_ECDH_RSA_WITH_AES_128_GCM_SHA256", "ECDH-RSA-AES128-GCM-SHA256"); SuiteToOSSL.put("SSL_ECDH_RSA_WITH_AES_256_CBC_SHA", "ECDH-RSA-AES256-SHA"); SuiteToOSSL.put("SSL_ECDH_RSA_WITH_AES_256_CBC_SHA384", "ECDH-RSA-AES256-SHA384"); SuiteToOSSL.put("SSL_ECDH_RSA_WITH_AES_256_GCM_SHA384", "ECDH-RSA-AES256-GCM-SHA384"); SuiteToOSSL.put("SSL_ECDH_RSA_WITH_NULL_SHA", "ECDH-RSA-NULL-SHA"); SuiteToOSSL.put("SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "ECDHE-ECDSA-AES128-SHA"); SuiteToOSSL.put("SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "ECDHE-ECDSA-AES128-SHA256"); SuiteToOSSL.put("SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256"); SuiteToOSSL.put("SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "ECDHE-ECDSA-AES256-SHA"); SuiteToOSSL.put("SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "ECDHE-ECDSA-AES256-SHA384"); SuiteToOSSL.put("SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "ECDHE-ECDSA-AES256-GCM-SHA384"); SuiteToOSSL.put("SSL_ECDHE_ECDSA_WITH_NULL_SHA", "ECDHE-ECDSA-NULL-SHA"); SuiteToOSSL.put("SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA", "ECDHE-RSA-AES128-SHA"); SuiteToOSSL.put("SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "ECDHE-RSA-AES128-SHA256"); SuiteToOSSL.put("SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA", "ECDHE-RSA-AES256-SHA"); SuiteToOSSL.put("SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "ECDHE-RSA-AES128-SHA384"); SuiteToOSSL.put("SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "ECDHE-RSA-AES256-GCM-SHA384"); SuiteToOSSL.put("SSL_ECDHE_RSA_WITH_NULL_SHA", "ECDHE-RSA-NULL-SHA"); SuiteToOSSL.put("SSL_RSA_WITH_AES_128_CBC_SHA", "AES128-SHA"); SuiteToOSSL.put("SSL_RSA_WITH_AES_128_CBC_SHA256", "AES128-SHA256"); SuiteToOSSL.put("SSL_RSA_WITH_AES_128_GCM_SHA256", "AES128-GCM-SHA256"); SuiteToOSSL.put("SSL_RSA_WITH_AES_256_CBC_SHA", "AES256-SHA"); SuiteToOSSL.put("SSL_RSA_WITH_AES_256_CBC_SHA256", "AES256-SHA256"); SuiteToOSSL.put("SSL_RSA_WITH_AES_256_GCM_SHA384", "AES256-GCM-SHA384"); SuiteToOSSL.put("SSL_RSA_WITH_NULL_SHA256", "NULL-SHA256"); // left overs supported by Java 7's SSLv3 / TLS v1.2 : // TLS_EMPTY_RENEGOTIATION_INFO_SCSV, // TLS_KRB5_WITH_3DES_EDE_CBC_SHA, // TLS_KRB5_WITH_3DES_EDE_CBC_MD5, // TLS_KRB5_WITH_RC4_128_SHA, // TLS_KRB5_WITH_RC4_128_MD5, // TLS_KRB5_WITH_DES_CBC_SHA, // TLS_KRB5_WITH_DES_CBC_MD5, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, // TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, // TLS_KRB5_EXPORT_WITH_RC4_40_SHA, // TLS_KRB5_EXPORT_WITH_RC4_40_MD5 for ( Def def : Ciphers ) CipherNames.put(def.name, def); } }// CipherStrings jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/Config.java000066400000000000000000000045521313661621600253430ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; /** * @author Ola Bini */ public class Config { // TODO: we cannot detect OS's default config file. ignore? public static final String DEFAULT_CONFIG_FILE = "./openssl.cnf"; public static void createConfig(Ruby runtime, RubyModule mOSSL) { RubyClass cConfig = mOSSL.defineClassUnder("Config", runtime.getObject(), runtime.getObject().getAllocator()); cConfig.defineAnnotatedMethods(Config.class); RubyClass openSSLError = mOSSL.getClass("OpenSSLError"); mOSSL.defineClassUnder("ConfigError", openSSLError, openSSLError.getAllocator()); // TODO: we should define this constant with proper path. (see above) //cConfig.setConstant("DEFAULT_CONFIG_FILE", runtime.newString(DEFAULT_CONFIG_FILE)); } }// Config jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/DefaultPEMHandler.java000066400000000000000000000036251313661621600273620ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.Reader; import java.io.Writer; /** * @author Ola Bini */ public class DefaultPEMHandler implements PEMHandler { public Object readPEM(Reader read, String password) { return null; } public void writePEM(Writer writ, Object obj, String algorithm, char[] password) { } public void writePEM(Writer writ, Object obj) { } }// DefaultPEMHandler jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/Digest.java000066400000000000000000000352231313661621600253540ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import org.jruby.util.ByteList; import static org.jruby.ext.openssl.OpenSSL.*; /** * @author Ola Bini */ public class Digest extends RubyObject { private static final long serialVersionUID = 7409857414064319518L; private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public Digest allocate(Ruby runtime, RubyClass klass) { return new Digest(runtime, klass); } }; public static void createDigest(Ruby runtime, RubyModule OpenSSL) { runtime.getLoadService().require("digest"); final RubyModule coreDigest = runtime.getModule("Digest"); final RubyClass DigestClass = coreDigest.getClass("Class"); // ::Digest::Class RubyClass Digest = OpenSSL.defineClassUnder("Digest", DigestClass, ALLOCATOR); Digest.defineAnnotatedMethods(Digest.class); RubyClass OpenSSLError = OpenSSL.getClass("OpenSSLError"); OpenSSL.defineClassUnder("DigestError", OpenSSLError, OpenSSLError.getAllocator()); String digestName; digestName = "DSS"; // OpenSSL::Digest::DSS Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "DSS1"; // OpenSSL::Digest::DSS1 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "MD2"; // OpenSSL::Digest::MD2 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "MD4"; // OpenSSL::Digest::MD4 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "MD5"; // OpenSSL::Digest::MD5 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "MDC2"; // OpenSSL::Digest::MDC2 NOTE: not really supported on Java Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "RIPEMD160"; // OpenSSL::Digest::RIPEMD160 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "SHA"; // OpenSSL::Digest::SHA Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "SHA1"; // OpenSSL::Digest::SHA1 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); // digestName = "SHA224"; // OpenSSL::Digest::SHA224 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "SHA256"; // OpenSSL::Digest::SHA256 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "SHA384"; // OpenSSL::Digest::SHA384 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); digestName = "SHA512"; // OpenSSL::Digest::SHA512 Digest.defineClassUnder(digestName, Digest, new NamedDigestAllocator(digestName)) .defineAnnotatedMethods(Named.class); } static RubyClass _Digest(final Ruby runtime) { return (RubyClass) runtime.getModule("OpenSSL").getConstantAt("Digest"); } static MessageDigest getDigest(final Ruby runtime, final String name) { final String algorithm = osslToJava( name ); try { return SecurityHelper.getMessageDigest(algorithm); } catch (NoSuchAlgorithmException e) { debug(runtime, "getMessageDigest failed: " + e); throw runtime.newNotImplementedError("Unsupported digest algorithm (" + name + ")"); } } private static Digest newInstance(final Ruby runtime, final IRubyObject name, final IRubyObject data) { final RubyClass klass = _Digest(runtime); final Digest instance = new Digest(runtime, klass); instance.initializeImpl(runtime, name.asString(), data); return instance; } public Digest(Ruby runtime, RubyClass type) { super(runtime,type); } private RubyString name; private MessageDigest digest; String getRealName() { return osslToJava(name.toString()); } MessageDigest getDigestImpl() { return digest; } public String getName() { return name.toString(); } @JRubyMethod(required = 1, optional = 1, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { IRubyObject data = context.nil; if ( args.length > 1 ) data = args[1]; initializeImpl(context.runtime, args[0].asString(), data); return this; } void initializeImpl(final Ruby runtime, final RubyString name, final IRubyObject data) { this.name = name; // e.g. "MD5" this.digest = getDigest(runtime, name.toString()); if ( ! data.isNil() ) update( data.asString() ); } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(final IRubyObject obj) { checkFrozen(); if ( this == obj ) return this; final Digest that = ((Digest) obj); this.name = (RubyString) that.name.dup(); try { this.digest = (MessageDigest) that.digest.clone(); } catch (CloneNotSupportedException e) { final Ruby runtime = getRuntime(); debug(runtime, "MessageDigest.clone() failed: " + e); throw runtime.newTypeError("Could not initialize copy of digest (" + name + ")"); } return this; } @JRubyMethod(name = "update", alias = "<<") public IRubyObject update(final IRubyObject obj) { final ByteList bytes = obj.asString().getByteList(); digest.update(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize()); return this; } @JRubyMethod public IRubyObject reset() { digest.reset(); return this; } @JRubyMethod public RubyString finish() { final byte[] hash = digest.digest(); digest.reset(); return StringHelper.newString(getRuntime(), hash); } @JRubyMethod public RubyString name() { return name; } @JRubyMethod public IRubyObject digest_length() { return RubyFixnum.newFixnum(getRuntime(), digest.getDigestLength()); } @JRubyMethod public RubyInteger block_length(final ThreadContext context) { final Ruby runtime = context.runtime; final int blockLength = getBlockLength( digest.getAlgorithm() ); if ( blockLength == -1 ) { throw runtime.newRuntimeError(getMetaClass() + " doesn't implement block_length()"); } return runtime.newFixnum(blockLength); } String getAlgorithm() { return this.digest.getAlgorithm(); } String getShortAlgorithm() { return getAlgorithm().replace("-", ""); } // name mapping for openssl -> JCE private static String osslToJava(final String digestName) { String name = digestName.toString(); final String[] parts = name.split("::"); if ( parts.length > 1 ) { // only want Digest names from the last part of class name name = parts[ parts.length - 1 ]; } // DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. // DSS is equal to SHA and DSS1 is equal to SHA1) if ( "DSS".equalsIgnoreCase(name) ) return "SHA"; if ( "DSS1".equalsIgnoreCase(name) ) return "SHA-1"; // BC accepts "SHA1" but it should be "SHA-1" per spec if ( "SHA1".equalsIgnoreCase(name) ) return "SHA-1"; if ( name.toUpperCase().startsWith("SHA") && name.length() > 4 && name.charAt(3) != '-' ) { // SHA512 return "SHA-" + name.substring(3); // SHA-512 } // BC handles MD2, MD4 and RIPEMD160 names fine ... return name; } private static int getBlockLength(final String algorithm) { final String alg = algorithm.toUpperCase(); if ( alg.startsWith("SHA") ) { if ( alg.equals("SHA-384") ) return 128; if ( alg.equals("SHA-512") ) return 128; return 64; // others 224/256 have 512 bit blocks } if ( alg.equals("MD5") ) return 64; if ( alg.equals("MD4") ) return 64; if ( alg.equals("MD2") ) return 48; if ( alg.equals("RIPEMD160") ) return 64; return -1; } @JRubyMethod(meta = true) // OpenSSL::Digest.digest("SHA256, "abc") public static RubyString digest(final ThreadContext context, final IRubyObject self, final IRubyObject name, final IRubyObject data) { return newInstance(context.runtime, name, data).finish(); } @JRubyMethod(meta = true) // OpenSSL::Digest.hexdigest("SHA1" "abc") public static RubyString hexdigest(final ThreadContext context, final IRubyObject self, final IRubyObject name, final IRubyObject data) { final Ruby runtime = context.runtime; return hexString( newInstance(runtime, name, data).finish() ); } private final static byte[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; private static RubyString hexString(final RubyString str) { final byte[] plain = str.getBytes(); final int len = plain.length; final ByteList bytes = str.getByteList(); // modify str in-place ! bytes.length( len * 2 ); bytes.invalidate(); final byte[] unsafeBytes = bytes.getUnsafeBytes(); int index = bytes.getBegin(); for ( int i = 0; i < len; i++ ) { final int b = plain[i] & 0xFF; unsafeBytes[ index++ ] = HEX[ b >> 4 ]; unsafeBytes[ index++ ] = HEX[ b & 0xF ]; } return str; } private static class NamedDigestAllocator implements ObjectAllocator { private final String digestName; NamedDigestAllocator(final String digestName) { this.digestName = digestName; } public Named allocate(Ruby runtime, RubyClass klass) { return new Named(runtime, klass, digestName); } }; public static class Named extends Digest { private static final long serialVersionUID = -8794569678070129828L; private final RubyString digestName; Named(Ruby runtime, RubyClass type, String digestName) { super(runtime, type); this.digestName = RubyString.newString(runtime, digestName); // e.g. "MD5" } /* MD5 = Class.new(Digest) do define_method(:initialize) do |*data| if data.length > 1 raise ArgumentError, "wrong number of arguments (#{data.length} for 1)" end super(name, data.first) end end */ @Override @JRubyMethod(required = 0, optional = 1, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { IRubyObject data = context.nil; if ( args.length > 0 ) data = args[0]; initializeImpl(context.runtime, digestName, data); // super(name, args[0]) return this; } /* define_method(:digest){ |data| Digest.digest(name, data) } define_method(:hexdigest){ |data| Digest.hexdigest(name, data) } */ @JRubyMethod(meta = true) public static RubyString digest(final ThreadContext context, final IRubyObject self, final IRubyObject data) { return newInstance(context.runtime, (RubyClass) self, data).finish(); } @JRubyMethod(meta = true) public static RubyString hexdigest(final ThreadContext context, final IRubyObject self, final IRubyObject data) { final Ruby runtime = context.runtime; return hexString( newInstance(runtime, (RubyClass) self, data).finish() ); } private static Named newInstance(final Ruby runtime, final RubyClass klass, final IRubyObject data) { final String name = klass.getBaseName(); final Named instance = new Named(runtime, klass, name); instance.initializeImpl(runtime, instance.digestName, data); return instance; } } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/HMAC.java000066400000000000000000000216731313661621600246510ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.runtime.Visibility; import static org.jruby.ext.openssl.OpenSSL.isDebug; /** * @author Ola Bini */ public class HMAC extends RubyObject { private static final long serialVersionUID = 7602535792884680307L; private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public HMAC allocate(Ruby runtime, RubyClass klass) { return new HMAC(runtime, klass); } }; public static void createHMAC(final Ruby runtime, final RubyModule OpenSSL) { RubyClass HMAC = OpenSSL.defineClassUnder("HMAC", runtime.getObject(), ALLOCATOR); RubyClass openSSLError = OpenSSL.getClass("OpenSSLError"); OpenSSL.defineClassUnder("HMACError",openSSLError,openSSLError.getAllocator()); HMAC.defineAnnotatedMethods(HMAC.class); } private static Mac getMacInstance(final String algorithmName) throws NoSuchAlgorithmException { // final String algorithmSuffix = algorithmName.replaceAll("-", ""); final StringBuilder algName = new StringBuilder(5 + algorithmName.length()); algName.append("HMAC"); // .append(algorithmSuffix); for ( int i = 0; i < algorithmName.length(); i++ ) { char c = algorithmName.charAt(i); if ( c != '-' ) algName.append(c); } try { return SecurityHelper.getMac(algName.toString()); } // some algorithms need the - removed; this is ugly, I know. catch (NoSuchAlgorithmException e) { algName.insert(5, '-'); // "HMAC-" + algorithmSuffix return SecurityHelper.getMac(algName.toString()); } } @JRubyMethod(name = "digest", meta = true) public static IRubyObject digest(IRubyObject self, IRubyObject digest, IRubyObject key, IRubyObject data) { final Ruby runtime = self.getRuntime(); final String algName = getDigestAlgorithmName(digest); final byte[] keyBytes = key.asString().getBytes(); final ByteList bytes = data.asString().getByteList(); try { Mac mac = getMacInstance(algName); mac.init( new SimpleSecretKey(mac.getAlgorithm(), keyBytes) ); mac.update(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize()); return runtime.newString( new ByteList(mac.doFinal(), false) ); } catch (NoSuchAlgorithmException e) { throw runtime.newNotImplementedError("Unsupported MAC algorithm (HMAC[-]" + algName + ")"); } catch (GeneralSecurityException e) { if ( isDebug(runtime) ) e.printStackTrace(runtime.getOut()); throw runtime.newNotImplementedError(e.getMessage()); } } @JRubyMethod(name = "hexdigest", meta = true) public static IRubyObject hexdigest(IRubyObject self, IRubyObject digest, IRubyObject key, IRubyObject data) { final Ruby runtime = self.getRuntime(); final String algName = getDigestAlgorithmName(digest); final byte[] keyBytes = key.asString().getBytes(); final ByteList bytes = data.asString().getByteList(); try { final Mac mac = getMacInstance(algName); mac.init( new SimpleSecretKey(mac.getAlgorithm(), keyBytes) ); mac.update(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize()); return runtime.newString( toHEX( mac.doFinal() ) ); } catch (NoSuchAlgorithmException e) { throw runtime.newNotImplementedError("Unsupported MAC algorithm (HMAC[-]" + algName + ")"); } catch (GeneralSecurityException e) { if ( isDebug(runtime) ) e.printStackTrace(runtime.getOut()); throw runtime.newNotImplementedError(e.getMessage()); } } public HMAC(Ruby runtime, RubyClass type) { super(runtime,type); } private Mac mac; private byte[] key; private ByteList data = new ByteList(64); @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(IRubyObject key, IRubyObject digest) { final String algName = getDigestAlgorithmName(digest); try { this.mac = getMacInstance(algName); this.key = key.asString().getBytes(); mac.init( SimpleSecretKey.copy(mac.getAlgorithm(), this.key) ); } catch (NoSuchAlgorithmException e) { throw getRuntime().newNotImplementedError("Unsupported MAC algorithm (HMAC[-]" + algName + ")"); } catch (GeneralSecurityException e) { if ( isDebug(getRuntime()) ) e.printStackTrace(getRuntime().getOut()); throw getRuntime().newNotImplementedError(e.getMessage()); } return this; } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(final IRubyObject obj) { if ( this == obj ) return this; checkFrozen(); final HMAC that = ((HMAC) obj); final String algName = that.mac.getAlgorithm(); try { this.mac = SecurityHelper.getMac(algName); this.key = that.key; mac.init( SimpleSecretKey.copy(algName, key) ); } catch (NoSuchAlgorithmException e) { throw getRuntime().newNotImplementedError("Unsupported MAC algorithm (" + algName + ")"); } catch (GeneralSecurityException e) { if ( isDebug(getRuntime()) ) e.printStackTrace(getRuntime().getOut()); throw getRuntime().newNotImplementedError(e.getMessage()); } data = new ByteList(that.data); return this; } @JRubyMethod(name = { "update", "<<" }) public IRubyObject update(final IRubyObject obj) { data.append(obj.asString().getByteList()); return this; } @JRubyMethod public IRubyObject reset() { data = new ByteList(64); return this; } @JRubyMethod public IRubyObject digest() { return RubyString.newString( getRuntime(), getSignatureBytes() ); } @JRubyMethod(name = { "hexdigest", "inspect", "to_s" }) public IRubyObject hexdigest() { return getRuntime().newString( toHEX(getSignatureBytes()) ); } String getAlgorithm() { return mac.getAlgorithm(); } private byte[] getSignatureBytes() { mac.reset(); mac.update(data.getUnsafeBytes(), data.getBegin(), data.getRealSize()); return mac.doFinal(); } private static String getDigestAlgorithmName(final IRubyObject digest) { if ( digest instanceof Digest ) { return ((Digest) digest).getShortAlgorithm(); } return digest.asString().toString(); } private static final char[] HEX = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' }; private static ByteList toHEX(final byte[] data) { final ByteList out = new ByteList(data.length * 2); for ( int i = 0; i < data.length; i++ ) { final byte b = data[i]; out.append( HEX[ (b >> 4) & 0xF ] ); out.append( HEX[ b & 0xF ] ); } return out; } }// HMAC jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/NetscapeSPKI.java000066400000000000000000000243251313661621600263670ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.impl.Base64; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.util.ByteList; // org.bouncycastle.jce.netscape.NetscapeCertRequest emulator: import org.jruby.ext.openssl.impl.NetscapeCertRequest; import static org.jruby.ext.openssl.PKeyDSA._DSA; import static org.jruby.ext.openssl.PKeyRSA._RSA; import static org.jruby.ext.openssl.OpenSSL.*; /** * @author Ola Bini */ public class NetscapeSPKI extends RubyObject { private static final long serialVersionUID = 3211242351810109432L; private static ObjectAllocator NETSCAPESPKI_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new NetscapeSPKI(runtime, klass); } }; public static void createNetscapeSPKI(Ruby runtime, RubyModule ossl) { RubyModule mNetscape = ossl.defineModuleUnder("Netscape"); RubyClass cSPKI = mNetscape.defineClassUnder("SPKI",runtime.getObject(),NETSCAPESPKI_ALLOCATOR); RubyClass openSSLError = ossl.getClass("OpenSSLError"); mNetscape.defineClassUnder("SPKIError",openSSLError,openSSLError.getAllocator()); cSPKI.defineAnnotatedMethods(NetscapeSPKI.class); } private static RubyModule _Netscape(final Ruby runtime) { return (RubyModule) runtime.getModule("OpenSSL").getConstant("Netscape"); } public NetscapeSPKI(Ruby runtime, RubyClass type) { super(runtime,type); } private IRubyObject public_key; private IRubyObject challenge; private Object cert; @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; if ( args.length > 0 ) { byte[] request = args[0].convertToString().getBytes(); request = tryBase64Decode(request); final NetscapeCertRequest cert; try { this.cert = cert = new NetscapeCertRequest(request); challenge = runtime.newString( cert.getChallenge() ); } catch (GeneralSecurityException e) { throw newSPKIError(e); } catch (IllegalArgumentException e) { throw newSPKIError(e); } final PublicKey publicKey = cert.getPublicKey(); final String algorithm = publicKey.getAlgorithm(); final RubyString pub_key = RubyString.newString(runtime, publicKey.getEncoded()); if ( "RSA".equalsIgnoreCase(algorithm) ) { this.public_key = _RSA(runtime).callMethod(context, "new", pub_key); } else if ( "DSA".equalsIgnoreCase(algorithm) ) { this.public_key = _DSA(runtime).callMethod(context, "new", pub_key); } else { throw runtime.newLoadError("not implemented algo for public key: " + algorithm); } } return this; } // just try to decode for the time when the given bytes are base64 encoded. private static byte[] tryBase64Decode(byte[] b) { try { b = Base64.decode(b, 0, b.length, Base64.NO_OPTIONS); } catch (IOException ignored) { } catch (IllegalArgumentException ignored) { } return b; } @JRubyMethod public IRubyObject to_der() { try { final byte[] derBytes = toDER(); return getRuntime().newString(new ByteList(derBytes, false)); } catch (IOException ioe) { throw newSPKIError(ioe); } } @JRubyMethod(name = { "to_pem", "to_s" }) public IRubyObject to_pem() { try { byte[] source = toDER(); // no Base64.DO_BREAK_LINES option needed for NSPKI : source = Base64.encodeBytesToBytes(source, 0, source.length, Base64.NO_OPTIONS); return getRuntime().newString(new ByteList(source, false)); } catch (IOException ioe) { throw newSPKIError(ioe); } } private byte[] toDER() throws IOException { ASN1Sequence b = (ASN1Sequence) ((NetscapeCertRequest) cert).toASN1Primitive(); ASN1ObjectIdentifier encType = (ASN1ObjectIdentifier)((ASN1Sequence)((ASN1Sequence)((ASN1Sequence)b.getObjectAt(0)).getObjectAt(0)).getObjectAt(0)).getObjectAt(0); ASN1ObjectIdentifier sigAlg = ((AlgorithmIdentifier)b.getObjectAt(1)).getAlgorithm(); DERBitString sig = (DERBitString) b.getObjectAt(2); DERBitString publicKey = new DERBitString(((PKey) public_key).to_der().convertToString().getBytes()); DERIA5String encodedChallenge = new DERIA5String(this.challenge.toString()); ASN1EncodableVector v1 = new ASN1EncodableVector(); ASN1EncodableVector v1_2 = new ASN1EncodableVector(); ASN1EncodableVector v2 = new ASN1EncodableVector(); ASN1EncodableVector v3 = new ASN1EncodableVector(); ASN1EncodableVector v4 = new ASN1EncodableVector(); v4.add(encType); v4.add(DERNull.INSTANCE); v3.add(new DLSequence(v4)); v3.add(publicKey); v2.add(new DLSequence(v3)); v2.add(encodedChallenge); v1.add(new DLSequence(v2)); v1_2.add(sigAlg); v1_2.add(DERNull.INSTANCE); v1.add(new DLSequence(v1_2)); v1.add(sig); return new DLSequence(v1).getEncoded(); } @JRubyMethod public IRubyObject to_text() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: Netscape::SPKI#to_text"); return getRuntime().getNil(); } @JRubyMethod public IRubyObject public_key() { return this.public_key; } @JRubyMethod(name="public_key=") public IRubyObject set_public_key(final IRubyObject public_key) { return this.public_key = public_key; } @JRubyMethod public IRubyObject sign(final IRubyObject key, final IRubyObject digest) { final String keyAlg = ((PKey) key).getAlgorithm(); final String digAlg = ((Digest) digest).getShortAlgorithm(); final String symKey = keyAlg.toLowerCase() + '-' + digAlg.toLowerCase(); try { final ASN1ObjectIdentifier alg = ASN1.sym2Oid( getRuntime(), symKey ); final PublicKey publicKey = ( (PKey) this.public_key ).getPublicKey(); final String challengeStr = challenge.toString(); final NetscapeCertRequest cert; this.cert = cert = new NetscapeCertRequest(challengeStr, new AlgorithmIdentifier(alg), publicKey); cert.sign( ((PKey) key).getPrivateKey() ); } catch (NoSuchAlgorithmException e) { debugStackTrace(getRuntime(), e); throw newSPKIError(e); } catch (GeneralSecurityException e) { throw newSPKIError(e); } return this; } @JRubyMethod public IRubyObject verify(final IRubyObject pkey) { final NetscapeCertRequest cert = (NetscapeCertRequest) this.cert; cert.setPublicKey( ((PKey) pkey).getPublicKey() ); try { boolean result = cert.verify(challenge.toString()); return getRuntime().newBoolean(result); } catch (NoSuchAlgorithmException e) { debugStackTrace(getRuntime(), e); throw newSPKIError(e); } catch (GeneralSecurityException e) { throw newSPKIError(e); } } @JRubyMethod public IRubyObject challenge() { return this.challenge; } @JRubyMethod(name="challenge=") public IRubyObject set_challenge(final IRubyObject challenge) { return this.challenge = challenge; } private RaiseException newSPKIError(final Exception e) { return newSPKIError(getRuntime(), e.getMessage()); } private static RaiseException newSPKIError(Ruby runtime, String message) { return Utils.newError(runtime, _Netscape(runtime).getClass("SPKIError"), message); } }// NetscapeSPKI jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OCSP.java000066400000000000000000000261171313661621600247030ustar00rootroot00000000000000/* * The contents of this file are subject to the Common Public License Version 1.0 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright (C) 2017 Donovan Lampa * Copyright (C) 2009-2017 The JRuby Team * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. * * * JRuby-OpenSSL includes software by The Legion of the Bouncy Castle Inc. * Please, visit (http://bouncycastle.org/license.html) for licensing details. */ package org.jruby.ext.openssl; import java.security.Security; import java.util.HashMap; import java.util.Map; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.builtin.IRubyObject; /** * OCSP * * @author lampad */ public class OCSP { //Response has valid confirmations private static final String _RESPONSE_STATUS_SUCCESSFUL_STR = "RESPONSE_STATUS_SUCCESSFUL"; private static final int _RESPONSE_STATUS_SUCCESSFUL = 0; //Illegal confirmation request private static final String _RESPONSE_STATUS_MALFORMEDREQUEST_STR = "RESPONSE_STATUS_MALFORMEDREQUEST"; private static final int _RESPONSE_STATUS_MALFORMEDREQUEST = 1; //Internal error in issuer private static final String _RESPONSE_STATUS_INTERNALERROR_STR = "RESPONSE_STATUS_INTERNALERROR"; private static final int _RESPONSE_STATUS_INTERNALERROR = 2; //Try again later private static final String _RESPONSE_STATUS_TRYLATER_STR = "RESPONSE_STATUS_TRYLATER"; private static final int _RESPONSE_STATUS_TRYLATER = 3; //You must sign the request and resubmit private static final String _RESPONSE_STATUS_SIGREQUIRED_STR = "RESPONSE_STATUS_SIGREQUIRED"; private static final int _RESPONSE_STATUS_SIGREQUIRED = 5; //Your request is unauthorized. private static final String _RESPONSE_STATUS_UNAUTHORIZED_STR = "RESPONSE_STATUS_UNAUTHORIZED"; private static final int _RESPONSE_STATUS_UNAUTHORIZED = 6; private static final Map responseMap; //The certificate was revoked for an unknown reason private static final int _REVOKED_STATUS_NOSTATUS = -1; //The certificate was revoked for an unspecified reason private static final int _REVOKED_STATUS_UNSPECIFIED = 0; //The certificate was revoked due to a key compromise private static final int _REVOKED_STATUS_KEYCOMPROMISE = 1; //This CA certificate was revoked due to a key compromise private static final int _REVOKED_STATUS_CACOMPROMISE = 2; //The certificate subject's name or other information changed private static final int _REVOKED_STATUS_AFFILIATIONCHANGED = 3; //The certificate was superseded by a new certificate private static final int _REVOKED_STATUS_SUPERSEDED = 4; //The certificate is no longer needed private static final int _REVOKED_STATUS_CESSATIONOFOPERATION = 5; //The certificate is on hold private static final int _REVOKED_STATUS_CERTIFICATEHOLD = 6; //The certificate was previously on hold and should now be removed from the CRL private static final int _REVOKED_STATUS_REMOVEFROMCRL = 8; //Do not include certificates in the response private static final int _NOCERTS = 0x1; //Do not search certificates contained in the response for a signer private static final int _NOINTERN = 0x2; //Do not check the signature on the response private static final int _NOSIGS = 0x4; //Do not verify the certificate chain on the response private static final int _NOCHAIN = 0x8; //Do not verify the response at all private static final int _NOVERIFY = 0x10; //Do not check trust private static final int _NOEXPLICIT = 0x20; //(This flag is not used by OpenSSL 1.0.1g) private static final int _NOCASIGN = 0x40; //(This flag is not used by OpenSSL 1.0.1g) private static final int _NODELEGATED = 0x80; //Do not make additional signing certificate checks private static final int _NOCHECKS = 0x100; //Do not verify additional certificates private static final int _TRUSTOTHER = 0x200; //Identify the response by signing the certificate key ID private static final int _RESPID_KEY = 0x400; //Do not include producedAt time in response private static final int _NOTIME = 0x800; /* * Indicates the certificate is not revoked but does not necessarily mean * the certificate was issued or that this response is within the * certificate's validity interval */ private static final int _V_CERTSTATUS_GOOD = 0; /* Indicates the certificate has been revoked either permanently or * temporarily (on hold). */ private static final int _V_CERTSTATUS_REVOKED = 1; /* Indicates the responder does not know about the certificate being * requested. */ private static final int _V_CERTSTATUS_UNKNOWN = 2; //The responder ID is based on the key name. private static final int _V_RESPID_NAME = 0; //The responder ID is based on the public key. private static final int _V_RESPID_KEY =1; static { Map resMap = new HashMap(); resMap.put(_RESPONSE_STATUS_SUCCESSFUL, _RESPONSE_STATUS_SUCCESSFUL_STR); resMap.put(_RESPONSE_STATUS_MALFORMEDREQUEST, _RESPONSE_STATUS_MALFORMEDREQUEST_STR); resMap.put(_RESPONSE_STATUS_INTERNALERROR, _RESPONSE_STATUS_INTERNALERROR_STR); resMap.put(_RESPONSE_STATUS_TRYLATER, _RESPONSE_STATUS_TRYLATER_STR); resMap.put(_RESPONSE_STATUS_SIGREQUIRED, _RESPONSE_STATUS_SIGREQUIRED_STR); resMap.put(_RESPONSE_STATUS_UNAUTHORIZED, _RESPONSE_STATUS_UNAUTHORIZED_STR); responseMap = resMap; } public static void createOCSP(final Ruby runtime, final RubyModule OpenSSL) { final RubyModule OCSP = OpenSSL.defineModuleUnder("OCSP"); final RubyClass OpenSSLError = OpenSSL.getClass("OpenSSLError"); Security.addProvider(new BouncyCastleProvider()); OCSP.defineClassUnder("OCSPError", OpenSSLError, OpenSSLError.getAllocator()); OCSPBasicResponse.createBasicResponse(runtime, OCSP); OCSPCertificateId.createCertificateId(runtime, OCSP); OCSPRequest.createRequest(runtime, OCSP); OCSPResponse.createResponse(runtime, OCSP); OCSPSingleResponse.createSingleResponse(runtime, OCSP); //ResponseStatuses OCSP.setConstant(_RESPONSE_STATUS_SUCCESSFUL_STR, runtime.newFixnum(_RESPONSE_STATUS_SUCCESSFUL)); OCSP.setConstant(_RESPONSE_STATUS_MALFORMEDREQUEST_STR, runtime.newFixnum(_RESPONSE_STATUS_MALFORMEDREQUEST)); OCSP.setConstant(_RESPONSE_STATUS_INTERNALERROR_STR, runtime.newFixnum(_RESPONSE_STATUS_INTERNALERROR)); OCSP.setConstant(_RESPONSE_STATUS_TRYLATER_STR, runtime.newFixnum(_RESPONSE_STATUS_TRYLATER)); OCSP.setConstant(_RESPONSE_STATUS_SIGREQUIRED_STR, runtime.newFixnum(_RESPONSE_STATUS_SIGREQUIRED)); OCSP.setConstant(_RESPONSE_STATUS_UNAUTHORIZED_STR, runtime.newFixnum(_RESPONSE_STATUS_UNAUTHORIZED)); //RevocationReasons OCSP.setConstant("REVOKED_STATUS_NOSTATUS", runtime.newFixnum(_REVOKED_STATUS_NOSTATUS)); OCSP.setConstant("REVOKED_STATUS_UNSPECIFIED", runtime.newFixnum(_REVOKED_STATUS_UNSPECIFIED)); OCSP.setConstant("REVOKED_STATUS_KEYCOMPROMISE", runtime.newFixnum(_REVOKED_STATUS_KEYCOMPROMISE)); OCSP.setConstant("REVOKED_STATUS_CACOMPROMISE", runtime.newFixnum(_REVOKED_STATUS_CACOMPROMISE)); OCSP.setConstant("REVOKED_STATUS_AFFILIATIONCHANGED", runtime.newFixnum(_REVOKED_STATUS_AFFILIATIONCHANGED)); OCSP.setConstant("REVOKED_STATUS_SUPERSEDED", runtime.newFixnum(_REVOKED_STATUS_SUPERSEDED)); OCSP.setConstant("REVOKED_STATUS_CESSATIONOFOPERATION", runtime.newFixnum(_REVOKED_STATUS_CESSATIONOFOPERATION)); OCSP.setConstant("REVOKED_STATUS_CERTIFICATEHOLD", runtime.newFixnum(_REVOKED_STATUS_CERTIFICATEHOLD)); OCSP.setConstant("REVOKED_STATUS_REMOVEFROMCRL", runtime.newFixnum(_REVOKED_STATUS_REMOVEFROMCRL)); OCSP.setConstant("NOCERTS", runtime.newFixnum(_NOCERTS)); OCSP.setConstant("NOINTERN", runtime.newFixnum(_NOINTERN)); OCSP.setConstant("NOSIGS", runtime.newFixnum(_NOSIGS)); OCSP.setConstant("NOCHAIN", runtime.newFixnum(_NOCHAIN)); OCSP.setConstant("NOVERIFY", runtime.newFixnum(_NOVERIFY)); OCSP.setConstant("NOEXPLICIT", runtime.newFixnum(_NOEXPLICIT)); OCSP.setConstant("NOCASIGN", runtime.newFixnum(_NOCASIGN)); OCSP.setConstant("NODELEGATED", runtime.newFixnum(_NODELEGATED)); OCSP.setConstant("NOCHECKS", runtime.newFixnum(_NOCHECKS)); OCSP.setConstant("TRUSTOTHER", runtime.newFixnum(_TRUSTOTHER)); OCSP.setConstant("RESPID_KEY", runtime.newFixnum(_RESPID_KEY)); OCSP.setConstant("NOTIME", runtime.newFixnum(_NOTIME)); OCSP.setConstant("V_CERTSTATUS_GOOD", runtime.newFixnum(_V_CERTSTATUS_GOOD)); OCSP.setConstant("V_CERTSTATUS_REVOKED", runtime.newFixnum(_V_CERTSTATUS_REVOKED)); OCSP.setConstant("V_CERTSTATUS_UNKNOWN", runtime.newFixnum(_V_CERTSTATUS_UNKNOWN)); OCSP.setConstant("V_RESPID_NAME", runtime.newFixnum(_V_RESPID_NAME)); OCSP.setConstant("V_RESPID_KEY", runtime.newFixnum(_V_RESPID_KEY)); } public static String getResponseStringForValue(IRubyObject fixnum) { RubyFixnum rubyFixnum = (RubyFixnum) fixnum; return responseMap.get((int)rubyFixnum.getLongValue()); } static RaiseException newOCSPError(Ruby runtime, Exception ex) { return Utils.newError(runtime, _OCSP(runtime).getClass("OCSPError"), ex); } static RubyModule _OCSP(final Ruby runtime) { return (RubyModule) runtime.getModule("OpenSSL").getConstant("OCSP"); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OCSPBasicResponse.java000066400000000000000000000723401313661621600273630ustar00rootroot00000000000000/* * The contents of this file are subject to the Common Public License Version 1.0 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright (C) 2017 Donovan Lampa * Copyright (C) 2009-2017 The JRuby Team * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. * * * JRuby-OpenSSL includes software by The Legion of the Bouncy Castle Inc. * Please, visit (http://bouncycastle.org/license.html) for licensing details. */ package org.jruby.ext.openssl; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.CertID; import org.bouncycastle.asn1.ocsp.CertStatus; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.ocsp.ResponderID; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.CRLReason; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.ocsp.BasicOCSPResp; import org.bouncycastle.cert.ocsp.BasicOCSPRespBuilder; import org.bouncycastle.cert.ocsp.CertificateID; import org.bouncycastle.cert.ocsp.RespID; import org.bouncycastle.cert.ocsp.SingleResp; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.DigestCalculatorProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.impl.ASN1Registry; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import org.jruby.ext.openssl.x509store.X509Utils; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import static org.jruby.ext.openssl.Digest._Digest; import static org.jruby.ext.openssl.OCSP._OCSP; import static org.jruby.ext.openssl.OCSP.newOCSPError; import static org.jruby.ext.openssl.X509._X509; import java.io.IOException; import java.security.MessageDigest; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Iterator; import java.util.List; /* * An OpenSSL::OCSP::BasicResponse contains the status of a certificate * check which is created from an OpenSSL::OCSP::Request. * A BasicResponse is more detailed than a Response. * * @author lampad */ public class OCSPBasicResponse extends RubyObject { private static final long serialVersionUID = 8755480816625884227L; private static final String OCSP_NOCERTS = "NOCERTS"; private static final String OCSP_NOCHAIN = "NOCHAIN"; private static final String OCSP_NOCHECKS = "NOCHECKS"; private static final String OCSP_NOTIME = "NOTIME"; private static final String OCSP_NOSIGS = "NOSIGS"; private static final String OCSP_NOVERIFY = "NOVERIFY"; private static final String OCSP_NOINTERN = "NOINTERN"; private static final String OCSP_RESPID_KEY = "RESPID_KEY"; private static final String OCSP_TRUSTOTHER = "TRUSTOTHER"; private static ObjectAllocator BASICRESPONSE_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new OCSPBasicResponse(runtime, klass); } }; public static void createBasicResponse(final Ruby runtime, final RubyModule OCSP) { RubyClass BasicResponse = OCSP.defineClassUnder("BasicResponse", runtime.getObject(), BASICRESPONSE_ALLOCATOR); BasicResponse.defineAnnotatedMethods(OCSPBasicResponse.class); } private byte[] nonce; private List singleResponses = new ArrayList(); private BasicOCSPResponse asn1BCBasicOCSPResp; private List extensions = new ArrayList(); public OCSPBasicResponse(Ruby runtime, RubyClass metaClass) { super(runtime, metaClass); } public OCSPBasicResponse(Ruby runtime) { this(runtime, (RubyClass) _OCSP(runtime).getConstantAt("BasicResponse")); } @JRubyMethod(name = "initialize", visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject der) { if (der == null || der.isNil()) return this; asn1BCBasicOCSPResp = BasicOCSPResponse.getInstance(StringHelper.readPossibleDERInput(context, der).getBytes()); return this; } @JRubyMethod(name = "initialize", visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context) { return this; } @Override @JRubyMethod(name = "initialize_copy", visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(IRubyObject obj) { if ( this == obj ) return this; checkFrozen(); this.asn1BCBasicOCSPResp = ((OCSPBasicResponse)obj).getASN1BCOCSPResp(); return this; } @JRubyMethod(name = "add_nonce", rest = true) public OCSPBasicResponse add_nonce(IRubyObject[] args) { Ruby runtime = getRuntime(); byte[] tmpNonce; if ( Arity.checkArgumentCount(runtime, args, 0, 1) == 0 ) { tmpNonce = generateNonce(); } else { RubyString input = (RubyString)args[0]; tmpNonce = input.getBytes(); } extensions.add(new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, tmpNonce)); nonce = tmpNonce; return this; } @JRubyMethod(name = "add_status", rest = true) public OCSPBasicResponse add_status(final ThreadContext context, IRubyObject[] args) { Ruby runtime = context.getRuntime(); Arity.checkArgumentCount(runtime, args, 7, 7); IRubyObject certificateId = args[0]; IRubyObject status = args[1]; IRubyObject reason = args[2]; IRubyObject revocation_time = args[3]; IRubyObject this_update = args[4]; IRubyObject next_update = args[5]; IRubyObject extensions = args[6]; CertStatus certStatus = null; switch (RubyFixnum.fix2int((RubyFixnum)status)) { case 0 : certStatus = new CertStatus(); break; case 1 : ASN1GeneralizedTime revTime = rubyIntOrTimeToGenTime(revocation_time); RevokedInfo revokedInfo = new RevokedInfo(revTime, CRLReason.lookup(RubyFixnum.fix2int((RubyFixnum)reason))); certStatus = new CertStatus(revokedInfo); break; case 2 : certStatus = new CertStatus(2, DERNull.INSTANCE); break; default : break; } ASN1GeneralizedTime thisUpdate = rubyIntOrTimeToGenTime(this_update); ASN1GeneralizedTime nextUpdate = rubyIntOrTimeToGenTime(next_update); Extensions singleExtensions = convertRubyExtensions(extensions); CertID certID = ((OCSPCertificateId)certificateId).getCertID(); SingleResponse ocspSingleResp = new SingleResponse(certID, certStatus, thisUpdate, nextUpdate, singleExtensions); OCSPSingleResponse rubySingleResp = new OCSPSingleResponse(runtime); try { rubySingleResp.initialize(context, RubyString.newString(runtime, ocspSingleResp.getEncoded())); singleResponses.add(rubySingleResp); } catch (IOException e) { throw newOCSPError(runtime, e); } return this; } @JRubyMethod(name = "copy_nonce") public IRubyObject copy_nonce(final ThreadContext context, IRubyObject request) { add_nonce(new IRubyObject[] {RubyString.newString(getRuntime(), ((OCSPRequest)request).getNonce())}); return RubyFixnum.one(context.getRuntime()); } @JRubyMethod(name = "find_response") public IRubyObject find_response(final ThreadContext context, IRubyObject certId) { if (certId.isNil()) return context.nil; OCSPCertificateId rubyCertId = (OCSPCertificateId)certId; IRubyObject retResp = context.nil; for (OCSPSingleResponse singleResp : singleResponses) { CertID thisId = rubyCertId.getCertID(); CertID thatId = singleResp.getBCSingleResp().getCertID(); if (thisId.equals(thatId)) { retResp = singleResp; break; } } return retResp; } @JRubyMethod(name = "responses") public IRubyObject responses() { return RubyArray.newArray(getRuntime(), singleResponses); } @JRubyMethod(name = "sign", rest = true) public IRubyObject sign(final ThreadContext context, IRubyObject[] args) { Ruby runtime = context.getRuntime(); int flag = 0; IRubyObject additionalCerts = context.nil; IRubyObject flags = context.nil; IRubyObject digest = context.nil; Digest digestInstance = new Digest(runtime, _Digest(runtime)); List addlCerts = new ArrayList(); switch (Arity.checkArgumentCount(runtime, args, 2, 5)) { case 3 : additionalCerts = args[2]; break; case 4 : additionalCerts = args[2]; flags = args[3]; break; case 5 : additionalCerts = args[2]; flags = args[3]; digest = args[4]; break; default : break; } if (digest.isNil()) digest = digestInstance.initialize(context, new IRubyObject[] { RubyString.newString(runtime, "SHA1") }); if (!flags.isNil()) flag = RubyFixnum.fix2int(flags); if (additionalCerts.isNil()) flag |= RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCERTS)); X509Cert signer = (X509Cert) args[0]; PKey signerKey = (PKey) args[1]; String keyAlg = signerKey.getAlgorithm(); String digAlg = ((Digest) digest).getShortAlgorithm(); JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(digAlg + "with" + keyAlg); signerBuilder.setProvider("BC"); ContentSigner contentSigner = null; try { contentSigner = signerBuilder.build(signerKey.getPrivateKey()); } catch (OperatorCreationException e) { throw newOCSPError(runtime, e); } BasicOCSPRespBuilder respBuilder = null; try { if ((flag & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_RESPID_KEY))) != 0) { JcaDigestCalculatorProviderBuilder dcpb = new JcaDigestCalculatorProviderBuilder(); dcpb.setProvider("BC"); DigestCalculatorProvider dcp = dcpb.build(); DigestCalculator calculator = dcp.get(contentSigner.getAlgorithmIdentifier()); respBuilder = new BasicOCSPRespBuilder(SubjectPublicKeyInfo.getInstance(signerKey.getPublicKey().getEncoded()), calculator); } else { respBuilder = new BasicOCSPRespBuilder(new RespID(signer.getSubject().getX500Name())); } } catch (Exception e) { throw newOCSPError(runtime, e); } X509CertificateHolder[] chain = null; try { if ((flag & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCERTS))) == 0) { addlCerts.add(new X509CertificateHolder(signer.getAuxCert().getEncoded())); if (!additionalCerts.isNil()) { Iterator rubyAddlCerts = ((RubyArray)additionalCerts).iterator(); while (rubyAddlCerts.hasNext()) { java.security.cert.Certificate cert = rubyAddlCerts.next(); addlCerts.add(new X509CertificateHolder(cert.getEncoded())); } } chain = addlCerts.toArray(new X509CertificateHolder[addlCerts.size()]); } } catch (Exception e) { throw newOCSPError(runtime, e); } Date producedAt = null; if ((flag & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOTIME))) == 0) { producedAt = new Date(); } for (OCSPSingleResponse resp : singleResponses) { SingleResp singleResp = new SingleResp(resp.getBCSingleResp()); respBuilder.addResponse(singleResp.getCertID(), singleResp.getCertStatus(), singleResp.getThisUpdate(), singleResp.getNextUpdate(), resp.getBCSingleResp().getSingleExtensions()); } try { Extension[] respExtAry = new Extension[extensions.size()]; Extensions respExtensions = new Extensions(extensions.toArray(respExtAry)); BasicOCSPResp bcBasicOCSPResp = respBuilder.setResponseExtensions(respExtensions).build(contentSigner, chain, producedAt); asn1BCBasicOCSPResp = BasicOCSPResponse.getInstance(bcBasicOCSPResp.getEncoded()); } catch (Exception e) { throw newOCSPError(runtime, e); } return this; } @JRubyMethod(name = "verify", rest = true) public IRubyObject verify(final ThreadContext context, IRubyObject[] args) { Ruby runtime = context.runtime; int flags = 0; IRubyObject certificates = args[0]; IRubyObject store = args[1]; boolean ret = false; if (Arity.checkArgumentCount(runtime, args, 2, 3) == 3) { flags = RubyFixnum.fix2int(args[2]); } JcaContentVerifierProviderBuilder jcacvpb = new JcaContentVerifierProviderBuilder(); jcacvpb.setProvider("BC"); BasicOCSPResp basicOCSPResp = getBasicOCSPResp(); java.security.cert.Certificate signer = findSignerCert(context, asn1BCBasicOCSPResp, convertRubyCerts(certificates), flags); if ( signer == null ) return RubyBoolean.newBoolean(runtime, false); if ( (flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOINTERN))) == 0 && (flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_TRUSTOTHER))) != 0 ) { flags |= RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOVERIFY)); } if ( (flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOSIGS))) == 0 ) { PublicKey sPKey = signer.getPublicKey(); if ( sPKey == null ) return RubyBoolean.newBoolean(runtime, false); try { ContentVerifierProvider cvp = jcacvpb.build(sPKey); ret = basicOCSPResp.isSignatureValid(cvp); } catch (Exception e) { throw newOCSPError(runtime, e); } } if ((flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOVERIFY))) == 0) { List untrustedCerts = null; if ((flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCHAIN))) != 0) { } else if (basicOCSPResp.getCerts() != null && (certificates != null && !((RubyArray)certificates).isEmpty())) { untrustedCerts = getCertsFromResp(); Iterator certIt = ((RubyArray)certificates).iterator(); while (certIt.hasNext()) { try { untrustedCerts.add(X509Cert.wrap(context, certIt.next().getEncoded())); } catch (CertificateEncodingException e) { throw newOCSPError(runtime, e); } } } else { untrustedCerts = getCertsFromResp(); } RubyArray rUntrustedCerts = RubyArray.newEmptyArray(runtime); if (untrustedCerts != null) { X509Cert[] rubyCerts = new X509Cert[untrustedCerts.size()]; rUntrustedCerts = RubyArray.newArray(runtime, untrustedCerts.toArray(rubyCerts)); } X509StoreContext ctx; try { ctx = X509StoreContext.newStoreContext(context, (X509Store)store, X509Cert.wrap(runtime, signer), rUntrustedCerts); } catch (CertificateEncodingException e) { throw newOCSPError(runtime, e); } ctx.set_purpose(context, _X509(runtime).getConstant("PURPOSE_OCSP_HELPER")); ret = ctx.verify(context).isTrue(); IRubyObject chain = ctx.chain(context); if ((flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCHECKS))) > 0) { ret = true; } try { if (checkIssuer(getBasicOCSPResp(), chain)) return RubyBoolean.newBoolean(runtime, true); } catch (IOException e) { throw newOCSPError(runtime, e); } if ((flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCHAIN))) != 0) { return RubyBoolean.newBoolean(runtime, ret); } else { X509Cert rootCA = (X509Cert)((RubyArray)chain).last(); PublicKey rootKey = rootCA.getAuxCert().getPublicKey(); try { // check if self-signed and valid (trusts itself) rootCA.getAuxCert().verify(rootKey); ret = true; } catch (Exception e) { ret = false; } } } return RubyBoolean.newBoolean(runtime, ret); } @JRubyMethod(name = "status") public IRubyObject status(ThreadContext context) { final Ruby runtime = context.runtime; RubyArray ret = RubyArray.newArray(runtime, singleResponses.size()); for (OCSPSingleResponse resp : singleResponses) { RubyArray respAry = RubyArray.newArray(runtime, 7); respAry.append(resp.certid(context)); respAry.append(resp.cert_status()); respAry.append(resp.revocation_reason()); respAry.append(resp.revocation_time()); respAry.append(resp.this_update()); respAry.append(resp.next_update()); respAry.append(resp.extensions()); ret.add(respAry); } return ret; } @JRubyMethod(name = "to_der") public IRubyObject to_der() { Ruby runtime = getRuntime(); IRubyObject ret; try { ret = RubyString.newString(runtime, asn1BCBasicOCSPResp.getEncoded()); } catch (IOException e) { throw newOCSPError(runtime, e); } return ret; } private boolean checkIssuer(BasicOCSPResp basicOCSPResp, IRubyObject chain) throws IOException { boolean ret = false; if ( ((RubyArray)chain).size() <= 0 ) return false; List singleResponses = Arrays.asList(basicOCSPResp.getResponses()); CertificateID certId = checkCertIds(singleResponses); X509Cert signer = (X509Cert)((RubyArray)chain).first(); if (((RubyArray)chain).size() > 1) { X509Cert signerCA = (X509Cert)((RubyArray)chain).entry(1); if(matchIssuerId(signerCA, certId, singleResponses)) { return checkDelegated(signerCA); } } else { ret = matchIssuerId(signer, certId, singleResponses); } return ret; } private boolean checkDelegated(X509Cert signerCA) { try { return (signerCA.getAuxCert().getExFlags() & X509Utils.EXFLAG_XKUSAGE) != 0 && (signerCA.getAuxCert().getExtendedKeyUsage().contains(ASN1Registry.OBJ_OCSP_sign)); } catch (CertificateParsingException e) { throw newOCSPError(getRuntime(), e); } } private boolean matchIssuerId(X509Cert signerCA, CertificateID certId, List singleResponses) throws IOException { Ruby runtime = getRuntime(); if (certId == null) { //gotta check em all for(SingleResp resp : singleResponses) { CertificateID tempId = resp.getCertID(); if(!matchIssuerId(signerCA, tempId, null)) return false; } return true; } else { // we have a matching cid ASN1ObjectIdentifier alg = certId.getHashAlgOID(); String sym = ASN1.oid2Sym(runtime, alg); MessageDigest md = Digest.getDigest(runtime, sym); byte[] issuerNameDigest = md.digest(signerCA.getIssuer().getX500Name().getEncoded()); byte[] issuerKeyDigest = md.digest(signerCA.getAuxCert().getPublicKey().getEncoded()); if(!issuerNameDigest.equals(certId.getIssuerNameHash())) return false; if(!issuerKeyDigest.equals(certId.getIssuerKeyHash())) return false; return true; } } private CertificateID checkCertIds(List singleResponses) { ArrayList ary = new ArrayList(singleResponses); CertificateID cid = ary.remove(0).getCertID(); for (SingleResp singleResp : ary) { if (!cid.equals(singleResp.getCertID())) return null; } return cid; } public BasicOCSPResponse getASN1BCOCSPResp() { return this.asn1BCBasicOCSPResp; } public byte[] getNonce() { return this.nonce; } private byte[] generateNonce() { // OSSL currently generates 16 byte nonce by default return generateNonce(new byte[16]); } private byte[] generateNonce(byte[] bytes) { OpenSSL.getSecureRandom(getRuntime()).nextBytes(bytes); return bytes; } private ASN1GeneralizedTime rubyIntOrTimeToGenTime(IRubyObject intOrTime) { if (intOrTime.isNil()) return null; Date retTime = new Date(); if (intOrTime instanceof RubyInteger) { retTime.setTime(retTime.getTime() + RubyFixnum.fix2int((RubyFixnum)intOrTime)*1000); } else if (intOrTime instanceof RubyTime) { retTime = ((RubyTime)intOrTime).getJavaDate(); } else { throw Utils.newArgumentError( getRuntime(), new IllegalArgumentException("Unknown Revocation Time class: " + intOrTime.getClass().getName()) ); } return new ASN1GeneralizedTime(retTime); } private Extensions convertRubyExtensions(IRubyObject extensions) { if (extensions.isNil()) return null; List retExtensions = new ArrayList(); Iterator rubyExtensions = ((RubyArray)extensions).iterator(); while (rubyExtensions.hasNext()) { X509Extension rubyExt = (X509Extension)rubyExtensions.next(); Extension ext = Extension.getInstance(((RubyString)rubyExt.to_der()).getBytes()); retExtensions.add(ext); } Extension[] exts = new Extension[retExtensions.size()]; retExtensions.toArray(exts); return new Extensions(exts); } private List convertRubyCerts(IRubyObject certificates) { Iterator it = ((RubyArray)certificates).iterator(); List ret = new ArrayList(); while (it.hasNext()) { ret.add(it.next()); } return ret; } private java.security.cert.Certificate findSignerCert(final ThreadContext context, BasicOCSPResponse basicResp, List certificates, int flags) { final Ruby runtime = context.runtime; ResponderID respID = basicResp.getTbsResponseData().getResponderID(); java.security.cert.Certificate ret; ret = findSignerByRespId(context, certificates, respID); if (ret == null && (flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOINTERN))) == 0) { List javaCerts = new ArrayList(); for (X509CertificateHolder cert : getBasicOCSPResp().getCerts()) { try { javaCerts.add(X509Cert.wrap(context, cert.getEncoded()).getAuxCert()); } catch (IOException e) { throw newOCSPError(runtime, e); } } ret = findSignerByRespId(context, javaCerts, respID); } return ret; } private java.security.cert.Certificate findSignerByRespId(final ThreadContext context, List certificates, ResponderID respID) { if (respID.getName() != null) { for (java.security.cert.Certificate cert : certificates) { try { X509Cert rubyCert = X509Cert.wrap(context, cert); if (rubyCert.getSubject().getX500Name().equals(respID.getName())) return cert; } catch (CertificateEncodingException e) { throw newOCSPError(context.runtime, e); } } } else { // Ignore anything that's not SHA1 (weirdly) SHA_DIGEST_LENGTH == 20 if (respID.getKeyHash().length != 20) return null; for (java.security.cert.Certificate cert : certificates) { byte[] pubKeyDigest = Digest.digest( context, this, RubyString.newString(context.runtime, "SHA1"), RubyString.newString(context.runtime, cert.getPublicKey().getEncoded()) ).getBytes(); if (respID.getKeyHash().equals(pubKeyDigest)) return cert; } } return null; } private List getCertsFromResp() { Ruby runtime = getRuntime(); ThreadContext context = runtime.getCurrentContext(); List retCerts = new ArrayList(); List respCerts = Arrays.asList(getBasicOCSPResp().getCerts()); for (X509CertificateHolder cert : respCerts) { try { retCerts.add(X509Cert.wrap(context, cert.getEncoded())); } catch (IOException e) { throw newOCSPError(runtime, e); } } return retCerts; } private BasicOCSPResp getBasicOCSPResp() { return new BasicOCSPResp(asn1BCBasicOCSPResp); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OCSPCertificateId.java000066400000000000000000000315421313661621600273210ustar00rootroot00000000000000/* * The contents of this file are subject to the Common Public License Version 1.0 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright (C) 2017 Donovan Lampa * Copyright (C) 2009-2017 The JRuby Team * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. * * * JRuby-OpenSSL includes software by The Legion of the Bouncy Castle Inc. * Please, visit (http://bouncycastle.org/license.html) for licensing details. */ package org.jruby.ext.openssl; import java.io.IOException; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ocsp.CertID; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.ocsp.CertificateID; import org.bouncycastle.operator.DigestCalculator; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; import org.jruby.Ruby; import org.jruby.RubyBignum; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import static org.jruby.ext.openssl.OCSP._OCSP; import static org.jruby.ext.openssl.Digest._Digest; import static org.jruby.ext.openssl.OCSP.newOCSPError; /** * An OpenSSL::OCSP::CertificateId identifies a certificate to the * CA so that a status check can be performed. * * @author lampad */ public class OCSPCertificateId extends RubyObject { private static final long serialVersionUID = 6324454052172773918L; private static ObjectAllocator CERTIFICATEID_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new OCSPCertificateId(runtime, klass); } }; public static void createCertificateId(final Ruby runtime, final RubyModule _OCSP) { RubyClass _certificateId = _OCSP.defineClassUnder("CertificateId", runtime.getObject(), CERTIFICATEID_ALLOCATOR); _certificateId.defineAnnotatedMethods(OCSPCertificateId.class); } private CertID bcCertId; private X509Cert originalIssuer; public OCSPCertificateId(Ruby runtime, RubyClass metaClass) { super(runtime, metaClass); } public OCSPCertificateId(Ruby runtime) { this(runtime, (RubyClass) _OCSP(runtime).getConstantAt("CertificateId")); } @JRubyMethod(name = "initialize", visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject subject, IRubyObject issuer, IRubyObject digest) { if (digest == null || digest.isNil()) { return initialize(context, subject, issuer); } X509Cert subjectCert = (X509Cert) subject; originalIssuer = (X509Cert) issuer; BigInteger serial = subjectCert.getSerial(); return initializeImpl(context, serial, originalIssuer, digest); } @JRubyMethod(name = "initialize", visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject subject, IRubyObject issuer) { Ruby runtime = context.getRuntime(); X509Cert subjectCert = (X509Cert) subject; originalIssuer = (X509Cert) issuer; BigInteger serial = subjectCert.getSerial(); Digest digestInstance = new Digest(runtime, _Digest(runtime)); IRubyObject digest = digestInstance.initialize(context, new IRubyObject[] { RubyString.newString(runtime, "SHA1") }); return initializeImpl(context, serial, originalIssuer, digest); } @JRubyMethod(name = "initialize", visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject der) { Ruby runtime = context.getRuntime(); RubyString derStr = StringHelper.readPossibleDERInput(context, der); try { return initializeImpl(derStr.getBytes()); } catch (IOException e) { throw newOCSPError(runtime, e); } } private IRubyObject initializeImpl(final ThreadContext context, BigInteger serial, IRubyObject issuerCert, IRubyObject digest) { Ruby runtime = context.getRuntime(); Digest rubyDigest = (Digest) digest; ASN1ObjectIdentifier oid = ASN1.sym2Oid(runtime, rubyDigest.getName().toLowerCase()); AlgorithmIdentifier bcAlgId = new AlgorithmIdentifier(oid); BcDigestCalculatorProvider calculatorProvider = new BcDigestCalculatorProvider(); DigestCalculator calc; try { calc = calculatorProvider.get(bcAlgId); } catch (OperatorCreationException e) { throw newOCSPError(runtime, e); } X509Cert rubyCert = (X509Cert) issuerCert; try { this.bcCertId = new CertificateID(calc, new X509CertificateHolder(rubyCert.getAuxCert().getEncoded()), serial).toASN1Primitive(); } catch (Exception e) { throw newOCSPError(runtime, e); } return this; } private IRubyObject initializeImpl(byte[] derByteStream) throws IOException { this.bcCertId = CertID.getInstance(derByteStream); return this; } @JRubyMethod(name = "serial") public IRubyObject serial() { return RubyBignum.newBignum(getRuntime(), bcCertId.getSerialNumber().getValue()); } @JRubyMethod(name = "issuer_name_hash") public IRubyObject issuer_name_hash() { Ruby runtime = getRuntime(); String oidSym = ASN1.oid2Sym(runtime, getBCCertificateID().getHashAlgOID()); RubyString digestName = RubyString.newString(runtime, oidSym); // For whatever reason, the MRI Ruby tests appear to suggest that they compute the hexdigest hash // of the issuer name over the original name instead of the hash computed in the created CertID. // I'm not sure how it's supposed to work with a passed in DER string since presumably the hash // is already computed and can't be reversed to get to the original name and thus we just compute // a hash of a hash if we don't have the original issuer around. if (originalIssuer == null) { try { return Digest.hexdigest(runtime.getCurrentContext(), this, digestName, RubyString.newString(runtime, bcCertId.getIssuerNameHash().getEncoded("DER"))); } catch (IOException e) { throw newOCSPError(runtime, e); } } else { return Digest.hexdigest(runtime.getCurrentContext(), this, digestName, originalIssuer.getSubject().to_der(runtime.getCurrentContext())); } } // For whatever reason, the MRI Ruby tests appear to suggest that they compute the hexdigest hash // of the issuer key over the original key instead of the hash computed in the created CertID. // I'm not sure how it's supposed to work with a passed in DER string since presumably the hash // is already computed and can't be reversed to get to the original key, so we just compute // a hash of a hash if we don't have the original issuer around. @JRubyMethod(name = "issuer_key_hash") public IRubyObject issuer_key_hash() { Ruby runtime = getRuntime(); String oidSym = ASN1.oid2Sym(runtime, getBCCertificateID().getHashAlgOID()); RubyString digestName = RubyString.newString(runtime, oidSym); if (originalIssuer == null) { try { return Digest.hexdigest(runtime.getCurrentContext(), this, RubyString.newString(runtime, oidSym), RubyString.newString(runtime, bcCertId.getIssuerKeyHash().getEncoded("DER"))); } catch (IOException e) { throw newOCSPError(runtime, e); } } else { PKey key = (PKey)originalIssuer.public_key(runtime.getCurrentContext()); return Digest.hexdigest(runtime.getCurrentContext(), this, digestName, key.to_der()); } } @JRubyMethod(name = "hash_algorithm") public IRubyObject hash_algorithm() { Ruby runtime = getRuntime(); ASN1ObjectIdentifier oid = bcCertId.getHashAlgorithm().getAlgorithm(); Integer nid = ASN1.oid2nid(runtime, oid); String ln = ASN1.nid2ln(runtime, nid); return RubyString.newString(runtime, ln); } @JRubyMethod(name = "cmp") public IRubyObject cmp(IRubyObject other) { Ruby runtime = getRuntime(); RubyFixnum ret = (RubyFixnum) this.cmp_issuer(other); if (!ret.eql(RubyFixnum.zero(runtime))) return ret; OCSPCertificateId that = (OCSPCertificateId) other; return RubyFixnum.newFixnum( runtime, this.getCertID().getSerialNumber().getValue().compareTo( that.getCertID().getSerialNumber().getValue() ) ); } @JRubyMethod(name = "cmp_issuer") public IRubyObject cmp_issuer(IRubyObject other) { Ruby runtime = getRuntime(); if ( equals(other) ) { return RubyFixnum.zero(runtime); } if (other instanceof OCSPCertificateId) { OCSPCertificateId that = (OCSPCertificateId) other; CertID thisCert = this.getCertID(); CertID thatCert = that.getCertID(); int ret = thisCert.getHashAlgorithm().getAlgorithm().toString().compareTo( thatCert.getHashAlgorithm().getAlgorithm().toString()); if (ret != 0) return RubyFixnum.newFixnum(runtime, ret); ret = thisCert.getIssuerNameHash().toString().compareTo( thatCert.getIssuerNameHash().toString()); if (ret != 0) return RubyFixnum.newFixnum(runtime, ret); return RubyFixnum.newFixnum(runtime, thisCert.getIssuerKeyHash().toString().compareTo( thatCert.getIssuerKeyHash().toString())); } else { return runtime.getCurrentContext().nil; } } @JRubyMethod(name = "to_der") public IRubyObject to_der() { Ruby runtime = getRuntime(); try { return StringHelper.newString(runtime, bcCertId.getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw newOCSPError(runtime, e); } } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(IRubyObject obj) { if ( this == obj ) return this; checkFrozen(); this.bcCertId = ((OCSPCertificateId)obj).getCertID(); return this; } @Override public boolean equals(Object other) { if ( this == other ) return true; if ( other instanceof OCSPCertificateId ) { OCSPCertificateId that = (OCSPCertificateId) other; return this.getCertID().equals(that.getCertID()); } else { return false; } } public CertID getCertID() { return bcCertId; } public CertificateID getBCCertificateID() { if (bcCertId == null) return null; return new CertificateID(bcCertId); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OCSPRequest.java000066400000000000000000000461131313661621600262520ustar00rootroot00000000000000/* * The contents of this file are subject to the Common Public License Version 1.0 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright (C) 2017 Donovan Lampa * Copyright (C) 2009-2017 The JRuby Team * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. * * * JRuby-OpenSSL includes software by The Legion of the Bouncy Castle Inc. * Please, visit (http://bouncycastle.org/license.html) for licensing details. */ package org.jruby.ext.openssl; import static org.jruby.ext.openssl.Digest._Digest; import static org.jruby.ext.openssl.OCSP._OCSP; import static org.jruby.ext.openssl.OCSP.newOCSPError; import static org.jruby.ext.openssl.OpenSSL.debugStackTrace; import static org.jruby.ext.openssl.X509._X509; import java.io.IOException; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.ocsp.Signature; import org.bouncycastle.asn1.ocsp.TBSRequest; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.ocsp.CertificateID; import org.bouncycastle.cert.ocsp.OCSPReq; import org.bouncycastle.cert.ocsp.OCSPReqBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; /* * An OpenSSL::OCSP::Request contains the certificate information for determining * if a certificate has been revoked or not. A Request can be created for a * certificate or from a DER-encoded request created elsewhere. * * @author lampad */ public class OCSPRequest extends RubyObject { private static final long serialVersionUID = -4020616730425816999L; private static ObjectAllocator REQUEST_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new OCSPRequest(runtime, klass); } }; public OCSPRequest(Ruby runtime, RubyClass metaClass) { super(runtime, metaClass); } public static void createRequest(final Ruby runtime, final RubyModule _OCSP) { RubyClass _request = _OCSP.defineClassUnder("Request", runtime.getObject(), REQUEST_ALLOCATOR); _request.defineAnnotatedMethods(OCSPRequest.class); } private final static String OCSP_NOCERTS = "NOCERTS"; private final static String OCSP_NOSIGS = "NOSIGS"; private final static String OCSP_NOINTERN = "NOINTERN"; private final static String OCSP_NOVERIFY = "NOVERIFY"; private final static String OCSP_TRUSTOTHER = "TRUSTOTHER"; private final static String OCSP_NOCHAIN = "NOCHAIN"; private org.bouncycastle.asn1.ocsp.OCSPRequest asn1bcReq; private List certificateIds = new ArrayList(); private byte[] nonce; @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject[] args) { Ruby runtime = context.getRuntime(); if ( Arity.checkArgumentCount(runtime, args, 0, 1) == 0 ) return this; RubyString derString = StringHelper.readPossibleDERInput(context, args[0]); asn1bcReq = org.bouncycastle.asn1.ocsp.OCSPRequest.getInstance(derString.getBytes()); return this; } @JRubyMethod(name = "add_certid") public IRubyObject add_certid(IRubyObject certId) { Ruby runtime = getRuntime(); OCSPCertificateId rubyCertId = (OCSPCertificateId) certId; certificateIds.add(rubyCertId); OCSPReqBuilder builder = new OCSPReqBuilder(); for (OCSPCertificateId certificateId : certificateIds) { builder.addRequest(new CertificateID(certificateId.getCertID())); } try { asn1bcReq = org.bouncycastle.asn1.ocsp.OCSPRequest.getInstance(builder.build().getEncoded()); } catch (Exception e) { throw newOCSPError(runtime, e); } if (nonce != null) { addNonceImpl(); } return this; } @JRubyMethod(name = "add_nonce", rest = true) public IRubyObject add_nonce(IRubyObject[] args) { Ruby runtime = getRuntime(); if ( Arity.checkArgumentCount(runtime, args, 0, 1) == 0 ) { nonce = generateNonce(); } else { RubyString input = (RubyString)args[0]; nonce = input.getBytes(); } addNonceImpl(); return this; } // BC doesn't have support for nonces... gotta do things manually private void addNonceImpl() { GeneralName requestorName = null; ASN1Sequence requestList = new DERSequence(); Extensions extensions = null; Signature sig = null; List tmpExtensions = new ArrayList(); if (asn1bcReq != null) { TBSRequest currentTbsReq = asn1bcReq.getTbsRequest(); extensions = currentTbsReq.getRequestExtensions(); sig = asn1bcReq.getOptionalSignature(); Enumeration oids = extensions.oids(); while (oids.hasMoreElements()) { tmpExtensions.add(extensions.getExtension(oids.nextElement())); } } tmpExtensions.add(new Extension(OCSPObjectIdentifiers.id_pkix_ocsp_nonce, false, nonce)); Extension[] exts = new Extension[tmpExtensions.size()]; Extensions newExtensions = new Extensions(tmpExtensions.toArray(exts)); TBSRequest newTbsReq = new TBSRequest(requestorName, requestList, newExtensions); asn1bcReq = new org.bouncycastle.asn1.ocsp.OCSPRequest(newTbsReq, sig); } @JRubyMethod(name = "certid") public IRubyObject certid() { Ruby runtime = getRuntime(); return RubyArray.newArray(runtime, certificateIds); } @JRubyMethod(name = "check_nonce") public IRubyObject check_nonce(ThreadContext context, IRubyObject response) { final Ruby runtime = context.runtime; if (response instanceof OCSPBasicResponse) { OCSPBasicResponse rubyBasicRes = (OCSPBasicResponse) response; return checkNonceImpl(runtime, this.nonce, rubyBasicRes.getNonce()); } else if (response instanceof OCSPResponse) { OCSPResponse rubyResp = (OCSPResponse) response; return checkNonceImpl(runtime, this.nonce, ((OCSPBasicResponse)rubyResp.basic(context)).getNonce()); } else { return checkNonceImpl(runtime, this.nonce, null); } } @JRubyMethod(name = "sign", rest = true) public IRubyObject sign(final ThreadContext context, IRubyObject[] args) { final Ruby runtime = context.runtime; int flag = 0; IRubyObject additionalCerts = context.nil; IRubyObject flags = context.nil; IRubyObject digest = context.nil; Digest digestInstance = new Digest(runtime, _Digest(runtime)); IRubyObject nocerts = (RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCERTS); switch (Arity.checkArgumentCount(runtime, args, 2, 5)) { case 3 : additionalCerts = args[2]; break; case 4 : additionalCerts = args[2]; flags = args[3]; break; case 5 : additionalCerts = args[2]; flags = args[3]; digest = args[4]; break; default : break; } if (digest.isNil()) digest = digestInstance.initialize(context, new IRubyObject[] { RubyString.newString(runtime, "SHA1") }); if (additionalCerts.isNil()) flag |= RubyFixnum.fix2int(nocerts); if (!flags.isNil()) flag = RubyFixnum.fix2int(flags); X509Cert signer = (X509Cert) args[0]; PKey signerKey = (PKey) args[1]; String keyAlg = signerKey.getAlgorithm(); String digAlg = ((Digest) digest).getShortAlgorithm(); JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(digAlg + "with" + keyAlg); signerBuilder.setProvider("BC"); ContentSigner contentSigner = null; try { contentSigner = signerBuilder.build(signerKey.getPrivateKey()); } catch (OperatorCreationException e) { throw newOCSPError(runtime, e); } OCSPReqBuilder builder = new OCSPReqBuilder(); builder.setRequestorName(signer.getSubject().getX500Name()); for (OCSPCertificateId certId : certificateIds) { builder.addRequest(new CertificateID(certId.getCertID())); } List certChain = new ArrayList(); if (flag != RubyFixnum.fix2int(nocerts)) { try { certChain.add(new X509CertificateHolder(signer.getAuxCert().getEncoded())); if (!additionalCerts.isNil()) { Iterator certIt = ((RubyArray)additionalCerts).iterator(); while (certIt.hasNext()) { certChain.add(new X509CertificateHolder(certIt.next().getEncoded())); } } } catch (Exception e) { throw newOCSPError(runtime, e); } } X509CertificateHolder[] chain = new X509CertificateHolder[certChain.size()]; certChain.toArray(chain); try { asn1bcReq = org.bouncycastle.asn1.ocsp.OCSPRequest.getInstance(builder.build(contentSigner, chain).getEncoded()); } catch (Exception e) { throw newOCSPError(runtime, e); } if (nonce != null) { addNonceImpl(); } return this; } @JRubyMethod(name = "verify", rest = true) public IRubyObject verify(IRubyObject[] args) { Ruby runtime = getRuntime(); ThreadContext context = runtime.getCurrentContext(); int flags = 0; boolean ret = false; if (Arity.checkArgumentCount(runtime, args, 2, 3) == 3) { flags = RubyFixnum.fix2int((RubyFixnum)args[2]); } IRubyObject certificates = args[0]; IRubyObject store = args[1]; OCSPReq bcOCSPReq = getBCOCSPReq(); if (bcOCSPReq == null) { throw newOCSPError(runtime, new NullPointerException("Missing BC asn1bcReq. Missing certIDs or signature?")); } if (!bcOCSPReq.isSigned()) { return RubyBoolean.newBoolean(runtime, ret); } GeneralName genName = bcOCSPReq.getRequestorName(); if (genName.getTagNo() != 4) { return RubyBoolean.newBoolean(runtime, ret); } X500Name genX500Name = X500Name.getInstance(genName.getName()); X509StoreContext storeContext = null; JcaContentVerifierProviderBuilder jcacvpb = new JcaContentVerifierProviderBuilder(); jcacvpb.setProvider("BC"); try { java.security.cert.Certificate signer = findCertByName(genX500Name, certificates, flags); if (signer == null) return RubyBoolean.newBoolean(runtime, ret); if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOINTERN))) > 0 && ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_TRUSTOTHER))) > 0)) flags |= RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOVERIFY)); if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOSIGS))) == 0) { PublicKey signerPubKey = signer.getPublicKey(); ContentVerifierProvider cvp = jcacvpb.build(signerPubKey); ret = bcOCSPReq.isSignatureValid(cvp); if (!ret) { return RubyBoolean.newBoolean(runtime, ret); } } if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOVERIFY))) == 0) { if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOCHAIN))) > 0) { storeContext = X509StoreContext.newStoreContext(context, (X509Store)store, X509Cert.wrap(runtime, signer), context.nil); } else { RubyArray certs = RubyArray.newEmptyArray(runtime); ASN1Sequence bcCerts = asn1bcReq.getOptionalSignature().getCerts(); if (bcCerts != null) { Iterator it = bcCerts.iterator(); while (it.hasNext()) { Certificate cert = Certificate.getInstance(it.next()); certs.add(X509Cert.wrap(runtime, new X509AuxCertificate(cert))); } } storeContext = X509StoreContext.newStoreContext(context, (X509Store)store, X509Cert.wrap(runtime, signer), certs); } storeContext.set_purpose(context, _X509(runtime).getConstant("PURPOSE_OCSP_HELPER")); storeContext.set_trust(context, _X509(runtime).getConstant("TRUST_OCSP_REQUEST")); ret = storeContext.verify(context).isTrue(); if (!ret) return RubyBoolean.newBoolean(runtime, false); } } catch (Exception e) { debugStackTrace(e); throw newOCSPError(runtime, e); } return RubyBoolean.newBoolean(getRuntime(), ret); } @JRubyMethod(name = "to_der") public IRubyObject to_der() { Ruby runtime = getRuntime(); try { return RubyString.newString(runtime, this.asn1bcReq.getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw newOCSPError(runtime, e); } } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(IRubyObject obj) { if ( this == obj ) return this; checkFrozen(); this.asn1bcReq = ((OCSPRequest)obj).getBCRequest(); return this; } private java.security.cert.Certificate findCertByName(ASN1Encodable genX500Name, IRubyObject certificates, int flags) throws CertificateException, IOException { Ruby runtime = getRuntime(); if ((flags & RubyFixnum.fix2int(_OCSP(runtime).getConstant(OCSP_NOINTERN))) == 0) { ASN1Sequence certs = asn1bcReq.getOptionalSignature().getCerts(); if (certs != null) { Iterator it = certs.iterator(); while (it.hasNext()) { Certificate cert = Certificate.getInstance(it.next()); if (genX500Name.equals(cert.getSubject())) return new X509AuxCertificate(cert); } } } @SuppressWarnings("unchecked") List certList = (RubyArray)certificates; for (X509Certificate cert : certList) { if (genX500Name.equals(X500Name.getInstance(cert.getSubjectX500Principal().getEncoded()))) return new X509AuxCertificate(cert); } return null; } public byte[] getNonce() { return this.nonce; } private IRubyObject checkNonceImpl(Ruby runtime, byte[] reqNonce, byte[] respNonce) { if (reqNonce != null && respNonce != null) { if (Arrays.equals(reqNonce, respNonce)) { return RubyFixnum.one(runtime); } else { return RubyFixnum.zero(runtime); } } else if (reqNonce == null && respNonce == null) { return RubyFixnum.two(runtime); } else if (reqNonce != null && respNonce == null) { return RubyFixnum.newFixnum(runtime, -1); } else { return RubyFixnum.three(runtime); } } private byte[] generateNonce() { // OSSL currently generates 16 byte nonce by default return generateNonce(new byte[16]); } private byte[] generateNonce(byte[] bytes) { OpenSSL.getSecureRandom(getRuntime()).nextBytes(bytes); return bytes; } public org.bouncycastle.asn1.ocsp.OCSPRequest getBCRequest() { return asn1bcReq; } public OCSPReq getBCOCSPReq() { if (asn1bcReq == null) return null; return new OCSPReq(asn1bcReq); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OCSPResponse.java000066400000000000000000000167021313661621600264210ustar00rootroot00000000000000/* * The contents of this file are subject to the Common Public License Version 1.0 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright (C) 2017 Donovan Lampa * Copyright (C) 2009-2017 The JRuby Team * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. * * * JRuby-OpenSSL includes software by The Legion of the Bouncy Castle Inc. * Please, visit (http://bouncycastle.org/license.html) for licensing details. */ package org.jruby.ext.openssl; import static org.jruby.ext.openssl.OCSP._OCSP; import static org.jruby.ext.openssl.OCSP.newOCSPError; import java.io.IOException; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.cert.ocsp.BasicOCSPResp; import org.bouncycastle.cert.ocsp.OCSPResp; import org.bouncycastle.cert.ocsp.OCSPRespBuilder; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; /* * An OpenSSL::OCSP::Response contains the status of a certificate check which * is created from an OpenSSL::OCSP::Request. * * @author lampad */ public class OCSPResponse extends RubyObject { private static final long serialVersionUID = 5763247988029815198L; private static ObjectAllocator RESPONSE_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new OCSPResponse(runtime, klass); } }; public OCSPResponse(Ruby runtime, RubyClass metaClass) { super(runtime, metaClass); } public OCSPResponse(Ruby runtime) { this(runtime, (RubyClass) _OCSP(runtime).getConstantAt("Response")); } public static void createResponse(final Ruby runtime, final RubyModule OCSP) { RubyClass Response = OCSP.defineClassUnder("Response", runtime.getObject(), RESPONSE_ALLOCATOR); Response.defineAnnotatedMethods(OCSPResponse.class); } private org.bouncycastle.asn1.ocsp.OCSPResponse bcResp; @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject args[]) { Ruby runtime = context.getRuntime(); if ( Arity.checkArgumentCount(runtime, args, 0, 1) == 0 ) return this; RubyString derString = (RubyString) args[0]; try { bcResp = org.bouncycastle.asn1.ocsp.OCSPResponse.getInstance(ASN1TaggedObject.fromByteArray(derString.getBytes())); } catch (IOException e) { throw newOCSPError(runtime, e); } return this; } @JRubyMethod(name = "create", meta = true) public static IRubyObject create(final ThreadContext context, final IRubyObject self, IRubyObject status) { Ruby runtime = context.runtime; OCSPRespBuilder builder = new OCSPRespBuilder(); OCSPResp tmpResp; OCSPResponse ret = new OCSPResponse(runtime); try { tmpResp = builder.build(RubyFixnum.fix2int((RubyFixnum)status), null); ret.initialize(context, new IRubyObject[] { RubyString.newString(runtime, tmpResp.getEncoded())}); } catch (Exception e) { throw newOCSPError(runtime, e); } return ret; } @JRubyMethod(name = "create", meta = true) public static IRubyObject create(final ThreadContext context, final IRubyObject self, IRubyObject status, IRubyObject basicResponse) { Ruby runtime = context.runtime; if (basicResponse == null || basicResponse.isNil()) { return create(context, self, status); } else { OCSPResponse ret = new OCSPResponse(runtime); OCSPBasicResponse rubyBasicResp = (OCSPBasicResponse) basicResponse; OCSPRespBuilder builder = new OCSPRespBuilder(); try { OCSPResp tmpResp = builder.build(RubyFixnum.fix2int((RubyFixnum)status), new BasicOCSPResp(rubyBasicResp.getASN1BCOCSPResp())); ret.initialize(context, new IRubyObject[] { RubyString.newString(runtime, tmpResp.getEncoded())}); } catch (Exception e) { throw newOCSPError(runtime, e); } return ret; } } @Override @JRubyMethod(name = "initialize_copy", visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(IRubyObject obj) { if ( this == obj ) return this; checkFrozen(); this.bcResp = ((OCSPResponse)obj).getBCResp(); return this; } @JRubyMethod(name = "basic") public IRubyObject basic(ThreadContext context) { Ruby runtime = context.runtime; if (bcResp == null || bcResp.getResponseBytes() == null || bcResp.getResponseBytes().getResponse() == null) { return context.nil; } else { OCSPBasicResponse ret = new OCSPBasicResponse(runtime); return ret.initialize(context, RubyString.newString(runtime, bcResp.getResponseBytes().getResponse().getOctets())); } } @JRubyMethod(name = "status") public IRubyObject status() { return RubyFixnum.newFixnum(getRuntime(), bcResp.getResponseStatus().getValue().longValue()); } @JRubyMethod(name = "status_string") public IRubyObject status_string() { String statusStr = OCSP.getResponseStringForValue(status()); return RubyString.newString(getRuntime(), statusStr); } @JRubyMethod(name = "to_der") public IRubyObject to_der() { Ruby runtime = getRuntime(); try { return RubyString.newString(runtime, bcResp.getEncoded()); } catch (IOException e) { throw newOCSPError(runtime, e); } } public org.bouncycastle.asn1.ocsp.OCSPResponse getBCResp() { return bcResp; } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OCSPSingleResponse.java000066400000000000000000000267451313661621600275730ustar00rootroot00000000000000/* * The contents of this file are subject to the Common Public License Version 1.0 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Copyright (C) 2017 Donovan Lampa * Copyright (C) 2009-2017 The JRuby Team * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. * * * JRuby-OpenSSL includes software by The Legion of the Bouncy Castle Inc. * Please, visit (http://bouncycastle.org/license.html) for licensing details. */ package org.jruby.ext.openssl; import static org.jruby.ext.openssl.OCSP._OCSP; import static org.jruby.ext.openssl.OCSP.newOCSPError; import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.ocsp.CertID; import org.bouncycastle.asn1.ocsp.RevokedInfo; import org.bouncycastle.asn1.ocsp.SingleResponse; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; /* * An OpenSSL::OCSP::SingleResponse represents an OCSP SingleResponse structure, * which contains the basic information of the status of the certificate. * * @author lampad */ public class OCSPSingleResponse extends RubyObject { private static final long serialVersionUID = 7947277768033100227L; private static ObjectAllocator SINGLERESPONSE_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new OCSPSingleResponse(runtime, klass); } }; public static void createSingleResponse(final Ruby runtime, final RubyModule _OCSP) { RubyClass _request = _OCSP.defineClassUnder("SingleResponse", runtime.getObject(), SINGLERESPONSE_ALLOCATOR); _request.defineAnnotatedMethods(OCSPSingleResponse.class); } public OCSPSingleResponse(Ruby runtime, RubyClass metaClass) { super(runtime, metaClass); } public OCSPSingleResponse(Ruby runtime) { this(runtime, (RubyClass) _OCSP(runtime).getConstantAt("SingleResponse")); } private SingleResponse bcSingleResponse; @JRubyMethod(name = "initialize", visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject derStr) { Ruby runtime = context.getRuntime(); RubyString rubyDerStr = (RubyString) derStr; try { bcSingleResponse = SingleResponse.getInstance(DERTaggedObject.fromByteArray(rubyDerStr.getBytes())); } catch (IOException e) { throw newOCSPError(runtime, e); } return this; } @JRubyMethod(name = "cert_status") public IRubyObject cert_status() { return RubyFixnum.newFixnum(getRuntime(), bcSingleResponse.getCertStatus().getTagNo()); } @JRubyMethod(name = "certid") public IRubyObject certid(ThreadContext context) { Ruby runtime = context.runtime; CertID bcCertId = bcSingleResponse.getCertID(); OCSPCertificateId rubyCertId = new OCSPCertificateId(runtime); try { rubyCertId.initialize(context, RubyString.newString(runtime, bcCertId.getEncoded())); } catch (IOException e) { throw newOCSPError(runtime, e); } return rubyCertId; } @JRubyMethod(name = "check_validity", rest = true) public IRubyObject check_validity(IRubyObject[] args) { Ruby runtime = getRuntime(); int nsec, maxsec; Date thisUpdate, nextUpdate; if ( Arity.checkArgumentCount(runtime, args, 0, 2) == 0 ) { nsec = 0; maxsec = -1; } else if ( Arity.checkArgumentCount(runtime, args, 0, 2) == 1 ) { RubyFixnum rNsec = (RubyFixnum) args[0]; nsec = (int)rNsec.getLongValue(); maxsec = -1; } else { RubyFixnum rNsec = (RubyFixnum) args[0]; RubyFixnum rMaxsec = (RubyFixnum) args[1]; nsec = (int)rNsec.getLongValue(); maxsec = (int)rMaxsec.getLongValue(); } try { ASN1GeneralizedTime bcThisUpdate = bcSingleResponse.getThisUpdate(); if (bcThisUpdate == null) { thisUpdate = null; } else { thisUpdate = bcThisUpdate.getDate(); } ASN1GeneralizedTime bcNextUpdate = bcSingleResponse.getNextUpdate(); if (bcNextUpdate == null) { nextUpdate = null; } else { nextUpdate = bcNextUpdate.getDate(); } } catch (ParseException e) { throw newOCSPError(runtime, e); } return RubyBoolean.newBoolean(runtime, checkValidityImpl(thisUpdate, nextUpdate, nsec, maxsec)); } @JRubyMethod(name = "extensions") public IRubyObject extensions() { Ruby runtime = getRuntime(); Extensions exts = bcSingleResponse.getSingleExtensions(); if (exts == null) return RubyArray.newEmptyArray(runtime); ASN1ObjectIdentifier[] extOIDs = exts.getExtensionOIDs(); RubyArray retExts = runtime.newArray(extOIDs.length); for (ASN1ObjectIdentifier extOID : extOIDs) { Extension ext = exts.getExtension(extOID); ASN1Encodable extAsn1 = ext.getParsedValue(); X509Extension retExt = X509Extension.newExtension(runtime, extOID, extAsn1, ext.isCritical()); retExts.append(retExt); } return retExts; } @JRubyMethod(name = "next_update") public IRubyObject next_update() { Ruby runtime = getRuntime(); if (bcSingleResponse.getNextUpdate() == null) return runtime.getNil(); Date nextUpdate; try { nextUpdate = bcSingleResponse.getNextUpdate().getDate(); } catch (ParseException e) { throw newOCSPError(runtime, e); } if (nextUpdate == null) { return runtime.getNil(); } return RubyTime.newTime(runtime, nextUpdate.getTime()); } @JRubyMethod(name = "this_update") public IRubyObject this_update() { Ruby runtime = getRuntime(); if (bcSingleResponse.getThisUpdate() == null) return runtime.getNil(); Date thisUpdate; try { thisUpdate = bcSingleResponse.getThisUpdate().getDate(); } catch (ParseException e) { throw newOCSPError(runtime, e); } return RubyTime.newTime(runtime, thisUpdate.getTime()); } @JRubyMethod(name = "revocation_reason") public IRubyObject revocation_reason() { Ruby runtime = getRuntime(); RubyFixnum revoked = (RubyFixnum) _OCSP(runtime).getConstant("V_CERTSTATUS_REVOKED"); if (bcSingleResponse.getCertStatus().getTagNo() == (int) revoked.getLongValue()) { try { RevokedInfo revokedInfo = RevokedInfo.getInstance( DERTaggedObject.fromByteArray(bcSingleResponse.getCertStatus().getStatus().toASN1Primitive().getEncoded()) ); return RubyFixnum.newFixnum(runtime, revokedInfo.getRevocationReason().getValue().intValue()); } catch (IOException e) { throw newOCSPError(runtime, e); } } return runtime.getNil(); } @JRubyMethod(name = "revocation_time") public IRubyObject revocation_time() { Ruby runtime = getRuntime(); RubyFixnum revoked = (RubyFixnum) _OCSP(runtime).getConstant("V_CERTSTATUS_REVOKED"); if (bcSingleResponse.getCertStatus().getTagNo() == (int)revoked.getLongValue()) { try { RevokedInfo revokedInfo = RevokedInfo.getInstance( DERTaggedObject.fromByteArray(bcSingleResponse.getCertStatus().getStatus().toASN1Primitive().getEncoded()) ); return RubyTime.newTime(runtime, revokedInfo.getRevocationTime().getDate().getTime()); } catch (Exception e) { throw newOCSPError(runtime, e); } } return runtime.getNil(); } @JRubyMethod(name = "to_der") public IRubyObject to_der() { Ruby runtime = getRuntime(); try { return RubyString.newString(runtime, bcSingleResponse.getEncoded()); } catch (IOException e) { throw newOCSPError(runtime, e); } } public SingleResponse getBCSingleResp() { return bcSingleResponse; } // see OCSP_check_validity in ocsp_cl.c private boolean checkValidityImpl(Date thisUpdate, Date nextUpdate, int nsec, int maxsec) { boolean ret = true; Date currentTime = new Date(); Date tempTime = new Date(); tempTime.setTime(currentTime.getTime() + (nsec*1000)); if (thisUpdate.compareTo(tempTime) > 0) { ret = false; } if (maxsec >= 0) { tempTime.setTime(currentTime.getTime() - (maxsec*1000)); if (thisUpdate.compareTo(tempTime) < 0) { ret = false; } } if (nextUpdate == null) { return ret; } tempTime.setTime(currentTime.getTime() - (nsec*1000)); if (nextUpdate.compareTo(tempTime) < 0) { ret = false; } if (nextUpdate.compareTo(thisUpdate) < 0) { ret = false; } return ret; } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OSSLLibrary.java000066400000000000000000000006361313661621600262420ustar00rootroot00000000000000package org.jruby.ext.openssl; import org.jruby.Ruby; import org.jruby.runtime.load.Library; import java.io.IOException; /** * @deprecated * @see OpenSSL */ public class OSSLLibrary implements Library { public static void load(final Ruby runtime) { OpenSSL.load(runtime); } @Override public void load(Ruby runtime, boolean wrap) throws IOException { load(runtime); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/ObjectSupport.java000066400000000000000000000066241313661621600267430ustar00rootroot00000000000000/* * The MIT License * * Copyright 2014 Karol Bucek. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import java.util.List; import org.jruby.Ruby; import org.jruby.RubyBasicObject; import org.jruby.RubyString; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.builtin.Variable; /** * (Ruby) Object support. * * @author kares */ abstract class ObjectSupport { @SuppressWarnings("unchecked") static RubyString inspect(final RubyBasicObject self) { return inspect(self, (List) self.getInstanceVariableList()); } static RubyString inspect(final RubyBasicObject self, final List variableList) { final Ruby runtime = self.getRuntime(); return RubyString.newString(runtime, inspect(runtime, self, variableList)); } private static StringBuilder inspect(final Ruby runtime, final RubyBasicObject self, final List variableList) { final StringBuilder part = new StringBuilder(); String cname = self.getMetaClass().getRealClass().getName(); part.append("#<").append(cname).append(":0x"); part.append(Integer.toHexString(System.identityHashCode(self))); if (runtime.isInspecting(self)) { /* 6:tags 16:addr 1:eos */ part.append(" ...>"); return part; } try { runtime.registerInspecting(self); final ThreadContext context = runtime.getCurrentContext(); return inspectObj(context, variableList, part); } finally { runtime.unregisterInspecting(self); } } private static StringBuilder inspectObj(final ThreadContext context, final List variableList, final StringBuilder part) { String sep = ""; for ( final Variable ivar : variableList ) { part.append(sep).append(' ').append( ivar.getName() ).append('='); final Object ival = ivar.getValue(); if ( ival instanceof IRubyObject ) { part.append( ((IRubyObject) ival).callMethod(context, "inspect") ); } else { // allow the variable to come formatted (as is) already : part.append( ival ); // ival == null ? "nil" : ival.toString() } sep = ","; } part.append('>'); return part; } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OpenSSL.java000066400000000000000000000326701313661621600254230ustar00rootroot00000000000000/* * The MIT License * * Copyright (c) 2014 Karol Bucek LTD. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.util.Map; import org.jruby.CompatVersion; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.anno.JRubyModule; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.util.SafePropertyAccessor; /** * OpenSSL (methods as well as an entry point) * * @author kares */ @JRubyModule(name = "OpenSSL") public final class OpenSSL { public static void load(final Ruby runtime) { createOpenSSL(runtime); } public static boolean isProviderAvailable() { return SecurityHelper.isProviderAvailable("BC"); } public static void createOpenSSL(final Ruby runtime) { SecurityHelper.setRegisterProvider( SafePropertyAccessor.getBoolean("jruby.openssl.provider.register") ); final RubyModule _OpenSSL = runtime.getOrCreateModule("OpenSSL"); RubyClass _StandardError = runtime.getClass("StandardError"); _OpenSSL.defineClassUnder("OpenSSLError", _StandardError, _StandardError.getAllocator()); _OpenSSL.defineAnnotatedMethods(OpenSSL.class); // set OpenSSL debug internal flag early on so it can print traces even while loading extension setDebug(_OpenSSL, runtime.newBoolean( SafePropertyAccessor.getBoolean("jruby.openssl.debug") ) ); final String warn = SafePropertyAccessor.getProperty("jruby.openssl.warn"); if ( warn != null ) OpenSSL.warn = Boolean.parseBoolean(warn); PKey.createPKey(runtime, _OpenSSL); BN.createBN(runtime, _OpenSSL); Digest.createDigest(runtime, _OpenSSL); Cipher.createCipher(runtime, _OpenSSL); Random.createRandom(runtime, _OpenSSL); HMAC.createHMAC(runtime, _OpenSSL); Config.createConfig(runtime, _OpenSSL); ASN1.createASN1(runtime, _OpenSSL); X509.createX509(runtime, _OpenSSL); NetscapeSPKI.createNetscapeSPKI(runtime, _OpenSSL); SSL.createSSL(runtime, _OpenSSL); PKCS7.createPKCS7(runtime, _OpenSSL); PKCS5.createPKCS5(runtime, _OpenSSL); OCSP.createOCSP(runtime, _OpenSSL); runtime.getLoadService().require("jopenssl/version"); // MRI 1.8.7 : // OpenSSL::VERSION: "1.0.0" // OpenSSL::OPENSSL_VERSION: "OpenSSL 1.0.1c 10 May 2012" // OpenSSL::OPENSSL_VERSION_NUMBER: 268439615 // MRI 1.9.3 / 2.2.3 : // OpenSSL::VERSION: "1.1.0" // OpenSSL::OPENSSL_VERSION: "OpenSSL 1.0.1f 6 Jan 2014" // OpenSSL::OPENSSL_VERSION_NUMBER: 268439663 // OpenSSL::OPENSSL_LIBRARY_VERSION: ""OpenSSL 1.0.2d 9 Jul 2015" // OpenSSL::FIPS: false final byte[] version = { '1','.','1','.','0' }; final boolean ruby18 = runtime.getInstanceConfig().getCompatVersion() == CompatVersion.RUBY1_8; if ( ruby18 ) version[2] = '0'; // 1.0.0 compatible on 1.8 _OpenSSL.setConstant("VERSION", StringHelper.newString(runtime, version)); final RubyModule _Jopenssl = runtime.getModule("Jopenssl"); final RubyModule _Version = (RubyModule) _Jopenssl.getConstantAt("Version"); final RubyString jVERSION = _Version.getConstantAt("VERSION").asString(); final byte[] JRuby_OpenSSL_ = { 'J','R','u','b','y','-','O','p','e','n','S','S','L',' ' }; final int OPENSSL_VERSION_NUMBER = 999999999; // NOTE: smt more useful? ByteList OPENSSL_VERSION = new ByteList( jVERSION.getByteList().length() + JRuby_OpenSSL_.length ); OPENSSL_VERSION.setEncoding( jVERSION.getEncoding() ); OPENSSL_VERSION.append( JRuby_OpenSSL_ ); OPENSSL_VERSION.append( jVERSION.getByteList() ); final RubyString VERSION; _OpenSSL.setConstant("OPENSSL_VERSION", VERSION = runtime.newString(OPENSSL_VERSION)); _OpenSSL.setConstant("OPENSSL_VERSION_NUMBER", runtime.newFixnum(OPENSSL_VERSION_NUMBER)); if ( ! ruby18 ) { // MRI 2.3 tests do: /\AOpenSSL +0\./ !~ OpenSSL::OPENSSL_LIBRARY_VERSION _OpenSSL.setConstant("OPENSSL_LIBRARY_VERSION", VERSION); _OpenSSL.setConstant("OPENSSL_FIPS", runtime.getFalse()); } } static RubyClass _OpenSSLError(final Ruby runtime) { return runtime.getModule("OpenSSL").getClass("OpenSSLError"); } // OpenSSL module methods : @JRubyMethod(name = "errors", meta = true) public static IRubyObject errors(IRubyObject self) { final Ruby runtime = self.getRuntime(); RubyArray result = runtime.newArray(); for (Map.Entry e : X509.getErrors().entrySet()) { result.add( runtime.newString( e.getValue() ) ); } return result; } @JRubyMethod(name = "debug", meta = true) public static IRubyObject getDebug(IRubyObject self) { return (IRubyObject) getDebug((RubyModule) self); } private static Object getDebug(RubyModule self) { return self.getInternalVariable("debug"); } @JRubyMethod(name = "debug=", meta = true) public static IRubyObject setDebug(IRubyObject self, IRubyObject debug) { ((RubyModule) self).setInternalVariable("debug", debug); OpenSSL.debug = debug.isTrue(); return debug; } @JRubyMethod(name = "Digest", meta = true) public static IRubyObject Digest(final IRubyObject self, final IRubyObject name) { // OpenSSL::Digest("MD5") -> OpenSSL::Digest::MD5 final Ruby runtime = self.getRuntime(); final RubyClass Digest = runtime.getModule("OpenSSL").getClass("Digest"); return Digest.getConstantAt( name.asString().toString() ); } // API "stubs" in JRuby-OpenSSL : @JRubyMethod(meta = true) public static IRubyObject deprecated_warning_flag(final IRubyObject self) { return self.getRuntime().getNil(); // no-op in JRuby-OpenSSL } @JRubyMethod(meta = true, rest = true) // check_func(func, header) public static IRubyObject check_func(final IRubyObject self, final IRubyObject[] args) { return self.getRuntime().getNil(); // no-op in JRuby-OpenSSL } // Added in 2.0; not masked because it does nothing anyway (there's no reader in MRI) @JRubyMethod(name = "fips_mode=", meta = true) public static IRubyObject set_fips_mode(ThreadContext context, IRubyObject self, IRubyObject value) { if ( value.isTrue() ) { warn(context, "WARNING: FIPS mode not supported on JRuby-OpenSSL"); } return value; } // internal (package-level) helpers : /** * PRIMARILY MEANT FOR TESTING ONLY, USAGE IS DISCOURAGED! * @see org.jruby.ext.openssl.util.CryptoSecurity */ @JRubyMethod(name = "_disable_security_restrictions!", visibility = Visibility.PRIVATE, meta = true) public static IRubyObject _disable_security_restrictions(ThreadContext context, IRubyObject self) { Boolean unrestrict = org.jruby.ext.openssl.util.CryptoSecurity.unrestrictSecurity(); Boolean allPerm = org.jruby.ext.openssl.util.CryptoSecurity.setAllPermissionPolicy(); if ( unrestrict == null || allPerm == null ) return context.nil; return context.runtime.newBoolean( unrestrict && allPerm ); } private static boolean debug; // on by default, warnings can be disabled using -Djruby.openssl.warn=false private static boolean warn = true; static boolean isDebug() { return debug; } public static void debugStackTrace(final Throwable e) { if ( isDebug() ) e.printStackTrace(System.out); } public static void debug(final String msg) { if ( isDebug() ) System.out.println(msg); } public static void debug(final String msg, final Throwable e) { if ( isDebug() ) System.out.println(msg + ' ' + e); } static boolean isDebug(final Ruby runtime) { final RubyModule OpenSSL = runtime.getModule("OpenSSL"); if ( OpenSSL == null ) return debug; // debug early on return getDebug( OpenSSL ) == runtime.getTrue(); } static void debugStackTrace(final Ruby runtime, final Throwable e) { if ( isDebug(runtime) ) e.printStackTrace(runtime.getOut()); } public static void debug(final Ruby runtime, final CharSequence msg) { if ( isDebug(runtime) ) runtime.getOut().println(msg.toString()); } public static void debug(final Ruby runtime, final CharSequence msg, final Throwable e) { if ( isDebug(runtime) ) runtime.getOut().println(msg.toString() + ' ' + e); } static void warn(final ThreadContext context, final CharSequence msg) { warn(context, RubyString.newString(context.runtime, msg)); } static void warn(final ThreadContext context, final RubyString msg) { warn(context, (IRubyObject) msg); } static void warn(final ThreadContext context, final IRubyObject msg) { if ( warn ) context.runtime.getModule("OpenSSL").callMethod(context, "warn", msg); } public static String javaVersion(final String def) { final String javaVersionProperty = SafePropertyAccessor.getProperty("java.version", def); if ( javaVersionProperty == "0" ) return "1.7.0"; // Android return javaVersionProperty; } static boolean javaVersion6(final boolean atLeast) { final int gt = "1.6".compareTo( javaVersion("0.0").substring(0, 3) ); return atLeast ? gt <= 0 : gt == 0; } static boolean javaVersion7(final boolean atLeast) { final int gt = "1.7".compareTo( javaVersion("0.0").substring(0, 3) ); return atLeast ? gt <= 0 : gt == 0; } static boolean javaVersion8(final boolean atLeast) { final int gt = "1.8".compareTo( javaVersion("0.0").substring(0, 3) ); return atLeast ? gt <= 0 : gt == 0; } static boolean javaVersion9(final boolean atLeast) { final int gt = "9".compareTo( javaVersion("0").substring(0, 1) ); return atLeast ? gt <= 0 : gt == 0; } private static String javaName(final String def) { // Sun Java 6 or Oracle Java 7/8 // "Java HotSpot(TM) Server VM" or "Java HotSpot(TM) 64-Bit Server VM" // OpenJDK : // "OpenJDK 64-Bit Server VM" return SafePropertyAccessor.getProperty("java.vm.name", def); } public static boolean javaHotSpot() { return javaName("").contains("HotSpot(TM)"); } public static boolean javaOpenJDK() { return javaName("").contains("OpenJDK"); } // shared secure-random : private static boolean tryContextSecureRandom = true; static SecureRandom getSecureRandom(final Ruby runtime) { return getSecureRandom(runtime, false); } static SecureRandom getSecureRandom(final Ruby runtime, final boolean nullByDefault) { if ( tryContextSecureRandom ) { SecureRandom random = getSecureRandomFrom(runtime.getCurrentContext()); if ( random != null ) return random; } return nullByDefault ? null : new SecureRandom(); } static SecureRandom getSecureRandomFrom(final ThreadContext context) { if ( tryContextSecureRandom ) { try { SecureRandom random = context.secureRandom; if (random == null) { // public SecureRandom getSecureRandom() on 9K random = (SecureRandom) context.getClass().getMethod("getSecureRandom").invoke(context); } return random; } catch (Throwable ex) { tryContextSecureRandom = false; debug(context.runtime, "JRuby-OpenSSL failed to retrieve secure random from thread-context", ex); } } return null; } // internals static IRubyObject to_der_if_possible(final ThreadContext context, IRubyObject obj) { if ( ! obj.respondsTo("to_der")) return obj; return obj.callMethod(context, "to_der"); } // static String bcExceptionMessage(NoSuchProviderException ex) { return "You need to configure JVM/classpath to enable BouncyCastle Security Provider: " + ex; } static String bcExceptionMessage(NoClassDefFoundError ex) { return "You need to configure JVM/classpath to enable BouncyCastle Security Provider: " + ex; } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OpenSSLImpl.java000066400000000000000000000043551313661621600262440ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import org.jruby.runtime.builtin.IRubyObject; /** * @deprecated no longer used * @see OpenSSL * @author Ola Bini */ @Deprecated public class OpenSSLImpl { private OpenSSLImpl() { /* no instances */ } @Deprecated public static IRubyObject to_der_if_possible(IRubyObject obj) { return OpenSSL.to_der_if_possible(obj.getRuntime().getCurrentContext(), obj); } @Deprecated // NOTE: seems to be no longer used ! public static PEMHandler getPEMHandler() { try { return new BouncyCastlePEMHandler(); } catch (Exception e) { if ( OpenSSL.isDebug() ) e.printStackTrace(System.out); } return new DefaultPEMHandler(); } }// OpenSSLImpl jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/OpenSSLReal.java000066400000000000000000000101431313661621600262160ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.security.GeneralSecurityException; import java.security.NoSuchProviderException; import java.security.Provider; /** * @deprecated no longer used * @see OpenSSL * @author Ola Bini */ public class OpenSSLReal { private OpenSSLReal() { /* no instances */ } @Deprecated public static interface Runnable { public void run() throws GeneralSecurityException; } public static interface Callable { public T call() throws GeneralSecurityException; } /** * Run a block of code with 'BC' provider installed. * * @deprecated No longer used within the JRuby-OpenSSL code-base, please avoid! * * @param block * @throws GeneralSecurityException */ @Deprecated public static void doWithBCProvider(final Runnable block) throws GeneralSecurityException { getWithBCProvider(new Callable() { public Void call() throws GeneralSecurityException { block.run(); return null; } }); } /** * Adds BouncyCastleProvider if it's allowed (no security exceptions thrown) * and runs the block of code. Once added the provider will stay registered * within java.security.Security API. This might lead to memory * leaks e.g. when the Ruby runtime that loaded BC is teared down. * * Removing the 'BC' provided (once the block run) can remove pre-installed * or another runtime-added BC provider thus causing unknown runtime errors. * * @deprecated No longer used within the JRuby-OpenSSL code-base, please avoid! * * @param * @param block * @return * @throws GeneralSecurityException */ @Deprecated public static T getWithBCProvider(final Callable block) throws GeneralSecurityException { try { final Provider provider = SecurityHelper.getSecurityProvider(); // BC if (provider != null && java.security.Security.getProvider(provider.getName()) == null) { java.security.Security.addProvider(provider); } return block.call(); } catch (NoSuchProviderException nspe) { throw new GeneralSecurityException(bcExceptionMessage(nspe), nspe); } catch (Exception e) { throw new GeneralSecurityException(e.getMessage(), e); } } public static String bcExceptionMessage(NoSuchProviderException e) { return OpenSSL.bcExceptionMessage(e); } public static String bcExceptionMessage(NoClassDefFoundError e) { return OpenSSL.bcExceptionMessage(e); } }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PEMHandler.java000066400000000000000000000036461313661621600260600ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.Reader; import java.io.Writer; /** * @deprecated * @see PEMUtils * @author Ola Bini */ @Deprecated // no longer used public interface PEMHandler { Object readPEM(Reader read, String password) throws Exception; void writePEM(Writer writ, Object obj, String algorithm, char[] password) throws Exception; void writePEM(Writer writ, Object obj) throws Exception; }// PEMHandler jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PEMUtils.java000066400000000000000000000346451313661621600256060ustar00rootroot00000000000000/* * The MIT License * * Copyright 2014 Karol Bucek. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.security.GeneralSecurityException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyStore; import java.security.Provider; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Collection; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; //import org.bouncycastle.openssl.MiscPEMGenerator; import org.bouncycastle.openssl.PEMWriter; import org.bouncycastle.operator.OperatorCreationException; import org.jruby.ext.openssl.impl.pem.MiscPEMGenerator; import org.jruby.ext.openssl.impl.pem.PEMDecryptor; import org.jruby.ext.openssl.impl.pem.PEMDecryptorProvider; import org.jruby.ext.openssl.impl.pem.PEMEncryptedKeyPair; import org.jruby.ext.openssl.impl.pem.PEMException; import org.jruby.ext.openssl.impl.pem.PEMKeyPair; import org.jruby.ext.openssl.impl.pem.PEMParser; import org.jruby.ext.openssl.util.ByteArrayOutputStream; //import org.bouncycastle.util.io.pem.PemReader; import static org.jruby.ext.openssl.x509store.PEMInputOutput.getKeyFactory; /** * PEM Utilities, for now mostly to replace {@link PEMHandler}. * * @author kares */ public abstract class PEMUtils { /* private static boolean bcPEMParser; private static Class pemReaderImpl; private static Reader newPemReader(final Reader reader) { if ( pemReaderImpl == null ) { synchronized(BouncyCastlePEMHandler.class) { if ( pemReaderImpl == null ) { try { pemReaderImpl = Class.forName("org.bouncycastle.openssl.PEMParser"); bcPEMParser = true; } catch (ClassNotFoundException ex) { pemReaderImpl = org.jruby.ext.openssl.impl.pem.PEMParser.class; } } } } try { Constructor constructor = (Constructor) pemReaderImpl.getConstructor(new Class[] { Reader.class }); return constructor.newInstance(reader); } catch (NoSuchMethodException e) { throw new IllegalStateException(e.getMessage(), e); } //catch (InstantiationException e) { //} catch (InvocationTargetException e) { throw new IllegalStateException(e.getTargetException()); } catch (Exception e) { if ( e instanceof RuntimeException ) throw (RuntimeException) e; throw new IllegalStateException(e); } } private static Object doInvoke(Object obj, String methodName, Class[] paramTypes, Object... params) throws IOException { final Method method; try { method = obj.getClass().getDeclaredMethod(methodName, paramTypes); method.setAccessible(true); return method.invoke(obj, params); } catch (NoSuchMethodException e) { throw new IllegalStateException(e.getMessage(), e); } catch (InvocationTargetException e) { final Throwable target = e.getTargetException(); if ( target instanceof IOException ) throw (IOException) target; if ( target instanceof RuntimeException ) throw (RuntimeException) target; throw new IllegalStateException(target); } catch (Exception e) { if ( e instanceof IOException ) throw (IOException) e; if ( e instanceof RuntimeException ) throw (RuntimeException) e; throw new IllegalStateException(e); } } */ public static KeyPair readKeyPair(final Reader reader) throws IOException { return readKeyPair(reader, null); } public static KeyPair readKeyPair(final Reader reader, final char[] password) throws IOException { PEMKeyPair pemKeyPair = readInternal(reader, password); return toKeyPair(pemKeyPair); } static PEMKeyPair readInternal(final Reader reader, final char[] password) throws IOException { Object keyPair = new PEMParser(reader).readObject(); if ( keyPair instanceof PEMEncryptedKeyPair ) { return ((PEMEncryptedKeyPair) keyPair).decryptKeyPair(new PEMDecryptorImpl(password)); } return (PEMKeyPair) keyPair; } private static KeyPair toKeyPair(final PEMKeyPair pemKeyPair) throws IOException { try { KeyFactory keyFactory = getKeyFactory( pemKeyPair.getPrivateKeyInfo().getPrivateKeyAlgorithm() ); return new KeyPair( keyFactory.generatePublic( new X509EncodedKeySpec( pemKeyPair.getPublicKeyInfo().getEncoded() ) ), keyFactory.generatePrivate( new PKCS8EncodedKeySpec( pemKeyPair.getPrivateKeyInfo().getEncoded() ) ) ); } catch (Exception e) { throw new PEMException("unable to convert key pair: " + e.getMessage(), e); } } public static void writePEM(final Writer writer, final Object obj, final String algorithm, final char[] password) throws IOException { final PEMWriter pemWriter = new PEMWriter(writer); final SecureRandom random = SecurityHelper.getSecureRandom(); pemWriter.writeObject(MiscPEMGenerator.newInstance(obj, algorithm, password, random)); pemWriter.flush(); } public static void writePEM(final Writer writer, final Object obj) throws IOException { writePEM(writer, obj, null, null); } public static byte[] generatePKCS12(final Reader keyReader, final byte[] cert, final String aliasName, final char[] password) throws IOException, GeneralSecurityException { final Collection certChain = SecurityHelper.getCertificateFactory("X.509").generateCertificates(new ByteArrayInputStream(cert)); final PEMKeyPair pemKeyPair = readInternal(keyReader, null); final KeyFactory keyFactory = getKeyFactory( pemKeyPair.getPrivateKeyInfo().getPrivateKeyAlgorithm() ); Key privateKey = keyFactory.generatePrivate( new PKCS8EncodedKeySpec( pemKeyPair.getPrivateKeyInfo().getEncoded() ) ); final KeyStore keyStore = SecurityHelper.getKeyStore("PKCS12"); keyStore.load(null, null); keyStore.setKeyEntry( aliasName, privateKey, null, certChain.toArray(new Certificate[certChain.size()]) ); final ByteArrayOutputStream pkcs12Out = new ByteArrayOutputStream(); keyStore.store(pkcs12Out, password == null ? new char[0] : password); return pkcs12Out.toByteArray(); } private static class PEMDecryptorImpl implements PEMDecryptorProvider, PEMDecryptor { PEMDecryptorImpl(char[] password) { this.password = password; } private char[] password; private String dekAlgName; public PEMDecryptor get(String dekAlgName) throws OperatorCreationException { this.dekAlgName = dekAlgName; return this; // PEMDecryptor } public byte[] decrypt(byte[] keyBytes, byte[] iv) throws PEMException { return decrypt(keyBytes, password, dekAlgName, iv); } static byte[] decrypt( byte[] bytes, char[] password, String dekAlgName, byte[] iv) throws PEMException { return decrypt(SecurityHelper.getSecurityProvider(), bytes, password, dekAlgName, iv); } static byte[] decrypt( Provider provider, byte[] bytes, char[] password, String dekAlgName, byte[] iv) throws PEMException { AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv); String alg; String blockMode = "CBC"; String padding = "PKCS5Padding"; Key sKey; // Figure out block mode and padding. if (dekAlgName.endsWith("-CFB")) { blockMode = "CFB"; padding = "NoPadding"; } if (dekAlgName.endsWith("-ECB") || "DES-EDE".equals(dekAlgName) || "DES-EDE3".equals(dekAlgName)) { // ECB is actually the default (though seldom used) when OpenSSL // uses DES-EDE (des2) or DES-EDE3 (des3). blockMode = "ECB"; paramSpec = null; } if (dekAlgName.endsWith("-OFB")) { blockMode = "OFB"; padding = "NoPadding"; } // Figure out algorithm and key size. if (dekAlgName.startsWith("DES-EDE")) { alg = "DESede"; // "DES-EDE" is actually des2 in OpenSSL-speak! // "DES-EDE3" is des3. boolean des2 = !dekAlgName.startsWith("DES-EDE3"); sKey = secretKeySpec(password, alg, 24, iv, des2); } else if (dekAlgName.startsWith("DES-")) { alg = "DES"; sKey = secretKeySpec(password, alg, 8, iv); } else if (dekAlgName.startsWith("BF-")) { alg = "Blowfish"; sKey = secretKeySpec(password, alg, 16, iv); } else if (dekAlgName.startsWith("RC2-")) { alg = "RC2"; int keyBits = 128; if (dekAlgName.startsWith("RC2-40-")) { keyBits = 40; } else if (dekAlgName.startsWith("RC2-64-")) { keyBits = 64; } sKey = secretKeySpec(password, alg, keyBits / 8, iv); if (paramSpec == null) // ECB block mode { paramSpec = new RC2ParameterSpec(keyBits); } else { paramSpec = new RC2ParameterSpec(keyBits, iv); } } else if (dekAlgName.startsWith("AES-")) { alg = "AES"; byte[] salt = iv; if (salt.length > 8) { salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); } int keyBits; if (dekAlgName.startsWith("AES-128-")) { keyBits = 128; } else if (dekAlgName.startsWith("AES-192-")) { keyBits = 192; } else if (dekAlgName.startsWith("AES-256-")) { keyBits = 256; } else { throw new PEMException("unknown AES encryption with private key"); } sKey = secretKeySpec(password, "AES", keyBits / 8, salt); } else { throw new PEMException("unknown encryption with private key"); } String transformation = alg + "/" + blockMode + "/" + padding; try { javax.crypto.Cipher cipher = SecurityHelper.getCipher(transformation); final int decryptMode = javax.crypto.Cipher.DECRYPT_MODE; if (paramSpec == null) // ECB block mode { cipher.init(decryptMode, sKey); } else { cipher.init(decryptMode, sKey, paramSpec); } return cipher.doFinal(bytes); } catch (Exception e) { throw new PEMException("exception using cipher - please check password and data.", e); } } private static SecretKey secretKeySpec( char[] password, String algorithm, int keyLength, byte[] salt) { return secretKeySpec(password, algorithm, keyLength, salt, false); } private static SecretKey secretKeySpec( char[] password, String algorithm, int keyLength, byte[] salt, boolean des2) { OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt); KeyParameter keyParam; keyParam = (KeyParameter)pGen.generateDerivedParameters(keyLength * 8); byte[] key = keyParam.getKey(); if (des2 && key.length >= 24) { // For DES2, we must copy first 8 bytes into the last 8 bytes. System.arraycopy(key, 0, key, 16, 8); } return new SecretKeySpec(key, algorithm); } } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PKCS5.java000066400000000000000000000156751313661621600247730ustar00rootroot00000000000000/* * The MIT License * * Copyright 2014-2015 Karol Bucek. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.jruby.Ruby; import org.jruby.RubyModule; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.anno.JRubyModule; import org.jruby.runtime.builtin.IRubyObject; /** * OpenSSL::PKCS5 * * @author kares */ @JRubyModule(name = "OpenSSL::PKCS5") public class PKCS5 { public static void createPKCS5(final Ruby runtime, final RubyModule ossl) { final RubyModule PKCS5 = ossl.defineModuleUnder("PKCS5"); PKCS5.defineAnnotatedMethods(PKCS5.class); } // def pbkdf2_hmac_sha1(pass, salt, iter, keylen) @JRubyMethod(meta = true, required = 4) public static IRubyObject pbkdf2_hmac_sha1(final IRubyObject self, final IRubyObject[] args) { //final byte[] pass = args[0].asString().getBytes(); final char[] pass = args[0].asString().toString().toCharArray(); final byte[] salt = args[1].asString().getBytes(); final int iter = (int) args[2].convertToInteger().getLongValue(); final int keySize = (int) args[3].convertToInteger().getLongValue(); // e.g. 64 return generatePBEKey(self.getRuntime(), pass, salt, iter, keySize); } // def pbkdf2_hmac_sha1(pass, salt, iter, keylen, digest) @JRubyMethod(meta = true, required = 5) public static IRubyObject pbkdf2_hmac(final IRubyObject self, final IRubyObject[] args) { final byte[] pass = args[0].asString().getBytes(); final byte[] salt = args[1].asString().getBytes(); final int iter = (int) args[2].convertToInteger().getLongValue(); final int keylen = (int) args[3].convertToInteger().getLongValue(); final String digestAlg; final IRubyObject digest = args[4]; if ( digest instanceof Digest ) { digestAlg = mapDigestName( ((Digest) digest).getRealName() ); } else { digestAlg = mapDigestName( digest.asString().toString() ); } // NOTE: on our own since e.g. "PBKDF2WithHmacMD5" not supported by Java final String macAlg = "Hmac" + digestAlg; final Ruby runtime = self.getRuntime(); try { final Mac mac = SecurityHelper.getMac( macAlg ); mac.init( new SimpleSecretKey(macAlg, pass) ); final byte[] key = deriveKey(mac, salt, iter, keylen); return StringHelper.newString(runtime, key); } catch (NoSuchAlgorithmException ex) { throw Utils.newRuntimeError(runtime, ex); // should no happen } catch (InvalidKeyException ex) { throw Utils.newRuntimeError(runtime, ex); // TODO } } private static String mapDigestName(final String name) { final String mapped = name.toUpperCase(); if ( mapped.startsWith("SHA-") ) { // SHA-512 return "SHA" + mapped.substring(4); // SHA512 } return mapped; } private static RubyString generatePBEKey(final Ruby runtime, final char[] pass, final byte[] salt, final int iter, final int keySize) { PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(pass), salt, iter); CipherParameters params = generator.generateDerivedParameters(keySize * 8); return StringHelper.newString(runtime, ((KeyParameter) params).getKey()); } // http://stackoverflow.com/questions/9147463/java-pbkdf2-with-hmacsha256-as-the-prf public static byte[] deriveKey( final Mac prf, byte[] salt, int iterationCount, int dkLen ) throws NoSuchAlgorithmException, InvalidKeyException { // Note: hLen, dkLen, l, r, T, F, etc. are horrible names for // variables and functions in this day and age, but they // reflect the terse symbols used in RFC 2898 to describe // the PBKDF2 algorithm, which improves validation of the // code vs. the RFC. // // dklen is expressed in bytes. (16 for a 128-bit key) int hLen = prf.getMacLength(); // 20 for SHA1 int l = Math.max( dkLen, hLen); // 1 for 128bit (16-byte) keys int r = dkLen - (l-1)*hLen; // 16 for 128bit (16-byte) keys byte T[] = new byte[l * hLen]; int ti_offset = 0; for (int i = 1; i <= l; i++) { F( T, ti_offset, prf, salt, iterationCount, i ); ti_offset += hLen; } if (r < hLen) { // Incomplete last block byte DK[] = new byte[dkLen]; System.arraycopy(T, 0, DK, 0, dkLen); return DK; } return T; } private static void F( byte[] dest, int offset, Mac prf, byte[] S, int c, int blockIndex ) { final int hLen = prf.getMacLength(); byte U_r[] = new byte[ hLen ]; // U0 = S || INT (i); byte U_i[] = new byte[S.length + 4]; System.arraycopy( S, 0, U_i, 0, S.length ); doINT( U_i, S.length, blockIndex ); for( int i = 0; i < c; i++ ) { U_i = prf.doFinal( U_i ); doXOR( U_r, U_i ); } System.arraycopy( U_r, 0, dest, offset, hLen ); } private static void doXOR( byte[] dest, byte[] src ) { for( int i = 0; i < dest.length; i++ ) { dest[i] ^= src[i]; } } private static void doINT( byte[] dest, int offset, int i ) { dest[offset + 0] = (byte) (i / (256 * 256 * 256)); dest[offset + 1] = (byte) (i / (256 * 256)); dest[offset + 2] = (byte) (i / (256)); dest[offset + 3] = (byte) (i); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PKCS7.java000066400000000000000000000702041313661621600247620ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import org.bouncycastle.asn1.ASN1Encodable; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBignum; import org.jruby.RubyClass; import org.jruby.RubyFile; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.ext.openssl.impl.ASN1Registry; import org.jruby.ext.openssl.impl.BIO; import org.jruby.ext.openssl.impl.CipherSpec; import org.jruby.ext.openssl.impl.MemBIO; import org.jruby.ext.openssl.impl.Mime; import org.jruby.ext.openssl.impl.NotVerifiedPKCS7Exception; import org.jruby.ext.openssl.impl.PKCS7Exception; import org.jruby.ext.openssl.impl.RecipInfo; import org.jruby.ext.openssl.impl.SMIME; import org.jruby.ext.openssl.impl.SignerInfoWithPkey; import org.jruby.ext.openssl.x509store.PEMInputOutput; import org.jruby.ext.openssl.x509store.Store; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import static org.jruby.ext.openssl.OpenSSL.*; /** * @author Ola Bini */ @JRubyClass(name = "OpenSSL::PKCS7") public class PKCS7 extends RubyObject { private static final long serialVersionUID = -3925104500966826973L; private static ObjectAllocator PKCS7_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new PKCS7(runtime, klass); } }; public static void createPKCS7(final Ruby runtime, final RubyModule _OpenSSL) { RubyClass _PKCS7 = _OpenSSL.defineClassUnder("PKCS7", runtime.getObject(), PKCS7_ALLOCATOR); RubyClass _OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); _PKCS7.defineClassUnder("PKCS7Error", _OpenSSLError, _OpenSSLError.getAllocator()); _PKCS7.addReadWriteAttribute(runtime.getCurrentContext(), "data"); _PKCS7.addReadWriteAttribute(runtime.getCurrentContext(), "error_string"); _PKCS7.defineAnnotatedMethods(PKCS7.class); SignerInfo.createSignerInfo(runtime, _PKCS7); RecipientInfo.createRecipientInfo(runtime, _PKCS7); _PKCS7.setConstant("TEXT", runtime.newFixnum(1)); _PKCS7.setConstant("NOCERTS", runtime.newFixnum(2)); _PKCS7.setConstant("NOSIGS", runtime.newFixnum(4)); _PKCS7.setConstant("NOCHAIN", runtime.newFixnum(8)); _PKCS7.setConstant("NOINTERN", runtime.newFixnum(16)); _PKCS7.setConstant("NOVERIFY", runtime.newFixnum(32)); _PKCS7.setConstant("DETACHED", runtime.newFixnum(64)); _PKCS7.setConstant("BINARY", runtime.newFixnum(128)); _PKCS7.setConstant("NOATTR", runtime.newFixnum(256)); _PKCS7.setConstant("NOSMIMECAP", runtime.newFixnum(512)); } public static BIO obj2bio(IRubyObject obj) { if ( obj instanceof RubyFile ) { throw obj.getRuntime().newNotImplementedError("TODO: handle RubyFile correctly"); // if (TYPE(obj) == T_FILE) { // OpenFile *fptr; // GetOpenFile(obj, fptr); // rb_io_check_readable(fptr); // bio = BIO_new_fp(fptr->f, BIO_NOCLOSE); } else { final ByteList str = obj.asString().getByteList(); return BIO.memBuf(str.getUnsafeBytes(), str.getBegin(), str.getRealSize()); } } @Deprecated // no loger used public static PKCS7 wrap(RubyClass klass, org.jruby.ext.openssl.impl.PKCS7 p7) { PKCS7 wrapped = new PKCS7(klass.getRuntime(), klass); wrapped.p7 = p7; return wrapped; } private static PKCS7 wrap(final Ruby runtime, org.jruby.ext.openssl.impl.PKCS7 p7) { PKCS7 wrapped = new PKCS7(runtime, _PKCS7(runtime)); wrapped.p7 = p7; return wrapped; } public static IRubyObject membio2str(Ruby runtime, BIO bio) { return runtime.newString( new ByteList(((MemBIO) bio).getMemCopy(), false) ); } private static List getAuxCerts(final IRubyObject arg) { final RubyArray arr = (RubyArray) arg; List certs = new ArrayList(arr.size()); for ( int i = 0; i auxCerts = certs.isNil() ? null : getAuxCerts(certs); org.jruby.ext.openssl.impl.PKCS7 pkcs7Impl; try { pkcs7Impl = org.jruby.ext.openssl.impl.PKCS7.sign(auxCert, privKey, auxCerts, dataBIO, flg); } catch (PKCS7Exception e) { throw newPKCS7Error(runtime, e); } final PKCS7 pkcs7 = wrap(runtime, pkcs7Impl); pkcs7.setData(data); return pkcs7; } /** ossl_pkcs7_s_encrypt * */ @JRubyMethod(meta = true, rest = true) public static IRubyObject encrypt(IRubyObject self, IRubyObject[] args) { final Ruby runtime = self.getRuntime(); IRubyObject certs, data, cipher = runtime.getNil(), flags = runtime.getNil(); switch ( Arity.checkArgumentCount(self.getRuntime(), args, 2, 4) ) { case 4: flags = args[3]; case 3: cipher = args[2]; } data = args[1]; certs = args[0]; CipherSpec cipherSpec = null; if ( cipher.isNil() ) { try { javax.crypto.Cipher c = SecurityHelper.getCipher("RC2/CBC/PKCS5Padding"); cipherSpec = new CipherSpec(c, Cipher.Algorithm.javaToOssl("RC2/CBC/PKCS5Padding", 40), 40); } catch (GeneralSecurityException e) { throw newPKCS7Error(runtime, e); } } else { final Cipher c = (Cipher) cipher; cipherSpec = new CipherSpec(c.getCipherInstance(), c.getName(), c.getGenerateKeyLength() * 8); } final int flg = flags.isNil() ? 0 : RubyNumeric.fix2int(flags); final List auxCerts = getAuxCerts(certs); final byte[] dataBytes = data.asString().getBytes(); org.jruby.ext.openssl.impl.PKCS7 pkcs7Impl; try { pkcs7Impl = org.jruby.ext.openssl.impl.PKCS7.encrypt(auxCerts, dataBytes, cipherSpec, flg); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(self.getRuntime(), pkcs7e); } final PKCS7 pkcs7 = wrap(runtime, pkcs7Impl); pkcs7.setData(data); return pkcs7; } public PKCS7(Ruby runtime, RubyClass type) { super(runtime,type); } private org.jruby.ext.openssl.impl.PKCS7 p7; @JRubyMethod(name="initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject[] args) { if ( Arity.checkArgumentCount(getRuntime(), args, 0, 1) == 0 ) { p7 = new org.jruby.ext.openssl.impl.PKCS7(); try { p7.setType(ASN1Registry.NID_undef); } catch (PKCS7Exception e) { throw newPKCS7Error(getRuntime(), e); } return this; } IRubyObject arg = to_der_if_possible(context, args[0]); BIO input = obj2bio(arg); try { p7 = org.jruby.ext.openssl.impl.PKCS7.readPEM(input); if (p7 == null) { input.reset(); p7 = org.jruby.ext.openssl.impl.PKCS7.fromASN1(input); } } catch (IllegalArgumentException e) { throw getRuntime().newArgumentError(e.getMessage()); } catch (IOException ioe) { throw newPKCS7Error(getRuntime(), ioe.getMessage()); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } setData( getRuntime().getNil() ); return this; } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#initialize_copy"); return this; } @JRubyMethod(name="type=") public IRubyObject set_type(IRubyObject type) { final String typeStr = type.toString(); // likely a Symbol int typeId = ASN1Registry.NID_undef; if ("signed".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_signed; } else if ("data".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_data; } else if ("signedAndEnveloped".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_signedAndEnveloped; } else if ("enveloped".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_enveloped; } else if ("encrypted".equals(typeStr)) { typeId = ASN1Registry.NID_pkcs7_encrypted; } try { p7.setType(typeId); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } return type; } @JRubyMethod(name="type") public IRubyObject get_type() { if(p7.isSigned()) { return getRuntime().newSymbol("signed"); } if(p7.isEncrypted()) { return getRuntime().newSymbol("encrypted"); } if(p7.isEnveloped()) { return getRuntime().newSymbol("enveloped"); } if(p7.isSignedAndEnveloped()) { return getRuntime().newSymbol("signedAndEnveloped"); } if(p7.isData()) { return getRuntime().newSymbol("data"); } return getRuntime().getNil(); } @JRubyMethod(name = "detached") public IRubyObject detached() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#detached"); return getRuntime().getNil(); } @JRubyMethod(name = "detached=") public IRubyObject set_detached(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#detached="); return getRuntime().getNil(); } @JRubyMethod(name = "detached?") public IRubyObject detached_p() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#detached?"); return getRuntime().getNil(); } @JRubyMethod(name="cipher=") public IRubyObject set_cipher(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#cipher="); return getRuntime().getNil(); } @JRubyMethod public IRubyObject add_signer(IRubyObject obj) { SignerInfoWithPkey signedInfo = ((SignerInfo) obj).getSignerInfo().dup(); try { p7.addSigner(signedInfo); } catch (PKCS7Exception e) { throw newPKCS7Error(getRuntime(), e); } // TODO: Handle exception here if ( p7.isSigned() ) { ASN1Encodable objectId = org.jruby.ext.openssl.impl.PKCS7.OID_pkcs7_data; signedInfo.addSignedAttribute(ASN1Registry.NID_pkcs9_contentType, objectId); } return this; } /** ossl_pkcs7_get_signer * * This seems to return a list of SignerInfo objects. * */ @JRubyMethod public IRubyObject signers() { Collection signerInfos = p7.getSignerInfo(); RubyArray ary = getRuntime().newArray(signerInfos.size()); for ( SignerInfoWithPkey signerInfo : signerInfos ) { ary.append( SignerInfo.create(getRuntime(), signerInfo) ); } return ary; } @JRubyMethod public IRubyObject add_recipient(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#add_recipient"); return getRuntime().getNil(); } @JRubyMethod public IRubyObject recipients() { Collection sk; if(p7.isEnveloped()) { sk = p7.getEnveloped().getRecipientInfo(); } else if(p7.isSignedAndEnveloped()) { sk = p7.getSignedAndEnveloped().getRecipientInfo(); } else { sk = null; } if(sk == null) { return getRuntime().newArray(); } RubyArray ary = getRuntime().newArray(sk.size()); for(RecipInfo ri : sk) { ary.append(RecipientInfo.create(getRuntime(), ri)); } return ary; } @JRubyMethod public IRubyObject add_certificate(IRubyObject obj) { try { p7.addCertificate(((X509Cert)obj).getAuxCert()); } catch (PKCS7Exception pkcse) { throw newPKCS7Error(getRuntime(), pkcse); } return this; } @JRubyMethod(name="certificates=") public IRubyObject set_certificates(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#certificates="); return getRuntime().getNil(); } private Collection getCertificates() { Collection certs; int i = p7.getType(); switch(i) { case ASN1Registry.NID_pkcs7_signed: certs = p7.getSign().getCert(); break; case ASN1Registry.NID_pkcs7_signedAndEnveloped: certs = p7.getSignedAndEnveloped().getCert(); break; default: certs = new HashSet(); break; } return certs; } private RubyArray certsToArray(Collection certs) throws CertificateEncodingException { RubyArray ary = getRuntime().newArray(certs.size()); for(X509AuxCertificate x509 : certs) { ary.append(X509Cert.wrap(getRuntime(), x509)); } return ary; } @JRubyMethod public IRubyObject certificates() { try { return certsToArray(getCertificates()); } catch (CertificateEncodingException cee) { throw newPKCS7Error(getRuntime(), cee.getMessage()); } } @JRubyMethod public IRubyObject add_crl(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#add_crl"); return getRuntime().getNil(); } @JRubyMethod(name="crls=") public IRubyObject set_crls(IRubyObject obj) { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#crls="); return getRuntime().getNil(); } @JRubyMethod public IRubyObject crls() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: PKCS7#crls"); return getRuntime().getNil(); } @JRubyMethod(name={"add_data", "data="}) public IRubyObject add_data(IRubyObject obj) { if (p7.isSigned()) { try { p7.contentNew(ASN1Registry.NID_pkcs7_data); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } } BIO in = obj2bio(obj); BIO out = null; try { out = p7.dataInit(null); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } byte[] buf = new byte[4096]; for(;;) { try { int i = in.read(buf, 0, buf.length); if(i <= 0) { break; } if(out != null) { out.write(buf, 0, i); } } catch(IOException e) { throw getRuntime().newIOErrorFromException(e); } } try { p7.dataFinal(out); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } setData(getRuntime().getNil()); return obj; } @JRubyMethod(rest=true) public IRubyObject verify(IRubyObject[] args) { final Ruby runtime = getRuntime(); IRubyObject certs; X509Store store; IRubyObject indata = runtime.getNil(); IRubyObject vflags = runtime.getNil(); switch ( Arity.checkArgumentCount(runtime, args, 2, 4) ) { case 4: vflags = args[3]; case 3: indata = args[2]; default: store = (X509Store) args[1]; certs = args[0]; } final int flg = vflags.isNil() ? 0 : RubyNumeric.fix2int(vflags); if ( indata.isNil() ) indata = getData(); final BIO in = indata.isNil() ? null : obj2bio(indata); List x509s = certs.isNil() ? null : getAuxCerts(certs); final Store storeStr = store.getStore(); final BIO out = BIO.mem(); boolean result = false; try { p7.verify(x509s, storeStr, in, out, flg); result = true; } catch (NotVerifiedPKCS7Exception e) { // result = false; } catch (PKCS7Exception pkcs7e) { if ( isDebug(runtime) ) { // runtime.getOut().println(pkcs7e); pkcs7e.printStackTrace(runtime.getOut()); } // result = false; } IRubyObject data = membio2str(getRuntime(), out); setData(data); return result ? runtime.getTrue() : runtime.getFalse(); } @JRubyMethod(rest=true) public IRubyObject decrypt(IRubyObject[] args) { IRubyObject dflags; if ( Arity.checkArgumentCount(getRuntime(), args, 2, 3) == 3 ) { dflags = args[2]; } else { dflags = getRuntime().getNil(); } PKey pkey = (PKey) args[0]; X509Cert cert = (X509Cert) args[1]; final PrivateKey privKey = pkey.getPrivateKey(); final X509AuxCertificate auxCert = cert.getAuxCert(); final int flg = dflags.isNil() ? 0 : RubyNumeric.fix2int(dflags); final BIO out = BIO.mem(); try { p7.decrypt(privKey, auxCert, out, flg); } catch (PKCS7Exception pkcs7e) { throw newPKCS7Error(getRuntime(), pkcs7e); } return membio2str(getRuntime(), out); } @JRubyMethod(name = {"to_pem", "to_s"}) public IRubyObject to_pem() { StringWriter writer = new StringWriter(); try { PEMInputOutput.writePKCS7(writer, p7.toASN1()); return getRuntime().newString( writer.toString() ); } catch (IOException e) { throw getRuntime().newIOErrorFromException(e); } } @JRubyMethod public IRubyObject to_der() { try { return getRuntime().newString(new ByteList(p7.toASN1(), false)); } catch (IOException e) { throw newPKCS7Error(getRuntime(), e.getMessage()); } } public void setData(IRubyObject object) { setInstanceVariable("@data", object); } public IRubyObject getData() { return getInstanceVariable("@data"); } @JRubyClass(name = "OpenSSL::PKCS7::SignerInfo") public static class SignerInfo extends RubyObject { private static final long serialVersionUID = -3799397032272738848L; private static ObjectAllocator SIGNERINFO_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new SignerInfo(runtime, klass); } }; public static void createSignerInfo(final Ruby runtime, final RubyModule _PKCS7) { RubyClass _SignerInfo = _PKCS7.defineClassUnder("SignerInfo", runtime.getObject(), SIGNERINFO_ALLOCATOR); _PKCS7.defineConstant("Signer",_SignerInfo); _SignerInfo.defineAnnotatedMethods(SignerInfo.class); } private static RubyClass _SignerInfo(final Ruby runtime) { return _PKCS7(runtime).getClass("SignerInfo"); } public static SignerInfo create(Ruby runtime, SignerInfoWithPkey info) { SignerInfo instance = new SignerInfo(runtime, _SignerInfo(runtime)); instance.info = info; return instance; } public SignerInfo(Ruby runtime, RubyClass type) { super(runtime,type); } private SignerInfoWithPkey info; SignerInfoWithPkey getSignerInfo() { return info; } @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3) { warn(context, "WARNING: unimplemented method called: signerInfo#initialize"); return this; } @JRubyMethod(name={"issuer","name"}) public IRubyObject issuer() { return X509Name.newName(getRuntime(), info.getIssuerAndSerialNumber().getName()); } @JRubyMethod public IRubyObject serial() { return RubyBignum.bignorm(getRuntime(), info.getIssuerAndSerialNumber().getCertificateSerialNumber().getValue()); } @JRubyMethod public IRubyObject signed_time(final ThreadContext context) { warn(context, "WARNING: unimplemented method called: signerInfo#signed_time"); return context.runtime.getNil(); } } @JRubyClass(name = "OpenSSL::PKCS7::RecipientInfo") public static class RecipientInfo extends RubyObject { private static final long serialVersionUID = 6977793206950149902L; private static ObjectAllocator RECIPIENTINFO_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new RecipientInfo(runtime, klass); } }; public static void createRecipientInfo(final Ruby runtime, final RubyModule _PKCS7) { RubyClass _Recipient = _PKCS7.defineClassUnder("RecipientInfo", runtime.getObject(), RECIPIENTINFO_ALLOCATOR); _Recipient.defineAnnotatedMethods(RecipientInfo.class); } private static RubyClass _RecipientInfo(final Ruby runtime) { return _PKCS7(runtime).getClass("RecipientInfo"); } public RecipientInfo(Ruby runtime, RubyClass type) { super(runtime, type); } public static RecipientInfo create(Ruby runtime, RecipInfo info) { RecipientInfo instance = new RecipientInfo(runtime, _RecipientInfo(runtime)); instance.info = info; return instance; } private RecipInfo info; @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject arg) { warn(context, "WARNING: unimplemented method called: recipientInfo#initialize"); return this; } @JRubyMethod public IRubyObject issuer() { return X509Name.newName(getRuntime(), info.getIssuerAndSerial().getName()); } @JRubyMethod public IRubyObject serial() { return RubyBignum.bignorm(getRuntime(), info.getIssuerAndSerial().getCertificateSerialNumber().getValue()); } @JRubyMethod public IRubyObject enc_key(final ThreadContext context) { warn(context, "WARNING: unimplemented method called: recipientInfo#enc_key"); return context.runtime.getNil(); } } private static RaiseException newPKCS7Error(Ruby runtime, Exception e) { return Utils.newError(runtime, _PKCS7(runtime).getClass("PKCS7Error"), e); } private static RaiseException newPKCS7Error(Ruby runtime, String message) { return Utils.newError(runtime, _PKCS7(runtime).getClass("PKCS7Error"), message); } static RubyClass _PKCS7(final Ruby runtime) { return (RubyClass) runtime.getModule("OpenSSL").getConstant("PKCS7"); } }// PKCS7 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PKey.java000066400000000000000000000424701313661621600250070ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; import java.math.BigInteger; import java.security.*; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import org.jruby.ext.openssl.x509store.PEMInputOutput; import static org.jruby.ext.openssl.OpenSSL.*; import org.jruby.ext.openssl.impl.CipherSpec; import org.jruby.util.ByteList; /** * @author Ola Bini */ public abstract class PKey extends RubyObject { private static final long serialVersionUID = 6114668087816965720L; public static void createPKey(final Ruby runtime, final RubyModule OpenSSL) { final RubyModule PKey = OpenSSL.defineModuleUnder("PKey"); PKey.defineAnnotatedMethods(PKeyModule.class); // PKey is abstract RubyClass PKeyPKey = PKey.defineClassUnder("PKey", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR); RubyClass OpenSSLError = OpenSSL.getClass("OpenSSLError"); PKey.defineClassUnder("PKeyError", OpenSSLError, OpenSSLError.getAllocator()); PKeyPKey.defineAnnotatedMethods(PKey.class); PKeyRSA.createPKeyRSA(runtime, PKey, PKeyPKey); PKeyDSA.createPKeyDSA(runtime, PKey, PKeyPKey); PKeyDH.createPKeyDH(runtime, PKey, PKeyPKey); PKeyEC.createPKeyEC(runtime, PKey, PKeyPKey); } public static RaiseException newPKeyError(Ruby runtime, String message) { return Utils.newError(runtime, _PKey(runtime).getClass("PKeyError"), message); } static RubyModule _PKey(final Ruby runtime) { return (RubyModule) runtime.getModule("OpenSSL").getConstantAt("PKey"); } public static class PKeyModule { @JRubyMethod(name = "read", meta = true, required = 1, optional = 1) public static IRubyObject read(final ThreadContext context, IRubyObject recv, IRubyObject[] args) { final Ruby runtime = context.runtime; final IRubyObject data; final char[] pass; switch (args.length) { case 1: data = args[0]; pass = null; break; default: data = args[0]; pass = args[1].isNil() ? null : args[1].toString().toCharArray(); } final byte[] input = StringHelper.readX509PEM(context, data); KeyPair key = null; // d2i_PrivateKey_bio try { key =org.jruby.ext.openssl.impl.PKey.readPrivateKey(input); } catch (IOException ioe) { // ignore } catch (GeneralSecurityException gse) { // ignore } // PEM_read_bio_PrivateKey if (key == null) { try { key = PEMInputOutput.readPrivateKey(new InputStreamReader(new ByteArrayInputStream(input)), pass); } catch (IOException ioe) { // ignore } } if (key != null) { final String alg = getAlgorithm(key); if ( "RSA".equals(alg) ) { return new PKeyRSA(runtime, _PKey(runtime).getClass("RSA"), (RSAPrivateCrtKey) key.getPrivate(), (RSAPublicKey) key.getPublic() ); } if ( "DSA".equals(alg) ) { return new PKeyDSA(runtime, _PKey(runtime).getClass("DSA"), (DSAPrivateKey) key.getPrivate(), (DSAPublicKey) key.getPublic() ); } if ( "ECDSA".equals(alg) ) { return new PKeyEC(runtime, _PKey(runtime).getClass("EC"), (PrivateKey) key.getPrivate(), (PublicKey) key.getPublic() ); } } PublicKey pubKey = null; // d2i_PUBKEY_bio try { pubKey = org.jruby.ext.openssl.impl.PKey.readPublicKey(input); } catch (IOException ioe) { // ignore } catch (GeneralSecurityException gse) { // ignore } // PEM_read_bio_PUBKEY if (pubKey == null) { try { pubKey = PEMInputOutput.readPubKey(new InputStreamReader(new ByteArrayInputStream(input))); } catch (IOException ioe) { // ignore } } if (pubKey != null) { if ( "RSA".equals(pubKey.getAlgorithm()) ) { return new PKeyRSA(runtime, (RSAPublicKey) pubKey); } if ( "DSA".equals(pubKey.getAlgorithm()) ) { return new PKeyDSA(runtime, (DSAPublicKey) pubKey); } if ( "ECDSA".equals(pubKey.getAlgorithm()) ) { return new PKeyEC(runtime, pubKey); } } throw runtime.newArgumentError("Could not parse PKey"); } private static String getAlgorithm(final KeyPair key) { if ( key.getPrivate() != null ) return key.getPrivate().getAlgorithm(); if ( key.getPublic() != null ) return key.getPublic().getAlgorithm(); return null; } } public PKey(Ruby runtime, RubyClass type) { super(runtime,type); } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(ThreadContext context) { return this; } public abstract PublicKey getPublicKey() ; public abstract PrivateKey getPrivateKey() ; public String getAlgorithm() { return "NONE"; } public boolean isPrivateKey() { return getPrivateKey() != null; } public abstract RubyString to_der() ; public abstract RubyString to_pem(final IRubyObject[] args) ; @Deprecated public RubyString export(final IRubyObject[] args) { return to_pem(args); } @JRubyMethod(name = "sign") public IRubyObject sign(IRubyObject digest, IRubyObject data) { final Ruby runtime = getRuntime(); if ( ! isPrivateKey() ) throw runtime.newArgumentError("Private key is needed."); String digAlg = (digest instanceof Digest) ? ((Digest) digest).getShortAlgorithm() : digest.asJavaString(); try { ByteList sign = sign(digAlg + "WITH" + getAlgorithm(), getPrivateKey(), data.convertToString().getByteList()); return RubyString.newString(runtime, sign); } catch (GeneralSecurityException ex) { throw newPKeyError(runtime, ex.getMessage()); } } static ByteList sign(final String signAlg, final PrivateKey privateKey, final ByteList data) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature signature = SecurityHelper.getSignature(signAlg); signature.initSign( privateKey ); signature.update( data.getUnsafeBytes(), data.getBegin(), data.getRealSize() ); return new ByteList(signature.sign(), false); } @JRubyMethod(name = "verify") public IRubyObject verify(IRubyObject digest, IRubyObject sign, IRubyObject data) { final Ruby runtime = getRuntime(); ByteList sigBytes = convertToString(runtime, sign, "OpenSSL::PKey::PKeyError", "invalid signature").getByteList(); ByteList dataBytes = convertToString(runtime, data, "OpenSSL::PKey::PKeyError", "invalid data").getByteList(); String digAlg = (digest instanceof Digest) ? ((Digest) digest).getShortAlgorithm() : digest.asJavaString(); final String algorithm = digAlg + "WITH" + getAlgorithm(); try { return runtime.newBoolean( verify(algorithm, getPublicKey(), dataBytes, sigBytes) ); } catch (NoSuchAlgorithmException e) { throw newPKeyError(runtime, "unsupported algorithm: " + algorithm); } catch (SignatureException e) { throw newPKeyError(runtime, "invalid signature"); } catch (InvalidKeyException e) { throw newPKeyError(runtime, "invalid key"); } } static RubyString convertToString(final Ruby runtime, final IRubyObject str, final String errorType, final CharSequence errorMsg) { try { return str.convertToString(); } catch (RaiseException ex) { // to_str conversion failed throw Utils.newError(runtime, (RubyClass) runtime.getClassFromPath(errorType), errorMsg == null ? null : errorMsg.toString()); } } static boolean verify(final String signAlg, final PublicKey publicKey, final ByteList data, final ByteList sign) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature signature = SecurityHelper.getSignature(signAlg); signature.initVerify(publicKey); signature.update(data.getUnsafeBytes(), data.getBegin(), data.getRealSize()); return signature.verify(sign.getUnsafeBytes(), sign.getBegin(), sign.getRealSize()); } static SecureRandom getSecureRandom(final Ruby runtime) { return OpenSSL.getSecureRandom(runtime); } // shared Helpers for PKeyRSA / PKEyDSA : protected PrivateKey tryPKCS8EncodedKey(final Ruby runtime, final KeyFactory keyFactory, final byte[] encodedKey) { try { return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey)); } catch (InvalidKeySpecException e) { if ( isDebug(runtime) ) { debug(runtime, getClass().getSimpleName() + " could not generate (PKCS8) private key", e); } } catch (RuntimeException e) { if ( isKeyGenerationFailure(e) ) { if( isDebug(runtime) ) { debug(runtime, getClass().getSimpleName() + " could not generate (PKCS8) private key", e); } } else debugStackTrace(runtime, e); } return null; } protected static boolean isKeyGenerationFailure(final RuntimeException e) { // NOTE handle "common-failure" more gently (no need for stack trace) : // java.lang.ClassCastException: org.bouncycastle.asn1.DLSequence cannot be cast to org.bouncycastle.asn1.ASN1Integer // at org.bouncycastle.asn1.pkcs.PrivateKeyInfo.(Unknown Source) // at org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(Unknown Source) // at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePrivate(Unknown Source) // at org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyFactorySpi.engineGeneratePrivate(Unknown Source) // at java.security.KeyFactory.generatePrivate(KeyFactory.java:366) if ( e instanceof ClassCastException ) { // RSA : final String msg = e.getMessage(); if ( msg != null && msg.contains("DLSequence cannot be cast to") ) { return true; } } return false; } protected PublicKey tryX509EncodedKey(final Ruby runtime, final KeyFactory keyFactory, final byte[] encodedKey) { try { return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); } catch (InvalidKeySpecException e) { if ( isDebug(runtime) ) { debug(runtime, getClass().getSimpleName() + " could not generate (X509) public key", e); } } catch (RuntimeException e) { if ( isKeyGenerationFailure(e) ) { // NOTE: not (yet) detected with X.509 if( isDebug(runtime) ) { debug(runtime, getClass().getSimpleName() + " could not generate (X509) public key", e); } } else debugStackTrace(runtime, e); } return null; } protected static void addSplittedAndFormatted(StringBuilder result, BigInteger value) { String v = value.toString(16); if ((v.length() % 2) != 0) { v = "0" + v; } String sep = ""; for (int i = 0; i < v.length(); i += 2) { result.append(sep); if ((i % 30) == 0) { result.append("\n "); } result.append(v.substring(i, i + 2)); sep = ":"; } result.append("\n"); } protected static CipherSpec cipherSpec(final IRubyObject cipher) { if ( cipher != null && ! cipher.isNil() ) { final Cipher c = (Cipher) cipher; return new CipherSpec(c.getCipherInstance(), c.getName(), c.getKeyLength() * 8); } return null; } protected static char[] password(final IRubyObject pass) { if ( pass != null && ! pass.isNil() ) { return pass.toString().toCharArray(); } return null; } protected static char[] passwordPrompt(final ThreadContext context) { return passwordPrompt(context, "Enter PEM pass phrase:"); } protected static char[] passwordPrompt(final ThreadContext context, final String prompt) { final RubyModule Kernel = context.runtime.getKernel(); // NOTE: just a fast and simple print && gets - hopefully better than nothing! Kernel.callMethod("print", context.runtime.newString(prompt)); final RubyString gets = Kernel.callMethod(context, "gets").convertToString(); gets.chomp_bang(context); return gets.toString().toCharArray(); } protected static boolean ttySTDIN(final ThreadContext context) { final IRubyObject stdin = context.runtime.getGlobalVariables().get("$stdin"); if ( stdin == null || stdin.isNil() ) return false; try { final IRubyObject tty = stdin.callMethod(context, "tty?"); return ! tty.isNil() && ! ( tty == context.runtime.getFalse() ); } catch (RaiseException ex) { return false; } } static Object readPrivateKey(final String str, final char[] passwd) throws PEMInputOutput.PasswordRequiredException, IOException { return PEMInputOutput.readPrivateKey(new StringReader(str), passwd); } static Object readPrivateKey(final RubyString str, final char[] passwd) throws PEMInputOutput.PasswordRequiredException, IOException { return readPrivateKey(str.toString(), passwd); } protected static RubyString readInitArg(final ThreadContext context, IRubyObject arg) { return StringHelper.readPossibleDERInput(context, arg); } static void supportedSignatureAlgorithm(final Ruby runtime, final RubyClass errorClass, final PKey key, final Digest digest) { // Have to obey some artificial constraints of the OpenSSL implementation. Stupid. final String keyAlg = key.getAlgorithm(); final String digAlg = digest.getShortAlgorithm(); if ( ( "DSA".equalsIgnoreCase(keyAlg) && "MD5".equalsIgnoreCase(digAlg)) || ( "RSA".equalsIgnoreCase(keyAlg) && "DSS1".equals( digest.name().toString() ) ) ) { throw Utils.newError(runtime, errorClass, "unsupported key / digest algorithm ( "+ keyAlg +" / "+ digAlg +" )"); } } static void supportedSignatureAlgorithm(final Ruby runtime, final PKey key, final Digest digest) { supportedSignatureAlgorithm(runtime, _OpenSSLError(runtime), key, digest); } }// PKey jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PKeyDH.java000066400000000000000000000373231313661621600252240ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2007 William N Dortch * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.util.HashMap; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPrivateKeySpec; import javax.crypto.spec.DHPublicKeySpec; import org.jruby.Ruby; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyHash; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.x509store.PEMInputOutput; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.runtime.Visibility; import static org.jruby.ext.openssl.OpenSSL.bcExceptionMessage; /** * OpenSSL::PKey::DH implementation. * * @author Bill Dortch */ public class PKeyDH extends PKey { private static final long serialVersionUID = -1893518804744046740L; private static final BigInteger TWO = BN.TWO; // from [ossl]/crypto/dh/dh.h private static final int OPENSSL_DH_MAX_MODULUS_BITS = 10000; private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public PKeyDH allocate(Ruby runtime, RubyClass klass) { return new PKeyDH(runtime, klass); } }; public static void createPKeyDH(final Ruby runtime, final RubyModule PKey, final RubyClass PKeyPKey) { RubyClass DH = PKey.defineClassUnder("DH", PKeyPKey, ALLOCATOR); RubyClass PKeyError = PKey.getClass("PKeyError"); PKey.defineClassUnder("DHError", PKeyError, PKeyError.getAllocator()); DH.defineAnnotatedMethods(PKeyDH.class); } public static RaiseException newDHError(Ruby runtime, String message) { return Utils.newError(runtime, _PKey(runtime).getClass("DHError"), message); } // transient because: we do not want these value serialized (insecure) // volatile because: permits unsynchronized reads in some cases private transient volatile BigInteger dh_p; private transient volatile BigInteger dh_g; private transient volatile BigInteger dh_y; private transient volatile BigInteger dh_x; // FIXME! need to figure out what it means in MRI/OSSL code to // claim a DH is(/has) private if an engine is present -- doesn't really // map to Java implementation. //private volatile boolean haveEngine; public PKeyDH(Ruby runtime, RubyClass clazz) { super(runtime, clazz); } @Override public IRubyObject initialize_copy(final IRubyObject original) { if (this == original) return this; checkFrozen(); final PKeyDH that = (PKeyDH) original; this.dh_p = that.dh_p; this.dh_g = that.dh_g; this.dh_y = that.dh_y; this.dh_x = that.dh_x; return this; } @JRubyMethod(name="initialize", rest=true, visibility = Visibility.PRIVATE) public synchronized IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; if (this.dh_p != null || this.dh_g != null || this.dh_y != null || this.dh_x != null) { throw newDHError(runtime, "illegal initialization"); } final int argc = Arity.checkArgumentCount(runtime, args, 0, 2); if ( argc > 0 ) { IRubyObject arg0 = args[0]; if ( argc == 1 && arg0 instanceof RubyString ) { try { DHParameterSpec spec = PEMInputOutput.readDHParameters(new StringReader(arg0.toString())); if (spec == null) { spec = org.jruby.ext.openssl.impl.PKey.readDHParameter(arg0.asString().getByteList().bytes()); } if (spec == null) { throw runtime.newArgumentError("invalid DH PARAMETERS"); } this.dh_p = spec.getP(); this.dh_g = spec.getG(); } catch (NoClassDefFoundError e) { throw newDHError(runtime, bcExceptionMessage(e)); } catch (IOException e) { throw runtime.newIOErrorFromException(e); } } else { int bits = RubyNumeric.fix2int(arg0); // g defaults to 2 int gval = argc == 2 ? RubyNumeric.fix2int(args[1]) : 2; BigInteger p; try { p = generateP(bits, gval); } catch(IllegalArgumentException e) { throw runtime.newArgumentError(e.getMessage()); } BigInteger g = BigInteger.valueOf(gval); BigInteger x = generateX(p); BigInteger y = generateY(p, g, x); this.dh_p = p; this.dh_g = g; this.dh_x = x; // private key this.dh_y = y; // public key } } return this; } public static BigInteger generateP(int bits, int g) { // FIXME? I'm following algorithms used in OpenSSL, could use JCE provider instead. // (Note that I tried that, but got mystifying values of g returned by the param generator. // In any case, in OpenSSL/MRI-OpenSSL, the caller supplies g, or it defaults to 2.) // see [ossl]/crypto/dh/dh_gen.c #dh_builtin_genparams if (bits < 2) throw new IllegalArgumentException("invalid bit length"); if (g < 2) throw new IllegalArgumentException("invalid generator"); // generate safe prime meeting appropriate add/rem (mod) criteria switch (g) { // parameters used in generating 'p'; see [ossl]/crypto/dh/dh_gen.c #dh_builtin_genparams case 2 : // add = 24, rem = 11 return BN.generatePrime(bits, true, BigInteger.valueOf(24), BigInteger.valueOf(11)); case 5 : // add = 10, rem = 3 return BN.generatePrime(bits, true, BigInteger.valueOf(10), BigInteger.valueOf(3)); default: // add = 2, rem = 1 return BN.generatePrime(bits, true, TWO, BigInteger.ONE); } } public static BigInteger generateX(BigInteger p, int limit) { if (limit < 0) throw new IllegalArgumentException("invalid limit"); BigInteger x; SecureRandom secureRandom = new SecureRandom(); // adapting algorithm from org.bouncycastle.crypto.generators.DHKeyGeneratorHelper, // which seems a little stronger (?) than OpenSSL's (OSSL just generates a random, // while BC generates a random potential prime [for limit > 0], though it's not // subject to Miller-Rabin [certainty = 0], but is subject to other constraints) // see also [ossl]/crypto/dh/dh_key.c #generate_key if (limit == 0) { final BigInteger pSub2 = p.subtract(TWO); do { x = BN.randomIntegerInRange(pSub2, secureRandom); } while (x.equals(BigInteger.ZERO)); } else { do { // generate potential prime, though with 0 certainty (no Miller-Rabin tests) x = new BigInteger(limit, 0, secureRandom); } while (x.equals(BigInteger.ZERO)); } return x; } public static BigInteger generateX(BigInteger p) { // OpenSSL default l(imit) is p bits - 1 -- see [ossl]/crypto/dh/dh_key.c #generate_key return generateX(p, p.bitLength() - 1); } public static BigInteger generateY(BigInteger p, BigInteger g, BigInteger x) { return g.modPow(x, p); } public static BigInteger generateY(BigInteger p, int g, BigInteger x) { return generateY(p, BigInteger.valueOf(g), x); } @JRubyMethod(name = "generate_key!") public synchronized IRubyObject generate_key() { BigInteger p, g, x, y; if ((p = this.dh_p) == null || (g = this.dh_g) == null) { throw newDHError(getRuntime(), "can't generate key"); } if ((x = this.dh_x) == null) { x = generateX(p); } y = generateY(p, g, x); this.dh_x = x; this.dh_y = y; return this; } @JRubyMethod(name = "compute_key") public synchronized IRubyObject compute_key(IRubyObject other_pub_key) { BigInteger x, y, p; if ((y = BN.asBigInteger(other_pub_key)) == null) { throw getRuntime().newArgumentError("invalid public key"); } if ((x = this.dh_x) == null || (p = this.dh_p) == null) { throw newDHError(getRuntime(), "incomplete DH"); } int plen; if ((plen = p.bitLength()) == 0 || plen > OPENSSL_DH_MAX_MODULUS_BITS) { throw newDHError(getRuntime(), "can't compute key"); } return getRuntime().newString(new ByteList(computeKey(y, x, p), false)); } public static byte[] computeKey(BigInteger y, BigInteger x, BigInteger p) { return y.modPow(x, p).toByteArray(); } @JRubyMethod(name = "public?") public RubyBoolean public_p() { return getRuntime().newBoolean(dh_y != null); } @Override public boolean isPrivateKey() { return dh_x != null /* || haveEngine */; } @JRubyMethod(name = "private?") public RubyBoolean private_p() { // FIXME! need to figure out what it means in MRI/OSSL code to // claim a DH is private if an engine is present -- doesn't really // map to Java implementation. return getRuntime().newBoolean(isPrivateKey()); } @Override @JRubyMethod(name = { "to_pem", "to_s" }, alias = "export", rest = true) public RubyString to_pem(final IRubyObject[] args) { //Arity.checkArgumentCount(getRuntime(), args, 0, 2); //CipherSpec spec = null; char[] passwd = null; //if ( args.length > 0 ) { // spec = cipherSpec( args[0] ); // if ( args.length > 1 ) passwd = password(args[1]); //} BigInteger p, g; synchronized(this) { p = this.dh_p; g = this.dh_g; } final StringWriter writer = new StringWriter(); try { PEMInputOutput.writeDHParameters(writer, new DHParameterSpec(p, g)); } catch (NoClassDefFoundError e) { throw newDHError(getRuntime(), bcExceptionMessage(e)); } catch (IOException e) { // shouldn't happen (string/buffer io only) throw getRuntime().newIOErrorFromException(e); } return RubyString.newString(getRuntime(), writer.getBuffer()); } @Override @JRubyMethod(name = "to_der") public RubyString to_der() { BigInteger p, g; synchronized (this) { p = this.dh_p; g = this.dh_g; } try { byte[] bytes = org.jruby.ext.openssl.impl.PKey.toDerDHKey(p, g); return StringHelper.newString(getRuntime(), bytes); } catch (NoClassDefFoundError e) { throw newDHError(getRuntime(), bcExceptionMessage(e)); } catch (IOException ioe) { throw newDHError(getRuntime(), ioe.getMessage()); } } @JRubyMethod(name = "params") public IRubyObject params() { BigInteger p, g, x, y; synchronized(this) { p = this.dh_p; g = this.dh_g; x = this.dh_x; y = this.dh_y; } final Ruby runtime = getRuntime(); HashMap params = new HashMap(); params.put(runtime.newString("p"), BN.newBN(runtime, p)); params.put(runtime.newString("g"), BN.newBN(runtime, g)); params.put(runtime.newString("pub_key"), BN.newBN(runtime, x)); params.put(runtime.newString("priv_key"), BN.newBN(runtime, y)); return RubyHash.newHash(runtime, params, runtime.getNil()); } // don't need synchronized as value is volatile @JRubyMethod(name = "p") public IRubyObject get_p() { return newBN(dh_p); } @JRubyMethod(name = "p=") public synchronized IRubyObject set_p(IRubyObject arg) { this.dh_p = BN.asBigInteger(arg); return arg; } // don't need synchronized as value is volatile @JRubyMethod(name = "g") public IRubyObject get_g() { return newBN(dh_g); } @JRubyMethod(name = "g=") public synchronized IRubyObject set_g(IRubyObject arg) { this.dh_g = BN.asBigInteger(arg); return arg; } // don't need synchronized as value is volatile @JRubyMethod(name = "pub_key") public IRubyObject pub_key() { return newBN(dh_y); } @Override public PublicKey getPublicKey() { try { return getKeyFactory().generatePublic(new DHPublicKeySpec(dh_y, dh_p, dh_g)); } catch (InvalidKeySpecException ex) { throw new RuntimeException(ex); } } @JRubyMethod(name = "pub_key=") public synchronized IRubyObject set_pub_key(IRubyObject arg) { this.dh_y = BN.asBigInteger(arg); return arg; } // don't need synchronized as value is volatile @JRubyMethod(name = "priv_key") public IRubyObject priv_key() { return newBN(dh_x); } @Override public PrivateKey getPrivateKey() { try { return getKeyFactory().generatePrivate(new DHPrivateKeySpec(dh_x, dh_p, dh_g)); } catch (InvalidKeySpecException ex) { throw new RuntimeException(ex); } } @JRubyMethod(name = "priv_key=") public synchronized IRubyObject set_priv_key(IRubyObject arg) { this.dh_x = BN.asBigInteger(arg); return arg; } private IRubyObject newBN(BigInteger value) { if (value == null) return getRuntime().getNil(); return BN.newBN(getRuntime(), value); } private static KeyFactory getKeyFactory() { try { return SecurityHelper.getKeyFactory("DiffieHellman"); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException(ex); } } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PKeyDSA.java000066400000000000000000000525751313661621600253460ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * Copyright (C) 2007 Wiliam N Dortch * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.security.*; import java.security.interfaces.DSAKey; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.InvalidKeySpecException; import org.jruby.Ruby; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.impl.CipherSpec; import org.jruby.ext.openssl.x509store.PEMInputOutput; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.util.ByteList; import static org.jruby.ext.openssl.OpenSSL.*; import static org.jruby.ext.openssl.impl.PKey.readDSAPrivateKey; import static org.jruby.ext.openssl.impl.PKey.readDSAPublicKey; import static org.jruby.ext.openssl.impl.PKey.toDerDSAKey; import static org.jruby.ext.openssl.PKey._PKey; /** * @author Ola Bini */ public class PKeyDSA extends PKey { private static final long serialVersionUID = 6351851846414049890L; private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public PKeyDSA allocate(Ruby runtime, RubyClass klass) { return new PKeyDSA(runtime, klass); } }; public static void createPKeyDSA(final Ruby runtime, final RubyModule PKey, final RubyClass PKeyPKey) { RubyClass DSA = PKey.defineClassUnder("DSA", PKeyPKey, ALLOCATOR); RubyClass PKeyError = PKey.getClass("PKeyError"); PKey.defineClassUnder("DSAError", PKeyError, PKeyError.getAllocator()); DSA.defineAnnotatedMethods(PKeyDSA.class); } static RubyClass _DSA(final Ruby runtime) { return _PKey(runtime).getClass("DSA"); } public PKeyDSA(Ruby runtime, RubyClass type) { super(runtime, type); } public PKeyDSA(Ruby runtime, RubyClass type, DSAPrivateKey privKey, DSAPublicKey pubKey) { super(runtime, type); this.privateKey = privKey; this.publicKey = pubKey; } PKeyDSA(Ruby runtime, DSAPublicKey pubKey) { this(runtime, _DSA(runtime), null, pubKey); } private volatile DSAPublicKey publicKey; private volatile transient DSAPrivateKey privateKey; // specValues holds individual DSAPublicKeySpec components. this allows // a public key to be constructed incrementally, as required by the // current implementation of Net::SSH. // (see net-ssh-1.1.2/lib/net/ssh/transport/ossl/buffer.rb #read_keyblob) private transient volatile BigInteger dsa_x; private transient volatile BigInteger dsa_y; private transient volatile BigInteger dsa_p; private transient volatile BigInteger dsa_q; private transient volatile BigInteger dsa_g; @Override public IRubyObject initialize_copy(final IRubyObject original) { if (this == original) return this; checkFrozen(); final PKeyDSA that = (PKeyDSA) original; this.publicKey = that.publicKey; this.privateKey = that.privateKey; this.dsa_x = that.dsa_x; this.dsa_y = that.dsa_y; this.dsa_p = that.dsa_p; this.dsa_q = that.dsa_q; this.dsa_g = that.dsa_g; return this; } @Override public PublicKey getPublicKey() { return publicKey; } @Override public PrivateKey getPrivateKey() { return privateKey; } @Override public String getAlgorithm() { return "DSA"; } @JRubyMethod(name = "generate", meta = true) public static IRubyObject generate(IRubyObject self, IRubyObject arg) { final Ruby runtime = self.getRuntime(); final int keySize = RubyNumeric.fix2int(arg); return dsaGenerate(runtime, new PKeyDSA(runtime, (RubyClass) self), keySize); } /* * c: dsa_generate */ private static PKeyDSA dsaGenerate(final Ruby runtime, PKeyDSA dsa, int keySize) throws RaiseException { try { KeyPairGenerator gen = SecurityHelper.getKeyPairGenerator("DSA"); gen.initialize(keySize, getSecureRandom(runtime)); KeyPair pair = gen.generateKeyPair(); dsa.privateKey = (DSAPrivateKey) pair.getPrivate(); dsa.publicKey = (DSAPublicKey) pair.getPublic(); return dsa; } catch (NoSuchAlgorithmException e) { throw newDSAError(runtime, e.getMessage()); } catch (RuntimeException e) { throw newDSAError(runtime, e.getMessage(), e); } } static PKeyDSA newInstance(final Ruby runtime, final PublicKey publicKey) { //if ( publicKey instanceof DSAPublicKey ) { return new PKeyDSA(runtime, (DSAPublicKey) publicKey); //} } @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; if ( Arity.checkArgumentCount(runtime, args, 0, 2) == 0 ) { this.privateKey = null; this.publicKey = null; return this; } IRubyObject arg = args[0]; IRubyObject pass = null; if ( args.length > 1 ) pass = args[1]; if ( arg instanceof RubyFixnum ) { int keySize = RubyNumeric.fix2int((RubyFixnum) arg); return dsaGenerate(context.runtime, this, keySize); } final char[] passwd = password(pass); final RubyString str = readInitArg(context, arg); final String strJava = str.toString(); Object key = null; final KeyFactory dsaFactory; try { dsaFactory = SecurityHelper.getKeyFactory("DSA"); } catch (NoSuchAlgorithmException e) { throw runtime.newRuntimeError("unsupported key algorithm (DSA)"); } catch (RuntimeException e) { throw runtime.newRuntimeError("unsupported key algorithm (DSA) " + e); } // TODO: ugly NoClassDefFoundError catching for no BC env. How can we remove this? boolean noClassDef = false; if ( key == null && ! noClassDef ) { // PEM_read_bio_DSAPrivateKey try { key = readPrivateKey(strJava, passwd); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (PEMInputOutput.PasswordRequiredException retry) { if ( ttySTDIN(context) ) { try { key = readPrivateKey(strJava, passwordPrompt(context)); } catch (Exception e) { debugStackTrace(runtime, e); } } } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { // PEM_read_bio_DSAPublicKey try { key = PEMInputOutput.readDSAPublicKey(new StringReader(strJava), passwd); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { // PEM_read_bio_DSA_PUBKEY try { key = PEMInputOutput.readDSAPubKey(new StringReader(strJava)); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { // d2i_DSAPrivateKey_bio try { key = readDSAPrivateKey(dsaFactory, str.getBytes()); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (InvalidKeySpecException e) { debug(runtime, "PKeyDSA could not read private key", e); } catch (IOException e) { debug(runtime, "PKeyDSA could not read private key", e); } catch (RuntimeException e) { if ( isKeyGenerationFailure(e) ) debug(runtime, "PKeyDSA could not read private key", e); else debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { // d2i_DSA_PUBKEY_bio try { key = readDSAPublicKey(dsaFactory, str.getBytes()); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (InvalidKeySpecException e) { debug(runtime, "PKeyDSA could not read public key", e); } catch (IOException e) { debug(runtime, "PKeyDSA could not read public key", e); } catch (RuntimeException e) { if ( isKeyGenerationFailure(e) ) debug(runtime, "PKeyDSA could not read public key", e); else debugStackTrace(runtime, e); } } if ( key == null ) key = tryPKCS8EncodedKey(runtime, dsaFactory, str.getBytes()); if ( key == null ) key = tryX509EncodedKey(runtime, dsaFactory, str.getBytes()); if ( key == null ) throw newDSAError(runtime, "Neither PUB key nor PRIV key:"); if ( key instanceof KeyPair ) { final PublicKey pubKey = ((KeyPair) key).getPublic(); final PrivateKey privKey = ((KeyPair) key).getPrivate(); if ( ! ( privKey instanceof DSAPrivateKey ) ) { if ( privKey == null ) { throw newDSAError(runtime, "Neither PUB key nor PRIV key: (private key is null)"); } throw newDSAError(runtime, "Neither PUB key nor PRIV key: (invalid key type " + privKey.getClass().getName() + ")"); } this.privateKey = (DSAPrivateKey) privKey; this.publicKey = (DSAPublicKey) pubKey; } else if ( key instanceof DSAPrivateKey ) { this.privateKey = (DSAPrivateKey) key; } else if ( key instanceof DSAPublicKey ) { this.publicKey = (DSAPublicKey) key; this.privateKey = null; } else { throw newDSAError(runtime, "Neither PUB key nor PRIV key: " + key.getClass().getName()); } return this; } //private static Object readPrivateKey(final RubyString str, final char[] passwd) // throws PEMInputOutput.PasswordRequiredException, IOException { // return PEMInputOutput.readDSAPrivateKey(new StringReader(str.toString()), passwd); //} @JRubyMethod(name = "public?") public RubyBoolean public_p() { return publicKey != null ? getRuntime().getTrue() : getRuntime().getFalse(); } @JRubyMethod(name = "private?") public RubyBoolean private_p() { return privateKey != null ? getRuntime().getTrue() : getRuntime().getFalse(); } @Override @JRubyMethod(name = "to_der") public RubyString to_der() { final byte[] bytes; try { bytes = toDerDSAKey(publicKey, privateKey); } catch (NoClassDefFoundError e) { throw newDSAError(getRuntime(), bcExceptionMessage(e)); } catch (IOException e) { throw newDSAError(getRuntime(), e.getMessage(), e); } return StringHelper.newString(getRuntime(), bytes); } @JRubyMethod public RubyString to_text() { StringBuilder result = new StringBuilder(); if (privateKey != null) { int len = privateKey.getParams().getP().bitLength(); result.append("Private-Key: (").append(len).append(" bit)").append("\n"); result.append("priv:"); addSplittedAndFormatted(result, privateKey.getX()); } result.append("pub:"); addSplittedAndFormatted(result, publicKey.getY()); result.append("P:"); addSplittedAndFormatted(result, publicKey.getParams().getP()); result.append("Q:"); addSplittedAndFormatted(result, publicKey.getParams().getQ()); result.append("G:"); addSplittedAndFormatted(result, publicKey.getParams().getG()); return RubyString.newString(getRuntime(), result); } @JRubyMethod public PKeyDSA public_key() { return new PKeyDSA(getRuntime(), this.publicKey); } @Override @JRubyMethod(name = { "to_pem", "to_s" }, alias = "export", rest = true) public RubyString to_pem(final IRubyObject[] args) { Arity.checkArgumentCount(getRuntime(), args, 0, 2); CipherSpec spec = null; char[] passwd = null; if ( args.length > 0 ) { spec = cipherSpec( args[0] ); if ( args.length > 1 ) passwd = password(args[1]); } try { final StringWriter writer = new StringWriter(); if ( privateKey != null ) { PEMInputOutput.writeDSAPrivateKey(writer, privateKey, spec, passwd); } else { PEMInputOutput.writeDSAPublicKey(writer, publicKey); } return RubyString.newString(getRuntime(), writer.getBuffer()); } catch (NoClassDefFoundError ncdfe) { throw newDSAError(getRuntime(), bcExceptionMessage(ncdfe)); } catch (IOException e) { throw newDSAError(getRuntime(), e.getMessage(), e); } } @JRubyMethod // ossl_dsa_sign public IRubyObject syssign(IRubyObject data) { final Ruby runtime = getRuntime(); DSAPrivateKey privateKey; if ((privateKey = this.privateKey) == null) { throw newDSAError(runtime, "Private DSA key needed!"); } try { ByteList sign = sign("NONEwithDSA", privateKey, data.convertToString().getByteList()); // DSS1 return RubyString.newString(runtime, sign); } catch (GeneralSecurityException ex) { throw newDSAError(runtime, ex.getMessage()); } } @JRubyMethod // ossl_dsa_verify public IRubyObject sysverify(IRubyObject data, IRubyObject sign) { final Ruby runtime = getRuntime(); ByteList sigBytes = convertToString(runtime, sign, "OpenSSL::PKey::DSAError", "invalid signature").getByteList(); ByteList dataBytes = convertToString(runtime, data, "OpenSSL::PKey::DSAError", "invalid data").getByteList(); try { return runtime.newBoolean( verify("NONEwithDSA", getPublicKey(), dataBytes, sigBytes) ); } catch (NoSuchAlgorithmException e) { throw newDSAError(runtime, e.getMessage()); } catch (SignatureException e) { throw newDSAError(runtime, "invalid signature"); } catch (InvalidKeyException e) { throw newDSAError(runtime, "invalid key"); } } private DSAKey getDsaKey() { DSAKey result; return (result = publicKey) != null ? result : privateKey; } private IRubyObject toBN(BigInteger value) { return value == null ? getRuntime().getNil() : BN.newBN(getRuntime(), value); } private synchronized BigInteger getP() { DSAKey key = getDsaKey(); if (key != null) { return key.getParams().getP(); } return dsa_p; } @JRubyMethod(name = "p") public IRubyObject get_p() { return toBN(getP()); } @JRubyMethod(name = "p=") public synchronized IRubyObject set_p(IRubyObject p) { return setKeySpecComponent(SPEC_P, p); } private synchronized BigInteger getQ() { DSAKey key = getDsaKey(); if (key != null) { return key.getParams().getQ(); } return dsa_q; } @JRubyMethod(name = "q") public IRubyObject get_q() { return toBN(getQ()); } @JRubyMethod(name = "q=") public synchronized IRubyObject set_q(IRubyObject q) { return setKeySpecComponent(SPEC_Q, q); } private synchronized BigInteger getG() { DSAKey key = getDsaKey(); if (key != null) { return key.getParams().getG(); } return dsa_g; } @JRubyMethod(name = "g") public IRubyObject get_g() { return toBN(getG()); } @JRubyMethod(name = "g=") public synchronized IRubyObject set_g(IRubyObject g) { return setKeySpecComponent(SPEC_G, g); } @JRubyMethod(name = "priv_key") public synchronized IRubyObject get_priv_key() { DSAPrivateKey key; if ((key = this.privateKey) != null) { return toBN(key.getX()); } return toBN(dsa_x); } @JRubyMethod(name = "priv_key=") public synchronized IRubyObject set_priv_key(IRubyObject priv_key) { return setKeySpecComponent(SPEC_X, priv_key); } @JRubyMethod(name = "pub_key") public synchronized IRubyObject get_pub_key() { DSAPublicKey key; if ( ( key = this.publicKey ) != null ) { return toBN(key.getY()); } return toBN(dsa_y); } @JRubyMethod(name = "pub_key=") public synchronized IRubyObject set_pub_key(IRubyObject pub_key) { return setKeySpecComponent(SPEC_Y, pub_key); } private IRubyObject setKeySpecComponent(final int index, final IRubyObject value) { final BigInteger val = BN.getBigInteger(value); switch (index) { case SPEC_X: this.dsa_x = val; break; case SPEC_Y: this.dsa_y = val; break; case SPEC_P: this.dsa_p = val; break; case SPEC_Q: this.dsa_q = val; break; case SPEC_G: this.dsa_g = val; break; } // Don't access the dsa_p, dsa_q and dsa_g fields directly. They may // have already been consumed and cleared. BigInteger _dsa_p = getP(); BigInteger _dsa_q = getQ(); BigInteger _dsa_g = getG(); if ( dsa_x != null && _dsa_p != null && _dsa_q != null && _dsa_g != null ) { // we now have all private key components. create the key : DSAPrivateKeySpec spec = new DSAPrivateKeySpec(dsa_x, _dsa_p, _dsa_q, _dsa_g); try { this.privateKey = (DSAPrivateKey) SecurityHelper.getKeyFactory("DSA").generatePrivate(spec); } catch (InvalidKeySpecException e) { throw newDSAError(getRuntime(), "invalid keyspec", e); } catch (NoSuchAlgorithmException e) { throw newDSAError(getRuntime(), "unsupported key algorithm (DSA)", e); } // clear out the specValues this.dsa_x = this.dsa_p = this.dsa_q = this.dsa_g = null; } if ( dsa_y != null && _dsa_p != null && _dsa_q != null && _dsa_g != null ) { // we now have all public key components. create the key : DSAPublicKeySpec spec = new DSAPublicKeySpec(dsa_y, _dsa_p, _dsa_q, _dsa_g); try { this.publicKey = (DSAPublicKey) SecurityHelper.getKeyFactory("DSA").generatePublic(spec); } catch (InvalidKeySpecException e) { throw newDSAError(getRuntime(), "invalid keyspec", e); } catch (NoSuchAlgorithmException e) { throw newDSAError(getRuntime(), "unsupported key algorithm (DSA)", e); } // clear out the specValues this.dsa_y = this.dsa_p = this.dsa_q = this.dsa_g = null; } return value; } private static final int SPEC_X = 0; private static final int SPEC_Y = 1; private static final int SPEC_P = 2; private static final int SPEC_Q = 3; private static final int SPEC_G = 4; public static RaiseException newDSAError(Ruby runtime, String message) { return Utils.newError(runtime, _PKey(runtime).getClass("DSAError"), message); } static RaiseException newDSAError(Ruby runtime, String message, Exception cause) { return Utils.newError(runtime, _PKey(runtime).getClass("DSAError"), message, cause); } }// PKeyDSA jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PKeyEC.java000066400000000000000000001073701313661621600252200ustar00rootroot00000000000000/* * Copyright (c) 2016 Karol Bucek. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.jruby.ext.openssl; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.spec.ECGenParameterSpec; import java.security.spec.ECParameterSpec; import java.security.spec.ECPoint; import java.security.spec.ECPrivateKeySpec; import java.security.spec.ECPublicKeySpec; import java.security.spec.EllipticCurve; import java.security.spec.InvalidKeySpecException; import java.util.Collections; import java.util.Enumeration; import java.util.List; import javax.crypto.KeyAgreement; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.crypto.params.ECNamedDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.signers.ECDSASigner; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.ECPointUtil; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECNamedCurveSpec; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyClass; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.component.VariableEntry; import org.jruby.ext.openssl.impl.CipherSpec; import static org.jruby.ext.openssl.OpenSSL.debug; import static org.jruby.ext.openssl.OpenSSL.debugStackTrace; import static org.jruby.ext.openssl.PKey._PKey; import org.jruby.ext.openssl.impl.ECPrivateKeyWithName; import static org.jruby.ext.openssl.impl.PKey.readECPrivateKey; import org.jruby.ext.openssl.util.ByteArrayOutputStream; import org.jruby.ext.openssl.x509store.PEMInputOutput; /** * OpenSSL::PKey::EC implementation. * * @author kares */ public final class PKeyEC extends PKey { private static final long serialVersionUID = 1L; private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public PKeyEC allocate(Ruby runtime, RubyClass klass) { return new PKeyEC(runtime, klass); } }; public static void createPKeyEC(final Ruby runtime, final RubyModule PKey, final RubyClass PKeyPKey) { RubyClass EC = PKey.defineClassUnder("EC", PKeyPKey, ALLOCATOR); RubyClass PKeyError = PKey.getClass("PKeyError"); PKey.defineClassUnder("ECError", PKeyError, PKeyError.getAllocator()); EC.defineAnnotatedMethods(PKeyEC.class); EC.setConstant("NAMED_CURVE", runtime.newFixnum(1)); Point.createPoint(runtime, EC); Group.createGroup(runtime, EC); } static RubyClass _EC(final Ruby runtime) { return _PKey(runtime).getClass("EC"); } public static RaiseException newECError(Ruby runtime, String message) { return Utils.newError(runtime, _PKey(runtime).getClass("ECError"), message); } @JRubyMethod(meta = true) public static RubyArray builtin_curves(ThreadContext context, IRubyObject self) { final Ruby runtime = context.runtime; final RubyArray curves = runtime.newArray(); Enumeration names; names = org.bouncycastle.asn1.x9.X962NamedCurves.getNames(); while ( names.hasMoreElements() ) { final String name = (String) names.nextElement(); RubyString desc; if ( name.startsWith("prime") ) { desc = RubyString.newString(runtime, "X9.62 curve over a xxx bit prime field"); } else { desc = RubyString.newString(runtime, "X9.62 curve over a xxx bit binary field"); } curves.append(RubyArray.newArrayNoCopy(runtime, new IRubyObject[] { RubyString.newString(runtime, name), desc })); } names = org.bouncycastle.asn1.sec.SECNamedCurves.getNames(); while ( names.hasMoreElements() ) { RubyString name = RubyString.newString(runtime, (String) names.nextElement()); RubyString desc = RubyString.newString(runtime, "SECG curve over a xxx bit binary field"); curves.append(RubyArray.newArrayNoCopy(runtime, new IRubyObject[] { name, desc })); } names = org.bouncycastle.asn1.nist.NISTNamedCurves.getNames(); while ( names.hasMoreElements() ) { RubyString name = RubyString.newString(runtime, (String) names.nextElement()); IRubyObject[] nameAndDesc = new IRubyObject[] { name, RubyString.newEmptyString(runtime) }; curves.append(RubyArray.newArrayNoCopy(runtime, nameAndDesc)); } names = org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves.getNames(); while ( names.hasMoreElements() ) { RubyString name = RubyString.newString(runtime, (String) names.nextElement()); RubyString desc = RubyString.newString(runtime, "RFC 5639 curve over a xxx bit prime field"); curves.append(RubyArray.newArrayNoCopy(runtime, new IRubyObject[] { name, desc })); } return curves; } private static ASN1ObjectIdentifier getCurveOID(final String curveName) { ASN1ObjectIdentifier id; id = org.bouncycastle.asn1.sec.SECNamedCurves.getOID(curveName); if ( id != null ) return id; id = org.bouncycastle.asn1.x9.X962NamedCurves.getOID(curveName); if ( id != null ) return id; id = org.bouncycastle.asn1.nist.NISTNamedCurves.getOID(curveName); if ( id != null ) return id; id = org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves.getOID(curveName); if ( id != null ) return id; throw new IllegalStateException("could not identify curve name: " + curveName); } private static boolean isCurveName(final String curveName) { try { return getCurveOID(curveName) != null; } catch (IllegalStateException ex) { return false; } } private static String getCurveName(final ASN1ObjectIdentifier oid) { String name; name = org.bouncycastle.asn1.sec.SECNamedCurves.getName(oid); if ( name != null ) return name; name = org.bouncycastle.asn1.x9.X962NamedCurves.getName(oid); if ( name != null ) return name; name = org.bouncycastle.asn1.nist.NISTNamedCurves.getName(oid); if ( name != null ) return name; name = org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves.getName(oid); if ( name != null ) return name; throw new IllegalStateException("could not identify curve name from: " + oid); } public PKeyEC(Ruby runtime, RubyClass type) { super(runtime, type); } PKeyEC(Ruby runtime, PublicKey pubKey) { this(runtime, _EC(runtime), null, pubKey); } PKeyEC(Ruby runtime, RubyClass type, PrivateKey privKey, PublicKey pubKey) { super(runtime, type); this.privateKey = privKey; this.publicKey = (ECPublicKey) pubKey; } private transient Group group; private ECPublicKey publicKey; private transient PrivateKey privateKey; private String curveName; private String getCurveName() { return curveName; } // private ECNamedCurveParameterSpec getParameterSpec() { // return ECNamedCurveTable.getParameterSpec( getCurveName() ); // } @Override public PublicKey getPublicKey() { return publicKey; } @Override public PrivateKey getPrivateKey() { return privateKey; } @Override public String getAlgorithm() { return "EC"; } @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; privateKey = null; publicKey = null; if ( Arity.checkArgumentCount(runtime, args, 0, 2) == 0 ) { return this; } IRubyObject arg = args[0]; if ( arg instanceof Group ) { this.group = (Group) arg; this.curveName = this.group.getCurveName(); return this; } IRubyObject pass = null; if ( args.length > 1 ) pass = args[1]; final char[] passwd = password(pass); final RubyString str = readInitArg(context, arg); final String strJava = str.toString(); if ( isCurveName(strJava) ) { this.curveName = strJava; return this; } Object key = null; final KeyFactory ecdsaFactory; try { ecdsaFactory = SecurityHelper.getKeyFactory("ECDSA"); } catch (NoSuchAlgorithmException e) { throw runtime.newRuntimeError("unsupported key algorithm (ECDSA)"); } catch (RuntimeException e) { throw runtime.newRuntimeError("unsupported key algorithm (ECDSA) " + e); } // TODO: ugly NoClassDefFoundError catching for no BC env. How can we remove this? boolean noClassDef = false; if ( key == null && ! noClassDef ) { // PEM_read_bio_DSAPrivateKey try { key = readPrivateKey(strJava, passwd); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (PEMInputOutput.PasswordRequiredException retry) { if ( ttySTDIN(context) ) { try { key = readPrivateKey(str, passwordPrompt(context)); } catch (Exception e) { debugStackTrace(runtime, e); } } } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { try { key = PEMInputOutput.readECPublicKey(new StringReader(strJava), passwd); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { try { key = PEMInputOutput.readECPubKey(new StringReader(strJava)); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { try { key = readECPrivateKey(ecdsaFactory, str.getBytes()); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (InvalidKeySpecException e) { debug(runtime, "PKeyEC could not read private key", e); } catch (IOException e) { debug(runtime, "PKeyEC could not read private key", e); } catch (RuntimeException e) { if ( isKeyGenerationFailure(e) ) debug(runtime, "PKeyEC could not read private key", e); else debugStackTrace(runtime, e); } } // if ( key == null && ! noClassDef ) { // try { // readECParameters // ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(str.getBytes()); // ECNamedCurveParameterSpec paramSpec = ECNamedCurveTable.getParameterSpec(oid.getId()); // // // ecdsaFactory.generatePublic(keySpec) // // } // catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } // catch (InvalidKeySpecException e) { debug(runtime, "PKeyEC could not read public key", e); } // catch (IOException e) { debug(runtime, "PKeyEC could not read public key", e); } // catch (RuntimeException e) { // if ( isKeyGenerationFailure(e) ) debug(runtime, "PKeyEC could not read public key", e); // else debugStackTrace(runtime, e); // } // } if ( key == null ) key = tryPKCS8EncodedKey(runtime, ecdsaFactory, str.getBytes()); if ( key == null ) key = tryX509EncodedKey(runtime, ecdsaFactory, str.getBytes()); if ( key == null ) throw newECError(runtime, "Neither PUB key nor PRIV key:"); if ( key instanceof KeyPair ) { final PublicKey pubKey = ((KeyPair) key).getPublic(); final PrivateKey privKey = ((KeyPair) key).getPrivate(); if ( ! ( privKey instanceof ECPrivateKey ) ) { if ( privKey == null ) { throw newECError(runtime, "Neither PUB key nor PRIV key: (private key is null)"); } throw newECError(runtime, "Neither PUB key nor PRIV key: (invalid key type " + privKey.getClass().getName() + ")"); } this.publicKey = (ECPublicKey) pubKey; this.privateKey = (ECPrivateKey) privKey; unwrapPrivateKeyWithName(); } else if ( key instanceof ECPrivateKey ) { this.privateKey = (ECPrivateKey) key; unwrapPrivateKeyWithName(); } else if ( key instanceof ECPublicKey ) { this.publicKey = (ECPublicKey) key; this.privateKey = null; } else { throw newECError(runtime, "Neither PUB key nor PRIV key: " + key.getClass().getName()); } if ( publicKey != null ) { publicKey.getParams().getCurve(); } // TODO set curveName ?!?!?!?!?!?!?! return this; } private void unwrapPrivateKeyWithName() { final ECPrivateKey privKey = (ECPrivateKey) this.privateKey; if ( privKey instanceof ECPrivateKeyWithName ) { this.privateKey = ((ECPrivateKeyWithName) privKey).unwrap(); this.curveName = getCurveName( ((ECPrivateKeyWithName) privKey).getCurveNameOID() ); } } //private static ECNamedCurveParameterSpec readECParameters(final byte[] input) throws IOException { // ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(input); // return ECNamedCurveTable.getParameterSpec(oid.getId()); //} @JRubyMethod public IRubyObject check_key(final ThreadContext context) { return context.runtime.getTrue(); // TODO not implemented stub } @JRubyMethod(name = "generate_key") public PKeyEC generate_key(final ThreadContext context) { // final ECDomainParameters params = getDomainParameters(); try { ECGenParameterSpec genSpec = new ECGenParameterSpec(getCurveName()); KeyPairGenerator gen = SecurityHelper.getKeyPairGenerator("ECDSA"); // "BC" gen.initialize(genSpec, new SecureRandom()); KeyPair pair = gen.generateKeyPair(); this.publicKey = (ECPublicKey) pair.getPublic(); this.privateKey = pair.getPrivate(); } catch (GeneralSecurityException ex) { throw newECError(context.runtime, ex.toString()); } return this; } @JRubyMethod(name = "dsa_sign_asn1") public IRubyObject dsa_sign_asn1(final ThreadContext context, final IRubyObject data) { try { ECNamedCurveParameterSpec params = ECNamedCurveTable.getParameterSpec(getCurveName()); ASN1ObjectIdentifier oid = getCurveOID(getCurveName()); ECNamedDomainParameters domainParams = new ECNamedDomainParameters(oid, params.getCurve(), params.getG(), params.getN(), params.getH(), params.getSeed() ); final ECDSASigner signer = new ECDSASigner(); final ECPrivateKey privKey = (ECPrivateKey) this.privateKey; signer.init(true, new ECPrivateKeyParameters(privKey.getS(), domainParams)); final byte[] message = data.convertToString().getBytes(); BigInteger[] signature = signer.generateSignature(message); // [r, s] // final byte[] r = signature[0].toByteArray(); // final byte[] s = signature[1].toByteArray(); // // ASN.1 encode as: 0x30 len 0x02 rlen (r) 0x02 slen (s) // final int len = 1 + (1 + r.length) + 1 + (1 + s.length); // // final byte[] encoded = new byte[1 + 1 + len]; int i; // encoded[0] = 0x30; // encoded[1] = (byte) len; // encoded[2] = 0x20; // encoded[3] = (byte) r.length; // System.arraycopy(r, 0, encoded, i = 4, r.length); i += r.length; // encoded[i++] = 0x20; // encoded[i++] = (byte) s.length; // System.arraycopy(s, 0, encoded, i, s.length); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); ASN1OutputStream asn1 = new ASN1OutputStream(bytes); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(signature[0])); // r v.add(new ASN1Integer(signature[1])); // s asn1.writeObject(new DLSequence(v)); return StringHelper.newString(context.runtime, bytes.buffer(), bytes.size()); } catch (IOException ex) { throw newECError(context.runtime, ex.toString()); } catch (RuntimeException ex) { throw newECError(context.runtime, ex.toString()); } } @JRubyMethod(name = "dh_compute_key") public IRubyObject dh_compute_key(final ThreadContext context, final IRubyObject point) { try { KeyAgreement agreement = SecurityHelper.getKeyAgreement("ECDH"); // "BC" agreement.init(getPrivateKey()); if ( point.isNil() ) { agreement.doPhase(getPublicKey(), true); } else { final ECPoint ecPoint = ((Point) point).asECPoint(); final String name = getCurveName(); KeyFactory keyFactory = KeyFactory.getInstance("EC"); // "BC" ECParameterSpec spec = getParamSpec(name); ECPublicKey ecPublicKey = (ECPublicKey) keyFactory.generatePublic(new ECPublicKeySpec(ecPoint, spec)); agreement.doPhase(ecPublicKey, true); } final byte[] secret = agreement.generateSecret(); return StringHelper.newString(context.runtime, secret); } catch (NoSuchAlgorithmException ex) { throw newECError(context.runtime, ex.toString()); } catch (InvalidKeyException ex) { throw newECError(context.runtime, ex.toString()); } catch (GeneralSecurityException ex) { throw newECError(context.runtime, ex.toString()); } } private Group getGroup(boolean required) { if (group == null) { if (publicKey != null) { return group = new Group(getRuntime(), this); } if (required) throw new IllegalStateException("no group (without public key)"); } return group; } /** * @return OpenSSL::PKey::EC::Group */ @JRubyMethod public IRubyObject group() { final Group group = getGroup(false); return group == null ? getRuntime().getNil() : group; } @JRubyMethod(name = "group=") public IRubyObject set_group(IRubyObject group) { this.group = group.isNil() ? null : (Group) group; return group; } /** * @return OpenSSL::PKey::EC::Point */ @JRubyMethod public IRubyObject public_key(final ThreadContext context) { if ( publicKey == null ) return context.nil; return new Point(context.runtime, publicKey, getGroup(true)); } @JRubyMethod(name = "public_key=") public IRubyObject set_public_key(final ThreadContext context, final IRubyObject arg) { if ( ! ( arg instanceof Point ) ) { throw context.runtime.newTypeError(arg, _EC(context.runtime).getClass("Point")); } final Point point = (Point) arg; ECPublicKeySpec keySpec = new ECPublicKeySpec(point.asECPoint(), getParamSpec()); try { this.publicKey = (ECPublicKey) SecurityHelper.getKeyFactory("ECDSA").generatePublic(keySpec); return arg; } catch (GeneralSecurityException ex) { throw newECError(context.runtime, ex.getMessage()); } } private static ECParameterSpec getParamSpec(final String curveName) { ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec(curveName); return new ECNamedCurveSpec(spec.getName(), spec.getCurve(), spec.getG(), spec.getN(), spec.getH(), spec.getSeed()); } private ECParameterSpec getParamSpec() { return getParamSpec(getCurveName()); } /** * @return OpenSSL::BN */ @JRubyMethod public IRubyObject private_key(final ThreadContext context) { if ( privateKey == null ) return context.nil; return BN.newBN(context.runtime, ((ECPrivateKey) privateKey).getS()); } @JRubyMethod(name = "private_key=") public IRubyObject set_private_key(final ThreadContext context, final IRubyObject arg) { final BigInteger s; if ( arg instanceof BN ) { s = ((BN) (arg)).getValue(); } else { s = (BigInteger) arg; } ECPrivateKeySpec keySpec = new ECPrivateKeySpec(s, getParamSpec()); try { this.privateKey = SecurityHelper.getKeyFactory("ECDSA").generatePrivate(keySpec); return arg; } catch (GeneralSecurityException ex) { throw newECError(context.runtime, ex.getMessage()); } } @JRubyMethod(name = "public_key?") public RubyBoolean public_p() { return publicKey != null ? getRuntime().getTrue() : getRuntime().getFalse(); } @JRubyMethod(name = "private_key?") public RubyBoolean private_p() { return privateKey != null ? getRuntime().getTrue() : getRuntime().getFalse(); } @Override @JRubyMethod(name = "to_der") public RubyString to_der() { final byte[] bytes; try { bytes = toDER(); } catch (IOException e) { throw newECError(getRuntime(), e.getMessage()); } return StringHelper.newString(getRuntime(), bytes); } private byte[] toDER() throws IOException { if ( publicKey != null && privateKey == null ) { return publicKey.getEncoded(); } if ( privateKey == null ) { throw new IllegalStateException("private key as well as public key are null"); } return privateKey.getEncoded(); } @Override @JRubyMethod(name = "to_pem", alias = "export", rest = true) public RubyString to_pem(final IRubyObject[] args) { Arity.checkArgumentCount(getRuntime(), args, 0, 2); CipherSpec spec = null; char[] passwd = null; if ( args.length > 0 ) { spec = cipherSpec( args[0] ); if ( args.length > 1 ) passwd = password( args[1] ); } try { final StringWriter writer = new StringWriter(); if ( privateKey != null ) { PEMInputOutput.writeECPrivateKey(writer, (ECPrivateKey) privateKey, spec, passwd); } else { PEMInputOutput.writeECPublicKey(writer, publicKey); } return RubyString.newString(getRuntime(), writer.getBuffer()); } catch (IOException ex) { throw newECError(getRuntime(), ex.getMessage()); } } @JRubyClass(name = "OpenSSL::PKey::EC::Group") public static final class Group extends RubyObject { private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public Group allocate(Ruby runtime, RubyClass klass) { return new Group(runtime, klass); } }; static void createGroup(final Ruby runtime, final RubyClass EC) { RubyClass Group = EC.defineClassUnder("Group", runtime.getObject(), ALLOCATOR); // OpenSSL::PKey::EC::Group::Error RubyClass OpenSSLError = OpenSSL._OpenSSLError(runtime); Group.defineClassUnder("Error", OpenSSLError, OpenSSLError.getAllocator()); Group.defineAnnotatedMethods(Group.class); } private transient PKeyEC key; private ECParameterSpec paramSpec; private RubyString curve_name; public Group(Ruby runtime, RubyClass type) { super(runtime, type); } Group(Ruby runtime, PKeyEC key) { this(runtime, _EC(runtime).getClass("Group")); this.key = key; this.paramSpec = key.publicKey.getParams(); } private String getCurveName() { if (key != null) return key.getCurveName(); return curve_name.toString(); } @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; if ( Arity.checkArgumentCount(runtime, args, 1, 4) == 1 ) { IRubyObject arg = args[0]; if ( arg instanceof Group ) { IRubyObject curve_name = ((Group) arg).curve_name(context); this.curve_name = curve_name.isNil() ? null : (RubyString) curve_name; return this; } this.curve_name = ((RubyString) arg); // TODO PEM/DER parsing not implemented } return this; } @Override @JRubyMethod(name = { "==", "eql?" }) public IRubyObject op_equal(final ThreadContext context, final IRubyObject obj) { if ( paramSpec == null ) return context.nil; if ( obj instanceof Group ) { final Group that = (Group) obj; boolean equals = this.paramSpec.equals(that.paramSpec); return context.runtime.newBoolean(equals); } return context.runtime.getFalse(); } @JRubyMethod public IRubyObject curve_name(final ThreadContext context) { if (curve_name == null) { String prefix, curveName = key.getCurveName(); // BC 1.54: "brainpoolP512t1" 1.55: "brainpoolp512t1" if (curveName.startsWith(prefix = "brainpoolp")) { curveName = "brainpoolP" + curveName.substring(prefix.length()); } curve_name = RubyString.newString(context.runtime, curveName); } return curve_name.dup(); } @JRubyMethod public IRubyObject order(final ThreadContext context) { if ( paramSpec == null ) return context.nil; return BN.newBN(context.runtime, paramSpec.getOrder()); } @JRubyMethod public IRubyObject cofactor(final ThreadContext context) { if ( paramSpec == null ) return context.nil; return context.runtime.newFixnum(paramSpec.getCofactor()); } @JRubyMethod public IRubyObject seed(final ThreadContext context) { if ( paramSpec == null ) return context.nil; final byte[] seed = paramSpec.getCurve().getSeed(); return seed == null ? context.nil : StringHelper.newString(context.runtime, seed); } @JRubyMethod public IRubyObject degree(final ThreadContext context) { if ( paramSpec == null ) return context.nil; final int fieldSize = paramSpec.getCurve().getField().getFieldSize(); return context.runtime.newFixnum(fieldSize); } @JRubyMethod public IRubyObject generator(final ThreadContext context) { if ( paramSpec == null ) return context.nil; final ECPoint generator = paramSpec.getGenerator(); //final int bitLength = paramSpec.getOrder().bitLength(); return new Point(context.runtime, generator, this); } @JRubyMethod(name = { "to_pem" }, alias = "export", rest = true) public RubyString to_pem(final ThreadContext context, final IRubyObject[] args) { Arity.checkArgumentCount(context.runtime, args, 0, 2); CipherSpec spec = null; char[] passwd = null; if ( args.length > 0 ) { spec = cipherSpec( args[0] ); if ( args.length > 1 ) passwd = password(args[1]); } try { final StringWriter writer = new StringWriter(); PEMInputOutput.writeECParameters(writer, getCurveOID(getCurveName()), spec, passwd); return RubyString.newString(context.runtime, writer.getBuffer()); } catch (IOException ex) { throw newECError(context.runtime, ex.getMessage()); } } final EllipticCurve getCurve() { if (paramSpec == null) { paramSpec = getParamSpec(getCurveName()); } return paramSpec.getCurve(); } // @Override // @JRubyMethod // @SuppressWarnings("unchecked") // public IRubyObject inspect() { // final EllipticCurve curve = getCurve(); // final StringBuilder part = new StringBuilder(); // String cname = getMetaClass().getRealClass().getName(); // part.append("#<").append(cname).append(":0x"); // part.append(Integer.toHexString(System.identityHashCode(this))); // // part.append(' '); // part.append(" a:").append(curve.getA()).append(" b:").append(curve.getA()); // return RubyString.newString(getRuntime(), part.append('>')); // } } @JRubyClass(name = "OpenSSL::PKey::EC::Point") public static final class Point extends RubyObject { private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public Point allocate(Ruby runtime, RubyClass klass) { return new Point(runtime, klass); } }; static void createPoint(final Ruby runtime, final RubyClass EC) { RubyClass Point = EC.defineClassUnder("Point", runtime.getObject(), ALLOCATOR); // OpenSSL::PKey::EC::Point::Error RubyClass OpenSSLError = OpenSSL._OpenSSLError(runtime); Point.defineClassUnder("Error", OpenSSLError, OpenSSLError.getAllocator()); Point.defineAnnotatedMethods(Point.class); } public Point(Ruby runtime, RubyClass type) { super(runtime, type); } // private transient ECPublicKey publicKey; private ECPoint point; //private int bitLength; private Group group; Point(Ruby runtime, ECPublicKey publicKey, Group group) { this(runtime, _EC(runtime).getClass("Point")); //this.publicKey = publicKey; this.point = publicKey.getW(); this.group = group; } Point(Ruby runtime, ECPoint point, Group group) { this(runtime, _EC(runtime).getClass("Point")); this.point = point; this.group = group; } private static RaiseException newError(final Ruby runtime, final String message) { final RubyClass Error = _EC(runtime).getClass("Point").getClass("Error"); return Utils.newError(runtime, Error, message); } @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; final int argc = Arity.checkArgumentCount(runtime, args, 1, 2); final IRubyObject arg = args[0]; if ( arg instanceof Point ) { this.group = ((Point) arg).group; this.point = ((Point) arg).point; return this; } if ( arg instanceof Group ) { this.group = (Group) arg; } if ( argc == 2 ) { // (group, bn) final byte[] encoded = ((BN) args[1]).getValue().abs().toByteArray(); try { this.point = ECPointUtil.decodePoint(group.getCurve(), encoded); } catch (IllegalArgumentException ex) { // MRI: OpenSSL::PKey::EC::Point::Error: invalid encoding throw newError(context.runtime, ex.getMessage()); } } return this; } @Override @JRubyMethod(name = { "==", "eql?" }) public IRubyObject op_equal(final ThreadContext context, final IRubyObject obj) { if (obj instanceof Point) { final Point that = (Point) obj; boolean equals = this.point.equals(that.point); return context.runtime.newBoolean(equals); } return context.runtime.getFalse(); } /** * @return OpenSSL::PKey::EC::Group */ @JRubyMethod public IRubyObject group() { return group == null ? getRuntime().getNil() : group; } private ECPoint asECPoint() { return point; // return publicKey.getW(); } private int bitLength() { return group.paramSpec.getOrder().bitLength(); } @JRubyMethod public BN to_bn(final ThreadContext context) { final byte[] encoded = encode(bitLength(), point); return BN.newBN(context.runtime, new BigInteger(1, encoded)); } private boolean isInfinity() { return point == ECPoint.POINT_INFINITY; } @JRubyMethod(name = "infinity?") public RubyBoolean infinity_p() { return getRuntime().newBoolean( isInfinity() ); } @JRubyMethod(name = "set_to_infinity!") public IRubyObject set_to_infinity_b() { this.point = ECPoint.POINT_INFINITY; return this; } @Override @JRubyMethod @SuppressWarnings("unchecked") public IRubyObject inspect() { VariableEntry entry = new VariableEntry( "group", group == null ? (Object) "nil" : group ); return ObjectSupport.inspect(this, (List) Collections.singletonList(entry)); } } static byte[] encode(final ECPublicKey pubKey) { return encode(pubKey.getParams().getOrder().bitLength(), pubKey.getW()); } private static byte[] encode(final int bitLength, final ECPoint point) { if ( point == ECPoint.POINT_INFINITY ) return new byte[1]; final int bytesLength = (bitLength + 7) / 8; byte[] encoded = new byte[1 + bytesLength + bytesLength]; encoded[0] = 0x04; addIntBytes(point.getAffineX(), bytesLength, encoded, 1); addIntBytes(point.getAffineY(), bytesLength, encoded, 1 + bytesLength); return encoded; } private static void addIntBytes(BigInteger i, final int length, final byte[] dest, final int destOffset) { final byte[] bytes = i.toByteArray(); if (length < bytes.length) { System.arraycopy(bytes, bytes.length - length, dest, destOffset, length); } else if (length > bytes.length) { System.arraycopy(bytes, 0, dest, destOffset + (length - bytes.length), bytes.length); } else { System.arraycopy(bytes, 0, dest, destOffset, length); } } }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/PKeyRSA.java000066400000000000000000000766531313661621600253670ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import static javax.crypto.Cipher.*; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyBignum; import org.jruby.RubyBoolean; import org.jruby.RubyFixnum; import org.jruby.RubyHash; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import org.jruby.ext.openssl.impl.CipherSpec; import org.jruby.ext.openssl.x509store.PEMInputOutput; import static org.jruby.ext.openssl.OpenSSL.*; import static org.jruby.ext.openssl.PKey._PKey; import static org.jruby.ext.openssl.impl.PKey.readRSAPrivateKey; import static org.jruby.ext.openssl.impl.PKey.readRSAPublicKey; import static org.jruby.ext.openssl.impl.PKey.toDerRSAKey; /** * @author Ola Bini */ public class PKeyRSA extends PKey { private static final long serialVersionUID = -2540383779256333197L; private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public PKeyRSA allocate(Ruby runtime, RubyClass klass) { return new PKeyRSA(runtime, klass); } }; public static void createPKeyRSA(final Ruby runtime, final RubyModule PKey, final RubyClass PKeyPKey) { RubyClass RSA = PKey.defineClassUnder("RSA", PKeyPKey, ALLOCATOR); RubyClass PKeyError = PKey.getClass("PKeyError"); PKey.defineClassUnder("RSAError", PKeyError, PKeyError.getAllocator()); RSA.defineAnnotatedMethods(PKeyRSA.class); RSA.setConstant("PKCS1_PADDING", runtime.newFixnum(1)); RSA.setConstant("SSLV23_PADDING", runtime.newFixnum(2)); RSA.setConstant("NO_PADDING", runtime.newFixnum(3)); RSA.setConstant("PKCS1_OAEP_PADDING", runtime.newFixnum(4)); } static RubyClass _RSA(final Ruby runtime) { return _PKey(runtime).getClass("RSA"); } public static RaiseException newRSAError(Ruby runtime, String message) { return Utils.newError(runtime, _PKey(runtime).getClass("RSAError"), message); } static RaiseException newRSAError(Ruby runtime, Throwable cause) { return Utils.newError(runtime, _PKey(runtime).getClass("RSAError"), cause.getMessage(), cause); } public PKeyRSA(Ruby runtime, RubyClass type) { super(runtime, type); } public PKeyRSA(Ruby runtime, RubyClass type, RSAPrivateCrtKey privKey, RSAPublicKey pubKey) { super(runtime, type); this.privateKey = privKey; this.publicKey = pubKey; } PKeyRSA(Ruby runtime, RSAPublicKey pubKey) { this(runtime, _RSA(runtime), null, pubKey); } private volatile RSAPublicKey publicKey; private volatile transient RSAPrivateCrtKey privateKey; // fields to hold individual RSAPublicKeySpec components. this allows // a public key to be constructed incrementally, as required by the // current implementation of Net::SSH. // (see net-ssh-1.1.2/lib/net/ssh/transport/ossl/buffer.rb #read_keyblob) private transient volatile BigInteger rsa_e; private transient volatile BigInteger rsa_n; private transient volatile BigInteger rsa_d; private transient volatile BigInteger rsa_p; private transient volatile BigInteger rsa_q; private transient volatile BigInteger rsa_dmp1; private transient volatile BigInteger rsa_dmq1; private transient volatile BigInteger rsa_iqmp; @Override public IRubyObject initialize_copy(final IRubyObject original) { if (this == original) return this; checkFrozen(); final PKeyRSA that = (PKeyRSA) original; this.publicKey = that.publicKey; this.privateKey = that.privateKey; this.rsa_e = that.rsa_e; this.rsa_n = that.rsa_n; this.rsa_d = that.rsa_d; this.rsa_p = that.rsa_p; this.rsa_q = that.rsa_q; this.rsa_dmp1 = that.rsa_dmp1; this.rsa_dmq1 = that.rsa_dmq1; this.rsa_iqmp = that.rsa_iqmp; return this; } @Override public PublicKey getPublicKey() { return publicKey; } @Override public PrivateKey getPrivateKey() { return privateKey; } @Override public String getAlgorithm() { return "RSA"; } @JRubyMethod(name = "generate", meta = true, rest = true) public static IRubyObject generate(IRubyObject self, IRubyObject[] args) { final Ruby runtime = self.getRuntime(); BigInteger exp = RSAKeyGenParameterSpec.F4; if ( Arity.checkArgumentCount(runtime, args, 1, 2) == 2 ) { if (args[1] instanceof RubyFixnum) { exp = BigInteger.valueOf(RubyNumeric.num2long(args[1])); } else { exp = ((RubyBignum) args[1]).getValue(); } } final int keySize = RubyNumeric.fix2int(args[0]); return rsaGenerate(runtime, new PKeyRSA(runtime, (RubyClass) self), keySize, exp); } /* * c: rsa_generate */ private static PKeyRSA rsaGenerate(final Ruby runtime, PKeyRSA rsa, int keySize, BigInteger exp) throws RaiseException { try { KeyPairGenerator gen = SecurityHelper.getKeyPairGenerator("RSA"); if ( "IBMJCEFIPS".equals( gen.getProvider().getName() ) ) { gen.initialize(keySize); // IBMJCEFIPS does not support parameters } else { gen.initialize(new RSAKeyGenParameterSpec(keySize, exp), getSecureRandom(runtime)); } KeyPair pair = gen.generateKeyPair(); rsa.privateKey = (RSAPrivateCrtKey) pair.getPrivate(); rsa.publicKey = (RSAPublicKey) pair.getPublic(); } catch (NoSuchAlgorithmException e) { throw newRSAError(runtime, e.getMessage()); } catch (InvalidAlgorithmParameterException e) { throw newRSAError(runtime, e.getMessage()); } catch (RuntimeException e) { throw newRSAError(rsa.getRuntime(), e); } return rsa; } static PKeyRSA newInstance(final Ruby runtime, final PublicKey publicKey) { //if ( publicKey instanceof RSAPublicKey ) { return new PKeyRSA(runtime, (RSAPublicKey) publicKey); //} } @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; if ( Arity.checkArgumentCount(runtime, args, 0, 2) == 0 ) { privateKey = null; publicKey = null; return this; } IRubyObject arg = args[0]; IRubyObject pass = null; if ( args.length > 1 ) pass = args[1]; if ( arg instanceof RubyFixnum ) { int keySize = RubyNumeric.fix2int((RubyFixnum) arg); BigInteger exp = RSAKeyGenParameterSpec.F4; if ( pass != null && ! pass.isNil() ) { exp = BigInteger.valueOf(RubyNumeric.num2long(pass)); } return rsaGenerate(runtime, this, keySize, exp); } final char[] passwd = password(pass); final RubyString str = readInitArg(context, arg); final String strJava = str.toString(); Object key = null; final KeyFactory rsaFactory; try { rsaFactory = SecurityHelper.getKeyFactory("RSA"); } catch (NoSuchAlgorithmException e) { throw runtime.newRuntimeError("unsupported key algorithm (RSA)"); } catch (RuntimeException e) { throw runtime.newRuntimeError("unsupported key algorithm (RSA) " + e); } // TODO: ugly NoClassDefFoundError catching for no BC env. How can we remove this? boolean noClassDef = false; if ( key == null && ! noClassDef ) { // PEM_read_bio_RSAPrivateKey try { key = readPrivateKey(strJava, passwd); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (PEMInputOutput.PasswordRequiredException retry) { if ( ttySTDIN(context) ) { try { key = readPrivateKey(strJava, passwordPrompt(context)); } catch (Exception e) { debugStackTrace(runtime, e); } } } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { // PEM_read_bio_RSAPublicKey try { key = PEMInputOutput.readRSAPublicKey(new StringReader(strJava), passwd); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { // PEM_read_bio_RSA_PUBKEY try { key = PEMInputOutput.readRSAPubKey(new StringReader(strJava)); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (Exception e) { debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { // d2i_RSAPrivateKey_bio try { key = readRSAPrivateKey(rsaFactory, str.getBytes()); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (InvalidKeySpecException e) { debug(runtime, "PKeyRSA could not read private key", e); } catch (IOException e) { debug(runtime, "PKeyRSA could not read private key", e); } catch (RuntimeException e) { if ( isKeyGenerationFailure(e) ) debug(runtime, "PKeyRSA could not read private key", e); else debugStackTrace(runtime, e); } } if ( key == null && ! noClassDef ) { // d2i_RSAPublicKey_bio try { key = readRSAPublicKey(rsaFactory, str.getBytes()); } catch (NoClassDefFoundError e) { noClassDef = true; debugStackTrace(runtime, e); } catch (InvalidKeySpecException e) { debug(runtime, "PKeyRSA could not read public key", e); } catch (IOException e) { debug(runtime, "PKeyRSA could not read public key", e); } catch (RuntimeException e) { if ( isKeyGenerationFailure(e) ) debug(runtime, "PKeyRSA could not read public key", e); else debugStackTrace(runtime, e); } } if ( key == null ) key = tryPKCS8EncodedKey(runtime, rsaFactory, str.getBytes()); if ( key == null ) key = tryX509EncodedKey(runtime, rsaFactory, str.getBytes()); if ( key == null ) throw newRSAError(runtime, "Neither PUB key nor PRIV key:"); if ( key instanceof KeyPair ) { PublicKey publicKey = ((KeyPair) key).getPublic(); PrivateKey privateKey = ((KeyPair) key).getPrivate(); if ( ! ( privateKey instanceof RSAPrivateCrtKey ) ) { if ( privateKey == null ) { throw newRSAError(runtime, "Neither PUB key nor PRIV key: (private key is null)"); } throw newRSAError(runtime, "Neither PUB key nor PRIV key: (invalid key type " + privateKey.getClass().getName() + ")"); } this.privateKey = (RSAPrivateCrtKey) privateKey; this.publicKey = (RSAPublicKey) publicKey; } else if ( key instanceof RSAPrivateCrtKey ) { this.privateKey = (RSAPrivateCrtKey) key; try { this.publicKey = (RSAPublicKey) rsaFactory.generatePublic(new RSAPublicKeySpec(privateKey.getModulus(), privateKey.getPublicExponent())); } catch (GeneralSecurityException e) { throw newRSAError(runtime, e.getMessage()); } catch (RuntimeException e) { debugStackTrace(runtime, e); throw newRSAError(runtime, e.toString()); } } else if ( key instanceof RSAPublicKey ) { this.publicKey = (RSAPublicKey) key; this.privateKey = null; } else { throw newRSAError(runtime, "Neither PUB key nor PRIV key: " + key.getClass().getName()); } return this; } @JRubyMethod(name = "public?") public RubyBoolean public_p() { return publicKey != null ? getRuntime().getTrue() : getRuntime().getFalse(); } @Override public boolean isPrivateKey() { return privateKey != null; } @JRubyMethod(name = "private?") public RubyBoolean private_p() { return getRuntime().newBoolean(isPrivateKey()); } @Override @JRubyMethod(name = "to_der") public RubyString to_der() { final byte[] bytes; try { bytes = toDerRSAKey(publicKey, privateKey); } catch (NoClassDefFoundError e) { throw newRSAError(getRuntime(), bcExceptionMessage(e)); } catch (IOException e) { throw newRSAError(getRuntime(), e.getMessage()); } return StringHelper.newString(getRuntime(), bytes); } @JRubyMethod public PKeyRSA public_key() { return new PKeyRSA(getRuntime(), this.publicKey); } @JRubyMethod public IRubyObject params(final ThreadContext context) { final Ruby runtime = context.runtime; RubyHash hash = RubyHash.newHash(runtime); if ( privateKey != null ) { hash.op_aset(context, runtime.newString("iqmp"), BN.newBN(runtime, privateKey.getCrtCoefficient())); hash.op_aset(context, runtime.newString("n"), BN.newBN(runtime, privateKey.getModulus())); hash.op_aset(context, runtime.newString("d"), BN.newBN(runtime, privateKey.getPrivateExponent())); hash.op_aset(context, runtime.newString("p"), BN.newBN(runtime, privateKey.getPrimeP())); hash.op_aset(context, runtime.newString("e"), BN.newBN(runtime, privateKey.getPublicExponent())); hash.op_aset(context, runtime.newString("q"), BN.newBN(runtime, privateKey.getPrimeQ())); hash.op_aset(context, runtime.newString("dmq1"), BN.newBN(runtime, privateKey.getPrimeExponentQ())); hash.op_aset(context, runtime.newString("dmp1"), BN.newBN(runtime, privateKey.getPrimeExponentP())); } else { hash.op_aset(context, runtime.newString("iqmp"), BN.newBN(runtime, BigInteger.ZERO)); hash.op_aset(context, runtime.newString("n"), BN.newBN(runtime, publicKey.getModulus())); hash.op_aset(context, runtime.newString("d"), BN.newBN(runtime, BigInteger.ZERO)); hash.op_aset(context, runtime.newString("p"), BN.newBN(runtime, BigInteger.ZERO)); hash.op_aset(context, runtime.newString("e"), BN.newBN(runtime, publicKey.getPublicExponent())); hash.op_aset(context, runtime.newString("q"), BN.newBN(runtime, BigInteger.ZERO)); hash.op_aset(context, runtime.newString("dmq1"), BN.newBN(runtime, BigInteger.ZERO)); hash.op_aset(context, runtime.newString("dmp1"), BN.newBN(runtime, BigInteger.ZERO)); } return hash; } @JRubyMethod public RubyString to_text() { StringBuilder result = new StringBuilder(); if (privateKey != null) { int len = privateKey.getModulus().bitLength(); result.append("Private-Key: (").append(len).append(" bit)").append('\n'); result.append("modulus:"); addSplittedAndFormatted(result, privateKey.getModulus()); result.append("publicExponent: ").append(privateKey.getPublicExponent()).append(" (0x").append(privateKey.getPublicExponent().toString(16)).append(")\n"); result.append("privateExponent:"); addSplittedAndFormatted(result, privateKey.getPrivateExponent()); result.append("prime1:"); addSplittedAndFormatted(result, privateKey.getPrimeP()); result.append("prime2:"); addSplittedAndFormatted(result, privateKey.getPrimeQ()); result.append("exponent1:"); addSplittedAndFormatted(result, privateKey.getPrimeExponentP()); result.append("exponent2:"); addSplittedAndFormatted(result, privateKey.getPrimeExponentQ()); result.append("coefficient:"); addSplittedAndFormatted(result, privateKey.getCrtCoefficient()); } else { int len = publicKey.getModulus().bitLength(); result.append("Modulus (").append(len).append(" bit):"); addSplittedAndFormatted(result, publicKey.getModulus()); result.append("Exponent: ").append(publicKey.getPublicExponent()).append(" (0x").append(publicKey.getPublicExponent().toString(16)).append(")\n"); } return RubyString.newString(getRuntime(), result); } @Override @JRubyMethod(name = { "to_pem", "to_s" }, alias = "export", rest = true) public RubyString to_pem(final IRubyObject[] args) { Arity.checkArgumentCount(getRuntime(), args, 0, 2); CipherSpec spec = null; char[] passwd = null; if ( args.length > 0 ) { spec = cipherSpec( args[0] ); if ( args.length > 1 ) passwd = password(args[1]); } try { final StringWriter writer = new StringWriter(); if ( privateKey != null ) { PEMInputOutput.writeRSAPrivateKey(writer, privateKey, spec, passwd); } else { PEMInputOutput.writeRSAPublicKey(writer, publicKey); } return RubyString.newString(getRuntime(), writer.getBuffer()); } catch (NoClassDefFoundError ncdfe) { throw newRSAError(getRuntime(), bcExceptionMessage(ncdfe)); } catch (IOException ioe) { throw newRSAError(getRuntime(), ioe.getMessage()); } } private String getPadding(final int padding) { if ( padding < 1 || padding > 4 ) { throw newRSAError(getRuntime(), ""); } // BC accepts "/NONE/*" but SunJCE doesn't. use "/ECB/*" String p = "/ECB/PKCS1Padding"; if ( padding == 3 ) { p = "/ECB/NoPadding"; } else if ( padding == 4 ) { p = "/ECB/OAEPWithSHA1AndMGF1Padding"; } else if ( padding == 2 ) { p = "/ECB/ISO9796-1Padding"; } return p; } @JRubyMethod(rest = true) public IRubyObject private_encrypt(final ThreadContext context, final IRubyObject[] args) { int padding = 1; if ( Arity.checkArgumentCount(context.runtime, args, 1, 2) == 2 && ! args[1].isNil() ) { padding = RubyNumeric.fix2int(args[1]); } if ( privateKey == null ) throw newRSAError(context.runtime, "incomplete RSA"); return doCipherRSA(context.runtime, args[0], padding, ENCRYPT_MODE, privateKey); } @JRubyMethod(rest = true) public IRubyObject private_decrypt(final ThreadContext context, final IRubyObject[] args) { int padding = 1; if ( Arity.checkArgumentCount(context.runtime, args, 1, 2) == 2 && ! args[1].isNil()) { padding = RubyNumeric.fix2int(args[1]); } if ( privateKey == null ) throw newRSAError(context.runtime, "incomplete RSA"); return doCipherRSA(context.runtime, args[0], padding, DECRYPT_MODE, privateKey); } @JRubyMethod(rest = true) public IRubyObject public_encrypt(final ThreadContext context, final IRubyObject[] args) { int padding = 1; if ( Arity.checkArgumentCount(context.runtime, args, 1, 2) == 2 && ! args[1].isNil()) { padding = RubyNumeric.fix2int(args[1]); } if ( publicKey == null ) throw newRSAError(context.runtime, "incomplete RSA"); return doCipherRSA(context.runtime, args[0], padding, ENCRYPT_MODE, publicKey); } @JRubyMethod(rest = true) public IRubyObject public_decrypt(final ThreadContext context, final IRubyObject[] args) { int padding = 1; if ( Arity.checkArgumentCount(context.runtime, args, 1, 2) == 2 && ! args[1].isNil() ) { padding = RubyNumeric.fix2int(args[1]); } if ( publicKey == null ) throw newRSAError(context.runtime, "incomplete RSA"); return doCipherRSA(context.runtime, args[0], padding, DECRYPT_MODE, publicKey); } private RubyString doCipherRSA(final Ruby runtime, final IRubyObject content, final int padding, final int initMode, final Key initKey) { final String cipherPadding = getPadding(padding); final RubyString buffer = content.convertToString(); try { javax.crypto.Cipher engine = SecurityHelper.getCipher("RSA" + cipherPadding); engine.init(initMode, initKey); byte[] output = engine.doFinal(buffer.getBytes()); return StringHelper.newString(runtime, output); } catch (GeneralSecurityException gse) { throw newRSAError(runtime, gse.getMessage()); } } @JRubyMethod(name="d=") public synchronized IRubyObject set_d(final ThreadContext context, IRubyObject value) { if ( privateKey != null ) { throw newRSAError(context.runtime, "illegal modification"); } rsa_d = BN.getBigInteger(value); generatePrivateKeyIfParams(context); return value; } @JRubyMethod(name="p=") public synchronized IRubyObject set_p(final ThreadContext context, IRubyObject value) { if ( privateKey != null ) { throw newRSAError(context.runtime, "illegal modification"); } rsa_p = BN.getBigInteger(value); generatePrivateKeyIfParams(context); return value; } @JRubyMethod(name="q=") public synchronized IRubyObject set_q(final ThreadContext context, IRubyObject value) { if ( privateKey != null ) { throw newRSAError(context.runtime, "illegal modification"); } rsa_q = BN.getBigInteger(value); generatePrivateKeyIfParams(context); return value; } @JRubyMethod(name="dmp1=") public synchronized IRubyObject set_dmp1(final ThreadContext context, IRubyObject value) { if ( privateKey != null ) { throw newRSAError(context.runtime, "illegal modification"); } rsa_dmp1 = BN.asBigInteger(value); generatePrivateKeyIfParams(context); return value; } @JRubyMethod(name="dmq1=") public synchronized IRubyObject set_dmq1(final ThreadContext context, IRubyObject value) { if ( privateKey != null ) { throw newRSAError(context.runtime, "illegal modification"); } rsa_dmq1 = BN.asBigInteger(value); generatePrivateKeyIfParams(context); return value; } @JRubyMethod(name="iqmp=") public synchronized IRubyObject set_iqmp(final ThreadContext context, IRubyObject value) { if ( privateKey != null ) { throw newRSAError(context.runtime, "illegal modification"); } rsa_iqmp = BN.asBigInteger(value); generatePrivateKeyIfParams(context); return value; } @JRubyMethod(name="iqmp") public synchronized IRubyObject get_iqmp() { BigInteger iqmp; if (privateKey != null) { iqmp = privateKey.getCrtCoefficient(); } else { iqmp = rsa_iqmp; } if (iqmp != null) { return BN.newBN(getRuntime(), iqmp); } return getRuntime().getNil(); } @JRubyMethod(name="dmp1") public synchronized IRubyObject get_dmp1() { BigInteger dmp1; if (privateKey != null) { dmp1 = privateKey.getPrimeExponentP(); } else { dmp1 = rsa_dmp1; } if (dmp1 != null) { return BN.newBN(getRuntime(), dmp1); } return getRuntime().getNil(); } @JRubyMethod(name="dmq1") public synchronized IRubyObject get_dmq1() { BigInteger dmq1; if (privateKey != null) { dmq1 = privateKey.getPrimeExponentQ(); } else { dmq1 = rsa_dmq1; } if (dmq1 != null) { return BN.newBN(getRuntime(), dmq1); } return getRuntime().getNil(); } @JRubyMethod(name="d") public synchronized IRubyObject get_d() { BigInteger d; if (privateKey != null) { d = privateKey.getPrivateExponent(); } else { d = rsa_d; } if (d != null) { return BN.newBN(getRuntime(), d); } return getRuntime().getNil(); } @JRubyMethod(name="p") public synchronized IRubyObject get_p() { BigInteger p; if (privateKey != null) { p = privateKey.getPrimeP(); } else { p = rsa_p; } if (p != null) { return BN.newBN(getRuntime(), p); } return getRuntime().getNil(); } @JRubyMethod(name="q") public synchronized IRubyObject get_q() { BigInteger q; if (privateKey != null) { q = privateKey.getPrimeQ(); } else { q = rsa_q; } if (q != null) { return BN.newBN(getRuntime(), q); } return getRuntime().getNil(); } private BigInteger getPublicExponent() { if (publicKey != null) { return publicKey.getPublicExponent(); } else if (privateKey != null) { return privateKey.getPublicExponent(); } else { return rsa_e; } } @JRubyMethod(name="e") public synchronized IRubyObject get_e() { BigInteger e = getPublicExponent(); if (e != null) { return BN.newBN(getRuntime(), e); } return getRuntime().getNil(); } @JRubyMethod(name="e=") public synchronized IRubyObject set_e(final ThreadContext context, IRubyObject value) { this.rsa_e = BN.getBigInteger(value); if ( privateKey == null ) { generatePrivateKeyIfParams(context); } if ( publicKey == null ) { generatePublicKeyIfParams(context); } return value; } private BigInteger getModulus() { if (publicKey != null) { return publicKey.getModulus(); } else if (privateKey != null) { return privateKey.getModulus(); } else { return rsa_n; } } @JRubyMethod(name="n") public synchronized IRubyObject get_n() { BigInteger n = getModulus(); if (n != null) { return BN.newBN(getRuntime(), n); } return getRuntime().getNil(); } @JRubyMethod(name="n=") public synchronized IRubyObject set_n(final ThreadContext context, IRubyObject value) { this.rsa_n = BN.getBigInteger(value); if ( privateKey == null ) { generatePrivateKeyIfParams(context); } if ( publicKey == null ) { generatePublicKeyIfParams(context); } return value; } private void generatePublicKeyIfParams(final ThreadContext context) { final Ruby runtime = context.runtime; if ( publicKey != null ) throw newRSAError(runtime, "illegal modification"); // Don't access the rsa_n and rsa_e fields directly. They may have // already been consumed and cleared by generatePrivateKeyIfParams. BigInteger _rsa_n = getModulus(); BigInteger _rsa_e = getPublicExponent(); if (_rsa_n != null && _rsa_e != null) { final KeyFactory rsaFactory; try { rsaFactory = SecurityHelper.getKeyFactory("RSA"); } catch (Exception ex) { throw runtime.newLoadError("unsupported key algorithm (RSA)"); } try { publicKey = (RSAPublicKey) rsaFactory.generatePublic(new RSAPublicKeySpec(_rsa_n, _rsa_e)); } catch (InvalidKeySpecException ex) { throw newRSAError(runtime, "invalid parameters"); } rsa_e = null; rsa_n = null; } } private void generatePrivateKeyIfParams(final ThreadContext context) { final Ruby runtime = context.runtime; if ( privateKey != null ) throw newRSAError(runtime, "illegal modification"); // Don't access the rsa_n and rsa_e fields directly. They may have // already been consumed and cleared by generatePublicKeyIfParams. BigInteger _rsa_n = getModulus(); BigInteger _rsa_e = getPublicExponent(); if (_rsa_n != null && _rsa_e != null && rsa_p != null && rsa_q != null && rsa_d != null && rsa_dmp1 != null && rsa_dmq1 != null && rsa_iqmp != null) { final KeyFactory rsaFactory; try { rsaFactory = SecurityHelper.getKeyFactory("RSA"); } catch (NoSuchAlgorithmException e) { throw runtime.newLoadError("unsupported key algorithm (RSA)"); } try { privateKey = (RSAPrivateCrtKey) rsaFactory.generatePrivate( new RSAPrivateCrtKeySpec(_rsa_n, _rsa_e, rsa_d, rsa_p, rsa_q, rsa_dmp1, rsa_dmq1, rsa_iqmp) ); } catch (InvalidKeySpecException e) { throw newRSAError(runtime, "invalid parameters"); } rsa_n = null; rsa_e = null; rsa_d = null; rsa_p = null; rsa_q = null; rsa_dmp1 = null; rsa_dmq1 = null; rsa_iqmp = null; } } }// PKeyRSA jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/Random.java000066400000000000000000000352731313661621600253620ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.util.SafePropertyAccessor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.concurrent.ThreadLocalRandom; /** * @author Ola Bini */ public class Random { // thread-local (default), shared, strong static final String HOLDER_TYPE = SafePropertyAccessor.getProperty("jruby.openssl.random", ""); private static Holder createHolderImpl() { if (HOLDER_TYPE.equals("default") || HOLDER_TYPE.equals("thread-local")) { return new ThreadLocalHolder(); } if (HOLDER_TYPE.equals("")) { // NOTE: fine to remove when support for running on Java 6 is gone ... if (OpenSSL.javaVersion6(false)) { return new SharedHolder(); // can not-use ThreadLocalRandom.current() } } if (HOLDER_TYPE.equals("shared")) { return new SharedHolder(); } if (HOLDER_TYPE.equals("strong")) { // TODO strong (thread-local) makes sense return new StrongHolder(); } if (ThreadLocalHolder.secureRandomField == null) { return new SharedHolder(); // fall-back on (older) JRuby <= 1.7.4 } return new ThreadLocalHolder(); } static abstract class Holder { abstract java.util.Random getPlainRandom() ; abstract java.security.SecureRandom getSecureRandom(ThreadContext context) ; void seedSecureRandom(ThreadContext context, byte[] seed) { getSecureRandom(context).setSeed(seed); } void seedPlainRandom(long seed) { getPlainRandom().setSeed(seed); } } private static class SharedHolder extends Holder { private volatile java.util.Random plainRandom; private volatile java.security.SecureRandom secureRandom; java.util.Random getPlainRandom() { if (plainRandom == null) { synchronized(this) { if (plainRandom == null) { plainRandom = new java.util.Random(); } } } return plainRandom; } java.security.SecureRandom getSecureRandom(ThreadContext context) { if (secureRandom == null) { synchronized(this) { if (secureRandom == null) { secureRandom = SecurityHelper.getSecureRandom(); } } } return secureRandom; } } private static class ThreadLocalHolder extends Holder { @Override java.util.Random getPlainRandom() { return ThreadLocalRandom.current(); } @Override void seedPlainRandom(long seed) { return; // NO-OP - UnsupportedOperationException } @Override java.security.SecureRandom getSecureRandom(ThreadContext context) { java.security.SecureRandom secureRandom = context.secureRandom; if (secureRandom == null) { secureRandom = getSecureRandomImpl(); setSecureRandom(context, secureRandom); // context.secureRandom = ... } return secureRandom; } private static final Field secureRandomField; private static void setSecureRandom(ThreadContext context, java.security.SecureRandom secureRandom) { if (secureRandomField != null) { try { secureRandomField.set(context, secureRandom); } catch (IllegalAccessException ex) { Utils.throwException(ex); /* should not happen */ } } } private static final String PREFERRED_PRNG; static { String prng = SafePropertyAccessor.getProperty("jruby.preferred.prng", null); if (prng == null) { // make sure the default experience is non-blocking for users prng = "NativePRNGNonBlocking"; if (SafePropertyAccessor.getProperty("os.name") != null) { if (jnr.posix.util.Platform.IS_WINDOWS) { // System.getProperty("os.name") won't fail prng = "Windows-PRNG"; } } } // setting it to "" (empty) or "default" should just use new SecureRandom() : if (prng.isEmpty() || prng.equalsIgnoreCase("default")) { prng = null; tryPreferredPRNG = false; trySHA1PRNG = false; } PREFERRED_PRNG = prng; Field secureRandom = null; try { secureRandom = ThreadContext.class.getField("secureRandom"); if ( ! secureRandom.isAccessible() || Modifier.isFinal(secureRandom.getModifiers()) ) { secureRandom = null; } } catch (Exception ex) { /* ignore NoSuchFieldException */ } secureRandomField = secureRandom; } private static boolean tryPreferredPRNG = true; private static boolean trySHA1PRNG = true; private static boolean tryStrongPRNG = false; // NOT-YET-IMPLEMENTED // copied from JRuby (not available in all 1.7.x) : public java.security.SecureRandom getSecureRandomImpl() { java.security.SecureRandom secureRandom = null; // Try preferred PRNG, which defaults to NativePRNGNonBlocking if (tryPreferredPRNG) { try { secureRandom = java.security.SecureRandom.getInstance(PREFERRED_PRNG); } catch (Exception e) { tryPreferredPRNG = false; OpenSSL.debug("SecureRandom '"+ PREFERRED_PRNG +"' failed:", e); } } // Try SHA1PRNG if (secureRandom == null && trySHA1PRNG) { try { secureRandom = java.security.SecureRandom.getInstance("SHA1PRNG"); } catch (Exception e) { trySHA1PRNG = false; OpenSSL.debug("SecureRandom SHA1PRNG failed:", e); } } // Just let JDK do whatever it does if (secureRandom == null) { secureRandom = new java.security.SecureRandom(); } return secureRandom; } } private static class StrongHolder extends Holder { static { Method method = null; if (OpenSSL.javaVersion8(true)) { try { method = java.security.SecureRandom.class.getMethod("getInstanceStrong"); } catch (NoSuchMethodException ex) { OpenSSL.debugStackTrace(ex); } } getInstanceStrong = method; } private static final Method getInstanceStrong; @Override java.util.Random getPlainRandom() { return new java.util.Random(); } @Override java.security.SecureRandom getSecureRandom(ThreadContext context) { // return java.security.SecureRandom.getInstanceStrong(); (on Java 8) if (getInstanceStrong == null) return SecurityHelper.getSecureRandom(); try { return (java.security.SecureRandom) getInstanceStrong.invoke(null); } catch (IllegalAccessException ex) { Utils.throwException(ex); return null; // won't happen } catch (InvocationTargetException ex) { Utils.throwException(ex.getTargetException()); return null; } } void seedSecureRandom(ThreadContext context, byte[] seed) { // NOOP - new instance returned for getSecureRandom } void seedPlainRandom(long seed) { // NOOP - new instance returned for getPlainRandom } } public static void createRandom(final Ruby runtime, final RubyModule OpenSSL) { final RubyModule Random = OpenSSL.defineModuleUnder("Random"); RubyClass OpenSSLError = (RubyClass) OpenSSL.getConstant("OpenSSLError"); Random.defineClassUnder("RandomError", OpenSSLError, OpenSSLError.getAllocator()); Random.defineAnnotatedMethods(Random.class); Random.dataWrapStruct(createHolderImpl()); } @JRubyMethod(meta = true) public static RubyString random_bytes(final ThreadContext context, final IRubyObject self, final IRubyObject arg) { return random_bytes(context, self, toInt(context.runtime, arg)); } static RubyString random_bytes(final ThreadContext context, final int len) { final RubyModule Random = (RubyModule) context.runtime.getModule("OpenSSL").getConstantAt("Random"); return generate(context, Random, len, true); // secure-random } private static RubyString random_bytes(final ThreadContext context, final IRubyObject self, final int len) { return generate(context, self, len, true); // secure-random } @JRubyMethod(meta = true) public static RubyString pseudo_bytes(final ThreadContext context, final IRubyObject self, final IRubyObject len) { return generate(context, self, toInt(context.runtime, len), false); // plain-random } private static int toInt(final Ruby runtime, final IRubyObject arg) { final long len = RubyNumeric.fix2long(arg); if ( len < 0 || len > Integer.MAX_VALUE ) { throw runtime.newArgumentError("negative string size (or size too big) " + len); } return (int) len; } private static RubyString generate(final ThreadContext context, final IRubyObject self, final int len, final boolean secure) { final Holder holder = retrieveHolder((RubyModule) self); final byte[] bytes = new byte[len]; ( secure ? holder.getSecureRandom(context) : holder.getPlainRandom() ).nextBytes(bytes); return RubyString.newString(context.runtime, new ByteList(bytes, false)); } static Holder getHolder(final Ruby runtime) { return retrieveHolder((RubyModule) runtime.getModule("OpenSSL").getConstantAt("Random")); } private static Holder retrieveHolder(final RubyModule Random) { return (Holder) Random.dataGetStruct(); } @JRubyMethod(meta = true) // seed(str) -> str public static IRubyObject seed(final ThreadContext context, final IRubyObject self, IRubyObject str) { seedImpl(context, (RubyModule) self, str); return str; } private static void seedImpl(ThreadContext context, final RubyModule Random, final IRubyObject str) { final byte[] seed = str.asString().getBytes(); final Holder holder = retrieveHolder(Random); holder.seedSecureRandom(context, seed); // seed supplements existing (secure) seeding mechanism long s; int l = seed.length; if ( l >= 4 ) { s = (seed[0] << 24) | (seed[1] << 16) | (seed[2] << 8) | seed[3]; if ( l >= 8 ) { s = s ^ (seed[l-4] << 24) | (seed[l-3] << 16) | (seed[l-2] << 8) | seed[l-1]; } holder.seedPlainRandom(s); } } // true if the PRNG has been seeded with enough data, false otherwise @JRubyMethod(meta = true, name = "status?") // status? => true | false public static IRubyObject status_p(final ThreadContext context, final IRubyObject self) { return context.runtime.newBoolean(true); } @JRubyMethod(meta = true, name = { "random_add", "add" }) // random_add(str, entropy) -> self public static IRubyObject random_add(final ThreadContext context, final IRubyObject self, IRubyObject str, IRubyObject entropy) { seedImpl(context, (RubyModule) self, str); // simply ignoring _entropy_ hint return self; } // C-Ruby OpenSSL::Random API stubs : @JRubyMethod(meta = true) // load_random_file(filename) public static IRubyObject load_random_file(final ThreadContext context, final IRubyObject self, IRubyObject fname) { return context.runtime.getNil(); } @JRubyMethod(meta = true) // write_random_file(filename) -> true public static IRubyObject write_random_file(final ThreadContext context, final IRubyObject self, IRubyObject fname) { return context.runtime.getNil(); } @JRubyMethod(meta = true) // egd(filename) -> true public static IRubyObject egd(final ThreadContext context, final IRubyObject self, IRubyObject fname) { // no-op let the JVM security infrastructure to its internal seeding return context.runtime.getTrue(); } @JRubyMethod(meta = true) // egd_bytes(filename, length) -> true public static IRubyObject egd_bytes(final ThreadContext context, final IRubyObject self, IRubyObject fname, IRubyObject len) { // no-op let the JVM security infrastructure to its internal seeding return context.runtime.getTrue(); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/SSL.java000066400000000000000000000375441313661621600246060ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.anno.JRubyMethod; import org.jruby.anno.JRubyModule; import org.jruby.exceptions.RaiseException; import org.jruby.internal.runtime.methods.DynamicMethod; import org.jruby.runtime.Block; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.SafePropertyAccessor; /** * @author Ola Bini */ public class SSL { public static final int VERIFY_NONE = 0x00; public static final int VERIFY_PEER = 0x01; public static final int VERIFY_FAIL_IF_NO_PEER_CERT = 0x02; public static final int VERIFY_CLIENT_ONCE = 0x04; public static final long OP_ALL = 0x00000FFFL; public static final long OP_NO_TICKET = 0x00004000L; public static final long OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 0x00010000L; public static final long OP_SINGLE_ECDH_USE = 0x00080000L; public static final long OP_SINGLE_DH_USE = 0x00100000L; public static final long OP_EPHEMERAL_RSA = 0x00200000L; public static final long OP_CIPHER_SERVER_PREFERENCE = 0x00400000L; public static final long OP_TLS_ROLLBACK_BUG = 0x00800000L; public static final long OP_NO_SSLv2 = 0x01000000L; // supported public static final long OP_NO_SSLv3 = 0x02000000L; // supported public static final long OP_NO_TLSv1 = 0x04000000L; // supported public static final long OP_PKCS1_CHECK_1 = 0x08000000L; public static final long OP_PKCS1_CHECK_2 = 0x10000000L; public static final long OP_NETSCAPE_CA_DN_BUG = 0x20000000L; public static final long OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 0x40000000L; private static final String JSSE_TLS_ephemeralDHKeySize = "jdk.tls.ephemeralDHKeySize" ; private static final String JSSE_TLS_ephemeralDHKeySize_default = "matched" ; private static final String JSSE_TLS_disabledAlgorithms = "jdk.tls.disabledAlgorithms" ; private static final String JSSE_TLS_disabledAlgorithms_default = "SSLv3, DHE" ; static { configureJSSE(); } private static void configureJSSE() { if ( OpenSSL.javaVersion8(true) ) { // >= 1.8 try { if ( System.getProperty(JSSE_TLS_ephemeralDHKeySize) == null ) { // The key size is the same as the authentication certificate, // but must be between 1024 bits and 2048 bits, inclusively. // However, the SunJCE provider only supports 2048-bit DH keys larger // than 1024 bits. Consequently, you may use the values 1024 or 2048 only. System.setProperty(JSSE_TLS_ephemeralDHKeySize, JSSE_TLS_ephemeralDHKeySize_default); } } catch (SecurityException ex) { OpenSSL.debug("setting " + JSSE_TLS_ephemeralDHKeySize + " failed: " + ex); } } else { // on JDK 7 DHE is weak - disable completely (unless user-set) try { if ( System.getProperty(JSSE_TLS_disabledAlgorithms) == null ) { System.setProperty(JSSE_TLS_disabledAlgorithms, JSSE_TLS_disabledAlgorithms_default); } } catch (SecurityException se) { OpenSSL.debug("setting " + JSSE_TLS_disabledAlgorithms + " failed: " + se); } } } static RaiseException handleCouldNotGenerateDHKeyPairError(final Ruby runtime, final RuntimeException ex) { String message = ex.getMessage(); if ( OpenSSL.javaHotSpot() || OpenSSL.javaOpenJDK() ) { if ( OpenSSL.javaVersion8(false) ) { // == 1.8 message += " (try disabling DHE using -D"+ JSSE_TLS_disabledAlgorithms +" as only keys of size 1024/2048 are supported in Java 8)"; } else if ( ! OpenSSL.javaVersion8(true) ) { // < 1.8 message += " (try disabling DHE using -D"+ JSSE_TLS_disabledAlgorithms +" as prior to Java 8 only keys of size < 1024 are supported)"; } } return newSSLError(runtime, message, ex); } public static void createSSL(final Ruby runtime, final RubyModule OpenSSL) { final RubyModule SSL = OpenSSL.defineModuleUnder("SSL"); final RubyClass OpenSSLError = OpenSSL.getClass("OpenSSLError"); final RubyClass SSLError = SSL.defineClassUnder("SSLError", OpenSSLError, OpenSSLError.getAllocator()); final IRubyObject WaitReadable = runtime.getIO().getConstantAt("WaitReadable"); if ( WaitReadable != null ) { // since 2.0 (do not exist in 1.8 / 1.9) SSL.defineClassUnder("SSLErrorWaitReadable", SSLError, OpenSSLError.getAllocator()). include(new IRubyObject[]{ WaitReadable }); } final IRubyObject WaitWritable = runtime.getIO().getConstantAt("WaitWritable"); if ( WaitWritable != null ) { // since 2.0 (do not exist in 1.8 / 1.9) SSL.defineClassUnder("SSLErrorWaitWritable", SSLError, OpenSSLError.getAllocator()). include(new IRubyObject[]{ WaitWritable }); } SSL.setConstant("VERIFY_NONE", runtime.newFixnum(VERIFY_NONE)); SSL.setConstant("VERIFY_PEER", runtime.newFixnum(VERIFY_PEER)); SSL.setConstant("VERIFY_FAIL_IF_NO_PEER_CERT", runtime.newFixnum(VERIFY_FAIL_IF_NO_PEER_CERT)); SSL.setConstant("VERIFY_CLIENT_ONCE", runtime.newFixnum(VERIFY_CLIENT_ONCE)); SSL.setConstant("OP_ALL", runtime.newFixnum(OP_ALL)); SSL.setConstant("OP_NO_TICKET", runtime.newFixnum(OP_NO_TICKET)); SSL.setConstant("OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", runtime.newFixnum(OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)); SSL.setConstant("OP_SINGLE_ECDH_USE", runtime.newFixnum(OP_SINGLE_ECDH_USE)); SSL.setConstant("OP_SINGLE_DH_USE", runtime.newFixnum(OP_SINGLE_DH_USE)); SSL.setConstant("OP_EPHEMERAL_RSA", runtime.newFixnum(OP_EPHEMERAL_RSA)); SSL.setConstant("OP_CIPHER_SERVER_PREFERENCE", runtime.newFixnum(OP_CIPHER_SERVER_PREFERENCE)); SSL.setConstant("OP_TLS_ROLLBACK_BUG", runtime.newFixnum(OP_TLS_ROLLBACK_BUG)); SSL.setConstant("OP_NO_SSLv2", runtime.newFixnum(OP_NO_SSLv2)); SSL.setConstant("OP_NO_SSLv3", runtime.newFixnum(OP_NO_SSLv3)); SSL.setConstant("OP_NO_TLSv1", runtime.newFixnum(OP_NO_TLSv1)); SSL.setConstant("OP_PKCS1_CHECK_1", runtime.newFixnum(OP_PKCS1_CHECK_1)); SSL.setConstant("OP_PKCS1_CHECK_2", runtime.newFixnum(OP_PKCS1_CHECK_2)); SSL.setConstant("OP_NETSCAPE_CA_DN_BUG", runtime.newFixnum(OP_NETSCAPE_CA_DN_BUG)); SSL.setConstant("OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", runtime.newFixnum(OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG)); SSLContext.createSSLContext(runtime, SSL); SSLSocket.createSSLSocket(runtime, SSL); SSLSession.createSession(runtime, SSL); createSocketForwarder(SSL); createNonblock(SSL); } public static RaiseException newSSLError(Ruby runtime, Exception ex) { return Utils.newError(runtime, _SSL(runtime).getClass("SSLError"), ex); } public static RaiseException newSSLError(Ruby runtime, String message) { return Utils.newError(runtime, _SSL(runtime).getClass("SSLError"), message, false); } private static RaiseException newSSLError(Ruby runtime, String message, Exception ex) { return Utils.newError(runtime, _SSL(runtime).getClass("SSLError"), message, ex); } public static RaiseException newSSLErrorWaitReadable(Ruby runtime, String message) { return newWaitSSLError(runtime, "SSLErrorWaitReadable", message); } public static RaiseException newSSLErrorWaitWritable(Ruby runtime, String message) { return newWaitSSLError(runtime, "SSLErrorWaitWritable", message); } // -Djruby.openssl.ssl.error_wait_nonblock.backtrace=false disables backtrace for WaitReadable/Writable private static final boolean waitErrorBacktrace; static { String backtrace = SafePropertyAccessor.getProperty("jruby.openssl.ssl.error_wait_nonblock.backtrace"); if (backtrace == null) { // default to JRuby's Option ERRNO_BACKTRACE = // ... "Generate backtraces for heavily-used Errno exceptions (EAGAIN)." backtrace = SafePropertyAccessor.getProperty("jruby.errno.backtrace", "false"); } waitErrorBacktrace = Boolean.parseBoolean(backtrace); } private static RaiseException newWaitSSLError(final Ruby runtime, final String name, final String message) { RubyClass errorClass = _SSL(runtime).getClass(name); if ( errorClass == null ) { // < Ruby 2.0 errorClass = _SSL(runtime).getClass("SSLError"); // fallback } if ( waitErrorBacktrace ) { return Utils.newError(runtime, errorClass, message, false); } return Utils.newErrorWithoutTrace(runtime, errorClass, message, false); } static RubyModule _SSL(final Ruby runtime) { return (RubyModule) runtime.getModule("OpenSSL").getConstant("SSL"); } private static RubyModule createSocketForwarder(final RubyModule SSL) { // OpenSSL::SSL final RubyModule SocketForwarder = SSL.defineModuleUnder("SocketForwarder"); SocketForwarder.defineAnnotatedMethods(SocketForwarder.class); return SocketForwarder; } @JRubyModule(name = "OpenSSL::SSL::SocketForwarder") public static class SocketForwarder { @JRubyMethod public static IRubyObject addr(ThreadContext context, IRubyObject self) { return to_io(context, self).callMethod(context, "addr"); } @JRubyMethod public static IRubyObject peeraddr(ThreadContext context, IRubyObject self) { return to_io(context, self).callMethod(context, "peeraddr"); } @JRubyMethod(name = "closed?") public static IRubyObject closed_p(ThreadContext context, IRubyObject self) { return to_io(context, self).callMethod(context, "closed?"); } @JRubyMethod //@JRubyMethod(required = 2) // def getsockopt(level, optname) //public static IRubyObject getsockopt(ThreadContext context, IRubyObject self, IRubyObject[] args) { public static IRubyObject getsockopt(ThreadContext context, IRubyObject self, IRubyObject level, IRubyObject optname) { //return to_io(context, self).callMethod(context, "getsockopt", args); return to_io(context, self).callMethod(context, "getsockopt", new IRubyObject[] { level, optname }); } @JRubyMethod //@JRubyMethod(required = 3) // def setsockopt(level, optname, optval) //public static IRubyObject setsockopt(ThreadContext context, IRubyObject self, IRubyObject[] args) { public static IRubyObject setsockopt(ThreadContext context, IRubyObject self, IRubyObject level, IRubyObject optname, IRubyObject optval) { //return to_io(context, self).callMethod(context, "setsockopt", args); return to_io(context, self).callMethod(context, "setsockopt", new IRubyObject[] { level, optname, optval }); } @JRubyMethod(name = "do_not_reverse_lookup=") // def do_not_reverse_lookup=(flag) public static IRubyObject do_not_reverse_lookup_eq(ThreadContext context, IRubyObject self, IRubyObject flag) { return to_io(context, self).callMethod(context, "do_not_reverse_lookup=", flag); } @JRubyMethod(rest = true) // def fcntl(*args) public static IRubyObject fcntl(ThreadContext context, IRubyObject self, IRubyObject[] args) { return to_io(context, self).callMethod(context, "fcntl", args); } private static IRubyObject to_io(ThreadContext context, IRubyObject self) { return self.callMethod(context, "to_io"); } } // SocketForwarder private static RubyModule createNonblock(final RubyModule SSL) { // OpenSSL::SSL final RubyModule Nonblock = SSL.defineModuleUnder("Nonblock"); Nonblock.defineAnnotatedMethods(Nonblock.class); return Nonblock; } @JRubyModule(name = "OpenSSL::SSL::Nonblock") public static class Nonblock { @JRubyMethod(rest = true, frame = true) // framed due super public static IRubyObject initialize(ThreadContext context, IRubyObject self, IRubyObject[] args) { final Ruby runtime = context.runtime; IRubyObject flag = runtime.getFile().getConstant("NONBLOCK"); // File::NONBLOCK IRubyObject Fcntl = runtime.getObject().getConstantAt("Fcntl"); if ( /* Fcntl != null && */ Fcntl instanceof RubyModule ) { final IRubyObject io = self.getInstanceVariables().getInstanceVariable("@io"); final RubyClass ioClass = self.getMetaClass(); final DynamicMethod fcntl = ioClass.searchMethod("fcntl"); IRubyObject F_GETFL = ((RubyModule) Fcntl).getConstantAt("F_GETFL"); if ( F_GETFL != null ) { // if defined?(Fcntl::F_GETFL) // flag |= @io.fcntl(Fcntl::F_GETFL) : flag = or(context, flag, fcntl.call(context, io, ioClass, "fcntl", F_GETFL)); } IRubyObject F_SETFL = ((RubyModule) Fcntl).getConstant("F_SETFL"); fcntl.call(context, io, ioClass, "fcntl", new IRubyObject[] { F_SETFL, flag }); // @io.fcntl(Fcntl::F_SETFL, flag) } return Utils.invokeSuper(context, self, args, Block.NULL_BLOCK); // super } private static IRubyObject or(final ThreadContext context, final IRubyObject flag, final IRubyObject flags) { if ( flag instanceof RubyFixnum && flags instanceof RubyFixnum ) { final long f = ((RubyFixnum) flag).getLongValue(); final long fs = ((RubyFixnum) flags).getLongValue(); return RubyFixnum.newFixnum(context.runtime, f | fs); } return flag.callMethod(context, "|", flags); } } // Nonblock }// SSL jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/SSLContext.java000066400000000000000000001314671313661621600261520ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import java.security.GeneralSecurityException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Collections; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLSessionContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509ExtendedKeyManager; import javax.net.ssl.X509TrustManager; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyHash; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubySymbol; import org.jruby.anno.JRubyMethod; import org.jruby.common.IRubyWarnings.ID; import org.jruby.runtime.Arity; import org.jruby.runtime.Block; import org.jruby.runtime.BlockCallback; import org.jruby.runtime.CallBlock; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import org.jruby.util.ByteList; import org.jruby.ext.openssl.x509store.Certificate; import org.jruby.ext.openssl.x509store.Name; import org.jruby.ext.openssl.x509store.Store; import org.jruby.ext.openssl.x509store.StoreContext; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import org.jruby.ext.openssl.x509store.X509Object; import org.jruby.ext.openssl.x509store.X509Utils; import static org.jruby.ext.openssl.StringHelper.*; import static org.jruby.ext.openssl.SSL.*; import static org.jruby.ext.openssl.X509._X509; import static org.jruby.ext.openssl.X509Cert._Certificate; import static org.jruby.ext.openssl.OpenSSL.debug; import static org.jruby.ext.openssl.OpenSSL.debugStackTrace; import static org.jruby.ext.openssl.OpenSSL.warn; import static org.jruby.ext.openssl.Utils.hasNonNilInstanceVariable; /** * @author Ola Bini */ public class SSLContext extends RubyObject { private static final long serialVersionUID = -6955774230685920773L; // Mapping table for OpenSSL's SSL_METHOD -> JSSE's SSLContext algorithm. private static final HashMap SSL_VERSION_OSSL2JSSE; // Mapping table for JSEE's enabled protocols for the algorithm. private static final Map ENABLED_PROTOCOLS; static { SSL_VERSION_OSSL2JSSE = new LinkedHashMap(20, 1); ENABLED_PROTOCOLS = new HashMap(8, 1); SSL_VERSION_OSSL2JSSE.put("TLSv1", "TLSv1"); SSL_VERSION_OSSL2JSSE.put("TLSv1_server", "TLSv1"); SSL_VERSION_OSSL2JSSE.put("TLSv1_client", "TLSv1"); ENABLED_PROTOCOLS.put("TLSv1", new String[] { "TLSv1" }); SSL_VERSION_OSSL2JSSE.put("SSLv2", "SSLv2"); SSL_VERSION_OSSL2JSSE.put("SSLv2_server", "SSLv2"); SSL_VERSION_OSSL2JSSE.put("SSLv2_client", "SSLv2"); ENABLED_PROTOCOLS.put("SSLv2", new String[] { "SSLv2" }); SSL_VERSION_OSSL2JSSE.put("SSLv3", "SSLv3"); SSL_VERSION_OSSL2JSSE.put("SSLv3_server", "SSLv3"); SSL_VERSION_OSSL2JSSE.put("SSLv3_client", "SSLv3"); ENABLED_PROTOCOLS.put("SSLv3", new String[] { "SSLv3" }); SSL_VERSION_OSSL2JSSE.put("SSLv23", "SSL"); SSL_VERSION_OSSL2JSSE.put("SSLv23_server", "SSL"); SSL_VERSION_OSSL2JSSE.put("SSLv23_client", "SSL"); if ( OpenSSL.javaVersion7(true) ) { // >= 1.7 ENABLED_PROTOCOLS.put("SSL", new String[] { "SSLv2", "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }); } else { ENABLED_PROTOCOLS.put("SSL", new String[] { "SSLv2", "SSLv3", "TLSv1" }); } // Historically we were ahead of MRI to support TLS // ... thus the non-standard names version names : SSL_VERSION_OSSL2JSSE.put("TLS", "TLS"); ENABLED_PROTOCOLS.put("TLS", new String[] { "TLSv1", "TLSv1.1", "TLSv1.2" }); SSL_VERSION_OSSL2JSSE.put("TLSv1.1", "TLSv1.1"); SSL_VERSION_OSSL2JSSE.put("TLSv1_1_server", "TLSv1.1"); SSL_VERSION_OSSL2JSSE.put("TLSv1_1_client", "TLSv1.1"); ENABLED_PROTOCOLS.put("TLSv1.1", new String[] { "TLSv1.1" }); SSL_VERSION_OSSL2JSSE.put("TLSv1_1", "TLSv1.1"); // supported on MRI 2.x SSL_VERSION_OSSL2JSSE.put("TLSv1_2", "TLSv1.2"); // supported on MRI 2.x ENABLED_PROTOCOLS.put("TLSv1.2", new String[] { "TLSv1.2" }); SSL_VERSION_OSSL2JSSE.put("TLSv1.2", "TLSv1.2"); // just for completeness SSL_VERSION_OSSL2JSSE.put("TLSv1_2_server", "TLSv1.2"); SSL_VERSION_OSSL2JSSE.put("TLSv1_2_client", "TLSv1.2"); } private static ObjectAllocator SSLCONTEXT_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new SSLContext(runtime, klass); } }; public static void createSSLContext(final Ruby runtime, final RubyModule SSL) { // OpenSSL::SSL RubyClass SSLContext = SSL.defineClassUnder("SSLContext", runtime.getObject(), SSLCONTEXT_ALLOCATOR); final ThreadContext context = runtime.getCurrentContext(); SSLContext.addReadWriteAttribute(context, "cert"); SSLContext.addReadWriteAttribute(context, "key"); SSLContext.addReadWriteAttribute(context, "client_ca"); SSLContext.addReadWriteAttribute(context, "ca_file"); SSLContext.addReadWriteAttribute(context, "ca_path"); SSLContext.addReadWriteAttribute(context, "timeout"); SSLContext.addReadWriteAttribute(context, "verify_mode"); SSLContext.addReadWriteAttribute(context, "verify_depth"); SSLContext.addReadWriteAttribute(context, "verify_callback"); SSLContext.addReadWriteAttribute(context, "options"); SSLContext.addReadWriteAttribute(context, "cert_store"); SSLContext.addReadWriteAttribute(context, "extra_chain_cert"); SSLContext.addReadWriteAttribute(context, "client_cert_cb"); SSLContext.addReadWriteAttribute(context, "session_id_context"); SSLContext.addReadWriteAttribute(context, "tmp_dh_callback"); SSLContext.addReadWriteAttribute(context, "servername_cb"); SSLContext.addReadWriteAttribute(context, "renegotiation_cb"); SSLContext.defineAlias("ssl_timeout", "timeout"); SSLContext.defineAlias("ssl_timeout=", "timeout="); SSLContext.defineAnnotatedMethods(SSLContext.class); SSLContext.undefineMethod("dup"); final Set methodKeys = SSL_VERSION_OSSL2JSSE.keySet(); final RubyArray methods = runtime.newArray( methodKeys.size() ); for ( final String method : methodKeys ) { if ( method.equals("SSLv2") || method.startsWith("SSLv2_") ) { continue; // do not report SSLv2, SSLv2_server, SSLv2_client } if ( method.indexOf('.') == -1 ) { // do not "officially" report TLSv1.1 and TLSv1.2 methods.append( runtime.newSymbol(method) ); } } SSLContext.defineConstant("METHODS", methods); // in 1.8.7 as well as 1.9.3 : // [:TLSv1, :TLSv1_server, :TLSv1_client, :SSLv3, :SSLv3_server, :SSLv3_client, :SSLv23, :SSLv23_server, :SSLv23_client] // in 2.0.0 : // [:TLSv1, :TLSv1_server, :TLSv1_client, :TLSv1_2, :TLSv1_2_server, :TLSv1_2_client, :TLSv1_1, :TLSv1_1_server, // :TLSv1_1_client, :SSLv3, :SSLv3_server, :SSLv3_client, :SSLv23, :SSLv23_server, :SSLv23_client] SSLContext.setConstant("SESSION_CACHE_OFF", runtime.newFixnum(SESSION_CACHE_OFF)); SSLContext.setConstant("SESSION_CACHE_CLIENT", runtime.newFixnum(SESSION_CACHE_CLIENT)); SSLContext.setConstant("SESSION_CACHE_SERVER", runtime.newFixnum(SESSION_CACHE_SERVER)); SSLContext.setConstant("SESSION_CACHE_BOTH", runtime.newFixnum(SESSION_CACHE_BOTH)); SSLContext.setConstant("SESSION_CACHE_NO_AUTO_CLEAR", runtime.newFixnum(SESSION_CACHE_NO_AUTO_CLEAR)); SSLContext.setConstant("SESSION_CACHE_NO_INTERNAL_LOOKUP", runtime.newFixnum(SESSION_CACHE_NO_INTERNAL_LOOKUP)); SSLContext.setConstant("SESSION_CACHE_NO_INTERNAL_STORE", runtime.newFixnum(SESSION_CACHE_NO_INTERNAL_STORE)); SSLContext.setConstant("SESSION_CACHE_NO_INTERNAL", runtime.newFixnum(SESSION_CACHE_NO_INTERNAL)); // DEFAULT_CERT_STORE = OpenSSL::X509::Store.new // DEFAULT_CERT_STORE.set_default_paths // if defined?(OpenSSL::X509::V_FLAG_CRL_CHECK_ALL) // DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL // end final X509Store DEFAULT_CERT_STORE = X509Store.newStore(runtime); DEFAULT_CERT_STORE.set_default_paths(context); final IRubyObject V_FLAG_CRL_CHECK_ALL = _X509(runtime).getConstantAt("V_FLAG_CRL_CHECK_ALL"); if ( V_FLAG_CRL_CHECK_ALL != null ) DEFAULT_CERT_STORE.set_flags(V_FLAG_CRL_CHECK_ALL); SSLContext.setConstant("DEFAULT_CERT_STORE", DEFAULT_CERT_STORE); // DEFAULT_PARAMS = { // :ssl_version => "SSLv23", // :verify_mode => OpenSSL::SSL::VERIFY_PEER, // :ciphers => "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW", // :options => OpenSSL::SSL::OP_ALL, // } // on MRI 2.1 (should not matter for us) : // :options => defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS) ? // OpenSSL::SSL::OP_ALL & ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS : // OpenSSL::SSL::OP_ALL final RubyHash DEFAULT_PARAMS = new RubyHash(runtime); IRubyObject ssl_version = StringHelper.newString(runtime, new byte[] { 'S','S','L','v','2','3' }); DEFAULT_PARAMS.op_aset(context, runtime.newSymbol("ssl_version"), ssl_version); IRubyObject verify_mode = runtime.newFixnum(VERIFY_PEER); DEFAULT_PARAMS.op_aset(context, runtime.newSymbol("verify_mode"), verify_mode); IRubyObject ciphers = StringHelper.newString(runtime, new byte[] { 'A','L','L',':', '!','A','D','H',':', '!','E','X','P','O','R','T',':', '!','S','S','L','v','2',':', 'R','C','4','+','R','S','A',':', '+','H','I','G','H',':', '+','M','E','D','I','U','M',':', '+','L','O','W' }); DEFAULT_PARAMS.op_aset(context, runtime.newSymbol("ciphers"), ciphers); IRubyObject options = runtime.newFixnum(OP_ALL); DEFAULT_PARAMS.op_aset(context, runtime.newSymbol("options"), options); SSLContext.setConstant("DEFAULT_PARAMS", DEFAULT_PARAMS); } static final int SESSION_CACHE_OFF = 0; static final int SESSION_CACHE_CLIENT = 1; static final int SESSION_CACHE_SERVER = 2; static final int SESSION_CACHE_BOTH = 3; // 1 | 2 static final int SESSION_CACHE_NO_AUTO_CLEAR = 128; static final int SESSION_CACHE_NO_INTERNAL_LOOKUP = 256; static final int SESSION_CACHE_NO_INTERNAL_STORE = 512; static final int SESSION_CACHE_NO_INTERNAL = 768; public SSLContext(Ruby runtime, RubyClass type) { super(runtime,type); } SSLContext(Ruby runtime) { super(runtime, _SSLContext(runtime)); } private String ciphers = CipherStrings.SSL_DEFAULT_CIPHER_LIST; private String protocol = "SSL"; // SSLv23 in OpenSSL by default private boolean protocolForServer = true; private boolean protocolForClient = true; private PKey t_key; private X509Cert t_cert; private int verifyResult = 1; /* avoid 0 (= X509_V_OK) just in case */ //private int sessionCacheMode; // 2 default on MRI private int sessionCacheSize; // 20480 private InternalContext internalContext; @JRubyMethod(required = 0, optional = 1, visibility = Visibility.PRIVATE) public IRubyObject initialize(IRubyObject[] args) { if ( args.length > 0 ) set_ssl_version(args[0]); return initializeImpl(); } final SSLContext initializeImpl() { return this; } @JRubyMethod public IRubyObject setup(final ThreadContext context) { final Ruby runtime = context.runtime; if ( isFrozen() ) return runtime.getNil(); synchronized(this) { if ( isFrozen() ) return runtime.getNil(); this.freeze(context); } final X509Store certStore = getCertStore(); // TODO: handle tmp_dh_callback : // #if !defined(OPENSSL_NO_DH) // if (RTEST(ossl_sslctx_get_tmp_dh_cb(self))){ // SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); // } // else{ // SSL_CTX_set_tmp_dh_callback(ctx, ossl_default_tmp_dh_callback); // } // #endif IRubyObject value; value = getInstanceVariable("@key"); final PKey key; if ( value != null && ! value.isNil() ) { if ( ! ( value instanceof PKey ) ) { throw runtime.newTypeError("OpenSSL::PKey::PKey expected but got @key = " + value.inspect()); } key = (PKey) value; } else { key = getCallbackKey(context); } value = getInstanceVariable("@cert"); final X509Cert cert; if ( value != null && ! value.isNil() ) { if ( ! ( value instanceof X509Cert ) ) { throw runtime.newTypeError("OpenSSL::X509::Certificate expected but got @cert = " + value.inspect()); } cert = (X509Cert) value; } else { cert = getCallbackCert(context); } value = getInstanceVariable("@client_ca"); final List clientCert; if ( value != null && ! value.isNil() ) { if ( value.respondsTo("each") ) { clientCert = convertToAuxCerts(context, value); } else { if ( ! ( value instanceof X509Cert ) ) { throw runtime.newTypeError("OpenSSL::X509::Certificate expected but got @client_ca = " + value.inspect()); } clientCert = Collections.singletonList( ((X509Cert) value).getAuxCert() ); } } else clientCert = Collections.emptyList(); value = getInstanceVariable("@extra_chain_cert"); final List extraChainCert; if ( value != null && ! value.isNil() ) { extraChainCert = convertToAuxCerts(context, value); } else { extraChainCert = null; } value = getInstanceVariable("@verify_mode"); final int verifyMode; if ( value != null && ! value.isNil() ) { verifyMode = RubyNumeric.fix2int(value); } else { verifyMode = SSL.VERIFY_NONE; // 0x00 } value = getInstanceVariable("@timeout"); final int timeout; if ( value != null && ! value.isNil() ) { timeout = RubyNumeric.fix2int(value); } else { timeout = 0; } final Store store = certStore != null ? certStore.getStore() : new Store(); final String caFile = getCaFile(); final String caPath = getCaPath(); if (caFile != null || caPath != null) { try { if (store.loadLocations(runtime, caFile, caPath) == 0) { runtime.getWarnings().warn(ID.MISCELLANEOUS, "can't set verify locations"); } } catch (Exception e) { if ( e instanceof RuntimeException ) debugStackTrace(runtime, e); throw newSSLError(runtime, e); } } value = getInstanceVariable("@verify_callback"); if ( value != null && ! value.isNil() ) { store.setExtraData(1, value); } else { store.setExtraData(1, null); } value = getInstanceVariable("@verify_depth"); if ( value != null && ! value.isNil() ) { store.setDepth(RubyNumeric.fix2int(value)); } else { store.setDepth(-1); } value = getInstanceVariable("@servername_cb"); if ( value != null && ! value.isNil() ) { // SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); } // NOTE: no API under javax.net to support session get/new/remove callbacks /* val = ossl_sslctx_get_sess_id_ctx(self); if (!NIL_P(val)){ StringValue(val); if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), RSTRING_LEN(val))){ ossl_raise(eSSLError, "SSL_CTX_set_session_id_context:"); } } if (RTEST(rb_iv_get(self, "@session_get_cb"))) { SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); OSSL_Debug("SSL SESSION get callback added"); } if (RTEST(rb_iv_get(self, "@session_new_cb"))) { SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); OSSL_Debug("SSL SESSION new callback added"); } if (RTEST(rb_iv_get(self, "@session_remove_cb"))) { SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); OSSL_Debug("SSL SESSION remove callback added"); } */ try { internalContext = createInternalContext(context, cert, key, store, clientCert, extraChainCert, verifyMode, timeout); } catch (GeneralSecurityException e) { throw newSSLError(runtime, e); } return runtime.getTrue(); } @JRubyMethod public RubyArray ciphers(final ThreadContext context) { return matchedCiphers(context); } private RubyArray matchedCiphers(final ThreadContext context) { final Ruby runtime = context.runtime; try { final String[] supported = getSupportedCipherSuites(this.protocol); final Collection cipherDefs = CipherStrings.matchingCiphers(this.ciphers, supported, false); final IRubyObject[] cipherList = new IRubyObject[ cipherDefs.size() ]; int i = 0; for ( CipherStrings.Def def : cipherDefs ) { cipherList[i++] = runtime.newArrayNoCopy( newUTF8String(runtime, def.name), // 0 newUTF8String(runtime, sslVersionString(def.algorithms)), // 1 runtime.newFixnum(def.algStrengthBits), // 2 runtime.newFixnum(def.algBits) // 3 ); } return runtime.newArrayNoCopy(cipherList); } catch (GeneralSecurityException gse) { throw newSSLError(runtime, gse.getMessage()); } } @JRubyMethod(name = "ciphers=") public IRubyObject set_ciphers(final ThreadContext context, final IRubyObject ciphers) { if ( ciphers.isNil() ) { this.ciphers = CipherStrings.SSL_DEFAULT_CIPHER_LIST; } else if ( ciphers instanceof RubyArray ) { final RubyArray ciphs = (RubyArray) ciphers; StringBuilder cipherStr = new StringBuilder(); String sep = ""; for ( int i = 0; i < ciphs.size(); i++ ) { cipherStr.append(sep).append( ciphs.eltInternal(i).toString() ); sep = ":"; } this.ciphers = cipherStr.toString(); } else { this.ciphers = ciphers.asString().toString(); } if ( matchedCiphers(context).isEmpty() ) { throw newSSLError(context.runtime, "no cipher match"); } return ciphers; } @JRubyMethod(name = "ssl_version=") public IRubyObject set_ssl_version(IRubyObject version) { final String versionStr; if ( version instanceof RubySymbol ) { versionStr = version.toString(); } else { versionStr = version.convertToString().toString(); } final String protocol = SSL_VERSION_OSSL2JSSE.get(versionStr); if ( protocol == null ) { throw getRuntime().newArgumentError("unknown SSL method `"+ versionStr +"'"); } this.protocol = protocol; protocolForServer = ! versionStr.endsWith("_client"); protocolForClient = ! versionStr.endsWith("_server"); return version; } final String getProtocol() { return this.protocol; } // ## // # Sets the parameters for this SSL context to the values in +params+. // # The keys in +params+ must be assignment methods on SSLContext. // # // # If the verify_mode is not VERIFY_NONE and ca_file, ca_path and // # cert_store are not set then the system default certificate store is // # used. // // def set_params(params={}) // params = DEFAULT_PARAMS.merge(params) // params.each{|name, value| self.__send__("#{name}=", value) } // if self.verify_mode != OpenSSL::SSL::VERIFY_NONE // unless self.ca_file or self.ca_path or self.cert_store // self.cert_store = DEFAULT_CERT_STORE // end // end // return params // end @JRubyMethod(optional = 1) public IRubyObject set_params(final ThreadContext context, final IRubyObject[] args) { final RubyHash params; final RubyClass SSLContext = _SSLContext(context.runtime); RubyHash DEFAULT_PARAMS = (RubyHash) SSLContext.getConstantAt("DEFAULT_PARAMS"); if ( args.length == 0 ) params = DEFAULT_PARAMS; else { params = (RubyHash) DEFAULT_PARAMS.merge(context, args[0], Block.NULL_BLOCK); } final SSLContext self = this; params.visitAll(new RubyHash.Visitor() { @Override public void visit(IRubyObject name, IRubyObject value) { self.callMethod(context, name.toString() + '=', value); } }); IRubyObject verify_mode = self.getInstanceVariable("@verify_mode"); if ( verify_mode != null && ! verify_mode.isNil() && RubyNumeric.fix2int(verify_mode) != SSL.VERIFY_NONE ) { if ( ! hasNonNilInstanceVariable(self, "@ca_file") && ! hasNonNilInstanceVariable(self, "@ca_path") && ! hasNonNilInstanceVariable(self, "@cert_store") ) { IRubyObject DEFAULT_CERT_STORE = SSLContext.getConstantAt("DEFAULT_CERT_STORE"); self.setInstanceVariable("@cert_store", DEFAULT_CERT_STORE); } } return params; } @JRubyMethod(name = "session_cache_mode") public IRubyObject session_cache_mode() { return getRuntime().getNil(); //return getRuntime().newFixnum(sessionCacheMode); } @JRubyMethod(name = "session_cache_mode=") public IRubyObject set_session_cache_mode(IRubyObject mode) { //this.sessionCacheMode = RubyInteger.fix2int(mode); //return mode; warn(getRuntime().getCurrentContext(), "SSLContext#session_cache_mode= has no effect under JRuby"); return session_cache_mode(); } @JRubyMethod(name = "session_cache_size") public IRubyObject session_cache_size() { return getRuntime().newFixnum(sessionCacheSize); } @JRubyMethod(name = "session_cache_size=") public IRubyObject set_session_cache_size(IRubyObject size) { this.sessionCacheSize = RubyInteger.fix2int(size); return size; } @JRubyMethod(name = "session_cache_stats") public RubyHash session_cache_stats(final ThreadContext context) { // NOTE: session cache NOT IMPLEMENTED // { :connect_renegotiate=>0, :cache_full=>0, :accept_good=>0, // :connect=>0, :timeouts=>0, :accept_renegotiate=>0, :accept=>0, // :cache_hits=>0, :cache_num=>0, :cb_hits=>0, :connect_good=>0, // :cache_misses=>0 } return RubyHash.newHash(context.runtime); } @JRubyMethod(name = "security_level=") public IRubyObject set_security_level(ThreadContext context, IRubyObject level) { warn(context, "WARNING: SSLContext#security_level= has no effect under JRuby"); return context.nil; } boolean isProtocolForServer() { return protocolForServer; } boolean isProtocolForClient() { return protocolForClient; } int getLastVerifyResult() { return verifyResult; } void setLastVerifyResult(int verifyResult) { this.verifyResult = verifyResult; } private static String cachedProtocol = null; private static String[] cachedSupportedCipherSuites; private static String[] getSupportedCipherSuites(final String protocol) throws GeneralSecurityException { if ( cachedProtocol == null ) { synchronized(SSLContext.class) { if ( cachedProtocol == null ) { cachedSupportedCipherSuites = dummySSLEngine(protocol).getSupportedCipherSuites(); cachedProtocol = protocol; return cachedSupportedCipherSuites; } } } if ( protocol.equals(cachedProtocol) ) return cachedSupportedCipherSuites; return dummySSLEngine(protocol).getSupportedCipherSuites(); } private static SSLEngine dummySSLEngine(final String protocol) throws GeneralSecurityException { javax.net.ssl.SSLContext sslContext = SecurityHelper.getSSLContext(protocol); sslContext.init(null, null, null); return sslContext.createSSLEngine(); } // should keep SSLContext as a member for introducin SSLSession. later... final SSLEngine createSSLEngine(String peerHost, int peerPort) throws NoSuchAlgorithmException, KeyManagementException { final SSLEngine engine; // an empty peerHost implies no SNI (RFC 3546) support requested if ( peerHost == null || peerHost.length() == 0 ) { // no hints for an internal session reuse strategy engine = internalContext.getSSLContext().createSSLEngine(); } // SNI is attempted for valid peerHost hostname on Java >= 7 // if peerHost is set to an IP address Java does not use SNI else { engine = internalContext.getSSLContext().createSSLEngine(peerHost, peerPort); } engine.setEnabledCipherSuites( getCipherSuites(engine.getSupportedCipherSuites()) ); engine.setEnabledProtocols( getEnabledProtocols(engine) ); return engine; } private String[] getCipherSuites(final String[] supported) { Collection cipherDefs = CipherStrings.matchingCiphers(this.ciphers, supported, true); final String[] result = new String[ cipherDefs.size() ]; int i = 0; for ( CipherStrings.Def def : cipherDefs ) { result[ i++ ] = def.getCipherSuite(); } return result; } private String[] getEnabledProtocols(final SSLEngine engine) { final String[] enabledProtocols = ENABLED_PROTOCOLS.get(protocol); if ( enabledProtocols != null ) { final long options = getOptions(); final String[] engineProtocols = engine.getEnabledProtocols(); final List protocols = new ArrayList(enabledProtocols.length); for ( final String enabled : enabledProtocols ) { if (((options & SSL.OP_NO_SSLv2) != 0) && enabled.equals("SSLv2")) { continue; } if (((options & SSL.OP_NO_SSLv3) != 0) && enabled.equals("SSLv3")) { continue; } if (((options & SSL.OP_NO_TLSv1) != 0) && enabled.equals("TLSv1")) { continue; } for ( final String allowed : engineProtocols ) { if ( allowed.equals(enabled) ) protocols.add(allowed); } } return protocols.toArray( new String[ protocols.size() ] ); } return new String[0]; } private static final byte[] TLSv1 = { 'T','L','S','v','1' }; private static final byte[] SSLv2 = { 'S','S','L','v','2' }; private static final byte[] SSLv3 = { 'S','S','L','v','3' }; private ByteList sslVersionString(long bits) { final ByteList str = new ByteList(18); boolean first = true; if ( ( bits & CipherStrings.SSL_SSLV3 ) != 0 ) { if ( ! first ) str.append('/'); first = false; str.append( TLSv1 ); str.append('/'); str.append( SSLv3 ); } if ( ( bits & CipherStrings.SSL_SSLV2 ) != 0 ) { if ( ! first ) str.append('/'); // first = false; str.append( SSLv2 ); } return str; } private PKey getCallbackKey(final ThreadContext context) { if ( t_key != null ) return t_key; initFromCallback(context); return t_key; } private X509Cert getCallbackCert(final ThreadContext context) { if ( t_cert != null ) return t_cert; initFromCallback(context); return t_cert; } private void initFromCallback(final ThreadContext context) { final IRubyObject callback = getInstanceVariable("@client_cert_cb"); if ( callback != null && ! callback.isNil() ) { IRubyObject arr = callback.callMethod(context, "call", this); if ( ! ( arr instanceof RubyArray ) ) { throw context.runtime.newTypeError("expected @client_cert_cb.call to return an Array but got: " + arr.getMetaClass().getName()); } final IRubyObject cert = ((RubyArray) arr).entry(0); final IRubyObject key = ((RubyArray) arr).entry(1); if ( ! ( cert instanceof X509Cert ) ) { throw context.runtime.newTypeError(cert.inspect() + " is not an instance of OpenSSL::X509::Certificate"); } if ( ! ( key instanceof PKey ) ) { throw context.runtime.newTypeError(key.inspect() + " is not an instance of OpenSSL::PKey::PKey"); } t_cert = (X509Cert) cert; t_key = (PKey) key; } } private X509Store getCertStore() { IRubyObject cert_store = getInstanceVariable("@cert_store"); if ( cert_store instanceof X509Store ) { return (X509Store) cert_store; } return null; } private String getCaFile() { IRubyObject ca_file = getInstanceVariable("@ca_file"); if ( ca_file != null && ! ca_file.isNil() ) { return ca_file.asString().toString(); } return null; } private String getCaPath() { IRubyObject ca_path = getInstanceVariable("@ca_path"); if ( ca_path != null && ! ca_path.isNil() ) { return ca_path.asString().toString(); } return null; } private long getOptions() { IRubyObject options = getInstanceVariable("@options"); if ( options != null && ! options.isNil() ) { return RubyNumeric.fix2long(options); } return 0; } private static List convertToAuxCerts(final ThreadContext context, IRubyObject value) { final RubyModule SSLContext = _SSLContext(context.runtime); final RubyModule Certificate = _Certificate(context.runtime); if ( value instanceof RubyArray ) { final RubyArray val = (RubyArray) value; final int size = val.size(); final ArrayList result = new ArrayList(size); for ( int i=0; i val = (List) value; final int size = val.size(); final ArrayList result = new ArrayList(size); for ( int i=0; i result = new ArrayList(); Utils.invoke(context, value, "each", CallBlock.newCallClosure(value, SSLContext, Arity.NO_ARGUMENTS, new BlockCallback() { public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block) { result.add( assureCertificate(context, Certificate, args[0]).getAuxCert() ); return context.nil; } }, context) ); return result; } private static X509Cert assureCertificate(final ThreadContext context, final RubyModule Certificate, final IRubyObject cert) { if ( ! ( Certificate.isInstance(cert) ) ) { throw context.runtime.newTypeError("wrong argument : " + cert.inspect() + " is not a " + Certificate.getName()); } return (X509Cert) cert; } static RubyClass _SSLContext(final Ruby runtime) { return (RubyClass) _SSL(runtime).getConstantAt("SSLContext"); } private InternalContext createInternalContext(ThreadContext context, final X509Cert xCert, final PKey pKey, final Store store, final List clientCert, final List extraChainCert, final int verifyMode, final int timeout) throws NoSuchAlgorithmException, KeyManagementException { InternalContext internalContext = new InternalContext(xCert, pKey, store, clientCert, extraChainCert, verifyMode, timeout); internalContext.initSSLContext(context); return internalContext; } /** * c: SSL_CTX */ private class InternalContext { InternalContext( final X509Cert xCert, final PKey pKey, final Store store, final List clientCert, final List extraChainCert, final int verifyMode, final int timeout) throws NoSuchAlgorithmException, KeyManagementException { if ( pKey != null && xCert != null ) { this.privateKey = pKey.getPrivateKey(); this.keyAlgorithm = pKey.getAlgorithm(); this.cert = xCert.getAuxCert(); } else { this.privateKey = null; this.keyAlgorithm = null; this.cert = null; } this.store = store; this.clientCert = clientCert; this.extraChainCert = extraChainCert; this.verifyMode = verifyMode; //this.timeout = timeout; // initialize SSL context : final javax.net.ssl.SSLContext sslContext = SecurityHelper.getSSLContext(protocol); if ( protocolForClient ) { final SSLSessionContext clientContext = sslContext.getClientSessionContext(); clientContext.setSessionTimeout(timeout); if ( sessionCacheSize >= 0 ) { clientContext.setSessionCacheSize(sessionCacheSize); } } if ( protocolForServer ) { final SSLSessionContext serverContext = sslContext.getClientSessionContext(); serverContext.setSessionTimeout(timeout); if ( sessionCacheSize >= 0 ) { serverContext.setSessionCacheSize(sessionCacheSize); } } this.sslContext = sslContext; } protected void initSSLContext(final ThreadContext context) throws KeyManagementException { final KeyManager[] keyManager = new KeyManager[] { new KeyManagerImpl(this) }; final TrustManager[] trustManager = new TrustManager[] { new TrustManagerImpl(this) }; // SSLContext (internals) on Sun JDK : // private final java.security.Provider provider; "SunJSSE" // private final javax.net.ssl.SSLContextSpi; sun.security.ssl.SSLContextImpl sslContext.init(keyManager, trustManager, OpenSSL.getSecureRandomFrom(context)); // if secureRandom == null JSSE will try : // - new SecureRandom(); // - SecureRandom.getInstance("PKCS11", cryptoProvider); } final Store store; final X509AuxCertificate cert; final String keyAlgorithm; final PrivateKey privateKey; final int verifyMode; final List clientCert; // assumed always != null final List extraChainCert; // empty assumed == null //final int timeout; private final javax.net.ssl.SSLContext sslContext; // part of ssl_verify_cert_chain StoreContext createStoreContext(final String purpose) { if ( store == null ) return null; final StoreContext storeContext = new StoreContext(store); if ( storeContext.init(null, null) == 0 ) return null; // for verify_cb storeContext.setExtraData(1, store.getExtraData(1)); if ( purpose != null ) storeContext.setDefault(purpose); storeContext.verifyParameter.inherit(store.verifyParameter); return storeContext; } final javax.net.ssl.SSLContext getSSLContext() { return sslContext; } void setLastVerifyResult(int lastVerifyResult) { SSLContext.this.setLastVerifyResult(lastVerifyResult); } } private static class KeyManagerImpl extends X509ExtendedKeyManager { final InternalContext internalContext; KeyManagerImpl(InternalContext internalContext) { super(); this.internalContext = internalContext; } @Override public String chooseEngineClientAlias(String[] keyType, java.security.Principal[] issuers, javax.net.ssl.SSLEngine engine) { if (internalContext.privateKey == null) return null; for (int i = 0; i < keyType.length; i++) { if (keyType[i].equalsIgnoreCase(internalContext.keyAlgorithm)) { return keyType[i]; } } return null; } @Override public String chooseEngineServerAlias(String keyType, java.security.Principal[] issuers, javax.net.ssl.SSLEngine engine) { if (internalContext.privateKey == null) return null; if (keyType.equalsIgnoreCase(internalContext.keyAlgorithm)) { return keyType; } return null; } @Override public String chooseClientAlias(String[] keyType, java.security.Principal[] issuers, java.net.Socket socket) { return null; } @Override public String chooseServerAlias(String keyType, java.security.Principal[] issuers, java.net.Socket socket) { return null; } @Override // c: ssl3_output_cert_chain public java.security.cert.X509Certificate[] getCertificateChain(String alias) { final List chain; if ( internalContext.extraChainCert != null ) { chain = (List) internalContext.extraChainCert; } else if ( internalContext.cert != null ) { chain = new ArrayList(8); StoreContext storeCtx = internalContext.createStoreContext(null); X509AuxCertificate x = internalContext.cert; while (true) { chain.add(x); if ( x.getIssuerDN().equals(x.getSubjectDN()) ) break; try { final Name name = new Name(x.getIssuerX500Principal()); X509Object[] s_obj = new X509Object[1]; if (storeCtx.getBySubject(X509Utils.X509_LU_X509, name, s_obj) <= 0) { break; } x = ((Certificate) s_obj[0]).x509; } catch (RuntimeException e) { debugStackTrace(e); break; } catch (Exception e) { debug("KeyManagerImpl bySubject failed", e); break; } } } else { chain = Collections.EMPTY_LIST; } return chain.toArray( new java.security.cert.X509Certificate[chain.size()] ); } @Override public String[] getClientAliases(String keyType, java.security.Principal[] issuers) { return null; } @Override public java.security.PrivateKey getPrivateKey(String alias) { return internalContext.privateKey; // might be null } @Override public String[] getServerAliases(String keyType, java.security.Principal[] issuers) { return null; } } private static class TrustManagerImpl implements X509TrustManager { final InternalContext internalContext; TrustManagerImpl(InternalContext internalContext) { super(); this.internalContext = internalContext; } @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { checkTrusted("ssl_client", chain); } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { checkTrusted("ssl_server", chain); } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { final int size = internalContext.clientCert.size(); return internalContext.clientCert.toArray( new java.security.cert.X509Certificate[size] ); } // c: ssl_verify_cert_chain private void checkTrusted(final String purpose, final X509Certificate[] chain) throws CertificateException { if ( chain != null && chain.length > 0 ) { if ( (internalContext.verifyMode & SSL.VERIFY_PEER) != 0 ) { // verify_peer final StoreContext storeContext = internalContext.createStoreContext(purpose); if ( storeContext == null ) { throw new CertificateException("couldn't initialize store"); } storeContext.setCertificate(chain[0]); storeContext.setChain(chain); verifyChain(storeContext); } } else { if ( (internalContext.verifyMode & SSL.VERIFY_FAIL_IF_NO_PEER_CERT) != 0 ) { // fail if no peer cert throw new CertificateException("no peer certificate"); } } } private void verifyChain(final StoreContext storeContext) throws CertificateException { final int ok; try { ok = storeContext.verifyCertificate(); } catch (Exception e) { internalContext.setLastVerifyResult(storeContext.error); if ( storeContext.error == X509Utils.V_OK ) { internalContext.setLastVerifyResult(X509Utils.V_ERR_CERT_REJECTED); } throw new CertificateException("certificate verify failed", e); } internalContext.setLastVerifyResult(storeContext.error); if ( ok == 0 ) { throw new CertificateException("certificate verify failed"); } } } }// SSLContext jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/SSLSession.java000066400000000000000000000143421313661621600261410ustar00rootroot00000000000000/* * The MIT License * * Copyright 2015 Karol Bucek. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import java.util.Arrays; import javax.net.ssl.SSLSessionContext; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import static org.jruby.ext.openssl.OpenSSL._OpenSSLError; import static org.jruby.ext.openssl.OpenSSL.warn; import static org.jruby.ext.openssl.SSL._SSL; import static org.jruby.ext.openssl.OpenSSL.warn; /** * OpenSSL::SSL::Session * * @author kares */ public class SSLSession extends RubyObject { private static final ObjectAllocator SESSION_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new SSLSession(runtime, klass); } }; public static void createSession(final Ruby runtime, final RubyModule SSL) { // OpenSSL::SSL RubyClass Session = SSL.defineClassUnder("Session", runtime.getObject(), SESSION_ALLOCATOR); Session.defineAnnotatedMethods(SSLSession.class); // OpenSSL::SSL::Session::SessionError RubyClass OpenSSLError = _OpenSSLError(runtime); Session.defineClassUnder("SessionError", OpenSSLError, OpenSSLError.getAllocator()); } private javax.net.ssl.SSLSession sslSession; SSLSession(Ruby runtime, RubyClass metaClass) { super(runtime, metaClass); } SSLSession(Ruby runtime) { this(runtime, (RubyClass) _SSL(runtime).getConstantAt("Session")); } @JRubyMethod(name = "initialize", visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject arg) { final Ruby runtime = context.runtime; if ( arg instanceof SSLSocket ) { return initializeImpl((SSLSocket) arg); } throw runtime.newNotImplementedError("Session#initialize with " + arg.getMetaClass().getName()); } SSLSession initializeImpl(final SSLSocket socket) { sslSession = socket.sslSession(); return this; } final javax.net.ssl.SSLSession sslSession() { return sslSession; } @JRubyMethod(name = "==") public IRubyObject op_eqq(final ThreadContext context, final IRubyObject other) { return context.runtime.newBoolean( equals(other) ); } @Override public boolean equals(final Object other) { if ( other instanceof SSLSession ) { final SSLSession that = (SSLSession) other; if ( this.sslSession.getProtocol().equals( that.sslSession.getProtocol() ) ) { if ( Arrays.equals( this.sslSession.getId(), that.sslSession.getId() ) ) { return true; } } } return false; } @Override public final int hashCode() { return 17 * sslSession.hashCode(); } @Override public RubyFixnum hash() { return getRuntime().newFixnum(hashCode()); } @JRubyMethod(name = "id") public RubyString id(final ThreadContext context) { final byte[] id = sslSession().getId(); return context.runtime.newString( new ByteList(id) ); } @JRubyMethod(name = "id=") public IRubyObject set_id(final ThreadContext context, IRubyObject id) { warn(context, "WARNING: Session#id= is not supported (read-only)"); return context.nil; } @JRubyMethod(name = "time") public RubyTime time(final ThreadContext context) { final long time = sslSession().getCreationTime(); return RubyTime.newTime(context.runtime, time); } @JRubyMethod(name = "time=") public IRubyObject set_time(final ThreadContext context, IRubyObject time) { warn(context, "WARNING: Session#time= is not supported (read-only)"); return context.nil; } @JRubyMethod(name = "timeout") public IRubyObject timeout(final ThreadContext context) { final SSLSessionContext sessionContext = sslSession().getSessionContext(); // default in OpenSSL is 300 if ( sessionContext == null ) return context.runtime.newFixnum(300); return context.runtime.newFixnum(sessionContext.getSessionTimeout()); } @JRubyMethod(name = "timeout=") public IRubyObject set_timeout(final ThreadContext context, IRubyObject timeout) { final SSLSessionContext sessionContext = sslSession().getSessionContext(); if ( sessionContext == null ) { warn(context, "WARNING: can not set Session#timeout=("+ timeout +") no session context"); return context.nil; } sessionContext.setSessionTimeout(RubyNumeric.fix2int(timeout)); // in seconds as well return timeout; } @Override public Object toJava(Class target) { if ( javax.net.ssl.SSLSession.class.isAssignableFrom(target) ) { return sslSession(); } return super.toJava(target); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/SSLSocket.java000066400000000000000000001342551313661621600257540ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.Channel; import java.nio.channels.ClosedChannelException; import java.nio.channels.NotYetConnectedException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLException; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLPeerUnverifiedException; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyHash; import org.jruby.RubyIO; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.RubyThread; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.x509store.X509Utils; import org.jruby.runtime.Arity; import org.jruby.runtime.Block; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.runtime.Visibility; import static org.jruby.ext.openssl.SSL.newSSLErrorWaitReadable; import static org.jruby.ext.openssl.SSL.newSSLErrorWaitWritable; import static org.jruby.ext.openssl.OpenSSL.*; /** * @author Ola Bini */ public class SSLSocket extends RubyObject { private static final long serialVersionUID = -2084816623554406237L; private static final ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new SSLSocket(runtime, klass); } }; public static void createSSLSocket(final Ruby runtime, final RubyModule SSL) { // OpenSSL::SSL final ThreadContext context = runtime.getCurrentContext(); RubyClass SSLSocket = SSL.defineClassUnder("SSLSocket", runtime.getObject(), ALLOCATOR); // SSLSocket.addReadAttribute(context, "io"); // SSLSocket.defineAlias("to_io", "io"); // SSLSocket.addReadAttribute(context, "context"); SSLSocket.addReadWriteAttribute(context, "sync_close"); SSLSocket.addReadWriteAttribute(context, "hostname"); SSLSocket.defineAnnotatedMethods(SSLSocket.class); SSLSocket.undefineMethod("dup"); } public SSLSocket(Ruby runtime, RubyClass type) { super(runtime, type); } private static RaiseException newSSLError(Ruby runtime, Exception exception) { return SSL.newSSLError(runtime, exception); } private static RaiseException newSSLError(Ruby runtime, String message) { return SSL.newSSLError(runtime, message); } private static RaiseException newSSLErrorFromHandshake(Ruby runtime, SSLHandshakeException exception) { // SSLHandshakeException is always a wrap around another exception that // is the actual cause. In some cases the diagnostic message from the original // exception is also lost and the handshake exception reads "General SSLEngine problem" // Follow the cause chain until we get the real message and use that to ensure // we raise an exception that contains the real reason for failure Exception cause = exception; while (cause.getCause() != null && (cause instanceof SSLHandshakeException)) { cause = (Exception) cause.getCause(); } return SSL.newSSLError(runtime, cause); } private SSLContext sslContext; private SSLEngine engine; private RubyIO io; private ByteBuffer peerAppData; private ByteBuffer peerNetData; private ByteBuffer netData; private ByteBuffer dummy; private boolean initialHandshake = false; private SSLEngineResult.HandshakeStatus handshakeStatus; private SSLEngineResult.Status status; int verifyResult = X509Utils.V_OK; @Deprecated public IRubyObject _initialize(final ThreadContext context, final IRubyObject[] args, final Block unused) { return initialize(context, args); } @JRubyMethod(name = "initialize", rest = true, frame = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; if ( Arity.checkArgumentCount(runtime, args, 1, 2) == 1 ) { sslContext = new SSLContext(runtime).initializeImpl(); } else { sslContext = (SSLContext) args[1]; } if ( ! ( args[0] instanceof RubyIO ) ) { throw runtime.newTypeError("IO expected but got " + args[0].getMetaClass().getName()); } setInstanceVariable("@io", this.io = (RubyIO) args[0]); // compat (we do not read @io) // Ruby 2.3 : @io.nonblock = true if @io.respond_to?(:nonblock=) if (io.respondsTo("nonblock=")) { io.callMethod(context, "nonblock=", runtime.getTrue()); } setInstanceVariable("@context", this.sslContext); // only compat (we do not use @context) // This is a bit of a hack: SSLSocket should share code with // RubyBasicSocket, which always sets sync to true. // Instead we set it here for now. this.set_sync(context, runtime.getTrue()); // io.sync = true this.callMethod(context, "sync_close=", runtime.getFalse()); sslContext.setup(context); return Utils.invokeSuper(context, this, args, Block.NULL_BLOCK); // super() } private SSLEngine ossl_ssl_setup(final ThreadContext context) throws NoSuchAlgorithmException, KeyManagementException, IOException { SSLEngine engine = this.engine; if ( engine != null ) return engine; // Server Name Indication (SNI) RFC 3546 // SNI support will not be attempted unless hostname is explicitly set by the caller String peerHost = this.callMethod(context, "hostname").toString(); final int peerPort = socketChannelImpl().getRemotePort(); engine = sslContext.createSSLEngine(peerHost, peerPort); final javax.net.ssl.SSLSession session = engine.getSession(); peerNetData = ByteBuffer.allocate(session.getPacketBufferSize()); peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize()); netData = ByteBuffer.allocate(session.getPacketBufferSize()); peerNetData.limit(0); peerAppData.limit(0); netData.limit(0); dummy = ByteBuffer.allocate(0); this.engine = engine; copySessionSetupIfSet(); return engine; } @JRubyMethod(name = "io", alias = "to_io") public final RubyIO io() { return this.io; } @JRubyMethod(name = "context") public final SSLContext context() { return this.sslContext; } @JRubyMethod(name = "sync") public IRubyObject sync(final ThreadContext context) { return this.io.callMethod(context, "sync"); } @JRubyMethod(name = "sync=") public IRubyObject set_sync(final ThreadContext context, final IRubyObject sync) { return this.io.callMethod(context, "sync=", sync); } @JRubyMethod public IRubyObject connect(final ThreadContext context) { return connectImpl(context, true, true); } @JRubyMethod public IRubyObject connect_nonblock(final ThreadContext context) { return connectImpl(context, false, true); } @JRubyMethod public IRubyObject connect_nonblock(final ThreadContext context, IRubyObject opts) { return connectImpl(context, false, getExceptionOpt(context, opts)); } private IRubyObject connectImpl(final ThreadContext context, final boolean blocking, final boolean exception) { if ( ! sslContext.isProtocolForClient() ) { throw newSSLError(context.runtime, "called a function you should not call"); } try { if ( ! initialHandshake ) { SSLEngine engine = ossl_ssl_setup(context); engine.setUseClientMode(true); engine.beginHandshake(); handshakeStatus = engine.getHandshakeStatus(); initialHandshake = true; } callRenegotiationCallback(context); final IRubyObject ex = doHandshake(blocking, exception); if ( ex != null ) return ex; // :wait_readable | :wait_writable } catch (SSLHandshakeException e) { //debugStackTrace(runtime, e); // unlike server side, client should close outbound channel even if // we have remaining data to be sent. forceClose(); throw newSSLErrorFromHandshake(context.runtime, e); } catch (NoSuchAlgorithmException e) { debugStackTrace(context.runtime, e); forceClose(); throw newSSLError(context.runtime, e); } catch (KeyManagementException e) { debugStackTrace(context.runtime, e); forceClose(); throw newSSLError(context.runtime, e); } catch (IOException e) { //debugStackTrace(context.runtime, e); forceClose(); throw newSSLError(context.runtime, e); } catch (NotYetConnectedException e) { throw newErrnoEPIPEError(context.runtime, "SSL_connect"); } return this; } private static RaiseException newErrnoEPIPEError(final Ruby runtime, final String detail) { return Utils.newError(runtime, runtime.getErrno().getClass("EPIPE"), detail); } @JRubyMethod public IRubyObject accept(final ThreadContext context) { return acceptImpl(context, true, true); } @JRubyMethod public IRubyObject accept_nonblock(final ThreadContext context) { return acceptImpl(context, false, true); } @JRubyMethod public IRubyObject accept_nonblock(final ThreadContext context, IRubyObject opts) { return acceptImpl(context, false, getExceptionOpt(context, opts)); } @Deprecated public SSLSocket acceptCommon(ThreadContext context, boolean blocking) { return (SSLSocket) acceptImpl(context, blocking, true); } private IRubyObject acceptImpl(final ThreadContext context, final boolean blocking, final boolean exception) { if ( ! sslContext.isProtocolForServer() ) { throw newSSLError(context.runtime, "called a function you should not call"); } try { if ( ! initialHandshake ) { final SSLEngine engine = ossl_ssl_setup(context); engine.setUseClientMode(false); final IRubyObject verify_mode = sslContext.callMethod(context, "verify_mode"); if ( ! verify_mode.isNil() ) { final int verify = RubyNumeric.fix2int(verify_mode); if ( verify == 0 ) { // VERIFY_NONE engine.setNeedClientAuth(false); engine.setWantClientAuth(false); } if ( ( verify & 1 ) != 0 ) { // VERIFY_PEER engine.setWantClientAuth(true); } if ( ( verify & 2 ) != 0 ) { // VERIFY_FAIL_IF_NO_PEER_CERT engine.setNeedClientAuth(true); } } engine.beginHandshake(); handshakeStatus = engine.getHandshakeStatus(); initialHandshake = true; } callRenegotiationCallback(context); final IRubyObject ex = doHandshake(blocking, exception); if ( ex != null ) return ex; // :wait_readable | :wait_writable } catch (SSLHandshakeException e) { final String msg = e.getMessage(); // updated JDK (>= 1.7.0_75) with deprecated SSL protocols : // javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate) if ( e.getCause() == null && msg != null && msg.contains("(protocol is disabled or cipher suites are inappropriate)") ) { debug(context.runtime, sslContext.getProtocol() + " protocol has been deactivated and is not available by default\n see the java.security.Security property jdk.tls.disabledAlgorithms in /lib/security/java.security file"); } else { debugStackTrace(context.runtime, e); } throw newSSLErrorFromHandshake(context.runtime, e); } catch (NoSuchAlgorithmException e) { debugStackTrace(context.runtime, e); throw newSSLError(context.runtime, e); } catch (KeyManagementException e) { debugStackTrace(context.runtime, e); throw newSSLError(context.runtime, e); } catch (IOException e) { debugStackTrace(context.runtime, e); throw newSSLError(context.runtime, e); } catch (RaiseException e) { throw e; } catch (RuntimeException e) { debugStackTrace(context.runtime, e); if ( "Could not generate DH keypair".equals( e.getMessage() ) ) { throw SSL.handleCouldNotGenerateDHKeyPairError(context.runtime, e); } throw newSSLError(context.runtime, e); } return this; } @JRubyMethod public IRubyObject verify_result(final ThreadContext context) { final Ruby runtime = context.runtime; if (engine == null) { runtime.getWarnings().warn("SSL session is not started yet."); return runtime.getNil(); } return runtime.newFixnum(verifyResult); } // This select impl is a copy of RubyThread.select, then blockingLock is // removed. This impl just set // SelectableChannel.configureBlocking(false) permanently instead of setting // temporarily. SSLSocket requires wrapping IO to be selectable so it should // be OK to set configureBlocking(false) permanently. private Object waitSelect(final int operations, final boolean blocking, final boolean exception) throws IOException { final SocketChannelImpl channel = socketChannelImpl(); if ( ! channel.isSelectable() ) return Boolean.TRUE; final Ruby runtime = getRuntime(); final RubyThread thread = runtime.getCurrentContext().getThread(); channel.configureBlocking(false); final Selector selector = runtime.getSelectorPool().get(); final SelectionKey key = channel.register(selector, operations); try { final int[] result = new int[1]; if ( ! blocking ) { try { result[0] = selector.selectNow(); if ( result[0] == 0 ) { if ((operations & SelectionKey.OP_READ) != 0 && (operations & SelectionKey.OP_WRITE) != 0) { if ( key.isReadable() ) { writeWouldBlock(runtime, exception, result); } //else if ( key.isWritable() ) { // readWouldBlock(runtime, exception, result); //} else { //neither, pick one readWouldBlock(runtime, exception, result); } } else if ((operations & SelectionKey.OP_READ) != 0) { readWouldBlock(runtime, exception, result); } else if ((operations & SelectionKey.OP_WRITE) != 0) { writeWouldBlock(runtime, exception, result); } } } catch (IOException ioe) { throw runtime.newRuntimeError("Error with selector: " + ioe.getMessage()); } } else { io.addBlockingThread(thread); thread.executeBlockingTask(new RubyThread.BlockingTask() { public void run() throws InterruptedException { try { result[0] = selector.select(); } catch (IOException ioe) { throw runtime.newRuntimeError("Error with selector: " + ioe.getMessage()); } } public void wakeup() { selector.wakeup(); } }); } switch ( result[0] ) { case READ_WOULD_BLOCK_RESULT : return runtime.newSymbol("wait_readable"); // exception: false case WRITE_WOULD_BLOCK_RESULT : return runtime.newSymbol("wait_writable"); // exception: false case 0 : return Boolean.FALSE; default : //key should always be contained in selectedKeys() here, however there is a bug in //JRuby <= 9.1.2.0 that makes this not always the case, so we have to check return selector.selectedKeys().contains(key) ? Boolean.TRUE : Boolean.FALSE; } } catch (InterruptedException interrupt) { return Boolean.FALSE; } finally { // Note: I don't like ignoring these exceptions, but it's // unclear how likely they are to happen or what damage we // might do by ignoring them. Note that the pieces are separate // so that we can ensure one failing does not affect the others // running. // clean up the key in the selector try { if ( key != null ) key.cancel(); if ( selector != null ) selector.selectNow(); } catch (Exception e) { // ignore debugStackTrace(runtime, e); } // shut down and null out the selector try { if ( selector != null ) { runtime.getSelectorPool().put(selector); } } catch (Exception e) { // ignore debugStackTrace(runtime, e); } if (blocking) { // remove this thread as a blocker against the given IO io.removeBlockingThread(thread); // clear thread state from blocking call thread.afterBlockingCall(); } } } private static final int READ_WOULD_BLOCK_RESULT = Integer.MIN_VALUE + 1; private static final int WRITE_WOULD_BLOCK_RESULT = Integer.MIN_VALUE + 2; private static void readWouldBlock(final Ruby runtime, final boolean exception, final int[] result) { if ( exception ) throw newSSLErrorWaitReadable(runtime, "read would block"); result[0] = READ_WOULD_BLOCK_RESULT; } private static void writeWouldBlock(final Ruby runtime, final boolean exception, final int[] result) { if ( exception ) throw newSSLErrorWaitWritable(runtime, "write would block"); result[0] = WRITE_WOULD_BLOCK_RESULT; } private void doHandshake(final boolean blocking) throws IOException { doHandshake(blocking, true); } // might return :wait_readable | :wait_writable in case (true, false) private IRubyObject doHandshake(final boolean blocking, final boolean exception) throws IOException { while (true) { Object sel = waitSelect(SelectionKey.OP_READ | SelectionKey.OP_WRITE, blocking, exception); if ( sel instanceof IRubyObject ) return (IRubyObject) sel; // :wait_readable | :wait_writable // if not blocking, raise EAGAIN if ( ! blocking && sel != Boolean.TRUE ) { throw getRuntime().newErrnoEAGAINError("Resource temporarily unavailable"); } // otherwise, proceed as before switch (handshakeStatus) { case FINISHED: case NOT_HANDSHAKING: if ( initialHandshake ) finishInitialHandshake(); return null; // OK case NEED_TASK: doTasks(); break; case NEED_UNWRAP: if (readAndUnwrap(blocking) == -1 && handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED) { throw new SSLHandshakeException("Socket closed"); } // during initialHandshake, calling readAndUnwrap that results UNDERFLOW // does not mean writable. we explicitly wait for readable channel to avoid // busy loop. if (initialHandshake && status == SSLEngineResult.Status.BUFFER_UNDERFLOW) { sel = waitSelect(SelectionKey.OP_READ, blocking, exception); if ( sel instanceof IRubyObject ) return (IRubyObject) sel; // :wait_readable } break; case NEED_WRAP: if ( netData.hasRemaining() ) { while ( flushData(blocking) ) { /* loop */ } } netData.clear(); SSLEngineResult result = engine.wrap(dummy, netData); handshakeStatus = result.getHandshakeStatus(); netData.flip(); flushData(blocking); break; default: throw new IllegalStateException("Unknown handshaking status: " + handshakeStatus); } } } private void doTasks() { Runnable task; while ((task = engine.getDelegatedTask()) != null) { task.run(); } handshakeStatus = engine.getHandshakeStatus(); verifyResult = sslContext.getLastVerifyResult(); } private boolean flushData(boolean blocking) throws IOException { try { writeToChannel(netData, blocking); } catch (IOException ioe) { netData.position(netData.limit()); throw ioe; } if ( netData.hasRemaining() ) { return true; } return false; } private int writeToChannel(ByteBuffer buffer, boolean blocking) throws IOException { int totalWritten = 0; while ( buffer.hasRemaining() ) { totalWritten += socketChannelImpl().write(buffer); if ( ! blocking ) break; // don't continue attempting to read } return totalWritten; } private void finishInitialHandshake() { initialHandshake = false; } private void callRenegotiationCallback(final ThreadContext context) throws RaiseException { IRubyObject renegotiationCallback = sslContext.getInstanceVariable("@renegotiation_cb"); if(renegotiationCallback == null || renegotiationCallback.isNil()) { return; } else { // the return of the Proc is not important // Can throw ruby exception to "disallow" renegotiations renegotiationCallback.callMethod(context, "call", this); } } public int write(ByteBuffer src, boolean blocking) throws SSLException, IOException { if ( initialHandshake ) { throw new IOException("Writing not possible during handshake"); } SocketChannelImpl channel = socketChannelImpl(); final boolean blockingMode = channel.isBlocking(); if ( ! blocking ) channel.configureBlocking(false); try { if ( netData.hasRemaining() ) { flushData(blocking); } netData.clear(); final SSLEngineResult result = engine.wrap(src, netData); if ( result.getStatus() == SSLEngineResult.Status.CLOSED ) { throw getRuntime().newIOError("closed SSL engine"); } netData.flip(); flushData(blocking); return result.bytesConsumed(); } finally { if ( ! blocking ) channel.configureBlocking(blockingMode); } } public int read(final ByteBuffer dst, final boolean blocking) throws IOException { if ( initialHandshake ) return 0; if ( engine.isInboundDone() ) return -1; if ( ! peerAppData.hasRemaining() ) { int appBytesProduced = readAndUnwrap(blocking); if (appBytesProduced == -1 || appBytesProduced == 0) { return appBytesProduced; } } int limit = Math.min(peerAppData.remaining(), dst.remaining()); peerAppData.get(dst.array(), dst.arrayOffset(), limit); dst.position(dst.arrayOffset() + limit); return limit; } private int readAndUnwrap(final boolean blocking) throws IOException { final int bytesRead = socketChannelImpl().read(peerNetData); if ( bytesRead == -1 ) { if ( ! peerNetData.hasRemaining() || ( status == SSLEngineResult.Status.BUFFER_UNDERFLOW ) ) { closeInbound(); return -1; } // inbound channel has been already closed but closeInbound() must // be defered till the last engine.unwrap() call. // peerNetData could not be empty. } peerAppData.clear(); peerNetData.flip(); SSLEngineResult result; do { result = engine.unwrap(peerNetData, peerAppData); } while ( result.getStatus() == SSLEngineResult.Status.OK && result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP && result.bytesProduced() == 0 ); if ( result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED ) { finishInitialHandshake(); } if ( peerAppData.position() == 0 && result.getStatus() == SSLEngineResult.Status.OK && peerNetData.hasRemaining() ) { result = engine.unwrap(peerNetData, peerAppData); } status = result.getStatus(); handshakeStatus = result.getHandshakeStatus(); if ( bytesRead == -1 && ! peerNetData.hasRemaining() ) { // now it's safe to call closeInbound(). closeInbound(); } if ( status == SSLEngineResult.Status.CLOSED ) { doShutdown(); return -1; } peerNetData.compact(); peerAppData.flip(); if ( ! initialHandshake && ( handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_TASK || handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP || handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED ) ) { doHandshake(blocking); } return peerAppData.remaining(); } private void closeInbound() { try { engine.closeInbound(); } catch (SSLException e) { debug(getRuntime(), "SSLSocket.closeInbound", e); // ignore any error on close. possibly an error like this; // Inbound closed before receiving peer's close_notify: possible truncation attack? } } private void doShutdown() throws IOException { if ( engine.isOutboundDone() ) return; netData.clear(); try { engine.wrap(dummy, netData); } catch (SSLException e) { debug(getRuntime(), "SSLSocket.doShutdown", e); return; } catch (RuntimeException e) { debugStackTrace(getRuntime(), e); return; } netData.flip(); flushData(true); } private IRubyObject sysreadImpl(final ThreadContext context, IRubyObject len, IRubyObject buff, final boolean blocking, final boolean exception) { final Ruby runtime = context.runtime; final int length = RubyNumeric.fix2int(len); final RubyString buffStr; if ( buff != null && ! buff.isNil() ) { buffStr = buff.asString(); } else { buffStr = RubyString.newEmptyString(runtime); // fine since we're setValue } if ( length == 0 ) { buffStr.clear(); return buffStr; } if ( length < 0 ) { throw runtime.newArgumentError("negative string size (or size too big)"); } try { // So we need to make sure to only block when there is no data left to process if ( engine == null || ! ( peerAppData.hasRemaining() || peerNetData.position() > 0 ) ) { final Object ex = waitSelect(SelectionKey.OP_READ, blocking, exception); if ( ex instanceof IRubyObject ) return (IRubyObject) ex; // :wait_readable } final ByteBuffer dst = ByteBuffer.allocate(length); int read = -1; // ensure >0 bytes read; sysread is blocking read. while ( read <= 0 ) { if ( engine == null ) { read = socketChannelImpl().read(dst); } else { read = read(dst, blocking); } if ( read == -1 ) { if ( exception ) throw runtime.newEOFError(); return runtime.getNil(); } if ( read == 0 && status == SSLEngineResult.Status.BUFFER_UNDERFLOW ) { // If we didn't get any data back because we only read in a partial TLS record, // instead of spinning until the rest comes in, call waitSelect to either block // until the rest is available, or throw a "read would block" error if we are in // non-blocking mode. final Object ex = waitSelect(SelectionKey.OP_READ, blocking, exception); if ( ex instanceof IRubyObject ) return (IRubyObject) ex; // :wait_readable } } final byte[] bytesRead = dst.array(); final int offset = dst.position() - read; buffStr.setValue(new ByteList(bytesRead, offset, read, false)); return buffStr; } catch (IOException ioe) { throw runtime.newIOError(ioe.getMessage()); } } @JRubyMethod public IRubyObject sysread(ThreadContext context, IRubyObject len) { return sysreadImpl(context, len, null, true, true); } @JRubyMethod public IRubyObject sysread(ThreadContext context, IRubyObject len, IRubyObject buff) { return sysreadImpl(context, len, buff, true, true); } @Deprecated // @JRubyMethod(rest = true, required = 1, optional = 1) public IRubyObject sysread(ThreadContext context, IRubyObject[] args) { switch ( args.length) { case 1 : return sysread(context, args[0]); case 2 : return sysread(context, args[0], args[1]); } Arity.checkArgumentCount(context.runtime, args.length, 1, 2); return null; // won't happen as checkArgumentCount raises } @JRubyMethod public IRubyObject sysread_nonblock(ThreadContext context, IRubyObject len) { return sysreadImpl(context, len, null, false, true); } @JRubyMethod public IRubyObject sysread_nonblock(ThreadContext context, IRubyObject len, IRubyObject arg) { if ( arg instanceof RubyHash ) { // exception: false // NOTE: on Ruby 2.3 this is expected to raise a TypeError (but not on 2.2) return sysreadImpl(context, len, null, false, getExceptionOpt(context, arg)); } return sysreadImpl(context, len, arg, false, true); // buffer arg } @JRubyMethod public IRubyObject sysread_nonblock(ThreadContext context, IRubyObject len, IRubyObject buff, IRubyObject opts) { return sysreadImpl(context, len, buff, false, getExceptionOpt(context, opts)); } @Deprecated // @JRubyMethod(rest = true, required = 1, optional = 2) public IRubyObject sysread_nonblock(ThreadContext context, IRubyObject[] args) { switch ( args.length) { case 1 : return sysread_nonblock(context, args[0]); case 2 : return sysread_nonblock(context, args[0], args[1]); case 3 : return sysread_nonblock(context, args[0], args[1], args[2]); } Arity.checkArgumentCount(context.runtime, args.length, 1, 3); return null; // won't happen as checkArgumentCount raises } private IRubyObject syswriteImpl(final ThreadContext context, final IRubyObject arg, final boolean blocking, final boolean exception) { final Ruby runtime = context.runtime; try { checkClosed(); final Object ex = waitSelect(SelectionKey.OP_WRITE, blocking, exception); if ( ex instanceof IRubyObject ) return (IRubyObject) ex; // :wait_writable ByteList bytes = arg.asString().getByteList(); ByteBuffer buff = ByteBuffer.wrap(bytes.getUnsafeBytes(), bytes.getBegin(), bytes.getRealSize()); final int written; if ( engine == null ) { written = writeToChannel(buff, blocking); } else { written = write(buff, blocking); } this.io.callMethod(context, "flush"); return runtime.newFixnum(written); } catch (IOException ioe) { throw runtime.newIOError(ioe.getMessage()); } } @JRubyMethod public IRubyObject syswrite(ThreadContext context, IRubyObject arg) { return syswriteImpl(context, arg, true, true); } @JRubyMethod public IRubyObject syswrite_nonblock(ThreadContext context, IRubyObject arg) { return syswriteImpl(context, arg, false, true); } @JRubyMethod public IRubyObject syswrite_nonblock(ThreadContext context, IRubyObject arg, IRubyObject opts) { return syswriteImpl(context, arg, false, getExceptionOpt(context, opts)); } private static boolean getExceptionOpt(final ThreadContext context, final IRubyObject opts) { if ( opts instanceof RubyHash ) { // exception: true final Ruby runtime = context.runtime; IRubyObject exc = ((RubyHash) opts).op_aref(context, runtime.newSymbol("exception")); return exc != runtime.getFalse(); } return true; } private void checkClosed() { if ( ! socketChannelImpl().isOpen() ) { throw getRuntime().newIOError("closed stream"); } } // do shutdown even if we have remaining data to be sent. // call this when you get an exception from client side. private void forceClose() { close(true); } private void close(boolean force) { if ( engine == null ) { // if ( force ) throw getRuntime().newEOFError(); return; } engine.closeOutbound(); if ( ! force && netData.hasRemaining() ) return; try { doShutdown(); } catch (IOException e) { // ignore? debug(getRuntime(), "SSLSocket.close doShutdown failed", e); } catch (NotYetConnectedException e) { debug(getRuntime(), "SSLSocket.close doShutdown failed", e); } } @JRubyMethod public IRubyObject sysclose(final ThreadContext context) { //if ( isClosed() ) return context.runtime.getNil(); if ( this.io.callMethod(context, "closed?").isTrue() ) { return context.runtime.getNil(); } // Ruby 2.3 // no need to try shutdown when it's a server close( sslContext.isProtocolForClient() ); if ( this.callMethod(context, "sync_close").isTrue() ) { return this.io.callMethod(context, "close"); } return context.runtime.getNil(); } @JRubyMethod public IRubyObject cert(final ThreadContext context) { final Ruby runtime = context.runtime; if ( engine == null ) return runtime.getNil(); try { Certificate[] cert = engine.getSession().getLocalCertificates(); if ( cert != null && cert.length > 0 ) { return X509Cert.wrap(context, cert[0]); } } catch (CertificateEncodingException e) { throw X509Cert.newCertificateError(runtime, e); } return runtime.getNil(); } // @Deprecated public final IRubyObject cert() { return cert(getRuntime().getCurrentContext()); } @JRubyMethod public IRubyObject peer_cert(final ThreadContext context) { final Ruby runtime = context.runtime; if ( engine == null ) return runtime.getNil(); try { Certificate[] cert = engine.getSession().getPeerCertificates(); if ( cert.length > 0 ) { return X509Cert.wrap(context, cert[0]); } } catch (CertificateEncodingException e) { throw X509Cert.newCertificateError(runtime, e); } catch (SSLPeerUnverifiedException e) { if (OpenSSL.isDebug(runtime)) { runtime.getWarnings().warning(String.format("%s: %s", e.getClass().getName(), e.getMessage())); } } return runtime.getNil(); } // @Deprecated public final IRubyObject peer_cert() { return peer_cert(getRuntime().getCurrentContext()); } @JRubyMethod public IRubyObject peer_cert_chain(final ThreadContext context) { final Ruby runtime = context.runtime; if ( engine == null ) return runtime.getNil(); try { javax.security.cert.Certificate[] certs = engine.getSession().getPeerCertificateChain(); IRubyObject[] cert_chain = new IRubyObject[ certs.length ]; for ( int i = 0; i < certs.length; i++ ) { cert_chain[i] = X509Cert.wrap(context, certs[i]); } return runtime.newArrayNoCopy(cert_chain); } catch (javax.security.cert.CertificateEncodingException e) { throw X509Cert.newCertificateError(getRuntime(), e); } catch (SSLPeerUnverifiedException e) { if (runtime.isVerbose() || OpenSSL.isDebug(runtime)) { runtime.getWarnings().warning(String.format("%s: %s", e.getClass().getName(), e.getMessage())); } } return runtime.getNil(); } // @Deprecated public final IRubyObject peer_cert_chain() { return peer_cert_chain(getRuntime().getCurrentContext()); } @JRubyMethod public IRubyObject cipher() { if ( engine == null ) return getRuntime().getNil(); return getRuntime().newString( engine.getSession().getCipherSuite() ); } @JRubyMethod public IRubyObject npn_protocol() { if ( engine == null ) return getRuntime().getNil(); // NOTE: maybe a time to use https://github.com/benmmurphy/ssl_npn warn(getRuntime().getCurrentContext(), "WARNING: SSLSocket#npn_protocol is not supported"); return getRuntime().getNil(); // throw new UnsupportedOperationException(); } @JRubyMethod public IRubyObject state() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: SSLSocket#state"); return getRuntime().getNil(); } @JRubyMethod public IRubyObject pending() { warn(getRuntime().getCurrentContext(), "WARNING: unimplemented method called: SSLSocket#pending"); return getRuntime().getNil(); } private boolean reusableSSLEngine() { if ( engine != null ) { final String peerHost = engine.getPeerHost(); if ( peerHost != null && peerHost.length() > 0 ) { // NOT getSSLContext().createSSLEngine() - no hints for session reuse return true; } } return false; } @JRubyMethod(name = "session_reused?") public IRubyObject session_reused_p() { if ( reusableSSLEngine() ) { if ( ! engine.getEnableSessionCreation() ) { // if session creation is disabled we can be sure its to be re-used return getRuntime().getTrue(); } //return getRuntime().getFalse(); // NOTE: likely incorrect (we can not decide) } //warn(getRuntime().getCurrentContext(), "WARNING: SSLSocket#session_reused? is not supported"); return getRuntime().getNil(); // can not decide - probably not } // JSSE: SSL Sessions can be reused only if connecting to the same host at the same port final javax.net.ssl.SSLSession sslSession() { return engine == null ? null : engine.getSession(); } private transient SSLSession session; @JRubyMethod(name = "session") public IRubyObject session(final ThreadContext context) { if ( sslSession() == null ) return context.nil; return getSession(context.runtime); } private SSLSession getSession(final Ruby runtime) { if ( session == null ) { return session = new SSLSession(runtime).initializeImpl(this); } return session; } private transient SSLSession setSession = null; @JRubyMethod(name = "session=") public IRubyObject set_session(IRubyObject session) { // NOTE: we can not fully support this without the SSL provider internals // but we can assume setting a session= is meant as a forced session re-use if ( session instanceof SSLSession ) { setSession = (SSLSession) session; if ( engine != null ) copySessionSetupIfSet(); } //warn(context, "WARNING: SSLSocket#session= has not effect"); return getRuntime().getNil(); } private void copySessionSetupIfSet() { if ( setSession != null ) { if ( reusableSSLEngine() ) { engine.setEnableSessionCreation(false); final ThreadContext context = getRuntime().getCurrentContext(); if ( ! setSession.equals( getSession(context.runtime) ) ) { getSession(context.runtime).set_timeout(context, setSession.timeout(context)); } } } } @JRubyMethod public IRubyObject ssl_version() { if ( engine == null ) return getRuntime().getNil(); return getRuntime().newString( engine.getSession().getProtocol() ); } private transient SocketChannelImpl socketChannel; private SocketChannelImpl socketChannelImpl() { if ( socketChannel != null ) return socketChannel; final Channel channel = io.getChannel(); if ( channel instanceof SocketChannel ) { return socketChannel = new JavaSocketChannel((SocketChannel) channel); } // TODO JNR throw new IllegalStateException("unknow channel impl: " + channel + " of type " + channel.getClass().getName()); } private interface SocketChannelImpl { boolean isOpen() ; int read(ByteBuffer dst) throws IOException ; int write(ByteBuffer src) throws IOException ; int getRemotePort(); boolean isSelectable() ; // SelectableChannel boolean isBlocking() ; void configureBlocking(boolean block) throws IOException ; SelectionKey register(Selector selector, int ops) throws IOException ; //boolean selectionOpsReadable(final int readyOps); //boolean selectionOpsWritable(final int readyOps) ; } private static final class JavaSocketChannel implements SocketChannelImpl { JavaSocketChannel(final SocketChannel channel) { this.channel = channel; } private final SocketChannel channel; public boolean isOpen() { return channel.isOpen(); } public int read(ByteBuffer dst) throws IOException { return channel.read(dst); } public int write(ByteBuffer src) throws IOException { return channel.write(src); } public int getRemotePort() { return channel.socket().getPort(); } public boolean isSelectable() { return true; // return channel instanceof SelectableChannel; } public boolean isBlocking() { return channel.isBlocking(); } public void configureBlocking(boolean block) throws IOException { channel.configureBlocking(block); } public SelectionKey register(Selector selector, int ops) throws ClosedChannelException { return channel.register(selector, ops); } public boolean selectionOpsReadable(final int readyOps) { return (readyOps & SelectionKey.OP_READ) != 0; } public boolean selectionOpsWritable(final int readyOps) { return (readyOps & SelectionKey.OP_WRITE) != 0; } } private static boolean jnrChannel(final Channel channel) { return channel.getClass().getName().startsWith("jnr."); } }// SSLSocket jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/SecurityHelper.java000066400000000000000000001041671313661621600271100ustar00rootroot00000000000000/* * The MIT License * * Copyright 2014 Karol Bucek. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import static org.jruby.ext.openssl.OpenSSL.debugStackTrace; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyFactorySpi; import java.security.KeyPairGenerator; import java.security.KeyPairGeneratorSpi; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.MessageDigest; import java.security.MessageDigestSpi; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.SecureRandomSpi; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.security.SignatureSpi; import java.security.cert.CRLException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactorySpi; import java.security.cert.X509CRL; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.Locale; import java.util.Map; import java.util.StringTokenizer; import java.util.concurrent.ConcurrentHashMap; import javax.crypto.Cipher; import javax.crypto.CipherSpi; import javax.crypto.KeyAgreement; import javax.crypto.KeyAgreementSpi; import javax.crypto.KeyGenerator; import javax.crypto.KeyGeneratorSpi; import javax.crypto.Mac; import javax.crypto.MacSpi; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKeyFactorySpi; import javax.net.ssl.SSLContext; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.CertificateList; import org.bouncycastle.cert.CertException; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.jce.provider.X509CRLObject; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder; import org.bouncycastle.operator.OperatorException; import org.bouncycastle.operator.bc.BcDSAContentVerifierProviderBuilder; import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder; /** * Java Security (and JCE) helpers. * * @author kares */ public abstract class SecurityHelper { private static String BC_PROVIDER_CLASS = "org.bouncycastle.jce.provider.BouncyCastleProvider"; private static String BC_PROVIDER_NAME = "BC"; static boolean setBouncyCastleProvider = true; // (package access for tests) static Provider securityProvider; // 'BC' provider (package access for tests) private static volatile Boolean registerProvider = null; static final Map implEngines = new ConcurrentHashMap(16, 0.75f, 1); /** * inject under a given name a cipher. also ensures that the registered * classes are getting used. * * @param name the name under which the class gets registered * @param clazz the CipherSpi class */ public static void addCipher(String name, Class clazz) { implEngines.put("Cipher:" + name, clazz); tryCipherInternal = true; } /** * inject under a given name a signature * * @param name the name under which the class gets registered * @param clazz the SignaturSpi class */ public static void addSignature(String name, Class clazz) { implEngines.put("Signature:" + name, clazz); } public static Provider getSecurityProvider() { if ( setBouncyCastleProvider && securityProvider == null ) { synchronized(SecurityHelper.class) { if ( setBouncyCastleProvider && securityProvider == null ) { setBouncyCastleProvider(); setBouncyCastleProvider = false; } } } doRegisterProvider(); return securityProvider; } static final boolean SPI_ACCESSIBLE; static { boolean canSetAccessible = true; if ( OpenSSL.javaVersion9(true) ) { final Provider provider = getSecurityProvider(); if ( provider != null ) { try { // NOTE: some getXxx pieces might still work // where SPI are returned directly + there's a public e.g. MessageDigest(...) getCertificateFactory("X.509", provider); // !!! disables EVERYTHING :( } catch (CertificateException ex) { debugStackTrace(ex); canSetAccessible = false; } catch (RuntimeException ex) { debugStackTrace(ex); // java.lang.reflect.InaccessibleObjectException (extends RuntimeException) canSetAccessible = false; } } } SPI_ACCESSIBLE = canSetAccessible; } static Provider getSecurityProviderIfAccessible() { return SPI_ACCESSIBLE ? getSecurityProvider() : null; } public static synchronized void setSecurityProvider(final Provider provider) { if ( provider != null ) OpenSSL.debug("using provider: " + provider); securityProvider = provider; } static synchronized void setBouncyCastleProvider() { setSecurityProvider( newBouncyCastleProvider() ); } private static Provider newBouncyCastleProvider() { try { return (Provider) Class.forName(BC_PROVIDER_CLASS).newInstance(); } catch (Throwable ignored) { /* no bouncy castle available */ } return null; } public static synchronized void setRegisterProvider(final boolean register) { registerProvider = Boolean.valueOf(register); if ( register ) getSecurityProvider(); // so that securityProvider != null // getSecurityProvider does doRegisterProvider(); } static boolean isProviderAvailable(final String name) { return Security.getProvider(name) != null; } public static boolean isProviderRegistered() { if ( securityProvider == null ) return false; return Security.getProvider(securityProvider.getName()) != null; } private static void doRegisterProvider() { if ( registerProvider != null ) { synchronized(SecurityHelper.class) { final Boolean register = registerProvider; if ( register != null && register.booleanValue() ) { if ( securityProvider != null ) { Security.addProvider(securityProvider); registerProvider = null; } } } } } /** * @note code calling this should not assume BC provider internals ! */ public static CertificateFactory getCertificateFactory(final String type) throws CertificateException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getCertificateFactory(type, provider); } catch (CertificateException e) { debugStackTrace(e); } return CertificateFactory.getInstance(type); } static CertificateFactory getCertificateFactory(final String type, final Provider provider) throws CertificateException { final CertificateFactorySpi spi; boolean addedBC = false; synchronized(SecurityHelper.class) { try { // TODO fixed since BC 1.55 (only needed on 1.54) and should be removed eventually ... if (provider.getName().equals(BC_PROVIDER_NAME) && Security.getProvider(BC_PROVIDER_NAME) == null) { Security.addProvider(provider); addedBC = true; } spi = (CertificateFactorySpi) getImplEngine("CertificateFactory", type); } finally { if (addedBC) { Security.removeProvider(BC_PROVIDER_NAME); } } } if ( spi == null ) throw new CertificateException(type + " not found"); return newInstance(CertificateFactory.class, new Class[]{ CertificateFactorySpi.class, Provider.class, String.class }, new Object[]{ spi, provider, type } ); } /** * @note code calling this should not assume BC provider internals ! */ public static KeyFactory getKeyFactory(final String algorithm) throws NoSuchAlgorithmException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getKeyFactory(algorithm, provider); } catch (NoSuchAlgorithmException e) { } return KeyFactory.getInstance(algorithm); } static KeyFactory getKeyFactory(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { KeyFactorySpi spi = (KeyFactorySpi) getImplEngine("KeyFactory", algorithm); if ( spi == null ) throw new NoSuchAlgorithmException(algorithm + " not found"); return newInstance(KeyFactory.class, new Class[] { KeyFactorySpi.class, Provider.class, String.class }, new Object[] { spi, provider, algorithm } ); } /** * @note code calling this should not assume BC provider internals ! */ public static KeyPairGenerator getKeyPairGenerator(final String algorithm) throws NoSuchAlgorithmException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getKeyPairGenerator(algorithm, provider); } catch (NoSuchAlgorithmException e) { } return KeyPairGenerator.getInstance(algorithm); } @SuppressWarnings("unchecked") static KeyPairGenerator getKeyPairGenerator(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { final Object spi = getImplEngine("KeyPairGenerator", algorithm); if ( spi == null ) { throw new NoSuchAlgorithmException(algorithm + " KeyPairGenerator not available"); } final KeyPairGenerator keyPairGenerator; if ( spi instanceof KeyPairGenerator ) { keyPairGenerator = (KeyPairGenerator) spi; } else { final Class delegate; try { delegate = (Class) Class.forName(KeyPairGenerator.class.getName() + "$Delegate"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } keyPairGenerator = newInstance(delegate, new Class[] { KeyPairGeneratorSpi.class, String.class }, spi, algorithm ); } setField(keyPairGenerator, KeyPairGenerator.class, "provider", provider); return keyPairGenerator; } /** * @note code calling this should not assume BC provider internals ! */ public static KeyStore getKeyStore(final String type) throws KeyStoreException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getKeyStore(type, provider); } catch (KeyStoreException e) { } return KeyStore.getInstance(type); } static KeyStore getKeyStore(final String type, final Provider provider) throws KeyStoreException { return KeyStore.getInstance(type, provider); } /** * @note code calling this should not assume BC provider internals ! */ public static MessageDigest getMessageDigest(final String algorithm) throws NoSuchAlgorithmException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getMessageDigest(algorithm, provider); } catch (NoSuchAlgorithmException e) { } return MessageDigest.getInstance(algorithm); } @SuppressWarnings("unchecked") static MessageDigest getMessageDigest(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { final Object spi = getImplEngine("MessageDigest", algorithm); if ( spi == null ) throw new NoSuchAlgorithmException(algorithm + " not found"); final MessageDigest messageDigest; if ( spi instanceof MessageDigest ) { messageDigest = (MessageDigest) spi; } else { final Class delegate; try { delegate = (Class) Class.forName(MessageDigest.class.getName() + "$Delegate"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } messageDigest = newInstance(delegate, new Class[] { MessageDigestSpi.class, String.class }, spi, algorithm ); } setField(messageDigest, MessageDigest.class, "provider", provider); return messageDigest; } public static SecureRandom getSecureRandom() { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) { final String algorithm = getSecureRandomAlgorithm(provider); if ( algorithm != null ) { return getSecureRandom(algorithm, provider); } } } catch (NoSuchAlgorithmException e) { } return new SecureRandom(); // likely "SHA1PRNG" from SPI sun.security.provider.SecureRandom } private static SecureRandom getSecureRandom(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { final SecureRandomSpi spi = (SecureRandomSpi) getImplEngine("SecureRandom", algorithm); if ( spi == null ) throw new NoSuchAlgorithmException(algorithm + " not found"); return newInstance(SecureRandom.class, new Class[] { SecureRandomSpi.class, Provider.class, String.class }, new Object[] { spi, provider, algorithm } ); } // NOTE: none (at least for BC 1.47) private static String getSecureRandomAlgorithm(final Provider provider) { for ( Provider.Service service : provider.getServices() ) { if ( "SecureRandom".equals( service.getType() ) ) { return service.getAlgorithm(); } } return null; } private static Boolean tryCipherInternal = Boolean.FALSE; /** * @note code calling this should not assume BC provider internals ! */ public static Cipher getCipher(final String transformation) throws NoSuchAlgorithmException, NoSuchPaddingException { try { if ( tryCipherInternal == Boolean.FALSE ) { final Provider provider = getSecurityProvider(); if ( provider != null ) { return getCipher(transformation, provider); } } } catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } catch (SecurityException e) { // java.lang.SecurityException: JCE cannot authenticate the provider BC if ( tryCipherInternal != null ) tryCipherInternal = Boolean.TRUE; debugStackTrace(e); } if ( tryCipherInternal == Boolean.TRUE ) { try { final Provider provider = getSecurityProvider(); if ( provider != null ) { return getCipherInternal(transformation, provider); } } catch (NoSuchAlgorithmException e) { } catch (RuntimeException e) { // likely javax.crypto.JceSecurityManager.isCallerTrusted gets // us a NPE from javax.crypto.Cipher.(Cipher.java:264) tryCipherInternal = null; // do not try BC at all debugStackTrace(e); } } return Cipher.getInstance(transformation); } static Cipher getCipher(final String transformation, final Provider provider) throws NoSuchAlgorithmException, NoSuchPaddingException { return Cipher.getInstance(transformation, provider); } private static final Class[] STRING_PARAM = { String.class }; private static Cipher getCipherInternal(String transformation, final Provider provider) throws NoSuchAlgorithmException { CipherSpi spi = (CipherSpi) getImplEngine("Cipher", transformation); if ( spi == null ) { // // try the long way // StringTokenizer tok = new StringTokenizer(transformation, "/"); final String algorithm = tok.nextToken(); spi = (CipherSpi) getImplEngine("Cipher", algorithm); if ( spi == null ) { // if ( silent ) return null; throw new NoSuchAlgorithmException(transformation + " not found"); } // // make sure we don't get fooled by a "//" in the string // if ( tok.hasMoreTokens() && ! transformation.regionMatches(algorithm.length(), "//", 0, 2) ) { // spi.engineSetMode(tok.nextToken()) : invoke(spi, CipherSpi.class, "engineSetMode", STRING_PARAM, tok.nextToken()); } if ( tok.hasMoreTokens() ) { // spi.engineSetPadding(tok.nextToken()) : invoke(spi, CipherSpi.class, "engineSetPadding", STRING_PARAM, tok.nextToken()); } } try { // this constructor does not verify the provider Cipher cipher = newInstance(Cipher.class, new Class[] { CipherSpi.class, String.class }, new Object[] { spi, transformation } ); setField(cipher, Cipher.class, "provider", provider); return cipher; } catch( Exception e ) { // this constructor does verify the provider which might fail return newInstance(Cipher.class, new Class[] { CipherSpi.class, Provider.class, String.class }, new Object[] { spi, provider, transformation } ); } } /** * @note code calling this should not assume BC provider internals ! */ public static Signature getSignature(final String algorithm) throws NoSuchAlgorithmException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getSignature(algorithm, provider); } catch (NoSuchAlgorithmException e) { } return Signature.getInstance(algorithm); } @SuppressWarnings("unchecked") static Signature getSignature(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { final Object spi = getImplEngine("Signature", algorithm); if ( spi == null ) throw new NoSuchAlgorithmException(algorithm + " Signature not available"); final Signature signature; if ( spi instanceof Signature ) { signature = (Signature) spi; } else { final Class delegate; try { delegate = (Class) Class.forName(Signature.class.getName() + "$Delegate"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } signature = newInstance(delegate, new Class[] { SignatureSpi.class, String.class }, spi, algorithm ); } setField(signature, Signature.class, "provider", provider); return signature; } /** * @note code calling this should not assume BC provider internals ! */ public static Mac getMac(final String algorithm) throws NoSuchAlgorithmException { Mac mac = null; final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) { mac = getMac(algorithm, provider, true); } if ( mac == null ) mac = Mac.getInstance(algorithm); return mac; } static Mac getMac(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { return getMac(algorithm, provider, false); } private static Mac getMac(final String algorithm, final Provider provider, boolean silent) throws NoSuchAlgorithmException { MacSpi spi = (MacSpi) getImplEngine("Mac", algorithm); if ( spi == null ) { if ( silent ) return null; throw new NoSuchAlgorithmException(algorithm + " not found"); } return newInstance(Mac.class, new Class[] { MacSpi.class, Provider.class, String.class }, new Object[] { spi, provider, algorithm } ); } /** * @note code calling this should not assume BC provider internals ! */ public static KeyGenerator getKeyGenerator(final String algorithm) throws NoSuchAlgorithmException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getKeyGenerator(algorithm, provider); } catch (NoSuchAlgorithmException e) { } catch (SecurityException e) { debugStackTrace(e); } return KeyGenerator.getInstance(algorithm); } static KeyGenerator getKeyGenerator(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { final KeyGeneratorSpi spi = (KeyGeneratorSpi) getImplEngine("KeyGenerator", algorithm); if ( spi == null ) throw new NoSuchAlgorithmException(algorithm + " not found"); return newInstance(KeyGenerator.class, new Class[] { KeyGeneratorSpi.class, Provider.class, String.class }, new Object[] { spi, provider, algorithm } ); } /** * @note code calling this should not assume BC provider internals ! */ public static KeyAgreement getKeyAgreement(final String algorithm) throws NoSuchAlgorithmException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getKeyAgreement(algorithm, provider); } catch (NoSuchAlgorithmException e) { } catch (SecurityException e) { debugStackTrace(e); } return KeyAgreement.getInstance(algorithm); } static KeyAgreement getKeyAgreement(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { final KeyAgreementSpi spi = (KeyAgreementSpi) getImplEngine("KeyAgreement", algorithm); if ( spi == null ) throw new NoSuchAlgorithmException(algorithm + " not found"); return newInstance(KeyAgreement.class, new Class[] { KeyAgreementSpi.class, Provider.class, String.class }, new Object[] { spi, provider, algorithm } ); } /** * @note code calling this should not assume BC provider internals ! */ public static SecretKeyFactory getSecretKeyFactory(final String algorithm) throws NoSuchAlgorithmException { try { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) return getSecretKeyFactory(algorithm, provider); } catch (NoSuchAlgorithmException e) { } catch (SecurityException e) { debugStackTrace(e); } return SecretKeyFactory.getInstance(algorithm); } static SecretKeyFactory getSecretKeyFactory(final String algorithm, final Provider provider) throws NoSuchAlgorithmException { final SecretKeyFactorySpi spi = (SecretKeyFactorySpi) getImplEngine("SecretKeyFactory", algorithm); if ( spi == null ) throw new NoSuchAlgorithmException(algorithm + " not found"); return newInstance(SecretKeyFactory.class, new Class[] { SecretKeyFactorySpi.class, Provider.class, String.class }, new Object[] { spi, provider, algorithm } ); } private static boolean providerSSLContext = false; // BC does not implement + JDK default is fine public static SSLContext getSSLContext(final String protocol) throws NoSuchAlgorithmException { try { if ( providerSSLContext ) { final Provider provider = getSecurityProviderIfAccessible(); if ( provider != null ) { return getSSLContext(protocol, provider); } } } catch (NoSuchAlgorithmException e) { } return SSLContext.getInstance(protocol); } private static SSLContext getSSLContext(final String protocol, final Provider provider) throws NoSuchAlgorithmException { return SSLContext.getInstance(protocol, provider); } public static boolean verify(final X509CRL crl, final PublicKey publicKey) throws NoSuchAlgorithmException, CRLException, InvalidKeyException, SignatureException { return verify(crl, publicKey, false); } static boolean verify(final X509CRL crl, final PublicKey publicKey, final boolean silent) throws NoSuchAlgorithmException, CRLException, InvalidKeyException, SignatureException { if ( crl instanceof X509CRLObject ) { final CertificateList crlList = (CertificateList) getCertificateList(crl); final AlgorithmIdentifier tbsSignatureId = crlList.getTBSCertList().getSignature(); if ( ! crlList.getSignatureAlgorithm().equals(tbsSignatureId) ) { if ( silent ) return false; throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList."); } final Signature signature = getSignature(crl.getSigAlgName(), securityProvider); signature.initVerify(publicKey); signature.update(crl.getTBSCertList()); if ( ! signature.verify( crl.getSignature() ) ) { if ( silent ) return false; throw new SignatureException("CRL does not verify with supplied public key."); } return true; } else { try { final DigestAlgorithmIdentifierFinder digestAlgFinder = new DefaultDigestAlgorithmIdentifierFinder(); final ContentVerifierProvider verifierProvider; if ( "DSA".equalsIgnoreCase( publicKey.getAlgorithm() )) { BigInteger y = ((DSAPublicKey) publicKey).getY(); DSAParams params = ((DSAPublicKey) publicKey).getParams(); DSAParameters parameters = new DSAParameters(params.getP(), params.getQ(), params.getG()); AsymmetricKeyParameter dsaKey = new DSAPublicKeyParameters(y, parameters); verifierProvider = new BcDSAContentVerifierProviderBuilder(digestAlgFinder).build(dsaKey); } else { BigInteger mod = ((RSAPublicKey) publicKey).getModulus(); BigInteger exp = ((RSAPublicKey) publicKey).getPublicExponent(); AsymmetricKeyParameter rsaKey = new RSAKeyParameters(false, mod, exp); verifierProvider = new BcRSAContentVerifierProviderBuilder(digestAlgFinder).build(rsaKey); } return new X509CRLHolder(crl.getEncoded()).isSignatureValid( verifierProvider ); } catch (OperatorException e) { throw new SignatureException(e); } catch (CertException e) { throw new SignatureException(e); } // can happen if the input is DER but does not match expected strucure catch (ClassCastException e) { throw new SignatureException(e); } catch (IOException e) { throw new SignatureException(e); } } } private static Object getCertificateList(final Object crl) { // X509CRLObject try { // private CertificateList c; final Field cField = X509CRLObject.class.getDeclaredField("c"); cField.setAccessible(true); return cField.get(crl); } catch (NoSuchFieldException e) { debugStackTrace(e); return null; } catch (IllegalAccessException e) { return null; } catch (SecurityException e) { return null; } } // these are BC JCE (@see javax.crypto.JCEUtil) inspired internals : // https://github.com/bcgit/bc-java/blob/master/jce/src/main/java/javax/crypto/JCEUtil.java private static Object getImplEngine(String baseName, String algorithm) { Object engine = findImplEngine(baseName, algorithm.toUpperCase(Locale.ENGLISH)); if (engine == null) { engine = findImplEngine(baseName, algorithm); } return engine; } private static Object findImplEngine(final String baseName, String algorithm) { Class implEngineClass = implEngines.get(baseName + ":" + algorithm); if (implEngineClass == null) { final Provider bcProvider = securityProvider; String alias; while ((alias = bcProvider.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } final String className = bcProvider.getProperty(baseName + "." + algorithm); if (className != null) { try { ClassLoader loader = bcProvider.getClass().getClassLoader(); if (loader != null) { implEngineClass = loader.loadClass(className); } else { implEngineClass = Class.forName(className); } implEngineClass.newInstance(); // this instance is thrown away to test newInstance, but only once } catch (ClassNotFoundException e) { throw new IllegalStateException("algorithm " + algorithm + " in provider " + bcProvider.getName() + " but no class \"" + className + "\" found!"); } catch (Exception e) { throw new IllegalStateException("algorithm " + algorithm + " in provider " + bcProvider.getName() + " but class \"" + className + "\" inaccessible!"); } } else { return null; } implEngines.put(baseName + ":" + algorithm, implEngineClass); } try { return implEngineClass.newInstance(); } catch (Exception e) { final Provider bcProvider = securityProvider; String className = implEngineClass.getName(); throw new IllegalStateException("algorithm " + algorithm + " in provider " + bcProvider.getName() + " but class \"" + className + "\" inaccessible!"); } } // the obligratory "reflection crap" : private static T newInstance(Class klass, Class[] paramTypes, Object... params) { final Constructor constructor; try { constructor = klass.getDeclaredConstructor(paramTypes); constructor.setAccessible(true); return constructor.newInstance(params); } catch (NoSuchMethodException e) { throw new IllegalStateException(e.getMessage(), e); } catch (InvocationTargetException e) { throw new IllegalStateException(e.getTargetException()); } catch (InstantiationException e) { throw new IllegalStateException(e); } catch (IllegalAccessException e) { throw new IllegalStateException(e); } } @SuppressWarnings("unchecked") private static T invoke(Object object, Class klass, String methodName, Class[] paramTypes, Object... params) { final Method method; try { method = klass.getDeclaredMethod(methodName, paramTypes); method.setAccessible(true); return (T) method.invoke(object, params); } catch (NoSuchMethodException e) { throw new IllegalStateException(e.getMessage(), e); } catch (InvocationTargetException e) { throw new IllegalStateException(e.getTargetException()); } catch (IllegalAccessException e) { throw new IllegalStateException(e); } } private static void setField(Object obj, Class fieldOwner, String fieldName, Object value) { final Field field; try { field = fieldOwner.getDeclaredField(fieldName); field.setAccessible(true); field.set(obj, value); } catch (NoSuchFieldException e) { throw new IllegalStateException("no field '" + fieldName + "' declared in " + fieldOwner + "", e); } catch (IllegalAccessException e) { throw new IllegalStateException(e); } } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/SimpleSecretKey.java000066400000000000000000000061731313661621600272070ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import javax.crypto.SecretKey; /** * @author Ola Bini */ public class SimpleSecretKey implements SecretKey { private static final long serialVersionUID = 1L; private final String algorithm; private final byte[] value; public SimpleSecretKey(final String algorithm, final byte[] value) { this.algorithm = algorithm; this.value = value; } public static SimpleSecretKey copy(String algorithm, final byte[] value) { return copy(algorithm, value, 0, value.length); } public static SimpleSecretKey copy(String algorithm, final byte[] value, int off, int len) { final byte[] val = new byte[len]; System.arraycopy(value, off, val, 0, len); return new SimpleSecretKey(algorithm, val); } public String getAlgorithm() { return algorithm; } public byte[] getEncoded() { return value; } public String getFormat() { return "RAW"; } public boolean equals(Object o) { if ( o instanceof SimpleSecretKey ) { byte[] ovalue = ((SimpleSecretKey) o).value; if ( value.length != ovalue.length ) return false; for ( int i = 0; i < value.length; i++ ) { if ( value[i] != ovalue[i] ) return false; } return algorithm.equals( ((SimpleSecretKey) o).algorithm ); } return false; } public int hashCode() { int code = 0; for ( int i = 0; i < value.length; i++ ) { code ^= (value[i] & 0xff) << (i << 3 & 31); } return code ^ algorithm.hashCode(); } }// SimpleSecretKey jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/StringHelper.java000066400000000000000000000203561313661621600265440ustar00rootroot00000000000000/* * The MIT License * * Copyright 2014 Karol Bucek. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Locale; import org.jcodings.specific.UTF8Encoding; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.jruby.Ruby; import org.jruby.RubyEncoding; import org.jruby.RubyFile; import org.jruby.RubyIO; import org.jruby.RubyString; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.ext.openssl.x509store.PEMInputOutput; /** * * @author kares */ abstract class StringHelper { static RubyString newString(final Ruby runtime, final byte[] bytes) { final ByteList byteList = new ByteList(bytes, false); return RubyString.newString(runtime, byteList); } static RubyString newString(final Ruby runtime, final byte[] bytes, final int count) { final ByteList byteList = new ByteList(bytes, 0, count, false); return RubyString.newString(runtime, byteList); } static ByteList setByteListShared(final RubyString str) { try { str.setByteListShared(); return str.getByteList(); } catch (NoSuchMethodError err) { // JRuby 1.6 RubyString dup = (RubyString) str.dup(); return dup.getByteList(); } } static RubyString newUTF8String(final Ruby runtime, final ByteList bytes) { ByteList byteList = new ByteList(RubyEncoding.encodeUTF8(bytes), UTF8Encoding.INSTANCE, false); return new RubyString(runtime, runtime.getString(), byteList); } static RubyString newUTF8String(final Ruby runtime, final CharSequence chars) { ByteList byteList = new ByteList(RubyEncoding.encodeUTF8(chars), UTF8Encoding.INSTANCE, false); return new RubyString(runtime, runtime.getString(), byteList); } static RubyString newStringFrozen(final Ruby runtime, final ByteList bytes) { final RubyString str = RubyString.newStringShared(runtime, bytes); str.setFrozen(true); return str; } static RubyString newStringFrozen(final Ruby runtime, final CharSequence chars) { final RubyString str = RubyString.newString(runtime, chars); str.setFrozen(true); return str; } static byte[] readX509PEM(final ThreadContext context, IRubyObject arg) { final RubyString str = StringHelper.readPossibleDERInput(context, arg); final ByteList bytes = str.getByteList(); return readX509PEM(bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize()); } static byte[] readX509PEM(final byte[] bytes, final int offset, final int length) { InputStreamReader in = new InputStreamReader(new ByteArrayInputStream(bytes, offset, length)); try { byte[] readBytes = PEMInputOutput.readX509PEM(in); if ( readBytes != null ) return readBytes; } catch (IOException e) { // this is not PEM encoded, let's use the default argument } return bytes; } static RubyString readPossibleDERInput(final ThreadContext context, final IRubyObject arg) { return readInput(context, OpenSSL.to_der_if_possible(context, arg)); } static RubyString readInput(final ThreadContext context, final IRubyObject arg) { if ( arg instanceof RubyIO ) { final IRubyObject result; if ( arg instanceof RubyFile ) { result = ( (RubyFile) arg.dup() ).read(context); } else { result = ( (RubyIO) arg ).read(context); } if ( result instanceof RubyString ) return (RubyString) result; throw context.runtime.newArgumentError("IO `" + arg.inspect() + "' contained no data"); } return arg.asString(); } static final ByteList NEW_LINE = new ByteList(new byte[] { '\n' }, false); static final ByteList COMMA_SPACE = new ByteList(new byte[] { ',',' ' }, false); static void gsub(final Ruby runtime, final ByteList str, final byte match, final byte replace) { final int begin = str.getBegin(); final int slen = str.getRealSize(); final byte[] bytes = str.getUnsafeBytes(); for ( int i = begin; i < begin + slen; i++ ) { if ( bytes[i] == match ) bytes[i] = replace; } } static final char[] S20 = new char[] { ' ',' ',' ',' ', ' ',' ',' ',' ', ' ',' ',' ',' ', ' ',' ',' ',' ', ' ',' ',' ',' ', }; private static final DateTimeFormatter ASN_DATE_NO_ZONE = DateTimeFormat.forPattern("MMM dd HH:mm:ss yyyy") // + " zzz" .withLocale(Locale.US) .withZone(DateTimeZone.UTC); static StringBuilder appendGMTDateTime(final StringBuilder text, final DateTime time) { final String date = ASN_DATE_NO_ZONE.print( time.getMillis() ); final int len = text.length(); text.append(date).append(' ').append("GMT"); if ( date.charAt(4) == '0' ) { // Jul 07 -> Jul 7 text.setCharAt(len + 4, ' '); } return text; } //static StringBuilder lowerHexBytes(final BigInteger bytes) { // return lowerHexBytes(bytes.toByteArray(), 1); // skip the sign bit //} static StringBuilder lowerHexBytes(final byte[] bytes, final int offset) { final int len = bytes.length; final StringBuilder hex = new StringBuilder(len * 3); for (int i = offset; i < bytes.length; i++ ) { final String h = Integer.toHexString( bytes[i] & 0xFF ); if ( h.length() == 1 ) hex.append('0'); hex.append( h ).append(':'); } if ( hex.length() > 0 ) hex.setLength( hex.length() - 1 ); return hex; } static void appendLowerHexValue(final StringBuilder text, final byte[] hex, final int indent, final int rowLength) { final StringBuilder hexStr = lowerHexBytes( hex, 0 ); final int len = hexStr.length(); int left = len; while ( left > 0 ) { int print = rowLength; if ( left < rowLength ) print = left; final int start = len - left; text.append(S20,0,indent).append( hexStr, start, start + print ).append('\n'); left -= print; } } @SuppressWarnings("unchecked") static ArrayList split(final T string, final char separator) { final ArrayList split = new ArrayList(8); int last = 0; for ( int i = 0; i < string.length(); i++ ) { if ( string.charAt(i) == separator ) { split.add( (T) string.subSequence(last, i) ); last = ++i; } } if ( last == 0 ) split.add(string); // split.isEmpty else split.add( (T) string.subSequence(last, string.length()) ); return split; } public static String[] split(final String string, final char separator) { final ArrayList split = split((CharSequence) string, separator); return split.toArray( new String[ split.size() ] ); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/Utils.java000066400000000000000000000145761313661621600252450ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.exceptions.RaiseException; import org.jruby.internal.runtime.methods.DynamicMethod; import org.jruby.internal.runtime.methods.UndefinedMethod; import org.jruby.runtime.Block; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; /** * @author Ola Bini */ final class Utils { private Utils() {} static RaiseException newIOError(Ruby runtime, IOException e) { RaiseException ex = newIOError(runtime, e.getMessage()); ex.initCause(e); return ex; } static RaiseException newIOError(Ruby runtime, String msg) { return new RaiseException(runtime, runtime.getIOError(), msg, true); } static RaiseException newRuntimeError(Ruby runtime, Exception e) { RaiseException ex = newRuntimeError(runtime, e.getMessage()); ex.initCause(e); return ex; } static RaiseException newArgumentError(Ruby runtime, Exception e) { return newError(runtime, runtime.getArgumentError(), e); } static RaiseException newRuntimeError(Ruby runtime, String msg) { return new RaiseException(runtime, runtime.getRuntimeError(), msg, true); } static RaiseException newErrorWithoutTrace(Ruby runtime, RubyClass errorClass, String message, boolean nativeException) { final IRubyObject backtrace = runtime.newEmptyArray(); // runtime.getNil(); return new RaiseException(runtime, errorClass, message, backtrace, nativeException); } static RaiseException newError(Ruby runtime, RubyClass errorClass, String message, boolean nativeException) { return new RaiseException(runtime, errorClass, message, nativeException); } static RaiseException newError(Ruby runtime, RubyClass errorClass, Throwable e) { return newError(runtime, errorClass, e.getMessage(), e); } static RaiseException newError(Ruby runtime, RubyClass errorClass, String msg) { return newError(runtime, errorClass, msg, true); } static RaiseException newError(Ruby runtime, RubyClass errorClass, String msg, Throwable e) { RaiseException ex = newError(runtime, errorClass, msg); ex.initCause(e); return ex; } static boolean hasNonNilInstanceVariable(final IRubyObject self, final String var) { final IRubyObject val = self.getInstanceVariables().getInstanceVariable(var); return val != null && ! val.isNil(); } // reinvented parts of org.jruby.runtime.Helpers for compatibility with "older" JRuby : static IRubyObject invoke(ThreadContext context, IRubyObject self, String name, Block block) { return self.getMetaClass().finvoke(context, self, name, block); } static IRubyObject invokeSuper(ThreadContext context, IRubyObject self, IRubyObject[] args, Block block) { return invokeSuper(context, self, context.getFrameKlazz(), context.getFrameName(), args, block); } static IRubyObject invokeSuper(ThreadContext context, IRubyObject self, RubyModule klass, String name, IRubyObject[] args, Block block) { checkSuperDisabledOrOutOfMethod(context, klass, name); RubyClass superClass = findImplementerIfNecessary(self.getMetaClass(), klass).getSuperClass(); DynamicMethod method = superClass != null ? superClass.searchMethod(name) : UndefinedMethod.INSTANCE; // NOTE: method_missing not implemented ! //if (method.isUndefined()) { // return callMethodMissing(context, self, method.getVisibility(), name, CallType.SUPER, args, block); //} return method.call(context, self, superClass, name, args, block); } private static void checkSuperDisabledOrOutOfMethod(ThreadContext context, RubyModule klass, String name) { if (klass == null) { if (name != null) { throw context.runtime.newNameError("superclass method '" + name + "' disabled", name); } else { throw context.runtime.newNoMethodError("super called outside of method", null, context.nil); } } } private static RubyModule findImplementerIfNecessary(RubyModule clazz, RubyModule implementationClass) { if (implementationClass != null && implementationClass.needsImplementer()) { // modules are included with a shim class; we must find that shim to handle super() appropriately return clazz.findImplementer(implementationClass); } else { // classes are directly in the hierarchy, so no special logic is necessary for implementer return implementationClass; } } static void throwException(final Throwable e) { Utils.throwsUnchecked(e); } private static void throwsUnchecked(Throwable t) throws T { throw (T) t; } }// Utils jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509.java000066400000000000000000000156101313661621600246000ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.util.Map; import org.jruby.Ruby; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.ext.openssl.x509store.X509Error; import org.jruby.ext.openssl.x509store.X509Utils; /** * @author Ola Bini */ public class X509 { public static void createX509(final Ruby runtime, final RubyModule _OpenSSL) { final RubyModule _X509 = _OpenSSL.defineModuleUnder("X509"); X509Name.createX509Name(runtime, _X509); X509Cert.createX509Cert(runtime, _X509); X509Extension.createX509Extension(runtime, _X509); X509CRL.createX509CRL(runtime, _X509); X509Revoked.createX509Revoked(runtime, _X509); X509Store.createX509Store(runtime, _X509); X509Request.createRequest(runtime, _X509); X509Attribute.createAttribute(runtime, _X509); final RubyFixnum _1 = runtime.newFixnum(1); final RubyFixnum _2 = runtime.newFixnum(2); final RubyFixnum _3 = runtime.newFixnum(3); final RubyFixnum _4 = runtime.newFixnum(4); final RubyFixnum _5 = runtime.newFixnum(5); final RubyFixnum _6 = runtime.newFixnum(6); final RubyFixnum _7 = runtime.newFixnum(7); final RubyFixnum _8 = runtime.newFixnum(8); _X509.setConstant("V_OK",runtime.newFixnum(0)); _X509.setConstant("V_ERR_UNABLE_TO_GET_ISSUER_CERT",_2); _X509.setConstant("V_ERR_UNABLE_TO_GET_CRL",_3); _X509.setConstant("V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE",_4); _X509.setConstant("V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE",_5); _X509.setConstant("V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY",_6); _X509.setConstant("V_ERR_CERT_SIGNATURE_FAILURE",_7); _X509.setConstant("V_ERR_CRL_SIGNATURE_FAILURE",_8); _X509.setConstant("V_ERR_CERT_NOT_YET_VALID",runtime.newFixnum(9)); _X509.setConstant("V_ERR_CERT_HAS_EXPIRED",runtime.newFixnum(10)); _X509.setConstant("V_ERR_CRL_NOT_YET_VALID",runtime.newFixnum(11)); _X509.setConstant("V_ERR_CRL_HAS_EXPIRED",runtime.newFixnum(12)); _X509.setConstant("V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD",runtime.newFixnum(13)); _X509.setConstant("V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD",runtime.newFixnum(14)); _X509.setConstant("V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD",runtime.newFixnum(15)); _X509.setConstant("V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD",runtime.newFixnum(16)); _X509.setConstant("V_ERR_OUT_OF_MEM",runtime.newFixnum(17)); _X509.setConstant("V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT",runtime.newFixnum(18)); _X509.setConstant("V_ERR_SELF_SIGNED_CERT_IN_CHAIN",runtime.newFixnum(19)); _X509.setConstant("V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY",runtime.newFixnum(20)); _X509.setConstant("V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE",runtime.newFixnum(21)); _X509.setConstant("V_ERR_CERT_CHAIN_TOO_LONG",runtime.newFixnum(22)); _X509.setConstant("V_ERR_CERT_REVOKED",runtime.newFixnum(23)); _X509.setConstant("V_ERR_INVALID_CA",runtime.newFixnum(24)); _X509.setConstant("V_ERR_PATH_LENGTH_EXCEEDED",runtime.newFixnum(25)); _X509.setConstant("V_ERR_INVALID_PURPOSE",runtime.newFixnum(26)); _X509.setConstant("V_ERR_CERT_UNTRUSTED",runtime.newFixnum(27)); _X509.setConstant("V_ERR_CERT_REJECTED",runtime.newFixnum(28)); _X509.setConstant("V_ERR_SUBJECT_ISSUER_MISMATCH",runtime.newFixnum(29)); _X509.setConstant("V_ERR_AKID_SKID_MISMATCH",runtime.newFixnum(30)); _X509.setConstant("V_ERR_AKID_ISSUER_SERIAL_MISMATCH",runtime.newFixnum(31)); _X509.setConstant("V_ERR_KEYUSAGE_NO_CERTSIGN",runtime.newFixnum(32)); _X509.setConstant("V_ERR_APPLICATION_VERIFICATION",runtime.newFixnum(50)); _X509.setConstant("V_FLAG_CRL_CHECK",_4); _X509.setConstant("V_FLAG_CRL_CHECK_ALL",_8); _X509.setConstant("PURPOSE_SSL_CLIENT",_1); _X509.setConstant("PURPOSE_SSL_SERVER",_2); _X509.setConstant("PURPOSE_NS_SSL_SERVER",_3); _X509.setConstant("PURPOSE_SMIME_SIGN",_4); _X509.setConstant("PURPOSE_SMIME_ENCRYPT",_5); _X509.setConstant("PURPOSE_CRL_SIGN",_6); _X509.setConstant("PURPOSE_ANY",_7); _X509.setConstant("PURPOSE_OCSP_HELPER",_8); _X509.setConstant("TRUST_COMPAT",_1); _X509.setConstant("TRUST_SSL_CLIENT",_2); _X509.setConstant("TRUST_SSL_SERVER",_3); _X509.setConstant("TRUST_EMAIL",_4); _X509.setConstant("TRUST_OBJECT_SIGN",_5); _X509.setConstant("TRUST_OCSP_SIGN",_6); _X509.setConstant("TRUST_OCSP_REQUEST",_7); // These should eventually point to correct things. _X509.setConstant("DEFAULT_CERT_AREA", runtime.newString(X509Utils.X509_CERT_AREA)); _X509.setConstant("DEFAULT_CERT_DIR", runtime.newString(X509Utils.X509_CERT_DIR)); _X509.setConstant("DEFAULT_CERT_FILE", runtime.newString(X509Utils.X509_CERT_FILE)); _X509.setConstant("DEFAULT_CERT_DIR_ENV", runtime.newString(X509Utils.X509_CERT_DIR_EVP)); _X509.setConstant("DEFAULT_CERT_FILE_ENV", runtime.newString(X509Utils.X509_CERT_FILE_EVP)); _X509.setConstant("DEFAULT_PRIVATE_DIR", runtime.newString(X509Utils.X509_PRIVATE_DIR)); } static RubyModule _X509(final Ruby runtime) { return (RubyModule) runtime.getModule("OpenSSL").getConstant("X509"); } static Map getErrors() { return X509Error.getErrors(); } }// X509 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509Attribute.java000066400000000000000000000154731313661621600264730ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.DERSet; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import static org.jruby.ext.openssl.OpenSSL.*; import static org.jruby.ext.openssl.ASN1._ASN1; import static org.jruby.ext.openssl.Utils.*; /** * @author Ola Bini */ public class X509Attribute extends RubyObject { private static final long serialVersionUID = 5569940260019783275L; private static ObjectAllocator ATTRIBUTE_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509Attribute(runtime, klass); } }; public static void createAttribute(Ruby runtime, RubyModule _X509) { RubyClass _Attribute = _X509.defineClassUnder("Attribute", runtime.getObject(), ATTRIBUTE_ALLOCATOR); RubyClass openSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); _X509.defineClassUnder("AttributeError", openSSLError, openSSLError.getAllocator()); _Attribute.defineAnnotatedMethods(X509Attribute.class); } static RubyClass _Attribute(final Ruby runtime) { RubyModule _X509 = (RubyModule) runtime.getModule("OpenSSL").getConstant("X509"); return _X509.getClass("Attribute"); } public X509Attribute(Ruby runtime, RubyClass type) { super(runtime,type); } private IRubyObject oid; // attribute type private IRubyObject value; private transient ASN1ObjectIdentifier objectId; static X509Attribute newAttribute(final Ruby runtime, final ASN1ObjectIdentifier type, final ASN1Set values) throws IOException { X509Attribute attribute = new X509Attribute(runtime, _Attribute(runtime)); attribute.objectId = type; final ThreadContext context = runtime.getCurrentContext(); attribute.value = ASN1.decodeObject(context, _ASN1(runtime), values); return attribute; } private ASN1ObjectIdentifier getTypeID() { if ( objectId != null ) return objectId; return objectId = ASN1.getObjectID(getRuntime(), oid.toString()); } ASN1Primitive toASN1(final ThreadContext context) { ASN1EncodableVector v1 = new ASN1EncodableVector(); v1.add( getTypeID() ); if ( value instanceof ASN1.Constructive ) { v1.add( ((ASN1.Constructive) value).toASN1(context) ); } else { ASN1EncodableVector v2 = new ASN1EncodableVector(); v2.add( ((ASN1.ASN1Data) value).toASN1(context) ); v1.add( new DERSet(v2) ); } return new DLSequence(v1); } @JRubyMethod(name="initialize", required = 1, optional = 1, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { if ( Arity.checkArgumentCount(context.runtime, args, 1, 2) == 1 ) { set_oid( to_der_if_possible(context, args[0]) ); return this; } set_oid(args[0]); set_value(context, args[1]); return this; } @Override public IRubyObject initialize_copy(final IRubyObject original) { if (this == original) return this; checkFrozen(); final X509Attribute that = (X509Attribute) original; this.value = that.value == null ? null : that.value.dup(); this.oid = that.oid; this.objectId = that.objectId; return this; } @JRubyMethod public IRubyObject to_der(final ThreadContext context) { final byte[] bytes; try { // NOTE: likely won't work due Constructive ! bytes = toASN1(context).getEncoded(ASN1Encoding.DER); } catch (IOException e) { throw newIOError(context.runtime, e); } return StringHelper.newString(context.runtime, bytes); } @JRubyMethod public IRubyObject oid() { if ( this.oid == null ) { final Ruby runtime = getRuntime(); oid = runtime.newString( ASN1.oid2Sym(runtime, objectId) ); } return this.oid; } @JRubyMethod(name="oid=") public IRubyObject set_oid(final IRubyObject oid) { this.objectId = null; return this.oid = oid; } @JRubyMethod public IRubyObject value() { return value; } @JRubyMethod(name="value=") public IRubyObject set_value(final ThreadContext context, final IRubyObject value) { try { //if ( value instanceof ASN1.ASN1Data ) { // return this.value = value; //} return this.value = ASN1.decodeImpl(context, value); } catch (IOException e) { throw newIOError(context.runtime, e); } catch (IllegalArgumentException e) { throw newArgumentError(context.runtime, e); } } }// X509Attribute jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509CRL.java000066400000000000000000000661161313661621600251500ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringWriter; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.security.GeneralSecurityException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.CRLException; import java.security.cert.CertificateFactory; import java.security.cert.X509CRLEntry; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509v2CRLBuilder; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; import org.joda.time.DateTime; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.x509store.PEMInputOutput; import org.jruby.runtime.Arity; import org.jruby.runtime.Block; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.Variable; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import static org.jruby.ext.openssl.OpenSSL.*; import static org.jruby.ext.openssl.X509._X509; import static org.jruby.ext.openssl.X509Extension.newExtension; import static org.jruby.ext.openssl.StringHelper.appendGMTDateTime; import static org.jruby.ext.openssl.StringHelper.appendLowerHexValue; /** * @author Ola Bini */ public class X509CRL extends RubyObject { private static final long serialVersionUID = -2463300006179688577L; private static ObjectAllocator X509CRL_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509CRL(runtime, klass); } }; public static void createX509CRL(final Ruby runtime, final RubyModule _X509) { RubyClass _CRL = _X509.defineClassUnder("CRL", runtime.getObject(), X509CRL_ALLOCATOR); RubyClass _OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); _X509.defineClassUnder("CRLError", _OpenSSLError, _OpenSSLError.getAllocator()); _CRL.defineAnnotatedMethods(X509CRL.class); } private RubyInteger version; private IRubyObject issuer; private RubyTime last_update; private RubyTime next_update; private RubyArray revoked; private RubyArray extensions; private IRubyObject signature_algorithm; private boolean changed = true; private java.security.cert.X509CRL crl = null; private transient X509CRLHolder crlHolder; private transient ASN1Primitive crlValue; static RubyClass _CRL(final Ruby runtime) { return _X509(runtime).getClass("CRL"); } public X509CRL(Ruby runtime, RubyClass type) { super(runtime, type); } private X509CRL(Ruby runtime) { super(runtime, _CRL(runtime)); } java.security.cert.X509CRL getCRL() { if ( crl != null ) return crl; try { if ( crlHolder == null ) { throw new IllegalStateException("no crl holder"); } final byte[] encoded = crlHolder.getEncoded(); return crl = generateCRL(encoded, 0, encoded.length); } catch (IOException ex) { throw newCRLError(getRuntime(), ex); } catch (GeneralSecurityException ex) { throw newCRLError(getRuntime(), ex); } } private X509CRLHolder getCRLHolder(boolean allowNull) { if ( crlHolder != null ) return crlHolder; try { if ( crl == null ) { if ( allowNull ) return null; throw new IllegalStateException("no crl"); } return crlHolder = new X509CRLHolder(crl.getEncoded()); } catch (IOException ex) { throw newCRLError(getRuntime(), ex); } catch (CRLException ex) { throw newCRLError(getRuntime(), ex); } } final byte[] getEncoded() throws IOException, CRLException { if ( crlHolder != null ) return crlHolder.getEncoded(); return getCRL().getEncoded(); } private byte[] getSignature() { return getCRL().getSignature(); } private static boolean avoidJavaSecurity = false; private static java.security.cert.X509CRL generateCRL( final byte[] bytes, final int offset, final int length) throws GeneralSecurityException { CertificateFactory factory = SecurityHelper.getCertificateFactory("X.509"); return (java.security.cert.X509CRL) factory.generateCRL( new ByteArrayInputStream(bytes, offset, length) ); } private static X509CRLHolder parseCRLHolder( final byte[] bytes, final int offset, final int length) throws IOException { return new X509CRLHolder(new ByteArrayInputStream(bytes, offset, length)); } @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args, final Block block) { final Ruby runtime = context.runtime; this.extensions = runtime.newArray(8); if ( Arity.checkArgumentCount(runtime, args, 0, 1) == 0 ) return this; final ByteList strList = args[0].asString().getByteList(); final byte[] bytes = strList.unsafeBytes(); final int offset = strList.getBegin(); final int length = strList.getRealSize(); try { if ( avoidJavaSecurity ) { this.crlHolder = parseCRLHolder(bytes, offset, length); } else { this.crl = generateCRL(bytes, offset, length); } } catch (IOException e) { debugStackTrace(runtime, e); throw newCRLError(runtime, e); } catch (GeneralSecurityException e) { debugStackTrace(runtime, e); throw newCRLError(runtime, e); } set_last_update( context, RubyTime.newTime(runtime, crl.getThisUpdate().getTime()) ); set_next_update( context, RubyTime.newTime(runtime, crl.getNextUpdate().getTime()) ); set_issuer( X509Name.newName(runtime, crl.getIssuerX500Principal()) ); final int version = crl.getVersion(); this.version = runtime.newFixnum( version > 0 ? version - 1 : 2 ); extractExtensions(context); Set revokedCRLs = crl.getRevokedCertificates(); if ( revokedCRLs != null && ! revokedCRLs.isEmpty() ) { final X509CRLEntry[] revokedSorted = revokedCRLs.toArray(new X509CRLEntry[ revokedCRLs.size() ]); Arrays.sort(revokedSorted, 0, revokedSorted.length, new Comparator() { public int compare(X509CRLEntry o1, X509CRLEntry o2) { return o1.getRevocationDate().compareTo( o2.getRevocationDate() ); } }); for ( X509CRLEntry entry : revokedSorted ) { revoked().append( X509Revoked.newInstance(context, entry) ); } } this.changed = false; return this; } private void extractExtensions(final ThreadContext context) { if ( crlHolder != null ) extractExtensions(context, crlHolder); else extractExtensionsCRL(context, getCRL()); } @SuppressWarnings("unchecked") private void extractExtensions(final ThreadContext context, final X509CRLHolder crl) { if ( ! crlHolder.hasExtensions() ) return; for ( ASN1ObjectIdentifier oid : (Collection) crl.getExtensionOIDs() ) { addExtension(context, oid, crl); } } private void addExtension(final ThreadContext context, final ASN1ObjectIdentifier extOID, final X509CRLHolder crl) { final Extension ext = crl.getExtension(extOID); final IRubyObject extension = newExtension(context.runtime, extOID, ext); this.extensions.append(extension); } private void extractExtensionsCRL(final ThreadContext context, final java.security.cert.X509Extension crl) { //final RubyClass _Extension = _Extension(context.runtime); final Set criticalExtOIDs = crl.getCriticalExtensionOIDs(); if ( criticalExtOIDs != null ) { for ( final String extOID : criticalExtOIDs ) { addExtensionCRL(context, extOID, crl, true); } } final Set nonCriticalExtOIDs = crl.getNonCriticalExtensionOIDs(); if ( nonCriticalExtOIDs != null ) { for ( final String extOID : nonCriticalExtOIDs ) { addExtensionCRL(context, extOID, crl, false); } } } private void addExtensionCRL(final ThreadContext context, final String extOID, final java.security.cert.X509Extension crl, final boolean critical) { try { final IRubyObject extension = newExtension(context, extOID, crl, critical); if ( extension != null ) this.extensions.append(extension); } catch (IOException e) { throw newCRLError(context.runtime, e); } } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(final IRubyObject obj) { if ( this == obj ) return this; return super.initialize_copy(obj); } @JRubyMethod(name = {"to_pem", "to_s"}) public IRubyObject to_pem(final ThreadContext context) { StringWriter writer = new StringWriter(); try { PEMInputOutput.writeX509CRL(writer, crl); return RubyString.newString(context.runtime, writer.getBuffer()); } catch (IOException e) { throw newCRLError(context.runtime, e); } } @JRubyMethod public IRubyObject to_der(final ThreadContext context) { try { return StringHelper.newString(context.runtime, getEncoded()); } catch (IOException e) { throw newCRLError(context.runtime, e); } catch (CRLException e) { throw newCRLError(context.runtime, e); } } @JRubyMethod @SuppressWarnings("unchecked") public IRubyObject to_text(final ThreadContext context) { final Ruby runtime = context.runtime; final char[] S16 = StringHelper.S20; final StringBuilder text = new StringBuilder(160); text.append("Certificate Revocation List (CRL):\n"); final int version = RubyNumeric.fix2int(this.version); text.append(S16,0,8).append("Version ").append( version + 1 ). append(" (0x").append( Integer.toString( version, 16 ) ).append(")\n"); text.append(S16,0,4).append("Signature Algorithm: ").append( signature_algorithm() ).append('\n'); text.append(S16,0,8).append("Issuer: ").append( issuer() ).append('\n'); text.append(S16,0,8).append("Last Update: "); appendGMTDateTime( text, getLastUpdate() ).append('\n'); if ( ! next_update().isNil() ) { text.append(S16,0,8).append("Next Update: "); appendGMTDateTime( text, getNextUpdate() ).append('\n'); } else { text.append(S16,0,8).append("Next Update: NONE\n"); } if ( extensions != null && extensions.size() > 0 ) { text.append(S16,0,8).append("CRL extensions:\n"); extensions_to_text(context, extensions, text, 12); } if ( revoked != null && revoked.size() > 0 ) { text.append("\nRevoked Certificates:\n"); for ( int i = 0; i < revoked.size(); i++ ) { final X509Revoked rev = (X509Revoked) revoked.entry(i); final String serial = rev.serial.toString(16); text.append(S16,0,4).append("Serial Number: "); if ( serial.length() % 2 == 0 ) text.append(serial).append('\n'); else text.append('0').append(serial).append('\n'); text.append(S16,0,8).append("Revocation Date: "); appendGMTDateTime( text, rev.getTime() ).append('\n'); if ( rev.hasExtensions() ) { text.append(S16,0,8).append("CRL entry extensions:\n"); extensions_to_text(context, extensions, text, 12); } } } else { text.append("No Revoked Certificates.\n"); } // TODO we shall parse / use crlValue when != null : text.append(S16,0,4).append("Signature Algorithm: ").append( signature_algorithm() ).append('\n'); appendLowerHexValue(text, getSignature(), 9, 54); return RubyString.newString( runtime, text ); } static void extensions_to_text(final ThreadContext context, final List exts, final StringBuilder text, final int indent) { final char[] S20 = StringHelper.S20; for ( int i = 0; i < exts.size(); i++ ) { final X509Extension ext = exts.get(i); final ASN1ObjectIdentifier oid = ext.getRealObjectID(); final String no = ASN1.o2a(context.runtime, oid); text.append(S20,0,indent).append( no ).append(": "); if ( ext.isRealCritical() ) text.append("critical"); text.append('\n'); final String value = ext.value(context).toString(); for ( String val : value.split("\n") ) { text.append(S20,0,16).append( val ).append('\n'); } } } @Override @JRubyMethod @SuppressWarnings("unchecked") public IRubyObject inspect() { return ObjectSupport.inspect(this, (List) getInstanceVariableList()); } @Override // FAKE'em to include "instance" variables in inspect public List> getInstanceVariableList() { final ArrayList> list = new ArrayList>(6); return list; } @JRubyMethod public IRubyObject version() { return version == null ? version = getRuntime().newFixnum(0) : version; } @JRubyMethod(name="version=") public IRubyObject set_version(IRubyObject version) { if ( ! version.equals(this.version) ) this.changed = true; return this.version = version.convertToInteger("to_i"); } @JRubyMethod public IRubyObject signature_algorithm() { return signature_algorithm == null ? signature_algorithm = signature_algorithm(getRuntime()) : signature_algorithm; } private RubyString signature_algorithm(final Ruby runtime) { return RubyString.newString(runtime, getSignatureAlgorithm(runtime, "itu-t")); } private String getSignatureAlgorithm(final Ruby runtime, final String def) { final X509CRLHolder crlHolder = getCRLHolder(true); if ( crlHolder == null ) return def; ASN1ObjectIdentifier algId = crlHolder.toASN1Structure().getSignatureAlgorithm().getAlgorithm(); //ASN1ObjectIdentifier algId = ASN1.toObjectID( getCRL().getSigAlgOID(), true ); String algName; if ( algId != null ) { algName = ASN1.o2a(runtime, algId, true); } else algName = null; //else { // algName = getCRL().getSigAlgName(); // algId = ASN1.toObjectID( algName, true ); // if ( algId != null ) { // algName = ASN1.o2a(runtime, algId, true); // } //} return algName == null ? def : algName; } @JRubyMethod public IRubyObject issuer() { return this.issuer == null ? this.issuer = X509Name.newName(getRuntime()) : this.issuer; } @JRubyMethod(name="issuer=") public IRubyObject set_issuer(final IRubyObject issuer) { if ( ! issuer.equals(this.issuer) ) this.changed = true; return this.issuer = issuer; } DateTime getLastUpdate() { if ( last_update == null ) return null; return last_update.getDateTime(); } @JRubyMethod public IRubyObject last_update() { return last_update == null ? getRuntime().getNil() : last_update; } @JRubyMethod(name="last_update=") public IRubyObject set_last_update(final ThreadContext context, IRubyObject val) { this.changed = true; final RubyTime value = (RubyTime) val.callMethod(context, "getutc"); value.setMicroseconds(0); return this.last_update = value; } DateTime getNextUpdate() { if ( next_update == null ) return null; return next_update.getDateTime(); } @JRubyMethod public IRubyObject next_update() { return next_update == null ? getRuntime().getNil() : next_update; } @JRubyMethod(name="next_update=") public IRubyObject set_next_update(final ThreadContext context, IRubyObject val) { this.changed = true; final RubyTime value = (RubyTime) val.callMethod(context, "getutc"); value.setMicroseconds(0); return this.next_update = value; } @JRubyMethod public RubyArray revoked() { return revoked == null ? revoked = getRuntime().newArray(4) : revoked; } @JRubyMethod(name="revoked=") public IRubyObject set_revoked(final IRubyObject revoked) { this.changed = true; return this.revoked = (RubyArray) revoked; } @JRubyMethod public IRubyObject add_revoked(final ThreadContext context, IRubyObject val) { this.changed = true; revoked().callMethod(context, "<<", val); return val; } @JRubyMethod public RubyArray extensions() { return this.extensions; } @SuppressWarnings("unchecked") @JRubyMethod(name="extensions=") public IRubyObject set_extensions(final IRubyObject extensions) { return this.extensions = (RubyArray) extensions; } @JRubyMethod public IRubyObject add_extension(final IRubyObject extension) { extensions().append(extension); return extension; } @JRubyMethod public IRubyObject sign(final ThreadContext context, final IRubyObject key, IRubyObject digest) { final Ruby runtime = context.runtime; final String signatureAlgorithm = getSignatureAlgorithm(runtime, (PKey) key, (Digest) digest); final X500Name issuerName = ((X509Name) issuer).getX500Name(); final java.util.Date thisUpdate = getLastUpdate().toDate(); final X509v2CRLBuilder generator = new X509v2CRLBuilder(issuerName, thisUpdate); final java.util.Date nextUpdate = getNextUpdate().toDate(); generator.setNextUpdate(nextUpdate); //signature_algorithm = RubyString.newString(runtime, digAlg); //generator.setSignatureAlgorithm( signatureAlgorithm ); if ( revoked != null ) { for ( int i = 0; i < revoked.size(); i++ ) { final X509Revoked rev = (X509Revoked) revoked.entry(i); BigInteger serial = new BigInteger( rev.callMethod(context, "serial").toString() ); RubyTime t1 = (RubyTime) rev.callMethod(context, "time").callMethod(context, "getutc"); t1.setMicroseconds(0); final Extensions revExts; if ( rev.hasExtensions() ) { final RubyArray exts = rev.extensions(); final ASN1Encodable[] array = new ASN1Encodable[ exts.size() ]; for ( int j = 0; j < exts.size(); j++ ) { final X509Extension ext = (X509Extension) exts.entry(j); try { array[j] = ext.toASN1Sequence(); } catch (IOException e) { throw newCRLError(runtime, e); } } revExts = Extensions.getInstance( new DERSequence(array) ); } else { revExts = null; } generator.addCRLEntry( serial, t1.getJavaDate(), revExts ); } } try { for ( int i = 0; i < extensions.size(); i++ ) { X509Extension ext = (X509Extension) extensions.entry(i); ASN1Encodable value = ext.getRealValue(); generator.addExtension(ext.getRealObjectID(), ext.isRealCritical(), value); } } catch (IOException e) { throw newCRLError(runtime, e); } final PrivateKey privateKey = ((PKey) key).getPrivateKey(); try { if ( avoidJavaSecurity ) { // NOT IMPLEMENTED } else { //crl = generator.generate(((PKey) key).getPrivateKey()); } /* AlgorithmIdentifier keyAldID = new AlgorithmIdentifier(new ASN1ObjectIdentifier(keyAlg)); AlgorithmIdentifier digAldID = new AlgorithmIdentifier(new ASN1ObjectIdentifier(digAlg)); final BcContentSignerBuilder signerBuilder; final AsymmetricKeyParameter signerPrivateKey; if ( isDSA ) { signerBuilder = new BcDSAContentSignerBuilder(keyAldID, digAldID); DSAPrivateKey privateKey = (DSAPrivateKey) ((PKey) key).getPrivateKey(); DSAParameters params = new DSAParameters( privateKey.getParams().getP(), privateKey.getParams().getQ(), privateKey.getParams().getG() ); signerPrivateKey = new DSAPrivateKeyParameters(privateKey.getX(), params); } */ ContentSigner signer = new JcaContentSignerBuilder( signatureAlgorithm ).build(privateKey); this.crlHolder = generator.build( signer ); this.crl = null; } catch (IllegalStateException e) { debugStackTrace(e); throw newCRLError(runtime, e); } catch (Exception e) { debugStackTrace(e); throw newCRLError(runtime, e.getMessage()); } final ASN1Primitive crlVal = getCRLValue(runtime); ASN1Sequence v1 = (ASN1Sequence) ( ((ASN1Sequence) crlVal).getObjectAt(0) ); final ASN1EncodableVector build1 = new ASN1EncodableVector(); int copyIndex = 0; if ( v1.getObjectAt(0) instanceof ASN1Integer ) copyIndex++; build1.add( new ASN1Integer( new BigInteger(version.toString()) ) ); while ( copyIndex < v1.size() ) { build1.add( v1.getObjectAt(copyIndex++) ); } final ASN1EncodableVector build2 = new ASN1EncodableVector(); build2.add( new DLSequence(build1) ); build2.add( ((ASN1Sequence) crlVal).getObjectAt(1) ); build2.add( ((ASN1Sequence) crlVal).getObjectAt(2) ); this.crlValue = new DLSequence(build2); changed = false; return this; } private String getSignatureAlgorithm(final Ruby runtime, final PKey key, final Digest digest) { // Have to obey some artificial constraints of the OpenSSL implementation. Stupid. final String keyAlg = key.getAlgorithm(); final String digAlg = digest.getShortAlgorithm(); if ( "DSA".equalsIgnoreCase(keyAlg) ) { if ( ( "MD5".equalsIgnoreCase( digAlg ) ) ) { // || // ( "SHA1".equals( digest.name().toString() ) ) ) { throw newCRLError(runtime, "unsupported key / digest algorithm ("+ key +" / "+ digAlg +")"); } } else if ( "RSA".equalsIgnoreCase(keyAlg) ) { if ( "DSS1".equals( digest.name().toString() ) ) { throw newCRLError(runtime, "unsupported key / digest algorithm ("+ key +" / "+ digAlg +")"); } } return digAlg + "WITH" + keyAlg; } private boolean isDSA(final PKey key) { return "DSA".equalsIgnoreCase( key.getAlgorithm() ); } private ASN1Primitive getCRLValue(final Ruby runtime) { if ( this.crlValue != null ) return this.crlValue; return this.crlValue = readCRL( runtime ); } private ASN1Primitive readCRL(final Ruby runtime) { try { return ASN1.readObject( getEncoded() ); } catch (CRLException e) { throw newCRLError(runtime, e); } catch (IOException e) { throw newCRLError(runtime, e); } } @JRubyMethod public IRubyObject verify(final ThreadContext context, final IRubyObject key) { if ( changed ) return context.runtime.getFalse(); final PublicKey publicKey = ((PKey) key).getPublicKey(); try { boolean valid = SecurityHelper.verify(getCRL(), publicKey, true); return context.runtime.newBoolean(valid); } catch (GeneralSecurityException e) { debug("CRL#verify() failed:", e); return context.runtime.getFalse(); } } private static RubyClass _CRLError(final Ruby runtime) { return _X509(runtime).getClass("CRLError"); } static RaiseException newCRLError(Ruby runtime, Exception e) { return Utils.newError(runtime, _CRLError(runtime), e); } private static RaiseException newCRLError(Ruby runtime, String message) { return Utils.newError(runtime, _CRLError(runtime), message); } }// X509CRL jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509Cert.java000066400000000000000000000726541313661621600254310ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringWriter; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.joda.time.DateTime; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.impl.ASN1Registry; import org.jruby.ext.openssl.x509store.PEMInputOutput; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import org.jruby.runtime.Block; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.builtin.Variable; import org.jruby.runtime.component.VariableEntry; import org.jruby.util.ByteList; import static org.jruby.ext.openssl.X509._X509; import static org.jruby.ext.openssl.X509Extension.newExtension; import static org.jruby.ext.openssl.X509CRL.extensions_to_text; import static org.jruby.ext.openssl.StringHelper.appendGMTDateTime; import static org.jruby.ext.openssl.StringHelper.appendLowerHexValue; import static org.jruby.ext.openssl.StringHelper.lowerHexBytes; import static org.jruby.ext.openssl.OpenSSL.debug; import static org.jruby.ext.openssl.OpenSSL.debugStackTrace; /** * @author Ola Bini */ public class X509Cert extends RubyObject { private static final long serialVersionUID = -6524431607032364369L; private static ObjectAllocator X509CERT_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509Cert(runtime, klass); } }; public static void createX509Cert(final Ruby runtime, final RubyModule X509) { RubyClass Certificate = X509.defineClassUnder("Certificate", runtime.getObject(), X509CERT_ALLOCATOR); RubyClass OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); X509.defineClassUnder("CertificateError", OpenSSLError, OpenSSLError.getAllocator()); Certificate.defineAnnotatedMethods(X509Cert.class); } public X509Cert(Ruby runtime, RubyClass type) { super(runtime, type); } private X509Cert(Ruby runtime) { super(runtime, _Certificate(runtime)); } private IRubyObject subject; private IRubyObject issuer; private BigInteger serial = BigInteger.ZERO; private RubyTime not_before; private RubyTime not_after; private IRubyObject sig_alg; private IRubyObject version; private X509Certificate cert; private transient PKey public_key; // lazy initialized private final List extensions = new ArrayList(); private boolean changed = true; final X509AuxCertificate getAuxCert() { if ( cert == null ) return null; if ( cert instanceof X509AuxCertificate ) { return (X509AuxCertificate) cert; } return new X509AuxCertificate(cert); } public static IRubyObject wrap(Ruby runtime, Certificate cert) throws CertificateEncodingException { return wrap(runtime.getCurrentContext(), cert.getEncoded()); } static X509Cert wrap(ThreadContext context, Certificate cert) throws CertificateEncodingException { return wrap(context, cert.getEncoded()); } // this is the javax.security counterpart of the previous wrap method public static IRubyObject wrap(Ruby runtime, javax.security.cert.Certificate cert) throws javax.security.cert.CertificateEncodingException { return wrap(runtime.getCurrentContext(), cert.getEncoded()); } static X509Cert wrap(ThreadContext context, javax.security.cert.Certificate cert) throws javax.security.cert.CertificateEncodingException { return wrap(context, cert.getEncoded()); } static X509Cert wrap(final ThreadContext context, final byte[] encoded) { //final Ruby runtime = context.runtime; //final RubyString enc = StringHelper.newString(runtime, encoded); //return _Certificate(runtime).callMethod(context, "new", enc); final X509Cert cert = new X509Cert(context.runtime); cert.initialize(context, encoded); return cert; } @JRubyMethod(name="initialize", optional = 1, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args, final Block unusedBlock) { if ( args.length == 0 ) { this.subject = X509Name.newName(context.runtime); this.issuer = X509Name.newName(context.runtime); return this; } final RubyString str = StringHelper.readPossibleDERInput(context, args[0]); final ByteList bytes = str.getByteList(); initialize(context, bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize()); return this; } private void initialize(final ThreadContext context, final byte[] encoded) { initialize(context, encoded, 0, encoded.length); } private void initialize(final ThreadContext context, final byte[] encoded, final int offset, final int length) { final Ruby runtime = context.runtime; byte[] bytes = StringHelper.readX509PEM(encoded, offset, length); try { final ByteArrayInputStream bis = new ByteArrayInputStream(bytes); cert = (X509Certificate) SecurityHelper.getCertificateFactory("X.509").generateCertificate(bis); } catch (CertificateException e) { throw newCertificateError(runtime, e); } if ( cert == null ) { throw newCertificateError(runtime, (String) null); } set_serial( RubyNumeric.str2inum(runtime, runtime.newString(cert.getSerialNumber().toString()), 10) ); set_not_before( context, RubyTime.newTime( runtime, cert.getNotBefore().getTime() ) ); set_not_after( context, RubyTime.newTime( runtime, cert.getNotAfter().getTime() ) ); this.subject = X509Name.newName(runtime, cert.getSubjectX500Principal()); this.issuer = X509Name.newName(runtime, cert.getIssuerX500Principal()); this.version = RubyFixnum.newFixnum(runtime, cert.getVersion() - 1); String sigAlgorithm = cert.getSigAlgOID(); if ( sigAlgorithm == null ) sigAlgorithm = cert.getSigAlgName(); // e.g. SHA256withRSA else { sigAlgorithm = ASN1.oid2name(runtime, new ASN1ObjectIdentifier(sigAlgorithm), true); if ( sigAlgorithm == null ) { sigAlgorithm = "itu-t"; // MRI compability ... the "crazy" parts // for some certificates that MRI parses, // we get getSigAlgOID() == getSigAlgName() == "0.0" if ( cert.getSigAlgName() != null && ! cert.getSigAlgOID().equals(cert.getSigAlgName()) ) { sigAlgorithm = cert.getSigAlgName(); // not sure if it makes any sense } } } // "hot" path e.g. sha256WithRSAEncryption this.sig_alg = RubyString.newString(runtime, sigAlgorithm); final Set criticalExtOIDs = cert.getCriticalExtensionOIDs(); if ( criticalExtOIDs != null ) { for ( final String extOID : criticalExtOIDs ) { addExtension(context, extOID, true); } } final Set nonCriticalExtOIDs = cert.getNonCriticalExtensionOIDs(); if ( nonCriticalExtOIDs != null ) { for ( final String extOID : nonCriticalExtOIDs ) { addExtension(context, extOID, false); } } changed = false; } private void addExtension(final ThreadContext context, final String extOID, final boolean critical) { try { final byte[] extValue = cert.getExtensionValue(extOID); if ( extValue == null ) return; final X509Extension[] extension = newExtension(context, extOID, extValue, critical); for ( int i = 0; i < extension.length; i++ ) this.extensions.add( extension[i] ); } catch (IOException e) { throw newCertificateError(context.runtime, e); } } private static RubyClass _CertificateError(final Ruby runtime) { return _X509(runtime).getClass("CertificateError"); } static RubyClass _Certificate(final Ruby runtime) { return _X509(runtime).getClass("Certificate"); } public static RaiseException newCertificateError(final Ruby runtime, Exception e) { return Utils.newError(runtime, _CertificateError(runtime), e); } static RaiseException newCertificateError(final Ruby runtime, String msg) { return Utils.newError(runtime, _CertificateError(runtime), msg); } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(IRubyObject obj) { if ( this == obj ) return this; checkFrozen(); return this; } @JRubyMethod public IRubyObject to_der() { try { return StringHelper.newString(getRuntime(), cert.getEncoded()); } catch (CertificateEncodingException ex) { throw newCertificateError(getRuntime(), ex); } } @JRubyMethod(name = {"to_pem", "to_s"}) public IRubyObject to_pem() { final StringWriter str = new StringWriter(); try { PEMInputOutput.writeX509Certificate(str, getAuxCert()); return getRuntime().newString( str.toString() ); } catch (IOException ex) { throw getRuntime().newIOErrorFromException(ex); } } @JRubyMethod public IRubyObject to_text(final ThreadContext context) { final Ruby runtime = context.runtime; final char[] S20 = StringHelper.S20; final StringBuilder text = new StringBuilder(240); text.append("Certificate:\n"); text.append(S20,0,4).append("Data:\n"); final int version = this.version == null ? 0 : RubyNumeric.fix2int(this.version); text.append(S20,0,8).append("Version: ").append( version + 1 ). append(" (0x").append( Integer.toString( version, 16 ) ).append(")\n"); // <= 0x1122334455667788 printed on same line as : // Serial Number: 1234605616436508552 (0x1122334455667788) // but 0x112233445566778899 ends up : // Serial Number: // 11:22:33:44:55:66:77:88:99 text.append(S20,0,8).append("Serial Number:"); if ( serial.compareTo( new BigInteger("FFFFFFFFFFFFFFFF", 16) ) > 0 ) { text.append('\n'); text.append(S20,0,12).append( lowerHexBytes(serial.toByteArray(), 1) ).append('\n'); } else { text.append(' ').append(serial.toString(10)).append(' '); text.append('(').append("0x").append(serial.toString(16)).append(')').append('\n'); } text.append(S20,0,4).append("Signature Algorithm: ").append( signature_algorithm() ).append('\n'); //final RubyString issuer = issuer().asString(); ByteList bytes = issuer.getByteList(); //StringHelper.gsub(runtime, bytes, (byte) '/', (byte) ' '); //if ( bytes.charAt(0) == ' ' ) bytes.setBegin(bytes.getBegin() + 1); text.append(S20,0,8).append("Issuer: ").append( issuer ).append('\n'); text.append(S20,0,8).append("Validity\n"); text.append(S20,0,12).append("Not Before: "); appendGMTDateTime( text, getNotBefore() ).append('\n'); text.append(S20,0,12).append("Not After : "); appendGMTDateTime( text, getNotAfter() ).append('\n'); text.append(S20,0,8).append("Subject: ").append( subject() ).append('\n'); text.append(S20,0,8).append("Subject Public Key Info:\n"); final PublicKey publicKey = getPublicKey(); text.append(S20,0,12).append("Public Key Algorithm: ").append(publicKey.getAlgorithm()).append('\n'); if ( "RSA".equals( publicKey.getAlgorithm() ) ) { final RSAPublicKey rsaKey = ((RSAPublicKey) publicKey); text.append(S20,0,16).append("Public-Key: (").append( rsaKey.getModulus().bitLength() ).append(" bit)\n"); text.append(S20,0,16).append("Modulus:\n"); appendLowerHexValue(text, rsaKey.getModulus().toByteArray(), 20, 45); final BigInteger exponent = rsaKey.getPublicExponent(); text.append(S20,0,16).append("Exponent: ").append(exponent). append(" (0x").append( exponent.toString(16) ).append(")\n"); } else if ( "DSA".equals( publicKey.getAlgorithm() ) ) { final DSAPublicKey dsaKey = ((DSAPublicKey) publicKey); text.append(S20,0,16).append("Public-Key: (").append( dsaKey.getY().bitLength() ).append(" bit)\n"); text.append(S20,0,16).append("TODO: not-implemented (PR HOME-WORK)").append('\n'); // left-TODO } else { text.append(S20,0,16).append("TODO: not-implemented (PRs WELCOME!)").append('\n'); // left-TODO } if ( extensions != null && extensions.size() > 0 ) { text.append(S20,0,8).append("X509v3 extensions:\n"); extensions_to_text(context, extensions, text, 12); } text.append(S20,0,4).append("Signature Algorithm: ").append( signature_algorithm() ).append('\n'); appendLowerHexValue(text, getSignature(), 9, 54); return RubyString.newString( runtime, text ); } @Override @JRubyMethod @SuppressWarnings("unchecked") public IRubyObject inspect() { final ArrayList> varList = new ArrayList>(5); varList.add(new VariableEntry( "subject", subject().isNil() ? "nil" : subject().asString().toString() )); varList.add(new VariableEntry( "issuer", issuer().isNil() ? "nil" : issuer().asString().toString() )); varList.add(new VariableEntry( "serial", serial().isNil() ? "nil" : serial().asString().toString() )); varList.add(new VariableEntry( "not_before", not_before().isNil() ? "nil" : not_before().toString() )); varList.add(new VariableEntry( "not_after", not_after().isNil() ? "nil" : not_after().toString() )); return ObjectSupport.inspect(this, (List) varList); } @JRubyMethod public IRubyObject version() { return version != null ? version : ( version = getRuntime().newFixnum(0) ); } @JRubyMethod(name = "version=") public IRubyObject set_version(final IRubyObject version) { if ( ! version().equals(version) ) { this.changed = true; } return this.version = version; } @JRubyMethod public IRubyObject signature_algorithm() { return sig_alg; } private byte[] getSignature() { return cert.getSignature(); } BigInteger getSerial() { return serial; } @JRubyMethod public IRubyObject serial() { return BN.newBN(getRuntime(), serial); } @JRubyMethod(name = "serial=") public IRubyObject set_serial(final IRubyObject serial) { final String serialStr = serial.asString().toString(); final BigInteger serialInt; if ( serialStr.equals("0") ) { // MRI compatibility: allow 0 serial number serialInt = BigInteger.ONE; } else { serialInt = new BigInteger(serialStr); } this.changed = ! serialInt.equals(this.serial); //generator.setSerialNumber( serialInt.abs() ); this.serial = serialInt; return serial; } X509Name getSubject() { return ((X509Name) subject); } @JRubyMethod public IRubyObject subject() { return subject; } @JRubyMethod(name = "subject=") public IRubyObject set_subject(final IRubyObject subject) { if ( ! subject.equals(this.subject) ) this.changed = true; return this.subject = subject; } X509Name getIssuer() { return ((X509Name) issuer); } @JRubyMethod public IRubyObject issuer() { return issuer; } @JRubyMethod(name = "issuer=") public IRubyObject set_issuer(final IRubyObject issuer) { if ( ! issuer.equals(this.issuer) ) this.changed = true; return this.issuer = issuer; } @JRubyMethod public IRubyObject not_before() { return not_before == null ? getRuntime().getNil() : not_before; } @JRubyMethod(name = "not_before=") public IRubyObject set_not_before(final ThreadContext context, final IRubyObject time) { changed = true; not_before = (RubyTime) time.callMethod(context, "getutc"); not_before.setMicroseconds(0); return time; } DateTime getNotBefore() { return not_before == null ? null : not_before.getDateTime(); } @JRubyMethod public IRubyObject not_after() { return not_after == null ? getRuntime().getNil() : not_after; } @JRubyMethod(name = "not_after=") public IRubyObject set_not_after(final ThreadContext context, final IRubyObject time) { changed = true; not_after = (RubyTime) time.callMethod(context, "getutc"); not_after.setMicroseconds(0); return time; } DateTime getNotAfter() { return not_after == null ? null : not_after.getDateTime(); } @JRubyMethod public IRubyObject public_key(final ThreadContext context) { if ( public_key == null ) initializePublicKey(); return public_key.callMethod(context, "public_key"); } @JRubyMethod(name = "public_key=") public IRubyObject set_public_key(IRubyObject public_key) { if ( ! ( public_key instanceof PKey ) ) { throw getRuntime().newTypeError("OpenSSL::PKey::PKey expected but got " + public_key.getMetaClass().getName()); } if ( ! public_key.equals(this.public_key) ) { this.changed = true; } return this.public_key = (PKey) public_key; } private PublicKey getPublicKey() { if ( public_key == null ) initializePublicKey(); return public_key.getPublicKey(); } private void initializePublicKey() throws RaiseException { final Ruby runtime = getRuntime(); final boolean changed = this.changed; if ( cert == null ) { throw newCertificateError(runtime, "no certificate"); } final PublicKey publicKey = cert.getPublicKey(); final String algorithm = publicKey.getAlgorithm(); if ( "RSA".equalsIgnoreCase(algorithm) ) { //if ( public_key == null ) { // throw new IllegalStateException("no public key encoded data"); //} set_public_key( PKeyRSA.newInstance(runtime, publicKey) ); } else if ( "DSA".equalsIgnoreCase(algorithm) ) { //if ( public_key == null ) { // throw new IllegalStateException("no public key encoded data"); //} set_public_key( PKeyDSA.newInstance(runtime, publicKey) ); } else { String message = "unsupported algorithm"; if ( algorithm != null ) message += " '" + algorithm + "'"; throw newCertificateError(runtime, message); } this.changed = changed; } @JRubyMethod public IRubyObject sign(final ThreadContext context, final IRubyObject key, final IRubyObject digest) { final Ruby runtime = context.runtime; // Have to obey some artificial constraints of the OpenSSL implementation. Stupid. final String keyAlg = ((PKey) key).getAlgorithm(); final String digAlg; final String digName; if (digest instanceof Digest) { digAlg = ((Digest) digest).getShortAlgorithm(); digName = ((Digest) digest).name().toString(); } else { digAlg = digest.asJavaString(); digName = null; } if( ( "DSA".equalsIgnoreCase(keyAlg) && "MD5".equalsIgnoreCase(digAlg) ) || ( "RSA".equalsIgnoreCase(keyAlg) && "DSS1".equals(digName) ) ) { throw newCertificateError(runtime, "signature_algorithm not supported"); } org.bouncycastle.x509.X509V3CertificateGenerator builder = getCertificateBuilder(); for ( X509Extension ext : uniqueExtensions() ) { try { final byte[] bytes = ext.getRealValueEncoded(); builder.addExtension(ext.getRealObjectID().getId(), ext.isRealCritical(), bytes); } catch (IOException ioe) { throw runtime.newIOErrorFromException(ioe); } } builder.setSignatureAlgorithm(digAlg + "WITH" + keyAlg); // "SHA1WITHRSA" try { cert = builder.generate( ((PKey) key).getPrivateKey() ); } catch (GeneralSecurityException e) { throw newCertificateError(runtime, e); } if (cert == null) throw newCertificateError(runtime, (String) null); String name = ASN1Registry.o2a(cert.getSigAlgOID()); if ( name == null ) name = cert.getSigAlgOID(); this.sig_alg = runtime.newString(name); this.changed = false; return this; } private org.bouncycastle.x509.X509V3CertificateGenerator getCertificateBuilder() { org.bouncycastle.x509.X509V3CertificateGenerator generator = new org.bouncycastle.x509.X509V3CertificateGenerator(); generator.setSerialNumber( serial.abs() ); if ( subject != null ) generator.setSubjectDN( ((X509Name) subject).getRealName() ); if ( issuer != null ) generator.setIssuerDN( ((X509Name) issuer).getRealName() ); generator.setNotBefore( not_before.getJavaDate() ); generator.setNotAfter( not_after.getJavaDate() ); generator.setPublicKey( getPublicKey() ); return generator; } //private transient org.bouncycastle.x509.X509V3CertificateGenerator generator; @JRubyMethod public RubyBoolean verify(final IRubyObject key) { final Ruby runtime = getRuntime(); if ( changed ) return runtime.getFalse(); try { cert.verify(((PKey) key).getPublicKey()); return runtime.getTrue(); } catch (CertificateException e) { debug(runtime, "Certificate#verify failed: ", e); throw newCertificateError(runtime, e); } catch (NoSuchAlgorithmException e) { debugStackTrace(runtime, e); throw newCertificateError(runtime, e); } catch (NoSuchProviderException e) { debugStackTrace(runtime, e); throw newCertificateError(runtime, e); } catch (SignatureException e) { debug(runtime, "Certificate#verify failed: ", e); return runtime.getFalse(); } catch (InvalidKeyException e) { debug(runtime, "Certificate#verify failed: ", e); return runtime.getFalse(); } } @JRubyMethod public RubyBoolean check_private_key(final IRubyObject key) { final PublicKey certPublicKey = cert.getPublicKey(); if ( certPublicKey.equals( ((PKey) key).getPublicKey() ) ) { return getRuntime().getTrue(); } return getRuntime().getFalse(); } @JRubyMethod public RubyArray extensions() { @SuppressWarnings("unchecked") final List extensions = (List) this.extensions; return getRuntime().newArray( extensions ); } @SuppressWarnings("unchecked") @JRubyMethod(name = "extensions=") public IRubyObject set_extensions(final IRubyObject array) { extensions.clear(); // RubyArray is a List : extensions.addAll( (List) array ); return array; } @JRubyMethod public IRubyObject add_extension(final IRubyObject ext) { changed = true; extensions.add((X509Extension) ext); return ext; } private Collection uniqueExtensions() { final Map unique = new LinkedHashMap(); for ( X509Extension current : this.extensions ) { final ASN1ObjectIdentifier oid = current.getRealObjectID(); final X509Extension existing = unique.get( oid ); if ( existing == null ) { unique.put( oid, current ); continue; } // NOTE: dealing with Java API limits here since it does not // handle multiple OID mappings to a sequence out of the box // commonly used e.g. with subjectAltName || issuserAltName : if ( "2.5.29.17".equals( oid.getId() ) || "2.5.29.18".equals( oid.getId() ) ) { final ASN1EncodableVector vec = new ASN1EncodableVector(); try { GeneralName[] n1 = extRealNames(existing); for ( int i = 0; i < n1.length; i++ ) vec.add( n1[i] ); GeneralName[] n2 = extRealNames(current); for ( int i = 0; i < n2.length; i++ ) vec.add( n2[i] ); GeneralNames nn = GeneralNames.getInstance(new DLSequence(vec)); final X509Extension existingDup = existing.clone(); existingDup.setRealValue( nn ); unique.put( oid, existingDup ); } catch (IOException ex) { throw getRuntime().newIOErrorFromException(ex); } continue; } // TODO do we need special care for any others here ?!? final ASN1EncodableVector vec = new ASN1EncodableVector(); try { final ASN1Encodable existingValue = existing.getRealValue(); if ( existingValue instanceof ASN1Sequence ) { final ASN1Sequence seq = (ASN1Sequence) existingValue; for ( int i = 0; i < seq.size(); i++ ) { vec.add( seq.getObjectAt(i) ); } } else { vec.add(existingValue); } vec.add( current.getRealValue() ); // existing.setRealValue( new DLSequence(vec) ); final X509Extension existingDup = existing.clone(); existingDup.setRealValue( new DLSequence(vec) ); unique.put( oid, existingDup ); } catch (IOException ex) { throw getRuntime().newIOErrorFromException(ex); } } return unique.values(); } private static GeneralName[] extRealNames(final X509Extension extension) throws IOException { final ASN1Encodable value = extension.getRealValue(); if ( value instanceof GeneralName ) { return new GeneralName[] { (GeneralName) value }; } return GeneralNames.getInstance( value ).getNames(); } @Override public Object toJava(Class target) { if ( target.isAssignableFrom(X509Certificate.class) ) { if ( target == X509AuxCertificate.class ) return getAuxCert(); return cert; } return super.toJava(target); } }// X509Cert jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509Extension.java000066400000000000000000001177151313661621600265060ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.lang.reflect.Field; import java.util.Hashtable; import java.util.Map; import org.bouncycastle.asn1.ASN1Boolean; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERUniversalString; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.util.encoders.Hex; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyHash; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.util.ConvertBytes; import static org.jruby.ext.openssl.ASN1._ASN1; import static org.jruby.ext.openssl.X509._X509; import static org.jruby.ext.openssl.OpenSSL.*; import static org.jruby.ext.openssl.StringHelper.*; /** * OpenSSL::X509::Extension * @author kares */ public class X509Extension extends RubyObject { private static final long serialVersionUID = 6463713017143658305L; private static ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509Extension(runtime, klass); } }; public static void createX509Extension(final Ruby runtime, final RubyModule _X509) { // OpenSSL::X509 final RubyClass _OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); _X509.defineClassUnder("ExtensionError", _OpenSSLError, _OpenSSLError.getAllocator()); RubyClass _Extension = _X509.defineClassUnder("Extension", runtime.getObject(), X509Extension.ALLOCATOR); _Extension.defineAnnotatedMethods(X509Extension.class); X509ExtensionFactory.createX509ExtensionFactory(runtime, _X509); } private ASN1ObjectIdentifier objectID; private Object value; private boolean critical; protected X509Extension(Ruby runtime, RubyClass type) { super(runtime, type); } static RubyClass _Extension(final Ruby runtime) { return _X509(runtime).getClass("Extension"); } static final byte[] critical__ = new byte[] { 'c','r','i','t','i','c','a','l',',',' ' }; static X509Extension newExtension(final ThreadContext context, final String oid, final java.security.cert.X509Extension ext, final boolean critical) throws IOException { final byte[] extValue = ext.getExtensionValue(oid); // DER encoded // TODO: wired. J9 returns null for an OID given in getNonCriticalExtensionOIDs() if ( extValue == null ) { warn(context, ext + " getExtensionValue returns null for '"+ oid +"'"); return null; } final Ruby runtime = context.runtime; final ASN1Encodable value = ASN1.readObject(extValue); return newExtension(runtime, ASN1.getObjectID(runtime, oid), value, critical); } static X509Extension[] newExtension(final ThreadContext context, final String oid, final byte[] extValue, final boolean critical) throws IOException { final Ruby runtime = context.runtime; final ASN1ObjectIdentifier objectId = ASN1.getObjectID(runtime, oid); final ASN1Encodable value = ASN1.readObject(extValue); if ( oid.equals("2.5.29.17") || oid.equals("2.5.29.18") ) { // subjectAltName || issuerAltName if ( value instanceof ASN1OctetString ) { // DEROctetString final ASN1Encodable oct = ASN1.readObject( ((ASN1OctetString) value).getOctets() ); if ( oct instanceof ASN1Sequence ) { final ASN1Sequence seq = (ASN1Sequence) oct; final X509Extension[] ext = new X509Extension[ seq.size() ]; for ( int i = 0; i < ext.length; i++ ) { ext[i] = newExtension(runtime, objectId, seq.getObjectAt(i), critical); } return ext; } // NOTE need to unwrap ((ASN1TaggedObject) oct).getObject() - likely not ?!? return new X509Extension[] { newExtension(runtime, objectId, oct, critical) }; } } return new X509Extension[] { newExtension(runtime, objectId, value, critical) }; } static X509Extension newExtension(final Ruby runtime, ASN1ObjectIdentifier objectId, final ASN1Encodable value, final boolean critical) { X509Extension ext = new X509Extension(runtime, _Extension(runtime)); ext.setRealObjectID(objectId); ext.setRealValue(value); ext.setRealCritical(critical); return ext; } static X509Extension newExtension(final Ruby runtime, ASN1ObjectIdentifier objectId, final Extension extension) { X509Extension ext = new X509Extension(runtime, _Extension(runtime)); ext.setRealObjectID(objectId); ext.setRealValue(extension.getParsedValue()); ext.setRealCritical(extension.isCritical()); return ext; } ASN1ObjectIdentifier getRealObjectID() { return objectID; } void setRealObjectID(ASN1ObjectIdentifier oid) { this.objectID = oid; } void setRealObjectID(final String oid) { setRealObjectID( ASN1.getObjectID(getRuntime(), oid) ); } final ASN1Encodable getRealValue() throws IOException { if ( value instanceof ASN1Encodable ) { return (ASN1Encodable) value; } if ( value instanceof ASN1.ASN1Data ) { return ((ASN1.ASN1Data) value).toASN1(getRuntime().getCurrentContext()); } if ( value == null ) throw new IllegalStateException("null extension value"); return ASN1.readObject( getRealValueEncoded() ); } final byte[] getRealValueEncoded() throws IOException { if ( value instanceof byte[] ) return (byte[]) value; if ( value instanceof RubyString ) return ((RubyString) value).getBytes(); if ( value instanceof String ) return ByteList.plain((String) value); if ( value instanceof ASN1OctetString ) { // initialize return ((ASN1OctetString) value).getOctets(); } return getRealValue().toASN1Primitive().getEncoded(ASN1Encoding.DER); } private IRubyObject getValue(final Ruby runtime) throws IOException { if ( value instanceof RubyString ) { return (RubyString) value; // explicitly set value } final ThreadContext context = runtime.getCurrentContext(); final byte[] enc = getRealValueEncoded(); IRubyObject extValue = runtime.newString( new ByteList(enc, false) ); extValue = ASN1.decodeImpl(context, _ASN1(runtime), extValue); return extValue.callMethod(context, "value"); } void setRealValue(final ASN1Encodable value) { if ( value == null ) { throw new IllegalStateException("null extension value"); } this.value = value; } //private void setRealValueEncoded(final byte[] value) { // this.value = value; //} boolean isRealCritical() { return critical; } void setRealCritical(boolean critical) { this.critical = critical; } @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { if ( args.length == 1 ) { final byte[] bytes = to_der_if_possible(context, args[0]).asString().getBytes(); try { ASN1Sequence seq = (ASN1Sequence) ASN1.readObject(bytes); setRealObjectID( (ASN1ObjectIdentifier) seq.getObjectAt(0) ); final ASN1Encodable criticalOrValue = seq.getObjectAt(1); if ( criticalOrValue instanceof ASN1Boolean ) { setRealCritical( ((ASN1Boolean) criticalOrValue).isTrue() ); this.value = ( (DEROctetString) seq.getObjectAt(2) ).getOctets(); // byte[] } else if ( criticalOrValue instanceof DERBoolean ) { // NOTE: keep it due BC <= 1.50 setRealCritical( ((DERBoolean) criticalOrValue).isTrue() ); this.value = ( (DEROctetString) seq.getObjectAt(2) ).getOctets(); // byte[] } else { this.value = ( (DEROctetString) criticalOrValue ).getOctets(); // byte[] } } catch (IOException e) { throw newExtensionError(context.runtime, e); } } else if ( args.length > 1 ) { setRealObjectID( ASN1.getObjectID(context.runtime, args[0].toString()) ); this.value = args[1]; // a RubyString } else { // args.length < 1 throw context.runtime.newArgumentError("wrong number of arguments (0 for 1..3)"); } if ( args.length > 2 ) setRealCritical( args[2].isTrue() ); return this; } @Override public IRubyObject initialize_copy(final IRubyObject original) { if (this == original) return this; checkFrozen(); final X509Extension that = (X509Extension) original; this.value = that.value; this.objectID = that.objectID; this.critical = that.critical; return this; } @JRubyMethod public IRubyObject oid(final ThreadContext context) { return context.runtime.newString( oidSym(context.runtime) ); } private String oidSym(final Ruby runtime) { final String name = ASN1.oid2Sym(runtime, objectID, true); return name == null ? objectID.toString() : name; } @JRubyMethod(name = "oid=") public IRubyObject set_oid(final ThreadContext context, IRubyObject arg) { if ( arg instanceof RubyString ) { setRealObjectID( arg.toString() ); return arg; } throw context.runtime.newTypeError(arg, context.runtime.getString()); } private static final byte[] CA_ = {'C', 'A', ':'}; private static final byte[] TRUE = {'T', 'R', 'U', 'E'}; private static final byte[] FALSE = {'F', 'A', 'L', 'S', 'E'}; private static final byte[] _ = {}; private static final byte[] SEP = {',', ' '}; private static final byte[] Decipher_Only = {'D', 'e', 'c', 'i', 'p', 'h', 'e', 'r', ' ', 'O', 'n', 'l', 'y'}; private static final byte[] Digital_Signature = {'D', 'i', 'g', 'i', 't', 'a', 'l', ' ', 'S', 'i', 'g', 'n', 'a', 't', 'u', 'r', 'e'}; private static final byte[] Non_Repudiation = {'N', 'o', 'n', ' ', 'R', 'e', 'p', 'u', 'd', 'i', 'a', 't', 'i', 'o', 'n'}; private static final byte[] Key_Encipherment = {'K', 'e', 'y', ' ', 'E', 'n', 'c', 'i', 'p', 'h', 'e', 'r', 'm', 'e', 'n', 't'}; private static final byte[] Data_Encipherment = {'D', 'a', 't', 'a', ' ', 'E', 'n', 'c', 'i', 'p', 'h', 'e', 'r', 'm', 'e', 'n', 't'}; private static final byte[] Key_Agreement = {'K', 'e', 'y', ' ', 'A', 'g', 'r', 'e', 'e', 'm', 'e', 'n', 't'}; private static final byte[] Certificate_Sign = {'C', 'e', 'r', 't', 'i', 'f', 'i', 'c', 'a', 't', 'e', ' ', 'S', 'i', 'g', 'n'}; private static final byte[] CRL_Sign = {'C', 'R', 'L', ' ', 'S', 'i', 'g', 'n'}; private static final byte[] Encipher_Only = {'E', 'n', 'c', 'i', 'p', 'h', 'e', 'r', ' ', 'O', 'n', 'l', 'y'}; private static final byte[] SSL_Client = {'S', 'S', 'L', ' ', 'C', 'l', 'i', 'e', 'n', 't'}; private static final byte[] SSL_Server = {'S', 'S', 'L', ' ', 'S', 'e', 'r', 'v', 'e', 'r'}; private static final byte[] SSL_CA = {'S', 'S', 'L', ' ', 'C', 'A'}; private static final byte[] SMIME = {'S', '/', 'M', 'I', 'M', 'E'}; private static final byte[] SMIME_CA = {'S', '/', 'M', 'I', 'M', 'E', ' ', 'C', 'A'}; private static final byte[] Object_Signing = {'O', 'b', 'j', 'e', 'c', 't', ' ', 'S', 'i', 'g', 'n', 'i', 'n', 'g'}; private static final byte[] Object_Signing_CA = {'O', 'b', 'j', 'e', 'c', 't', ' ', 'S', 'i', 'g', 'n', 'i', 'n', 'g', ' ', 'C', 'A'}; private static final byte[] Unused = {'U', 'n', 'u', 's', 'e', 'd'}; private static final byte[] Unspecified = {'U', 'n', 's', 'p', 'e', 'c', 'i', 'f', 'i', 'e', 'd'}; //private static final byte[] Key_Compromise = { 'K','e','y',' ','C','o','m','p','r','o','m','i','s','e' }; //private static final byte[] CA_Compromise = { 'C','A',' ','C','o','m','p','r','o','m','i','s','e' }; //private static final byte[] Affiliation_Changed = { 'A','f','f','i','l','i','a','t','i','o','n',' ','C','h','a','n','g','e','d' }; private static final byte[] keyid_ = {'k', 'e', 'y', 'i', 'd', ':'}; @JRubyMethod public RubyString value(final ThreadContext context) { if ( this.value instanceof RubyString ) { // return the same as set return (RubyString) this.value; } final Ruby runtime = context.runtime; final String oid = getRealObjectID().getId(); try { if ( oid.equals("2.5.29.19") ) { // basicConstraints ASN1Sequence seq2 = (ASN1Sequence) ASN1.readObject( getRealValueEncoded() ); final ByteList val = new ByteList(32); if (seq2.size() > 0) { val.append(CA_); ASN1Encodable obj0 = seq2.getObjectAt(0); final boolean bool; if ( obj0 instanceof ASN1Boolean ) { bool = ((ASN1Boolean) obj0).isTrue(); } else { // NOTE: keep it due BC <= 1.50 bool = ((DERBoolean) obj0).isTrue(); } val.append( bool ? TRUE : FALSE ); } if (seq2.size() > 1) { val.append(", pathlen:".getBytes()); val.append(seq2.getObjectAt(1).toString().getBytes()); } return runtime.newString(val); } if ( oid.equals("2.5.29.15") ) { // keyUsage final byte[] enc = getRealValueEncoded(); byte b3 = 0; byte b2 = enc[2]; if ( enc.length > 3 ) b3 = enc[3]; final ByteList val = new ByteList(64); byte[] sep = _; if ((b2 & (byte) 128) != 0) { val.append(sep); val.append(Decipher_Only); sep = SEP; } if ((b3 & (byte) 128) != 0) { val.append(sep); val.append(Digital_Signature); sep = SEP; } if ((b3 & (byte) 64) != 0) { val.append(sep); val.append(Non_Repudiation); sep = SEP; } if ((b3 & (byte) 32) != 0) { val.append(sep); val.append(Key_Encipherment); sep = SEP; } if ((b3 & (byte) 16) != 0) { val.append(sep); val.append(Data_Encipherment); sep = SEP; } if ((b3 & (byte) 8) != 0) { val.append(sep); val.append(Key_Agreement); sep = SEP; } if ((b3 & (byte) 4) != 0) { val.append(sep); val.append(Certificate_Sign); sep = SEP; } if ((b3 & (byte) 2) != 0) { val.append(sep); val.append(CRL_Sign); sep = SEP; } if ((b3 & (byte) 1) != 0) { val.append(sep); val.append(Encipher_Only); // sep = SEP; } return runtime.newString(val); } if ( oid.equals("2.16.840.1.113730.1.1") ) { // nsCertType final byte b0 = getRealValueEncoded()[0]; final ByteList val = new ByteList(64); byte[] sep = _; if ((b0 & (byte) 128) != 0) { val.append(sep); val.append(SSL_Client); sep = SEP; } if ((b0 & (byte) 64) != 0) { val.append(sep); val.append(SSL_Server); sep = SEP; } if ((b0 & (byte) 32) != 0) { val.append(sep); val.append(SMIME); sep = SEP; } if ((b0 & (byte) 16) != 0) { val.append(sep); val.append(Object_Signing); sep = SEP; } if ((b0 & (byte) 8) != 0) { val.append(sep); val.append(Unused); sep = SEP; } if ((b0 & (byte) 4) != 0) { val.append(sep); val.append(SSL_CA); sep = SEP; } if ((b0 & (byte) 2) != 0) { val.append(sep); val.append(SMIME_CA); sep = SEP; } if ((b0 & (byte) 1) != 0) { val.append(sep); val.append(Object_Signing_CA); } return runtime.newString(val); } if ( oid.equals("2.5.29.14") ) { // subjectKeyIdentifier ASN1Encodable value = getRealValue(); if ( value instanceof ASN1OctetString ) { byte[] octets = ((ASN1OctetString) value).getOctets(); if ( octets.length > 0 && octets[0] == BERTags.OCTET_STRING ) { value = ASN1.readObject( octets ); // read nested octets } } return runtime.newString( hexBytes( keyidBytes(value.toASN1Primitive()), 0 ) ); } if ( oid.equals("2.5.29.35") ) { // authorityKeyIdentifier ASN1Encodable value = getRealValue(); if ( value instanceof ASN1OctetString ) { value = ASN1.readObject( ((ASN1OctetString) value).getOctets() ); } final ByteList val = new ByteList(72); val.append(keyid_); if ( value instanceof ASN1Sequence ) { final ASN1Sequence seq = (ASN1Sequence) value; final int size = seq.size(); if ( size == 0 ) return RubyString.newEmptyString(runtime); ASN1Primitive keyid = seq.getObjectAt(0).toASN1Primitive(); hexBytes( keyidBytes(keyid), val ).append('\n'); for ( int i = 1; i < size; i++ ) { final ASN1Encodable issuer = seq.getObjectAt(i); // NOTE: blindly got OpenSSL tests passing (likely in-complete) : if ( issuer instanceof ASN1TaggedObject ) { ASN1Primitive obj = ((ASN1TaggedObject) issuer).getObject(); switch( ((ASN1TaggedObject) issuer).getTagNo() ) { case 1 : if ( obj instanceof ASN1TaggedObject ) { formatGeneralName(GeneralName.getInstance(obj), val, true); } break; case 2 : // serial val.append(new byte[] { 's','e','r','i','a','l',':' }); hexBytes( ((ASN1OctetString) obj).getOctets(), val ); break; } } val.append('\n'); } return runtime.newString( val ); } hexBytes( keyidBytes(value.toASN1Primitive()), val ).append('\n'); return runtime.newString( val ); } if ( oid.equals("2.5.29.21") ) { // CRLReason final IRubyObject value = getValue(runtime); switch ( RubyNumeric.fix2int(value) ) { case 0: return runtime.newString(new ByteList(Unspecified)); case 1: return RubyString.newString(runtime, "Key Compromise"); case 2: return RubyString.newString(runtime, "CA Compromise"); case 3: return RubyString.newString(runtime, "Affiliation Changed"); case 4: return RubyString.newString(runtime, "Superseded"); case 5: return RubyString.newString(runtime, "Cessation Of Operation"); case 6: return RubyString.newString(runtime, "Certificate Hold"); case 8: return RubyString.newString(runtime, "Remove From CRL"); case 9: return RubyString.newString(runtime, "Privilege Withdrawn"); default: return runtime.newString(new ByteList(Unspecified)); } } if ( oid.equals("2.5.29.17") || oid.equals("2.5.29.18") ) { // subjectAltName || issuerAltName try { ASN1Encodable value = getRealValue(); final ByteList val = new ByteList(64); if ( value instanceof ASN1TaggedObject ) { formatGeneralName(GeneralName.getInstance(value), val, false); return runtime.newString( val ); } if ( value instanceof GeneralName ) { formatGeneralName((GeneralName) value, val, false); return runtime.newString( val ); } if ( value instanceof ASN1OctetString ) { // decoded octets will end up as an ASN1Sequence instance : value = ASN1.readObject( ((ASN1OctetString) value).getOctets()); } if ( value instanceof ASN1TaggedObject ) { // DERTaggedObject (issuerAltName wrapping) formatGeneralName(GeneralName.getInstance(value), val, false); return runtime.newString( val ); } final GeneralName[] names = GeneralNames.getInstance(value).getNames(); for ( int i = 0; i < names.length; i++ ) { boolean other = formatGeneralName(names[i], val, false); if ( i < names.length - 1 ) { if ( other ) val.append(';'); else val.append(',').append(' '); } } return runtime.newString( val ); } catch (IllegalArgumentException e) { debugStackTrace(runtime, e); return rawValueAsString(context); } } if ( oid.equals("2.5.29.37") ) { // extendedKeyUsage final ByteList val = new ByteList(64); if ( this.value instanceof ASN1Sequence ) { // opt "short" path final ASN1Sequence seq = (ASN1Sequence) this.value; final int size = seq.size(); for ( int i = 0; i < size; i++ ) { ASN1Encodable o = seq.getObjectAt(i); String name = o.toString(); Integer nid = ASN1.oid2nid(runtime, new ASN1ObjectIdentifier(name)); if ( nid != null ) name = ASN1.nid2ln(runtime, nid); if ( name == null ) name = o.toString(); val.append( ByteList.plain(name) ); if ( i < size - 1 ) val.append(',').append(' '); } return runtime.newString( val ); } final IRubyObject value = getValue(runtime); if ( value instanceof RubyArray ) { final RubyArray arr = (RubyArray) value; final int size = arr.size(); for ( int i = 0; i < size; i++ ) { IRubyObject entry = arr.eltInternal(i); if ( "ObjectId".equals(entry.getMetaClass().getBaseName()) ) { entry = entry.callMethod(context, "ln"); } else if ( entry.respondsTo("value") ) { entry = entry.callMethod(context, "value"); } val.append( entry.asString().getByteList() ); if ( i < size - 1 ) val.append(',').append(' '); } } return runtime.newString( val ); } return rawValueAsString(context); } catch (IOException e) { debugStackTrace(runtime, e); throw newExtensionError(runtime, e); } } private RubyString rawValueAsString(final ThreadContext context) throws IOException { final Ruby runtime = context.runtime; final IRubyObject value = getValue(runtime); // e.g. [ ASN1::UTF8String, ... ] if ( value instanceof RubyArray ) { final RubyArray arr = (RubyArray) value; final ByteList strVal = new ByteList(64); final int len = arr.size(); for ( int i = 0; i < len; i++ ) { IRubyObject entry = arr.eltInternal(i); if ( entry.respondsTo("value") ) { entry = entry.callMethod(context, "value"); } strVal.append( entry.asString().getByteList() ); if ( i < len - 1 ) strVal.append(',').append(' '); } return runtime.newString(strVal); } return value.asString(); } private static byte[] keyidBytes(ASN1Primitive keyid) throws IOException { if ( keyid instanceof ASN1TaggedObject ) { keyid = ((ASN1TaggedObject) keyid).getObject(); } if ( keyid instanceof ASN1OctetString ) { return ((ASN1OctetString) keyid).getOctets(); } return keyid.getEncoded(ASN1Encoding.DER); } @SuppressWarnings("unchecked") private static boolean formatGeneralName(final GeneralName name, final ByteList out, final boolean slashed) { final ASN1Encodable obj = name.getName(); String val; boolean tagged = false; switch ( name.getTagNo() ) { case GeneralName.rfc822Name: if ( ! tagged ) out.append('e').append('m').append('a').append('i').append('l'). append(':'); tagged = true; case GeneralName.dNSName: if ( ! tagged ) out.append('D').append('N').append('S'). append(':'); tagged = true; case GeneralName.uniformResourceIdentifier: if ( ! tagged ) out.append('U').append('R').append('I'). append(':'); val = DERIA5String.getInstance(obj).getString(); out.append( ByteList.plain(val) ); break; case GeneralName.directoryName: out.append('D').append('i').append('r').append('N').append('a').append('m').append('e'). append(':'); final X500Name dirName = X500Name.getInstance(obj); if ( slashed ) { final RDN[] rdns = dirName.getRDNs(); final Hashtable defaultSymbols = getDefaultSymbols(); for (int i = 0; i < rdns.length; i++) { appendRDN(out.append('/'), rdns[i], defaultSymbols); } } else { out.append( ByteList.plain(dirName.toString()) ); } break; case GeneralName.iPAddress: out.append('I').append('P'). append(':'); final byte[] ip = ((ASN1OctetString) name.getName()).getOctets(); int len = ip.length; boolean ip4 = len == 4; for ( int i = 0; i < ip.length; i++ ) { out.append( ConvertBytes.intToCharBytes( ((int) ip[i]) & 0xff ) ); if ( i != len - 1 ) { if ( ip4 ) out.append('.'); else out.append(':').append(':'); } } break; case GeneralName.otherName: out.append('o').append('t').append('h').append('e').append('r').append('N').append('a').append('m').append('e'). append(':'); out.append( ByteList.plain( obj.toString() ) ); return true; //tagged = true; case GeneralName.registeredID: out.append('R').append('I').append('D'). append(':'); //tagged = true; default: out.append( ByteList.plain( obj.toString() ) ); } return false; } // re-invented IETFUtils.appendRDN related pieces : public static ByteList appendRDN(final ByteList out, final RDN rdn, final Map oidSymbols) { if ( rdn.isMultiValued() ) { AttributeTypeAndValue[] atv = rdn.getTypesAndValues(); boolean firstAtv = true; for ( int j = 0; j != atv.length; j++ ) { if (firstAtv) firstAtv = false; else out.append('+'); appendTypeAndValue(out, atv[j], oidSymbols); } return out; } return appendTypeAndValue(out, rdn.getFirst(), oidSymbols); } private static ByteList appendTypeAndValue(final ByteList out, final AttributeTypeAndValue typeAndValue, final Map oidSymbols) { ASN1ObjectIdentifier type = typeAndValue.getType(); final String sym = oidSymbols.get(type); if (sym != null) { out.append( ByteList.plain(sym) ); } else { out.append( ByteList.plain(type.getId()) ); } out.append('='); valueToString(typeAndValue.getValue(), out); return out; } private static void valueToString(final ASN1Encodable value, final ByteList out) { final int size = out.getRealSize(); if ( value instanceof ASN1String && !(value instanceof DERUniversalString) ) { final String str = ((ASN1String) value).getString(); if ( str.length() > 0 && str.charAt(0) == '#' ) { out.append('\\'); } out.append( ByteList.plain(str) ); } else { try { byte[] val = value.toASN1Primitive().getEncoded(ASN1Encoding.DER); out.append('#').append( Hex.encode(val) ); } catch (IOException e) { throw new IllegalArgumentException("Other value has no encoded form", e); } } int index = size; // 0 int end = out.getRealSize() - size; if (end >= 2 && out.charAt(index) == '\\' && out.charAt(index + 1) == '#') { index += 2; } while ( index <= end ) { final char c = out.charAt(index); if ( c == ',' || c == '"' || c == '\\' || c == '+' || c == '=' || c == '<' || c == '>' || c == ';' ) { out.insert(index, '\\'); index++; end++; } index++; } if ( out.getRealSize() - size > 0 ) { index = size; // 0 while ( out.charAt(index) == ' ' ) { out.insert(index, '\\'); index += 2; } } index = out.getRealSize() - 1; // length - 1 while ( index >= size && out.charAt(index) == ' ' ) { out.insert(index, '\\'); index--; } } private static Hashtable getDefaultSymbols() { try { Field field = BCStyle.class.getDeclaredField("DefaultSymbols"); field.setAccessible(true); return (Hashtable) field.get(null); } catch (NoSuchFieldException ex) { debug("getDefaultSymbols", ex); } catch (SecurityException ex) { debug("getDefaultSymbols", ex); } catch (IllegalAccessException ex) { debug("getDefaultSymbols", ex); } return new Hashtable(); } @JRubyMethod(name = "value=") public IRubyObject set_value(final ThreadContext context, IRubyObject arg) { if ( arg instanceof RubyString ) { this.value = arg; return arg; } throw context.runtime.newTypeError(arg, context.runtime.getString()); } @JRubyMethod(name = "critical?") public IRubyObject critical_p(final ThreadContext context) { return context.runtime.newBoolean(isRealCritical()); } @JRubyMethod(name = "critical=") public IRubyObject set_critical(final ThreadContext context, IRubyObject arg) { setRealCritical(arg.isTrue()); return arg; } @JRubyMethod public IRubyObject to_der() { try { final byte[] enc = toASN1Sequence().getEncoded(ASN1Encoding.DER); return StringHelper.newString(getRuntime(), enc); } catch (IOException e) { throw newExtensionError(getRuntime(), e); } } ASN1Sequence toASN1Sequence() throws IOException { final ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add( getRealObjectID() ); if ( critical ) vec.add( DERBoolean.TRUE ); vec.add( new DEROctetString( getRealValueEncoded() ) ); return new DLSequence(vec); } // [ self.oid, self.value, self.critical? ] @JRubyMethod public RubyArray to_a(final ThreadContext context) { RubyArray array = RubyArray.newArray(context.runtime, 3); array.append(oid(context)); array.append(value(context)); array.append(critical_p(context)); return array; } // {"oid"=>self.oid,"value"=>self.value,"critical"=>self.critical? @JRubyMethod public RubyHash to_h(final ThreadContext context) { final Ruby runtime = context.runtime; RubyHash hash = RubyHash.newHash(runtime); hash.op_aset(context, newStringFrozen(runtime, "oid"), oid(context)); hash.op_aset(context, newStringFrozen(runtime, "value"), value(context)); hash.op_aset(context, newStringFrozen(runtime, "critical"), critical_p(context)); return hash; } // "oid = critical, value" @JRubyMethod public RubyString to_s(final ThreadContext context) { final Ruby runtime = context.runtime; final RubyString str = RubyString.newString(runtime, oidSym(runtime)); str.getByteList().append(' ').append('=').append(' '); if ( isRealCritical() ) str.getByteList().append(critical__); // self.value.gsub(/\n/, ", ") final RubyString value = value(context); value.callMethod(context, "gsub!", new IRubyObject[] { RubyString.newStringShared(runtime, StringHelper.NEW_LINE), RubyString.newStringShared(runtime, StringHelper.COMMA_SPACE) }); str.getByteList().append(value.getByteList()); return str; } @Override public X509Extension clone() { try { return (X509Extension) super.clone(); } catch (CloneNotSupportedException ex) { throw new RuntimeException(ex); } } @Override @SuppressWarnings(value = "unchecked") @JRubyMethod public IRubyObject inspect() { return ObjectSupport.inspect(this); } static RaiseException newExtensionError(Ruby runtime, Exception e) { return Utils.newError(runtime, _X509(runtime).getClass("ExtensionError"), e); } static RaiseException newExtensionError(Ruby runtime, String message) { return Utils.newError(runtime, _X509(runtime).getClass("ExtensionError"), message); } // our custom "internal" HEX helpers : private static boolean isHex(final char c) { return ('0' <= c && c <= '9') || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f'); } static boolean isHex(final String str) { for ( int i = 0; i < str.length(); i++ ) { if ( ! isHex(str.charAt(i)) ) return false; } return true; } static int upHex(final char c) { switch (c) { case '0' : return '0'; case '1' : return '1'; case '2' : return '2'; case '3' : return '3'; case '4' : return '4'; case '5' : return '5'; case '6' : return '6'; case '7' : return '7'; case '8' : return '8'; case '9' : return '9'; case 'A' : case 'a' : return 'A'; case 'B' : case 'b' : return 'B'; case 'C' : case 'c' : return 'C'; case 'D' : case 'd' : return 'D'; case 'E' : case 'e' : return 'E'; case 'F' : case 'f' : return 'F'; } return -1; } private static ByteList hexBytes(final byte[] data, final int off) { final int len = data.length - off; return hexBytes(data, off, len, new ByteList( len * 3 )); } private static ByteList hexBytes(final byte[] data, final ByteList out) { return hexBytes(data, 0, data.length, out); } //@SuppressWarnings("deprecation") //private static ByteList hexBytes(final ByteList data, final ByteList out) { // return hexBytes(data.bytes, data.begin, data.realSize, out); //} private static ByteList hexBytes(final byte[] data, final int off, final int len, final ByteList out) { boolean notFist = false; out.ensure( len * 3 - 1 ); for ( int i = off; i < (off + len); i++ ) { if ( notFist ) out.append(':'); final byte b = data[i]; out.append( HEX[ (b >> 4) & 0xF ] ); out.append( HEX[ b & 0xF ] ); notFist = true; } return out; } private static final char[] HEX = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' }; } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509ExtensionFactory.java000066400000000000000000000612121313661621600300240ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; import org.bouncycastle.asn1.*; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyHash; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.Arity; import org.jruby.runtime.Block; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.util.ByteList; import org.jruby.ext.openssl.impl.ASN1Registry; import static org.jruby.ext.openssl.OpenSSL.debug; import static org.jruby.ext.openssl.X509Extension.*; /** * OpenSSL::X509::ExtensionFactory * @author kares */ public class X509ExtensionFactory extends RubyObject { private static final long serialVersionUID = 3180447029639456500L; private static ObjectAllocator ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509ExtensionFactory(runtime, klass); } }; static void createX509ExtensionFactory(final Ruby runtime, final RubyModule _X509) { // OpenSSL::X509 final RubyClass _ExtensionFactory = _X509.defineClassUnder("ExtensionFactory", runtime.getObject(), X509ExtensionFactory.ALLOCATOR); _ExtensionFactory.defineAnnotatedMethods(X509ExtensionFactory.class); } public X509ExtensionFactory(Ruby runtime, RubyClass type) { super(runtime, type); } @JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final IRubyObject[] args, final Block unusedBlock) { Arity.checkArgumentCount(getRuntime(), args, 0, 4); if (args.length > 0 && !args[0].isNil()) { set_issuer_cert(args[0]); } if (args.length > 1 && !args[1].isNil()) { set_subject_cert(args[1]); } if (args.length > 2 && !args[2].isNil()) { set_subject_req(args[2]); } if (args.length > 3 && !args[3].isNil()) { set_crl(args[3]); } return this; } @JRubyMethod(name = "issuer_certificate") public IRubyObject issuer_cert() { return getInstanceVariable("@issuer_certificate"); } @JRubyMethod(name = "issuer_certificate=") public IRubyObject set_issuer_cert(IRubyObject arg) { setInstanceVariable("@issuer_certificate", arg); return arg; } @JRubyMethod(name = "subject_certificate") public IRubyObject subject_cert() { return getInstanceVariable("@subject_certificate"); } @JRubyMethod(name = "subject_certificate=") public IRubyObject set_subject_cert(IRubyObject arg) { setInstanceVariable("@subject_certificate", arg); return arg; } @JRubyMethod(name = "subject_request") public IRubyObject subject_req() { return getInstanceVariable("@subject_request"); } @JRubyMethod(name = "subject_request=") public IRubyObject set_subject_req(IRubyObject arg) { setInstanceVariable("@subject_request", arg); return arg; } @JRubyMethod(name = "crl") public IRubyObject crl() { return getInstanceVariable("@crl"); } @JRubyMethod(name = "crl=") public IRubyObject set_crl(IRubyObject arg) { setInstanceVariable("@crl", arg); return arg; } @JRubyMethod(name = "config") public IRubyObject config() { return getInstanceVariable("@config"); } @JRubyMethod(name = "config=") public IRubyObject set_config(IRubyObject arg) { setInstanceVariable("@config", arg); return arg; } @JRubyMethod(rest = true) public IRubyObject create_ext(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; IRubyObject critical; if (Arity.checkArgumentCount(runtime, args, 2, 3) == 3 && !args[2].isNil()) { critical = args[2]; } else { critical = runtime.getFalse(); } final String oid = args[0].toString(); String valuex = args[1].toString(); final ASN1ObjectIdentifier objectId; try { objectId = ASN1.getObjectID(runtime, oid); } catch (IllegalArgumentException e) { debug(runtime, "ASN1.getObjectIdentifier() at ExtensionFactory.create_ext", e); throw newExtensionError(runtime, "unknown OID `" + oid + "'"); } final String critical_ = "critical,"; if ( valuex.startsWith(critical_) ) { critical = runtime.getTrue(); valuex = valuex.substring(critical_.length()).trim(); } final ASN1Encodable value; try { final String id = objectId.getId(); if (id.equals("2.5.29.14")) { // subjectKeyIdentifier value = new DEROctetString(parseSubjectKeyIdentifier(context, oid, valuex)); } else if (id.equals("2.5.29.35")) { // authorityKeyIdentifier value = parseAuthorityKeyIdentifier(context, valuex); } else if (id.equals("2.5.29.17")) { // subjectAltName value = parseSubjectAltName(valuex); } else if (id.equals("2.5.29.18")) { // issuerAltName value = parseIssuerAltName(context, valuex); } else if (id.equals("2.5.29.19")) { // basicConstraints value = parseBasicConstrains(valuex); } else if (id.equals("2.5.29.15")) { // keyUsage value = parseKeyUsage(oid, valuex); } else if (id.equals("2.16.840.1.113730.1.1")) { // nsCertType value = parseNsCertType(oid, valuex); } else if (id.equals("2.5.29.37")) { // extendedKeyUsage value = parseExtendedKeyUsage(valuex); } else { value = new DEROctetString(new DEROctetString(ByteList.plain(valuex)).getEncoded(ASN1Encoding.DER)); } } catch (IOException e) { OpenSSL.debugStackTrace(e); throw newExtensionError(runtime, "Unable to create extension: " + e.getMessage()); } return newExtension(runtime, objectId, value, critical.isNil() ? null : critical.isTrue()); } @JRubyMethod(rest = true) public IRubyObject create_extension(final ThreadContext context, final IRubyObject[] args) { if (args.length > 1) { return create_ext(context, args); } final IRubyObject arg = args[0]; if (arg instanceof RubyArray) { return create_ext_from_array(context, arg); } if (arg instanceof RubyHash) { return create_ext_from_hash(context, arg); } if (arg instanceof RubyString) { return create_ext_from_string(context, arg); } throw context.runtime.newArgumentError("unexpected argument: " + arg.inspect()); } @JRubyMethod public IRubyObject create_ext_from_array(final ThreadContext context, final IRubyObject arg) { final RubyArray ary = (RubyArray) arg; if ( ary.size() > 3 ) throw newExtensionError(context.runtime, "unexpected array form"); return create_ext(context, ary.toJavaArrayUnsafe()); } @JRubyMethod public IRubyObject create_ext_from_hash(final ThreadContext context, final IRubyObject arg) { final RubyHash hash = (RubyHash) arg; final Ruby runtime = context.runtime; final IRubyObject oid = hash.op_aref(context, StringHelper.newStringFrozen(runtime, "oid")); final IRubyObject value = hash.op_aref(context, StringHelper.newStringFrozen(runtime, "value")); final IRubyObject critical = hash.op_aref(context, StringHelper.newStringFrozen(runtime, "critical")); return create_ext(context, new IRubyObject[]{oid, value, critical}); } // "oid = critical, value" @JRubyMethod public IRubyObject create_ext_from_string(final ThreadContext context, final IRubyObject arg) { final RubyString str = (RubyString) arg; final Ruby runtime = context.runtime; RubyInteger i = str.index19(context, StringHelper.newString(runtime, new byte[]{'='})).convertToInteger("to_i"); final int ind = (int) i.getLongValue(); RubyString oid = (RubyString) str.substr19(runtime, 0, ind); oid.strip_bang19(context); final int len = (int) str.length19().getLongValue() - ind; RubyString value = (RubyString) str.substr19(runtime, ind + 1, len); value.lstrip_bang19(context); IRubyObject critical = context.nil; if (value.start_with_p(context, StringHelper.newString(runtime, critical__)).isTrue()) { critical = runtime.newBoolean(true); // value[ 0, 'critical, '.length ] = '' value.op_aset19(context, runtime.newFixnum(0), runtime.newFixnum(critical__.length), RubyString.newEmptyString(runtime)); } value.strip_bang19(context); return create_ext(context, new IRubyObject[]{oid, value, critical}); } private DERBitString parseKeyUsage(final String oid, final String valuex) { byte[] inp; try { final String[] val = StringHelper.split(valuex, ':'); inp = new byte[val.length]; for (int i = 0; i < val.length; i++) { inp[i] = (byte) Integer.parseInt(val[i], 16); } } catch (NumberFormatException e) { inp = null; } if (inp == null && valuex.length() < 3) { inp = ByteList.plain(valuex); } if (inp == null) { byte v1 = 0; byte v2 = 0; final String[] val = StringHelper.split(valuex, ','); for (int i = 0; i < val.length; i++) { final String value = val[i].trim(); if ("decipherOnly".equals(value) || "Decipher Only".equals(value)) { v2 |= (byte) 128; } else if ("digitalSignature".equals(value) || "Digital Signature".equals(value)) { v1 |= (byte) 128; } else if ("nonRepudiation".equals(value) || "Non Repudiation".equals(value)) { v1 |= (byte) 64; } else if ("keyEncipherment".equals(value) || "Key Encipherment".equals(value)) { v1 |= (byte) 32; } else if ("dataEncipherment".equals(value) || "Data Encipherment".equals(value)) { v1 |= (byte) 16; } else if ("keyAgreement".equals(value) || "Key Agreement".equals(value)) { v1 |= (byte) 8; } else if ("keyCertSign".equals(value) || "Key Cert Sign".equals(value)) { v1 |= (byte) 4; } else if ("cRLSign".equals(value)) { v1 |= (byte) 2; } else if ("encipherOnly".equals(value) || "Encipher Only".equals(value)) { v1 |= (byte) 1; } else { throw newExtensionError(getRuntime(), oid + " = " + valuex + ": unknown bit string argument"); } } inp = (v2 == 0) ? new byte[]{v1} : new byte[]{v1, v2}; } int unused = 0; for (int i = inp.length - 1; i > -1; i--) { if (inp[i] == 0) { unused += 8; } else { byte a2 = inp[i]; int x = 8; while (a2 != 0) { a2 <<= 1; x--; } unused += x; break; } } return new DERBitString(inp, unused); } private DERBitString parseNsCertType(String oid, String valuex) { byte v = 0; if (valuex.length() < 3) { byte[] inp = ByteList.plain(valuex); v = inp[0]; } else { final String[] val = StringHelper.split(valuex, ','); for (int i = 0; i < val.length; i++) { final String value = val[i].trim(); if ("SSL Client".equals(value) || "client".equals(value)) { v |= (byte) 128; } else if ("SSL Server".equals(value) || "server".equals(value)) { v |= (byte) 64; } else if ("S/MIME".equals(value) || "email".equals(value)) { v |= (byte) 32; } else if ("Object Signing".equals(value) || "objsign".equals(value)) { v |= (byte) 16; } else if ("Unused".equals(value) || "reserved".equals(value)) { v |= (byte) 8; } else if ("SSL CA".equals(value) || "sslCA".equals(value)) { v |= (byte) 4; } else if ("S/MIME CA".equals(value) || "emailCA".equals(value)) { v |= (byte) 2; } else if ("Object Signing CA".equals(value) || "objCA".equals(value)) { v |= (byte) 1; } else { throw newExtensionError(getRuntime(), oid + " = " + valuex + ": unknown bit string argument"); } } } int unused = 0; if (v == 0) { unused += 8; } else { byte a2 = v; int x = 8; while (a2 != 0) { a2 <<= 1; x--; } unused += x; } return new DERBitString(new byte[]{v}, unused); } private static DLSequence parseBasicConstrains(final String valuex) { final String[] val = StringHelper.split(valuex, ','); final ASN1EncodableVector vec = new ASN1EncodableVector(); for (int i = 0; i < val.length; i++) { final String value = val[i] = val[i].trim(); if (value.length() > 3 && value.substring(0, 3).equalsIgnoreCase("CA:")) { boolean isTrue = "true".equalsIgnoreCase(value.substring(3).trim()); vec.add(ASN1Boolean.getInstance(isTrue)); } } for (int i = 0; i < val.length; i++) { final String value = val[i]; if (value.length() > 8 && value.substring(0, 8).equalsIgnoreCase("pathlen:")) { int pathlen = Integer.parseInt(value.substring(8).trim()); vec.add(new ASN1Integer(BigInteger.valueOf(pathlen))); } } return new DLSequence(vec); } private ASN1Sequence parseAuthorityKeyIdentifier(final ThreadContext context, final String valuex) { final ASN1EncodableVector vec = new ASN1EncodableVector(); for ( String value : valuex.split(",") ) { // e.g. "keyid:always,issuer:always" if ( value.startsWith("keyid:") ) { // keyid:always ASN1Encodable publicKeyIdentifier = new DEROctetString(publicKeyIdentifier(context)); vec.add(new DERTaggedObject(false, 0, publicKeyIdentifier)); } else if ( value.startsWith("issuer:") ) { // issuer:always GeneralName issuerName = new GeneralName(authorityCertIssuer(context)); vec.add(new DERTaggedObject(false, 1, new GeneralNames(issuerName))); BigInteger issuerSerial = getIssuerSerialNumber(context); if ( issuerSerial != null ) { vec.add(new DERTaggedObject(false, 2, new ASN1Integer(issuerSerial))); } } } return new DERSequence(vec); } private byte[] publicKeyIdentifier(final ThreadContext context) { final Ruby runtime = context.runtime; IRubyObject pkey = getPublicKey(context); IRubyObject der; if (pkey instanceof PKeyRSA) { der = pkey.callMethod(context, "to_der"); } else { der = ASN1.decode(context, ASN1._ASN1(runtime), pkey.callMethod(context, "to_der")); der = der.callMethod(context, "value").callMethod(context, "[]", runtime.newFixnum(1)).callMethod(context, "value"); } return getSHA1Digest(runtime, der.asString().getBytes()); } private IRubyObject getPublicKey(final ThreadContext context) { IRubyObject issuer_cert = getInstanceVariable("@issuer_certificate"); if ( issuer_cert instanceof X509Cert ) { return ((X509Cert) issuer_cert).public_key(context); } return issuer_cert.callMethod(context, "public_key"); } private X500Name authorityCertIssuer(final ThreadContext context) { IRubyObject issuer = getIssuer(context); if ( issuer instanceof X509Name ) { return ((X509Name) issuer).getX500Name(); } throw new UnsupportedOperationException(); } private IRubyObject getIssuer(final ThreadContext context) { IRubyObject issuer_cert = getInstanceVariable("@issuer_certificate"); if ( issuer_cert instanceof X509Cert ) { return ((X509Cert) issuer_cert).getIssuer(); } return issuer_cert.callMethod(context, "issuer"); } private BigInteger getIssuerSerialNumber(final ThreadContext context) { IRubyObject issuer_cert = getInstanceVariable("@issuer_certificate"); if ( issuer_cert instanceof X509Cert ) { return ((X509Cert) issuer_cert).getSerial(); } IRubyObject serial = issuer_cert.callMethod(context, "serial"); return serial.isNil() ? null : ((BN) serial).getValue(); } private static byte[] getSHA1Digest(Ruby runtime, byte[] bytes) { try { return SecurityHelper.getMessageDigest("SHA-1").digest(bytes); } catch (GeneralSecurityException e) { throw newExtensionError(runtime, e.getMessage()); } } private ASN1Encodable parseIssuerAltName(final ThreadContext context, final String valuex) throws IOException { if ( valuex.startsWith("issuer:copy") ) { RubyArray exts = (RubyArray) getInstanceVariable("@issuer_certificate").callMethod(context, "extensions"); for ( int i = 0; i < exts.size(); i++ ) { X509Extension ext = (X509Extension) exts.entry(i); final String oid = ext.getRealObjectID().getId(); if ( "2.5.29.17".equals(oid) ) return ext.getRealValue(); } } throw new IOException("Malformed IssuerAltName: " + valuex); } private static final String DNS_ = "DNS:"; private static final String DNS_Name_ = "DNS Name:"; private static final String URI_ = "URI:"; private static final String RID_ = "RID:"; private static final String email_ = "email:"; private static final String dirName_ = "dirName:"; private static final String otherName_ = "otherName:"; private static ASN1Encodable parseSubjectAltName(final String valuex) throws IOException { if ( valuex.startsWith(DNS_) ) { final String[] vals = valuex.split(","); final GeneralName[] names = new GeneralName[vals.length]; for ( int i = 0; i < vals.length; i++ ) { final String dns = vals[i].substring(DNS_.length()); names[i] = new GeneralName(GeneralName.dNSName, dns); } return new GeneralNames(names); } if ( valuex.startsWith(DNS_Name_) ) { final String dns = valuex.substring(DNS_Name_.length()); return new GeneralName(GeneralName.dNSName, dns); } if ( valuex.startsWith(URI_) ) { final String uri = valuex.substring(URI_.length()); return new GeneralName(GeneralName.uniformResourceIdentifier, uri); } if ( valuex.startsWith(RID_) ) { final String rid = valuex.substring(RID_.length()); return new GeneralName(GeneralName.registeredID, rid); } if ( valuex.startsWith(email_) ) { final String[] vals = valuex.split(","); final GeneralName[] names = new GeneralName[vals.length]; for ( int i = 0; i < vals.length; i++ ) { if (vals[i].startsWith(email_)) { String mail = vals[i].substring(email_.length()); names[i] = new GeneralName(GeneralName.rfc822Name, mail); } else { ASN1Encodable name = parseSubjectAltName(vals[i]); names[i] = name instanceof GeneralNames ? ((GeneralNames) name).getNames()[0] : (GeneralName) name; } } return new GeneralNames(names); } if ( valuex.startsWith("IP:") || valuex.startsWith("IP Address:") ) { final int idx = valuex.charAt(2) == ':' ? 3 : 11; String[] vals = valuex.substring(idx).split("\\.|::"); final byte[] ip = new byte[vals.length]; for ( int i = 0; i < vals.length; i++ ) { ip[i] = (byte) (Integer.parseInt(vals[i]) & 0xff); } return new GeneralName(GeneralName.iPAddress, new DEROctetString(ip)); } if ( valuex.startsWith("other") ) { // otherName || othername final String other = valuex.substring(otherName_.length()); return new GeneralName(GeneralName.otherName, other); } if ( valuex.startsWith("dir") ) { // dirName || dirname final String dir = valuex.substring(dirName_.length()); return new GeneralName(GeneralName.directoryName, dir); } throw new IOException("could not parse SubjectAltName: " + valuex); } private DEROctetString parseSubjectKeyIdentifier(final ThreadContext context, final String oid, final String valuex) { if ( "hash".equalsIgnoreCase(valuex) ) { return new DEROctetString(publicKeyIdentifier(context)); } if ( valuex.length() == 20 || ! isHex(valuex) ) { return new DEROctetString(ByteList.plain(valuex)); } final int len = valuex.length(); final ByteList hex = new ByteList(len / 2 + 1); for (int i = 0; i < len; i += 2) { if (i + 1 >= len) { throw newExtensionError(context.runtime, oid + " = " + valuex + ": odd number of digits"); } final int c1 = upHex( valuex.charAt(i) ); final int c2 = upHex( valuex.charAt(i + 1) ); if (c1 != -1 && c2 != -1) { hex.append(((c1 << 4) & 0xF0) | (c2 & 0xF)); } else { throw newExtensionError(context.runtime, oid + " = " + valuex + ": illegal hex digit"); } while ((i + 2) < len && valuex.charAt(i + 2) == ':') { i++; } } final byte[] hexBytes = new byte[hex.length()]; System.arraycopy(hex.getUnsafeBytes(), hex.getBegin(), hexBytes, 0, hexBytes.length); return new DEROctetString(hexBytes); } private static DLSequence parseExtendedKeyUsage(final String valuex) { ASN1EncodableVector vector = new ASN1EncodableVector(); for (String name : valuex.split(", ?")) { vector.add(ASN1Registry.sym2oid(name)); } return new DLSequence(vector); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509Name.java000066400000000000000000000631221313661621600254020ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.BERTags; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.DLSet; import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x500.X500NameBuilder; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x509.X509DefaultEntryConverter; import org.bouncycastle.asn1.x509.X509NameEntryConverter; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyBoolean; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyHash; import org.jruby.RubyInteger; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.ext.openssl.x509store.Name; import static org.jruby.ext.openssl.OpenSSL.*; import static org.jruby.ext.openssl.X509._X509; import static org.jruby.ext.openssl.StringHelper.newString; /** * * TODO member variables and methods are based on BC X509 way of doing things (now deprecated). Change * it to do it the X500 way, with RDN and X500NameBuilder. * * @author Ola Bini */ public class X509Name extends RubyObject { private static final long serialVersionUID = -226196051911335103L; private static ObjectAllocator X509NAME_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509Name(runtime, klass); } }; public static void createX509Name(final Ruby runtime, final RubyModule _X509) { RubyClass _Name = _X509.defineClassUnder("Name", runtime.getObject(), X509NAME_ALLOCATOR); RubyClass _OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); _X509.defineClassUnder("NameError", _OpenSSLError, _OpenSSLError.getAllocator()); _Name.defineAnnotatedMethods(X509Name.class); _Name.includeModule(runtime.getComparable()); _Name.setConstant("COMPAT", runtime.newFixnum(COMPAT)); _Name.setConstant("RFC2253", runtime.newFixnum(RFC2253)); _Name.setConstant("ONELINE", runtime.newFixnum(ONELINE)); _Name.setConstant("MULTILINE", runtime.newFixnum(MULTILINE)); final RubyFixnum UTF8_STRING = runtime.newFixnum(BERTags.UTF8_STRING); _Name.setConstant("DEFAULT_OBJECT_TYPE", UTF8_STRING); final RubyFixnum PRINTABLE_STRING = runtime.newFixnum(BERTags.PRINTABLE_STRING); final RubyFixnum IA5_STRING = runtime.newFixnum(BERTags.IA5_STRING); final ThreadContext context = runtime.getCurrentContext(); final RubyHash hash = new RubyHash(runtime, UTF8_STRING); hash.op_aset(context, newString(runtime, new byte[] { 'C' }), PRINTABLE_STRING); final byte[] countryName = { 'c','o','u','n','t','r','y','N','a','m','e' }; hash.op_aset(context, newString(runtime, countryName), PRINTABLE_STRING); final byte[] serialNumber = { 's','e','r','i','a','l','N','u','m','b','e','r' }; hash.op_aset(context, newString(runtime, serialNumber), PRINTABLE_STRING); final byte[] dnQualifier = { 'd','n','Q','u','a','l','i','f','i','e','r' }; hash.op_aset(context, newString(runtime, dnQualifier), PRINTABLE_STRING); hash.op_aset(context, newString(runtime, new byte[] { 'D','C' }), IA5_STRING); final byte[] domainComponent = { 'd','o','m','a','i','n','C','o','m','p','o','n','e','n','t' }; hash.op_aset(context, newString(runtime, domainComponent), IA5_STRING); final byte[] emailAddress = { 'e','m','a','i','l','A','d','d','r','e','s','s' }; hash.op_aset(context, newString(runtime, emailAddress), IA5_STRING); _Name.setConstant("OBJECT_TYPE_TEMPLATE", hash); } static X509Name newName(final Ruby runtime) { return new X509Name(runtime, _Name(runtime)); } static X509Name newName(final Ruby runtime, final X500Principal principal) { final X509Name name = newName(runtime); name.fromASN1Sequence( principal.getEncoded() ); return name; } static X509Name newName(final Ruby runtime, org.bouncycastle.asn1.x500.X500Name realName) { final X509Name name = newName(runtime); name.fromASN1Sequence((ASN1Sequence) realName.toASN1Primitive()); return name; } @Deprecated public static X509Name create(final Ruby runtime, org.bouncycastle.asn1.x500.X500Name realName) { return newName(runtime, realName); } static RubyClass _Name(final Ruby runtime) { return _X509(runtime).getClass("Name"); } public static final int COMPAT = 0; public static final int RFC2253 = 17892119; public static final int ONELINE = 8520479; public static final int MULTILINE = 44302342; public X509Name(Ruby runtime, RubyClass type) { super(runtime,type); oids = new ArrayList(); values = new ArrayList(); types = new ArrayList(); } private final List oids; private final List values; // private final List types; private transient X500Name name; private void fromASN1Sequence(final byte[] encoded) { try { fromASN1Sequence((ASN1Sequence) new ASN1InputStream(encoded).readObject()); } catch (IOException e) { throw newNameError(getRuntime(), e.getClass().getName() + ":" + e.getMessage()); } } void fromASN1Sequence(final ASN1Sequence seq) { oids.clear(); values.clear(); types.clear(); if ( seq != null ) { for ( Enumeration e = seq.getObjects(); e.hasMoreElements(); ) { ASN1Object element = (ASN1Object) e.nextElement(); if ( element instanceof RDN ) { fromRDNElement((RDN) element); } else if ( element instanceof ASN1Sequence ) { fromASN1Sequence(element); } else { fromASN1Set(element); } } } } private void fromRDNElement(final RDN rdn) { final Ruby runtime = getRuntime(); for( AttributeTypeAndValue tv: rdn.getTypesAndValues() ) { oids.add( tv.getType() ); final ASN1Encodable val = tv.getValue(); addValue( val ); addType( runtime, val ); } } private void fromASN1Set(final ASN1Object element) { ASN1Set typeAndValue = ASN1Set.getInstance(element); for ( int i = 0; i < typeAndValue.size(); i++ ) { fromASN1Sequence( typeAndValue.getObjectAt(i) ); } } private void fromASN1Sequence(final ASN1Encodable element) { ASN1Sequence typeAndValue = ASN1Sequence.getInstance(element); oids.add( (ASN1ObjectIdentifier) typeAndValue.getObjectAt(0) ); final ASN1Encodable val = typeAndValue.getObjectAt(1); addValue( val ); addType( getRuntime(), val ); } private void addValue(final ASN1Encodable value) { if ( value instanceof ASN1String ) { this.values.add( value ); } else { warn(getRuntime().getCurrentContext(), this + " addValue() value not an ASN1 string = '" + value + "' (" + ( value == null ? "" : value.getClass().getName()) + ")"); this.values.add( value ); // TODO should not happen?! } } @SuppressWarnings("unchecked") private void addType(final Ruby runtime, final ASN1Encodable value) { this.name = null; // NOTE: each fromX factory calls this ... final Integer type = ASN1.typeId(value); if ( type == null ) { warn(runtime.getCurrentContext(), this + " addType() could not resolve type for: " + value + " (" + (value == null ? "" : value.getClass().getName()) + ")"); ((List) this.types).add( runtime.getNil() ); } else { this.types.add( runtime.newFixnum( type.intValue() ) ); } } private void addEntry(ASN1ObjectIdentifier oid, RubyString value, RubyInteger type) throws IOException { this.name = null; this.oids.add(oid); final ASN1Encodable convertedValue = getNameEntryConverted(). getConvertedValue(oid, value.toString() ); this.values.add( convertedValue ); this.types.add(type); } private static X509NameEntryConverter getNameEntryConverted() { return new X509DefaultEntryConverter(); } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(ThreadContext context) { return this; } @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(ThreadContext context, IRubyObject str_or_dn) { return initialize(context, str_or_dn, context.nil); } @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, IRubyObject dn, IRubyObject template) { final Ruby runtime = context.runtime; if ( dn instanceof RubyArray ) { RubyArray ary = (RubyArray) dn; final RubyClass _Name = _Name(runtime); if ( template.isNil() ) template = _Name.getConstant("OBJECT_TYPE_TEMPLATE"); for (int i = 0; i < ary.size(); i++) { IRubyObject obj = ary.eltOk(i); if ( ! (obj instanceof RubyArray) ) { throw runtime.newTypeError(obj, runtime.getArray()); } RubyArray arr = (RubyArray)obj; IRubyObject entry0, entry1, entry2; entry0 = arr.size() > 0 ? arr.eltOk(0) : context.nil; entry1 = arr.size() > 1 ? arr.eltOk(1) : context.nil; entry2 = arr.size() > 2 ? arr.eltOk(2) : context.nil; if (entry2.isNil()) entry2 = template.callMethod(context, "[]", entry0); if (entry2.isNil()) entry2 = _Name.getConstant("DEFAULT_OBJECT_TYPE"); add_entry(context, entry0, entry1, entry2); } } else { IRubyObject enc = to_der_if_possible(context, dn); fromASN1Sequence( enc.asString().getBytes() ); } return this; } /* private static void printASN(final ASN1Encodable obj, final StringBuilder out) { printASN(obj, 0, out); } private static void printASN(final ASN1Encodable obj, final int indent, final StringBuilder out) { for( int i = 0; i < indent; i++ ) out.append(' '); if ( obj instanceof ASN1Sequence ) { out.append("- Sequence:"); for ( Enumeration e = ((ASN1Sequence) obj).getObjects(); e.hasMoreElements(); ) { printASN((ASN1Encodable) e.nextElement(), indent + 1, out); } } else if ( obj instanceof ASN1Set ) { out.append("- Set:"); for ( Enumeration e = ((ASN1Set) obj).getObjects(); e.hasMoreElements(); ) { printASN((ASN1Encodable) e.nextElement(), indent + 1, out); } } else { if ( obj instanceof ASN1String ) { out.append("- ").append(obj). append('=').append( ((ASN1String) obj).getString() ). append('[').append( obj.getClass().getName() ).append(']'); } else { out.append("- ").append(obj). append('[').append( obj.getClass().getName() ).append(']'); } } } */ @JRubyMethod public IRubyObject add_entry(ThreadContext context, IRubyObject oid, IRubyObject value) { return add_entry(context, oid, value, null); } @JRubyMethod public IRubyObject add_entry(final ThreadContext context, final IRubyObject oid, final IRubyObject value, IRubyObject type) { final Ruby runtime = context.runtime; final RubyString oidStr = oid.asString(); if ( type == null || type.isNil() ) type = getDefaultType(context, oidStr); final ASN1ObjectIdentifier objectId; try { objectId = ASN1.getObjectID( runtime, oidStr.toString() ); } catch (IllegalArgumentException e) { throw newNameError(runtime, "invalid field name: " + oidStr, e); } // NOTE: won't reach here : if ( objectId == null ) throw newNameError(runtime, "invalid field name"); try { addEntry(objectId, value.asString(), (RubyInteger) type); } catch (IOException e) { throw newNameError(runtime, "invalid value", e); } return this; } private static IRubyObject getDefaultType(final ThreadContext context, final RubyString oid) { IRubyObject template = _Name(context.runtime).getConstant("OBJECT_TYPE_TEMPLATE"); if ( template instanceof RubyHash ) { return ((RubyHash) template).op_aref(context, oid); } return template.callMethod(context, "[]", oid); } @SuppressWarnings("unchecked") @JRubyMethod(name = "to_s", rest = true) public IRubyObject to_s(IRubyObject[] args) { final Ruby runtime = getRuntime(); int flag = 0; if ( args.length > 0 && ! args[0].isNil() ) { flag = RubyNumeric.fix2int( args[0] ); } /* Should follow parameters like this: if 0 (COMPAT): irb(main):025:0> x.to_s(OpenSSL::X509::Name::COMPAT) => "CN=ola.bini, O=sweden/streetAddress=sweden, O=sweden/2.5.4.43343=sweden" irb(main):026:0> x.to_s(OpenSSL::X509::Name::ONELINE) => "CN = ola.bini, O = sweden, streetAddress = sweden, O = sweden, 2.5.4.43343 = sweden" irb(main):027:0> x.to_s(OpenSSL::X509::Name::MULTILINE) => "commonName = ola.bini\norganizationName = sweden\nstreetAddress = sweden\norganizationName = sweden\n2.5.4.43343 = sweden" irb(main):028:0> x.to_s(OpenSSL::X509::Name::RFC2253) => "2.5.4.43343=#0C0673776564656E,O=sweden,streetAddress=sweden,O=sweden,CN=ola.bini" else => /CN=ola.bini/O=sweden/streetAddress=sweden/O=sweden/2.5.4.43343=sweden */ final Iterator oidsIter; final Iterator valuesIter; if ( flag == RFC2253 ) { ArrayList reverseOids = new ArrayList(oids); ArrayList reverseValues = new ArrayList(values); Collections.reverse(reverseOids); Collections.reverse(reverseValues); oidsIter = reverseOids.iterator(); valuesIter = reverseValues.iterator(); } else { oidsIter = oids.iterator(); valuesIter = (Iterator) values.iterator(); } final StringBuilder str = new StringBuilder(48); String sep = ""; while( oidsIter.hasNext() ) { final ASN1ObjectIdentifier oid = oidsIter.next(); String oName = name(runtime, oid); if ( oName == null ) oName = oid.toString(); final Object value = valuesIter.next(); switch(flag) { case RFC2253: str.append(sep).append(oName).append('=').append(value); sep = ","; break; case ONELINE: str.append(sep).append(oName).append(" = ").append(value); sep = ","; break; case MULTILINE: final Integer nid = ASN1.oid2nid(runtime, oid); if ( nid != null ) { final String ln = ASN1.nid2ln(runtime, nid); if ( ln != null ) oName = ln; } // TODO need indention : str.append(sep).append(oName).append(" = ").append(value); sep = "\n"; break; case COMPAT: default: str.append('/').append(oName).append('=').append(value); } } return runtime.newString( str.toString() ); } @Override @SuppressWarnings("unchecked") @JRubyMethod public IRubyObject inspect() { return ObjectSupport.inspect(this, Collections.EMPTY_LIST); } @Override @JRubyMethod public RubyArray to_a() { final Ruby runtime = getRuntime(); final RubyArray entries = runtime.newArray( oids.size() ); final Iterator oidsIter = oids.iterator(); @SuppressWarnings("unchecked") final Iterator valuesIter = (Iterator) values.iterator(); final Iterator typesIter = types.iterator(); while ( oidsIter.hasNext() ) { final ASN1ObjectIdentifier oid = oidsIter.next(); String oName = name(runtime, oid); if ( oName == null ) oName = oid.toString(); final String value = valuesIter.next().toString(); final IRubyObject type = typesIter.next(); final IRubyObject[] entry = new IRubyObject[] { runtime.newString(oName), runtime.newString(value), type }; entries.append( runtime.newArrayNoCopy(entry) ); } return entries; } private static String name(final Ruby runtime, final ASN1ObjectIdentifier oid) { return ASN1.oid2name(runtime, oid, true); } @Deprecated @SuppressWarnings("unchecked") org.bouncycastle.asn1.x509.X509Name getRealName() { final java.util.Vector strValues = new java.util.Vector(); for ( ASN1Encodable value : values ) strValues.add( value.toString() ); return new org.bouncycastle.asn1.x509.X509Name( new java.util.Vector(oids), strValues ); } final X500Name getX500Name() { if ( name != null ) return name; final X500NameBuilder builder = new X500NameBuilder( BCStyle.INSTANCE ); for ( int i = 0; i < oids.size(); i++ ) { builder.addRDN( oids.get(i), values.get(i) ); } return name = builder.build(); } @JRubyMethod(name = { "cmp", "<=>" }) public RubyFixnum cmp(IRubyObject other) { if ( equals(other) ) { return RubyFixnum.zero( getRuntime() ); } // TODO: do we really need cmp - if so what order huh? if ( other instanceof X509Name ) { final X509Name that = (X509Name) other; final X500Name thisName = this.getX500Name(); final X500Name thatName = that.getX500Name(); int cmp = thisName.toString().compareTo( thatName.toString() ); return RubyFixnum.newFixnum( getRuntime(), cmp ); } return RubyFixnum.one( getRuntime() ); } @Override public boolean equals(Object other) { if ( this == other ) return true; if ( other instanceof X509Name ) { final X509Name that = (X509Name) other; final X500Name thisName = this.getX500Name(); final X500Name thatName = that.getX500Name(); return thisName.equals(thatName); } return false; } @Override public int hashCode() { try { return Name.hash( getX500Name() ); } catch (IOException e) { debugStackTrace(getRuntime(), e); return 0; } catch (RuntimeException e) { debugStackTrace(getRuntime(), e); return 0; } // return 41 * this.oids.hashCode(); } @JRubyMethod(name = "eql?") public RubyBoolean eql_p(final ThreadContext context, final IRubyObject other) { if ( ! (other instanceof X509Name) ) return getRuntime().getFalse(); return getRuntime().newBoolean( equals(other) ); } @Override public IRubyObject eql_p(final IRubyObject obj) { return eql_p(getRuntime().getCurrentContext(), obj); } @Override @JRubyMethod public RubyFixnum hash() { return getRuntime().newFixnum( hashCode() ); } @JRubyMethod public RubyString to_der(final ThreadContext context) { final Ruby runtime = context.runtime; final DLSequence seq; if ( oids.size() > 0 ) { ASN1EncodableVector vec = new ASN1EncodableVector(); ASN1EncodableVector sVec = new ASN1EncodableVector(); ASN1ObjectIdentifier lastOid = null; for ( int i = 0; i != oids.size(); i++ ) { final ASN1ObjectIdentifier oid = oids.get(i); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(oid); // TODO DO NOT USE DL types ! //final String value = values.get(i); //final int type = RubyNumeric.fix2int(types.get(i)); //v.add( convert(oid, value, type) ); v.add( values.get(i) ); if ( lastOid == null ) { sVec.add(new DLSequence(v)); } else { vec.add(new DLSet(sVec)); sVec = new ASN1EncodableVector(); sVec.add(new DLSequence(v)); } lastOid = oid; } vec.add(new DLSet(sVec)); seq = new DLSequence(vec); } else { seq = new DLSequence(); } try { return StringHelper.newString(runtime, seq.getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw newNameError(runtime, e); } } private ASN1Primitive convert(ASN1ObjectIdentifier oid, String value, int type) { final Class clazz = ASN1.typeClass(type); try { if ( clazz != null ) { Constructor ctor = clazz.getConstructor(new Class[]{ String.class }); if (null != ctor) { return (ASN1Primitive) ctor.newInstance(new Object[]{ value }); } } return new X509DefaultEntryConverter().getConvertedValue(oid, value); } catch (NoSuchMethodException e) { throw newNameError(getRuntime(), e); } catch (InstantiationException e) { throw newNameError(getRuntime(), e); } catch (IllegalAccessException e) { throw newNameError(getRuntime(), e); } catch (IllegalArgumentException e) { throw newNameError(getRuntime(), e); } catch (InvocationTargetException e) { throw newNameError(getRuntime(), e.getTargetException()); } catch (RuntimeException e) { debugStackTrace(getRuntime(), e); throw newNameError(getRuntime(), e); } } private static RaiseException newNameError(Ruby runtime, String msg, Throwable e) { return Utils.newError(runtime, _X509(runtime).getClass("NameError"), msg, e); } private static RaiseException newNameError(Ruby runtime, Throwable e) { return Utils.newError(runtime, _X509(runtime).getClass("NameError"), e); } private static RaiseException newNameError(Ruby runtime, String message) { return Utils.newError(runtime, _X509(runtime).getClass("NameError"), message); } }// X509Name jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509Request.java000066400000000000000000000344141313661621600261540ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.util.ArrayList; import java.util.List; import java.io.IOException; import java.io.StringWriter; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.PublicKey; import java.security.PrivateKey; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.x500.X500Name; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.x509store.PEMInputOutput; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import org.jruby.ext.openssl.impl.PKCS10Request; import static org.jruby.ext.openssl.OpenSSL.*; import static org.jruby.ext.openssl.PKey._PKey; import static org.jruby.ext.openssl.X509._X509; import static org.jruby.ext.openssl.PKey.supportedSignatureAlgorithm; /** * @author Ola Bini */ public class X509Request extends RubyObject { private static final long serialVersionUID = -2886532636278901502L; private static ObjectAllocator REQUEST_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509Request(runtime, klass); } }; public static void createRequest(final Ruby runtime, final RubyModule _X509) { RubyClass _Request = _X509.defineClassUnder("Request", runtime.getObject(), REQUEST_ALLOCATOR); RubyClass _OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); _X509.defineClassUnder("RequestError", _OpenSSLError, _OpenSSLError.getAllocator()); _Request.defineAnnotatedMethods(X509Request.class); } static RubyClass _RequestError(final Ruby runtime) { return (RubyClass) _X509(runtime).getConstantAt("RequestError"); } private IRubyObject subject; private PKey public_key; private IRubyObject version; private final List attributes; private transient PKCS10Request request; public X509Request(Ruby runtime, RubyClass type) { super(runtime, type); attributes = new ArrayList(4); } @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; if ( Arity.checkArgumentCount(runtime, args, 0, 1) == 0 ) return this; try { request = new PKCS10Request( StringHelper.readX509PEM(context, args[0]) ); } catch (RuntimeException e) { debugStackTrace(runtime, e); throw newRequestError(runtime, "invalid certificate request data", e); } final String algorithm; final byte[] encoded; try { final PublicKey pkey = request.generatePublicKey(); algorithm = pkey.getAlgorithm(); encoded = pkey.getEncoded(); } catch (IOException e) { throw newRequestError(runtime, e); } catch (GeneralSecurityException e) { throw newRequestError(runtime, e); } final RubyString enc = RubyString.newString(runtime, encoded); if ( "RSA".equalsIgnoreCase(algorithm) ) { this.public_key = newPKeyImplInstance(context, "RSA", enc); } else if ( "DSA".equalsIgnoreCase(algorithm) ) { this.public_key = newPKeyImplInstance(context, "DSA", enc); } else { throw runtime.newNotImplementedError("public key algorithm: " + algorithm); } this.subject = newName( context, request.getSubject() ); final Attribute[] attrs = request.getAttributes(); try { // final RubyModule _ASN1 = _ASN1(runtime); if ( attrs != null ) { for ( final Attribute attr : attrs ) { final ASN1ObjectIdentifier type = attr.getAttrType(); final ASN1Set values = attr.getAttrValues(); attributes.add( newAttribute( context, type, values ) ); } } } catch (IOException e) { throw newRequestError(runtime, e); } return this; } private static PKey newPKeyImplInstance(final ThreadContext context, final String className, final RubyString encoded) { // OpenSSL::PKey::RSA.new(encoded) return (PKey) _PKey(context.runtime).getClass(className).callMethod(context, "new", encoded); } private static X509Attribute newAttribute(final ThreadContext context, final ASN1ObjectIdentifier type, final ASN1Set values) throws IOException { return X509Attribute.newAttribute(context.runtime, type, values); } private static IRubyObject newName(final ThreadContext context, X500Name name) { if ( name == null ) return context.nil; return X509Name.newName(context.runtime, name); } @Override @JRubyMethod(visibility = Visibility.PRIVATE) public IRubyObject initialize_copy(IRubyObject obj) { final Ruby runtime = getRuntime(); warn(runtime.getCurrentContext(), "WARNING: unimplemented method called: request#initialize_copy"); if ( this == obj ) return this; checkFrozen(); // subject = public_key = null; return this; } private PKCS10Request getRequest() { if ( request != null ) return request; PublicKey publicKey = null; if ( public_key != null && ! public_key.isNil() ) { publicKey = public_key.getPublicKey(); } X500Name subjectName = subject != null ? getX500Name(subject) : null; final ThreadContext context = getRuntime().getCurrentContext(); return request = new PKCS10Request( subjectName, publicKey, newAttributesImpl(context) ); } private static X500Name getX500Name(final IRubyObject name) { if ( name.isNil() ) return null; return ((X509Name) name).getX500Name(); } @JRubyMethod(name = { "to_pem", "to_s" }) public RubyString to_pem() { StringWriter writer = new StringWriter(); try { PEMInputOutput.writeX509Request(writer, getRequest()); return getRuntime().newString( writer.toString() ); } catch (IOException e) { throw Utils.newIOError(getRuntime(), e); } } @JRubyMethod public RubyString to_der() { final ASN1Sequence seq = getRequest().toASN1Structure(); try { return StringHelper.newString(getRuntime(), seq.getEncoded(ASN1Encoding.DER)); } catch (IOException ex) { throw getRuntime().newIOErrorFromException(ex); } } @JRubyMethod public IRubyObject to_text(final ThreadContext context) { warn(context, "WARNING: unimplemented method called: X509::Request#to_text"); return context.runtime.getNil(); } @JRubyMethod public IRubyObject version() { final PKCS10Request request = getRequest(); // (false) if ( request != null ) { BigInteger certVersion = request.getVersion(); if ( certVersion != null ) { return getRuntime().newFixnum( certVersion.intValue() ); } } return version == null ? getRuntime().newFixnum(0) : version; } @JRubyMethod(name="version=") public IRubyObject set_version(final ThreadContext context, IRubyObject version) { warn(context, "X509::Request#version= has no effect on certification request"); return this.version = version; } @JRubyMethod public IRubyObject subject() { return subject == null ? subject = getRuntime().getNil() : subject; } @JRubyMethod(name="subject=") public IRubyObject set_subject(final IRubyObject val) { if ( val != this.subject ) { if (request != null) { request.setSubject( getX500Name(val) ); } this.subject = val; } return val; } @JRubyMethod public IRubyObject signature_algorithm(final ThreadContext context) { warn(context, "WARNING: unimplemented method called: request#signature_algorithm"); return context.runtime.getNil(); } @JRubyMethod public IRubyObject public_key() { return public_key == null ? getRuntime().getNil() : public_key; } @JRubyMethod(name="public_key=") public IRubyObject set_public_key(final IRubyObject pkey) { if ( pkey != this.public_key ) { if (request != null) { request.setPublicKey( ((PKey) pkey).getPublicKey() ); } this.public_key = (PKey) pkey; } return pkey; } @JRubyMethod public IRubyObject sign(final ThreadContext context, final IRubyObject key, final IRubyObject digest) { // PublicKey publicKey = public_key.getPublicKey(); PrivateKey privateKey = ((PKey) key).getPrivateKey(); final Ruby runtime = context.runtime; supportedSignatureAlgorithm(runtime, _RequestError(runtime), public_key, (Digest) digest); final String digAlg = ((Digest) digest).getShortAlgorithm(); try { request = null; getRequest().sign( privateKey, digAlg ); } catch (GeneralSecurityException e) { debugStackTrace(runtime, e); throw newRequestError(runtime, e); } //catch (IOException e) { // debugStackTrace(runtime, e); // throw newRequestError(runtime, e); //} return this; } private List newAttributesImpl(final ThreadContext context) { ArrayList attrs = new ArrayList(attributes.size()); for ( X509Attribute attribute : attributes ) { attrs.add( newAttributeImpl(context, attribute) ); } return attrs; } private Attribute newAttributeImpl(final ThreadContext context, final X509Attribute attribute) { return Attribute.getInstance( attribute.toASN1( context ) ); } @JRubyMethod public IRubyObject verify(final ThreadContext context, IRubyObject key) { final Ruby runtime = context.runtime; final PublicKey publicKey; try { publicKey = ( (PKey) key.callMethod(context, "public_key") ).getPublicKey(); return runtime.newBoolean( getRequest().verify(publicKey) ); } catch (InvalidKeyException e) { debug(runtime, "X509::Request.verify invalid key", e); throw newRequestError(runtime, "invalid key supplied", e); } //catch (IOException e) { // debug(runtime, "X509::Request.verify failed", e); // return runtime.getFalse(); //} //catch (RuntimeException e) { // debug(runtime, "X509::Request.verify failed", e); // return runtime.getFalse(); //} } @JRubyMethod public IRubyObject attributes() { @SuppressWarnings("unchecked") List attributes = (List) this.attributes; return getRuntime().newArray(attributes); } @JRubyMethod(name="attributes=") public IRubyObject set_attributes(final ThreadContext context,final IRubyObject attributes) { this.attributes.clear(); final RubyArray attrs = (RubyArray) attributes; for ( int i = 0; i < attrs.size(); i++ ) { this.attributes.add( (X509Attribute) attrs.entry(i) ); } if (request != null) { request.setAttributes( newAttributesImpl(context) ); } return attributes; } @JRubyMethod public IRubyObject add_attribute(final ThreadContext context,final IRubyObject attribute) { attributes.add( (X509Attribute) attribute ); if (request != null) { request.addAttribute( newAttributeImpl( context, (X509Attribute) attribute ) ); } return attribute; } private static RaiseException newRequestError(Ruby runtime, Exception e) { return Utils.newError(runtime, _X509(runtime).getClass("RequestError"), e); } private static RaiseException newRequestError(Ruby runtime, String message) { return Utils.newError(runtime, _X509(runtime).getClass("RequestError"), message); } private static RaiseException newRequestError(Ruby runtime, String message, Exception cause) { return Utils.newError(runtime, _X509(runtime).getClass("RequestError"), message, cause); } }// X509Request jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509Revoked.java000066400000000000000000000151651313661621600261250ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.math.BigInteger; import java.security.cert.X509CRLEntry; import java.io.IOException; import java.util.Collections; import java.util.Set; import org.joda.time.DateTime; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyModule; import org.jruby.RubyObject; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import static org.jruby.ext.openssl.X509._X509; import static org.jruby.ext.openssl.X509Extension.newExtension; import static org.jruby.ext.openssl.X509Extension.newExtensionError; /** * @author Ola Bini */ public class X509Revoked extends RubyObject { private static final long serialVersionUID = -6238325248555061878L; private static ObjectAllocator X509REVOKED_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509Revoked(runtime, klass); } }; public static void createX509Revoked(final Ruby runtime, final RubyModule _X509) { RubyClass _Revoked = _X509.defineClassUnder("Revoked", runtime.getObject(), X509REVOKED_ALLOCATOR); RubyClass _OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); _X509.defineClassUnder("RevokedError", _OpenSSLError, _OpenSSLError.getAllocator()); _Revoked.defineAnnotatedMethods(X509Revoked.class); } static RubyClass _Revoked(final Ruby runtime) { return _X509(runtime).getClass("Revoked"); } static X509Revoked newInstance(final ThreadContext context, final X509CRLEntry entry) { final Ruby runtime = context.runtime; final X509Revoked revoked = new X509Revoked(runtime, _Revoked(runtime)); revoked.serial = BN.newInstance(runtime, entry.getSerialNumber()); revoked.time = RubyTime.newTime(runtime, entry.getRevocationDate().getTime()); if ( entry.hasExtensions() ) { final Set criticalExtOIDs = entry.getCriticalExtensionOIDs(); if ( criticalExtOIDs != null ) { for ( final String extOID : criticalExtOIDs ) { revoked.addExtension(context, entry, extOID, true); } } final Set nonCriticalExtOIDs = entry.getNonCriticalExtensionOIDs(); if ( nonCriticalExtOIDs != null ) { for ( final String extOID : nonCriticalExtOIDs ) { revoked.addExtension(context, entry, extOID, false); } } } return revoked; } private void addExtension(final ThreadContext context, final X509CRLEntry entry, final String extOID, final boolean critical) { try { final IRubyObject extension = newExtension(context, extOID, entry, critical); if ( extension != null ) extensions().append( extension ); } catch (IOException e) { throw newExtensionError(context.runtime, e); } } BN serial; RubyArray extensions; RubyTime time; public X509Revoked(Ruby runtime, RubyClass type) { super(runtime,type); } @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { serial = BN.newInstance(context.runtime, BigInteger.ZERO); return this; } BigInteger getSerial() { return this.serial.getValue(); } @JRubyMethod public IRubyObject serial() { return this.serial; } @JRubyMethod(name = "serial=") public IRubyObject set_serial(final IRubyObject serial) { if ( serial instanceof BN ) { return this.serial = (BN) serial; } BigInteger value = serial.convertToInteger("to_i").getBigIntegerValue(); return this.serial = BN.newInstance(getRuntime(), value); } DateTime getTime() { if ( time == null ) return null; return time.getDateTime(); } @JRubyMethod public IRubyObject time() { return time == null ? getRuntime().getNil() : time; } @JRubyMethod(name = "time=") public IRubyObject set_time(final IRubyObject time) { return this.time = (RubyTime) time; } boolean hasExtensions() { return extensions != null && extensions.size() > 0; } @JRubyMethod public RubyArray extensions() { return extensions == null ? extensions = RubyArray.newArray(getRuntime(), 4) : extensions; } @JRubyMethod(name = "extensions=") public IRubyObject set_extensions(final IRubyObject extensions) { return this.extensions = (RubyArray) extensions; } @JRubyMethod public IRubyObject add_extension(final ThreadContext context, final IRubyObject ext) { return extensions().callMethod(context, "<<", ext); } @Override @SuppressWarnings("unchecked") @JRubyMethod public IRubyObject inspect() { return ObjectSupport.inspect(this, Collections.EMPTY_LIST); } }// X509Revoked jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509Store.java000066400000000000000000000245651313661621600256260ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import static org.jruby.ext.openssl.OpenSSL.debugStackTrace; import static org.jruby.ext.openssl.OpenSSL.warn; import static org.jruby.ext.openssl.X509._X509; import org.jruby.Ruby; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.ext.openssl.x509store.Store; import org.jruby.ext.openssl.x509store.StoreContext; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import org.jruby.ext.openssl.x509store.X509Error; import org.jruby.ext.openssl.x509store.X509Utils; import org.jruby.runtime.Arity; import org.jruby.runtime.Block; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.Visibility; import org.jruby.runtime.builtin.IRubyObject; /** * @author Ola Bini */ public class X509Store extends RubyObject { private static final long serialVersionUID = -2969708892287379665L; private static ObjectAllocator X509STORE_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509Store(runtime, klass); } }; public static void createX509Store(final Ruby runtime, final RubyModule X509) { RubyClass Store = X509.defineClassUnder("Store", runtime.getObject(), X509STORE_ALLOCATOR); RubyClass OpenSSLError = runtime.getModule("OpenSSL").getClass("OpenSSLError"); X509.defineClassUnder("StoreError", OpenSSLError, OpenSSLError.getAllocator()); final ThreadContext context = runtime.getCurrentContext(); Store.addReadWriteAttribute(context, "error"); Store.addReadWriteAttribute(context, "error_string"); Store.addReadWriteAttribute(context, "chain"); Store.defineAnnotatedMethods(X509Store.class); Store.undefineMethod("dup"); X509StoreContext.createX509StoreContext(runtime, X509); } public X509Store(Ruby runtime, RubyClass type) { super(runtime, type); } private X509Store(Ruby runtime) { super(runtime, _X509(runtime).getClass("Store")); } static X509Store newStore(final Ruby runtime) { final X509Store store = new X509Store(runtime); store.initialize(runtime.getCurrentContext(), NULL_ARRAY); return store; } private final Store store = new Store(); final Store getStore() { return store; } @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { final Ruby runtime = context.runtime; final IRubyObject nil = runtime.getNil(); final IRubyObject zero = RubyFixnum.zero(runtime); store.setVerifyCallbackFunction(verifyCallback); this.set_verify_callback(nil); this.setInstanceVariable("@flags", zero); this.setInstanceVariable("@purpose", zero); this.setInstanceVariable("@trust", zero); this.setInstanceVariable("@error", nil); this.setInstanceVariable("@error_string", nil); this.setInstanceVariable("@chain", nil); this.setInstanceVariable("@time", nil); return this; } @JRubyMethod public IRubyObject verify_callback() { return this.getInstanceVariable("@verify_callback"); } @JRubyMethod(name = "verify_callback=") public IRubyObject set_verify_callback(final IRubyObject callback) { store.setExtraData(1, callback); this.setInstanceVariable("@verify_callback", callback); return callback; } @JRubyMethod(name = "flags=") public IRubyObject set_flags(final IRubyObject arg) { store.setFlags(RubyNumeric.fix2long(arg)); return arg; } @JRubyMethod(name = "purpose=") public IRubyObject set_purpose(final IRubyObject arg) { store.setPurpose(RubyNumeric.fix2int(arg)); return arg; } @JRubyMethod(name = "trust=") public IRubyObject set_trust(final IRubyObject arg) { store.setTrust(RubyNumeric.fix2int(arg)); return arg; } @JRubyMethod(name = "time=") public IRubyObject set_time(final IRubyObject arg) { setInstanceVariable("@time", arg); return arg; } @JRubyMethod public IRubyObject add_path(final ThreadContext context, final IRubyObject arg) { warn(context, "WARNING: unimplemented method called: Store#add_path"); return context.nil; } @JRubyMethod public IRubyObject add_file(final IRubyObject arg) { String file = arg.toString(); final Ruby runtime = getRuntime(); try { store.loadLocations(runtime, file, null); } catch (Exception e) { debugStackTrace(runtime, e); throw newStoreError(runtime, "loading file failed: ", e); } return this; } @JRubyMethod public IRubyObject set_default_paths(final ThreadContext context) { final Ruby runtime = context.runtime; try { store.setDefaultPaths(runtime); } catch (Exception e) { debugStackTrace(runtime, e); throw newStoreError(runtime, "setting default path failed: ", e); } return runtime.getNil(); } @JRubyMethod public X509Store add_cert(final IRubyObject cert) { X509AuxCertificate auxCert = cert instanceof X509Cert ? ((X509Cert) cert).getAuxCert() : null; if ( store.addCertificate(auxCert) != 1 ) { throw newStoreError(getRuntime(), X509Error.getLastErrorMessage()); } return this; } @JRubyMethod public X509Store add_crl(final IRubyObject crl) { java.security.cert.X509CRL jCRL = (crl instanceof X509CRL) ? ((X509CRL) crl).getCRL() : null; if ( store.addCRL(jCRL) != 1 ) { throw newStoreError(getRuntime(), X509Error.getLastErrorMessage()); } return this; } @JRubyMethod(rest = true) public IRubyObject verify(final ThreadContext context, final IRubyObject[] args, final Block block) { final Ruby runtime = context.runtime; final IRubyObject cert = args[0], chain; if ( Arity.checkArgumentCount(runtime, args, 1, 2) == 2 ) { chain = args[1]; } else { chain = runtime.getNil(); } final IRubyObject verify_callback; if (block.isGiven()) { verify_callback = runtime.newProc(Block.Type.PROC, block); } else { verify_callback = getInstanceVariable("@verify_callback"); } final X509StoreContext store_context = X509StoreContext.newStoreContext(context, this, cert, chain); store_context.setInstanceVariable("@verify_callback", verify_callback); IRubyObject result = store_context.callMethod(context, "verify"); this.setInstanceVariable("@error", store_context.error(context)); this.setInstanceVariable("@error_string", store_context.error_string(context)); this.setInstanceVariable("@chain", store_context.chain(context)); return result; } private static Store.VerifyCallbackFunction verifyCallback = new Store.VerifyCallbackFunction() { public int call(final StoreContext context, final Integer outcome) { int ok = outcome.intValue(); IRubyObject proc = (IRubyObject) context.getExtraData(1); if (proc == null) { proc = (IRubyObject) context.getStore().getExtraData(0); } if ( proc == null ) return ok; if ( ! proc.isNil() ) { final Ruby runtime = proc.getRuntime(); X509StoreContext store_context = X509StoreContext.newStoreContext(runtime, context); IRubyObject ret = proc.callMethod(runtime.getCurrentContext(), "call", new IRubyObject[] { runtime.newBoolean(ok != 0), store_context } ); if (ret.isTrue()) { context.setError(X509Utils.V_OK); ok = 1; } else { if (context.getError() == X509Utils.V_OK) { context.setError(X509Utils.V_ERR_CERT_REJECTED); } ok = 0; } } return ok; } }; private static RubyClass _StoreError(final Ruby runtime) { return _X509(runtime).getClass("StoreError"); } private static RaiseException newStoreError(final Ruby runtime, final String message) { return Utils.newError(runtime, _StoreError(runtime), message); } private static RaiseException newStoreError(final Ruby runtime, final String message, final Exception e) { return newStoreError(runtime, message + (e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage())); } }// X509Store jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/X509StoreContext.java000066400000000000000000000254131313661621600271640ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006, 2007 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl; import java.security.cert.CRLException; import java.security.cert.CertificateEncodingException; import java.util.ArrayList; import java.util.List; import org.jruby.Ruby; import org.jruby.RubyArray; import org.jruby.RubyClass; import org.jruby.RubyFixnum; import org.jruby.RubyModule; import org.jruby.RubyNumeric; import org.jruby.RubyObject; import org.jruby.RubyString; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; import org.jruby.runtime.Arity; import org.jruby.runtime.ObjectAllocator; import org.jruby.runtime.ThreadContext; import org.jruby.runtime.builtin.IRubyObject; import org.jruby.runtime.Visibility; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import org.jruby.ext.openssl.x509store.StoreContext; import static org.jruby.ext.openssl.OpenSSL.debugStackTrace; import static org.jruby.ext.openssl.OpenSSL.warn; import static org.jruby.ext.openssl.X509._X509; import static org.jruby.ext.openssl.X509CRL._CRL; import static org.jruby.ext.openssl.X509Cert._Certificate; import static org.jruby.ext.openssl.x509store.X509Utils.verifyCertificateErrorString; /** * @author Ola Bini */ public class X509StoreContext extends RubyObject { private static final long serialVersionUID = -4165247923898746888L; private static ObjectAllocator X509STORECTX_ALLOCATOR = new ObjectAllocator() { public IRubyObject allocate(Ruby runtime, RubyClass klass) { return new X509StoreContext(runtime, klass); } }; public static void createX509StoreContext(final Ruby runtime, final RubyModule X509) { RubyClass StoreContext = X509.defineClassUnder("StoreContext", runtime.getObject(), X509STORECTX_ALLOCATOR); StoreContext.defineAnnotatedMethods(X509StoreContext.class); StoreContext.undefineMethod("dup"); } private static RubyClass _StoreContext(final Ruby runtime) { return _X509(runtime).getClass("StoreContext"); } private StoreContext storeContext; public X509StoreContext(Ruby runtime, RubyClass type) { super(runtime, type); } // constructor for creating callback parameter object of verify_cb private X509StoreContext(Ruby runtime, RubyClass type, StoreContext storeContext) { super(runtime, type); this.storeContext = storeContext; } static X509StoreContext newStoreContext(final Ruby runtime, final StoreContext storeContext) { return new X509StoreContext(runtime, _StoreContext(runtime), storeContext); } static X509StoreContext newStoreContext(final ThreadContext context, final X509Store store, final IRubyObject cert, final IRubyObject chain) { final Ruby runtime = context.runtime; X509StoreContext instance = new X509StoreContext(runtime, _StoreContext(runtime)); instance.initialize(context, new IRubyObject[] { store, cert, chain } ); return instance; } @JRubyMethod(name = "initialize", rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) { X509Store store; IRubyObject cert, chain; cert = chain = context.nil; store = (X509Store) args[0]; if ( Arity.checkArgumentCount(context.runtime, args, 1, 3) > 1 ) { cert = args[1]; if ( args.length > 2) chain = args[2]; } final X509AuxCertificate _cert; if (cert.isNil()) { _cert = null; } else { if ( ! (cert instanceof X509Cert) ) { throw context.runtime.newTypeError(cert, "OpenSSL::X509::Certificate"); } _cert = ((X509Cert) cert).getAuxCert(); } final List _chain; if ( ! chain.isNil() ) { @SuppressWarnings("unchecked") final RubyArray certs = (RubyArray) chain; _chain = new ArrayList( certs.size() ); for (int i = 0; i < certs.size(); i++) { // NOTE: if we use the normal java syntax for iterating over this // RubyArray, the `toJava` method of the X509Cert class will be // implicitly called, and that will return the BC certificate object // rather than the JRuby one. X509Cert c = (X509Cert) certs.eltOk(i); _chain.add(c.getAuxCert()); } } else { _chain = new ArrayList(4); } this.storeContext = new StoreContext(store.getStore()); if ( storeContext.init(_cert, _chain) != 1 ) { throw newStoreError(context.runtime, null); } IRubyObject time = store.getInstanceVariables().getInstanceVariable("@time"); if ( ! time.isNil() ) set_time(time); this.setInstanceVariable("@verify_callback", store.verify_callback()); this.setInstanceVariable("@cert", cert); return this; } @JRubyMethod public IRubyObject verify(final ThreadContext context) { final Ruby runtime = context.runtime; storeContext.setExtraData(1, getInstanceVariable("@verify_callback")); try { final int result = storeContext.verifyCertificate(); return result != 0 ? runtime.getTrue() : runtime.getFalse(); } catch (Exception e) { debugStackTrace(runtime, e); // TODO: define suitable exception for jopenssl and catch it. throw newStoreError(runtime, e.getMessage()); } } @JRubyMethod public IRubyObject chain(final ThreadContext context) { final Ruby runtime = context.runtime; final List chain = storeContext.getChain(); if ( chain == null ) return runtime.getNil(); final RubyArray result = runtime.newArray(chain.size()); final RubyClass _Certificate = _Certificate(runtime); try { for (X509AuxCertificate x509 : chain) { RubyString encoded = StringHelper.newString(runtime, x509.getEncoded()); result.append( _Certificate.callMethod( context, "new", encoded ) ); } } catch (CertificateEncodingException e) { throw newStoreError(runtime, e.getMessage()); } return result; } @JRubyMethod public IRubyObject error(final ThreadContext context) { return context.runtime.newFixnum( storeContext.getError() ); } @JRubyMethod(name="error=") public IRubyObject set_error(final IRubyObject error) { storeContext.setError( RubyNumeric.fix2int(error) ); return error; } @JRubyMethod public IRubyObject error_string(final ThreadContext context) { final int error = storeContext.getError(); return context.runtime.newString( verifyCertificateErrorString(error) ); } @JRubyMethod public IRubyObject error_depth(final ThreadContext context) { final int depth = storeContext.getErrorDepth(); return context.runtime.newFixnum( depth ); } @JRubyMethod public IRubyObject current_cert(final ThreadContext context) { final X509AuxCertificate x509 = storeContext.getCurrentCertificate(); try { return X509Cert.wrap(context, x509.getEncoded()); } catch (CertificateEncodingException e) { throw newStoreError(context.runtime, e.getMessage()); } } @JRubyMethod public IRubyObject current_crl(final ThreadContext context) { final Ruby runtime = context.runtime; final RubyClass _CRL = _CRL(runtime); try { final java.security.cert.X509CRL crl = storeContext.getCurrentCRL(); return _CRL.callMethod(context, "new", StringHelper.newString(runtime, crl.getEncoded())); } catch (CRLException e) { throw newStoreError(runtime, e.getMessage()); } } @JRubyMethod public IRubyObject cleanup(final ThreadContext context) { try { storeContext.cleanup(); } catch (RuntimeException e) { throw e; } catch (Exception e) { debugStackTrace(context.runtime, e); throw newStoreError(context.runtime, e.getMessage()); } return context.runtime.getNil(); } @JRubyMethod(name = "flags=") public IRubyObject set_flags(final ThreadContext context, final IRubyObject arg) { storeContext.setFlags(RubyFixnum.fix2long((RubyFixnum)arg)); return arg; } @JRubyMethod(name = "purpose=") public IRubyObject set_purpose(final ThreadContext context, final IRubyObject arg) { storeContext.setPurpose(RubyFixnum.fix2int((RubyFixnum)arg)); return arg; } @JRubyMethod(name = "trust=") public IRubyObject set_trust(final ThreadContext context, final IRubyObject arg) { storeContext.setTrust(RubyFixnum.fix2int((RubyFixnum)arg)); return arg; } @JRubyMethod(name = "time=") public IRubyObject set_time(IRubyObject arg) { storeContext.setTime( 0, ( (RubyTime) arg ).getJavaDate() ); return arg; } private static RaiseException newStoreError(Ruby runtime, String message) { return Utils.newError(runtime, _X509(runtime).getClass("StoreError"), message); } }// X509StoreContext jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/000077500000000000000000000000001313661621600242265ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/ASN1Registry.java000066400000000000000000021405541313661621600273370ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.util.HashMap; import java.util.Map; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * * @author Ola Bini */ public class ASN1Registry { public static Integer oid2nid(final ASN1ObjectIdentifier oid) { return OID_TO_NID.get( oid.getId() ); } public static Integer oid2nid(final String oid) { return OID_TO_NID.get(oid); } public static String oid2sym(final ASN1ObjectIdentifier oid) { return OID_TO_SYM.get( oid.getId() ); } public static String o2a(String oid) { Integer nid = OID_TO_NID.get(oid); if ( nid == null ) return null; String name = NID_TO_LN[ nid ]; if( name == null ) name = NID_TO_SN[ nid ]; return name; } public static String o2a(final ASN1ObjectIdentifier oid) { return o2a( oid.getId() ); } //@Deprecated public static ASN1ObjectIdentifier sym2oid(final String name) { final String oid = SYM_TO_OID.get( name.toLowerCase() ); return oid == null ? null : new ASN1ObjectIdentifier( oid ); } public static String name2oid(final String name) { return SYM_TO_OID.get( name.toLowerCase() ); } public static Map getOIDLookup() { return SYM_TO_OID; } static ASN1ObjectIdentifier nid2obj(int nid) { return new ASN1ObjectIdentifier( NID_TO_OID[ nid ] ); } public static String nid2oid(int nid) { return NID_TO_OID[ nid ]; } public static String nid2ln(int nid) { return NID_TO_LN[ nid ]; } public static String nid2sn(int nid) { return NID_TO_SN[ nid ]; } // ---------------------------------------- // GENERATED FROM OpenSSL's crypto/objects/obj_dat.h // ---------------------------------------- public static final String SN_undef = "UNDEF"; public static final String LN_undef = "undefined"; public static final short NID_undef = 0; public static final String OBJ_undef = "0"; public static final String SN_itu_t = "ITU-T"; public static final String LN_itu_t = "itu-t"; public static final short NID_itu_t = 645; public static final String OBJ_itu_t = "0"; public static final short NID_ccitt = 404; public static final String OBJ_ccitt = "0"; public static final String SN_iso = "ISO"; public static final String LN_iso = "iso"; public static final short NID_iso = 181; public static final String OBJ_iso = "1"; public static final String SN_joint_iso_itu_t = "JOINT-ISO-ITU-T"; public static final String LN_joint_iso_itu_t = "joint-iso-itu-t"; public static final short NID_joint_iso_itu_t = 646; public static final String OBJ_joint_iso_itu_t = "2"; public static final short NID_joint_iso_ccitt = 393; public static final String OBJ_joint_iso_ccitt = "2"; public static final String SN_member_body = "member-body"; public static final String LN_member_body = "ISO Member Body"; public static final short NID_member_body = 182; public static final String OBJ_member_body = "1.2"; public static final String SN_identified_organization = "identified-organization"; public static final short NID_identified_organization = 676; public static final String OBJ_identified_organization = "1.3"; public static final String SN_hmac_md5 = "HMAC-MD5"; public static final String LN_hmac_md5 = "hmac-md5"; public static final short NID_hmac_md5 = 780; public static final String OBJ_hmac_md5 = "1.3.6.1.5.5.8.1.1"; public static final String SN_hmac_sha1 = "HMAC-SHA1"; public static final String LN_hmac_sha1 = "hmac-sha1"; public static final short NID_hmac_sha1 = 781; public static final String OBJ_hmac_sha1 = "1.3.6.1.5.5.8.1.2"; public static final String SN_certicom_arc = "certicom-arc"; public static final short NID_certicom_arc = 677; public static final String OBJ_certicom_arc = "1.3.132"; public static final String SN_international_organizations = "international-organizations"; public static final String LN_international_organizations = "International Organizations"; public static final short NID_international_organizations = 647; public static final String OBJ_international_organizations = "2.23"; public static final String SN_wap = "wap"; public static final short NID_wap = 678; public static final String OBJ_wap = "2.23.43"; public static final String SN_wap_wsg = "wap-wsg"; public static final short NID_wap_wsg = 679; public static final String OBJ_wap_wsg = "2.23.43.1"; public static final String SN_selected_attribute_types = "selected-attribute-types"; public static final String LN_selected_attribute_types = "Selected Attribute Types"; public static final short NID_selected_attribute_types = 394; public static final String OBJ_selected_attribute_types = "2.5.1.5"; public static final String SN_clearance = "clearance"; public static final short NID_clearance = 395; public static final String OBJ_clearance = "2.5.1.5.55"; public static final String SN_ISO_US = "ISO-US"; public static final String LN_ISO_US = "ISO US Member Body"; public static final short NID_ISO_US = 183; public static final String OBJ_ISO_US = "1.2.840"; public static final String SN_X9_57 = "X9-57"; public static final String LN_X9_57 = "X9.57"; public static final short NID_X9_57 = 184; public static final String OBJ_X9_57 = "1.2.840.10040"; public static final String SN_X9cm = "X9cm"; public static final String LN_X9cm = "X9.57 CM ?"; public static final short NID_X9cm = 185; public static final String OBJ_X9cm = "1.2.840.10040.4"; public static final String SN_dsa = "DSA"; public static final String LN_dsa = "dsaEncryption"; public static final short NID_dsa = 116; public static final String OBJ_dsa = "1.2.840.10040.4.1"; public static final String SN_dsaWithSHA1 = "DSA-SHA1"; public static final String LN_dsaWithSHA1 = "dsaWithSHA1"; public static final short NID_dsaWithSHA1 = 113; public static final String OBJ_dsaWithSHA1 = "1.2.840.10040.4.3"; public static final String SN_ansi_X9_62 = "ansi-X9-62"; public static final String LN_ansi_X9_62 = "ANSI X9.62"; public static final short NID_ansi_X9_62 = 405; public static final String OBJ_ansi_X9_62 = "1.2.840.10045"; public static final String OBJ_X9_62_id_fieldType = "1.2.840.10045.1"; public static final String SN_X9_62_prime_field = "prime-field"; public static final short NID_X9_62_prime_field = 406; public static final String OBJ_X9_62_prime_field = "1.2.840.10045.1.1"; public static final String SN_X9_62_characteristic_two_field = "characteristic-two-field"; public static final short NID_X9_62_characteristic_two_field = 407; public static final String OBJ_X9_62_characteristic_two_field = "1.2.840.10045.1.2"; public static final String SN_X9_62_id_characteristic_two_basis = "id-characteristic-two-basis"; public static final short NID_X9_62_id_characteristic_two_basis = 680; public static final String OBJ_X9_62_id_characteristic_two_basis = "1.2.840.10045.1.2.3"; public static final String SN_X9_62_onBasis = "onBasis"; public static final short NID_X9_62_onBasis = 681; public static final String OBJ_X9_62_onBasis = "1.2.840.10045.1.2.3.1"; public static final String SN_X9_62_tpBasis = "tpBasis"; public static final short NID_X9_62_tpBasis = 682; public static final String OBJ_X9_62_tpBasis = "1.2.840.10045.1.2.3.2"; public static final String SN_X9_62_ppBasis = "ppBasis"; public static final short NID_X9_62_ppBasis = 683; public static final String OBJ_X9_62_ppBasis = "1.2.840.10045.1.2.3.3"; public static final String OBJ_X9_62_id_publicKeyType = "1.2.840.10045.2"; public static final String SN_X9_62_id_ecPublicKey = "id-ecPublicKey"; public static final short NID_X9_62_id_ecPublicKey = 408; public static final String OBJ_X9_62_id_ecPublicKey = "1.2.840.10045.2.1"; public static final String OBJ_X9_62_ellipticCurve = "1.2.840.10045.3"; public static final String OBJ_X9_62_c_TwoCurve = "1.2.840.10045.3.0"; public static final String SN_X9_62_c2pnb163v1 = "c2pnb163v1"; public static final short NID_X9_62_c2pnb163v1 = 684; public static final String OBJ_X9_62_c2pnb163v1 = "1.2.840.10045.3.0.1"; public static final String SN_X9_62_c2pnb163v2 = "c2pnb163v2"; public static final short NID_X9_62_c2pnb163v2 = 685; public static final String OBJ_X9_62_c2pnb163v2 = "1.2.840.10045.3.0.2"; public static final String SN_X9_62_c2pnb163v3 = "c2pnb163v3"; public static final short NID_X9_62_c2pnb163v3 = 686; public static final String OBJ_X9_62_c2pnb163v3 = "1.2.840.10045.3.0.3"; public static final String SN_X9_62_c2pnb176v1 = "c2pnb176v1"; public static final short NID_X9_62_c2pnb176v1 = 687; public static final String OBJ_X9_62_c2pnb176v1 = "1.2.840.10045.3.0.4"; public static final String SN_X9_62_c2tnb191v1 = "c2tnb191v1"; public static final short NID_X9_62_c2tnb191v1 = 688; public static final String OBJ_X9_62_c2tnb191v1 = "1.2.840.10045.3.0.5"; public static final String SN_X9_62_c2tnb191v2 = "c2tnb191v2"; public static final short NID_X9_62_c2tnb191v2 = 689; public static final String OBJ_X9_62_c2tnb191v2 = "1.2.840.10045.3.0.6"; public static final String SN_X9_62_c2tnb191v3 = "c2tnb191v3"; public static final short NID_X9_62_c2tnb191v3 = 690; public static final String OBJ_X9_62_c2tnb191v3 = "1.2.840.10045.3.0.7"; public static final String SN_X9_62_c2onb191v4 = "c2onb191v4"; public static final short NID_X9_62_c2onb191v4 = 691; public static final String OBJ_X9_62_c2onb191v4 = "1.2.840.10045.3.0.8"; public static final String SN_X9_62_c2onb191v5 = "c2onb191v5"; public static final short NID_X9_62_c2onb191v5 = 692; public static final String OBJ_X9_62_c2onb191v5 = "1.2.840.10045.3.0.9"; public static final String SN_X9_62_c2pnb208w1 = "c2pnb208w1"; public static final short NID_X9_62_c2pnb208w1 = 693; public static final String OBJ_X9_62_c2pnb208w1 = "1.2.840.10045.3.0.10"; public static final String SN_X9_62_c2tnb239v1 = "c2tnb239v1"; public static final short NID_X9_62_c2tnb239v1 = 694; public static final String OBJ_X9_62_c2tnb239v1 = "1.2.840.10045.3.0.11"; public static final String SN_X9_62_c2tnb239v2 = "c2tnb239v2"; public static final short NID_X9_62_c2tnb239v2 = 695; public static final String OBJ_X9_62_c2tnb239v2 = "1.2.840.10045.3.0.12"; public static final String SN_X9_62_c2tnb239v3 = "c2tnb239v3"; public static final short NID_X9_62_c2tnb239v3 = 696; public static final String OBJ_X9_62_c2tnb239v3 = "1.2.840.10045.3.0.13"; public static final String SN_X9_62_c2onb239v4 = "c2onb239v4"; public static final short NID_X9_62_c2onb239v4 = 697; public static final String OBJ_X9_62_c2onb239v4 = "1.2.840.10045.3.0.14"; public static final String SN_X9_62_c2onb239v5 = "c2onb239v5"; public static final short NID_X9_62_c2onb239v5 = 698; public static final String OBJ_X9_62_c2onb239v5 = "1.2.840.10045.3.0.15"; public static final String SN_X9_62_c2pnb272w1 = "c2pnb272w1"; public static final short NID_X9_62_c2pnb272w1 = 699; public static final String OBJ_X9_62_c2pnb272w1 = "1.2.840.10045.3.0.16"; public static final String SN_X9_62_c2pnb304w1 = "c2pnb304w1"; public static final short NID_X9_62_c2pnb304w1 = 700; public static final String OBJ_X9_62_c2pnb304w1 = "1.2.840.10045.3.0.17"; public static final String SN_X9_62_c2tnb359v1 = "c2tnb359v1"; public static final short NID_X9_62_c2tnb359v1 = 701; public static final String OBJ_X9_62_c2tnb359v1 = "1.2.840.10045.3.0.18"; public static final String SN_X9_62_c2pnb368w1 = "c2pnb368w1"; public static final short NID_X9_62_c2pnb368w1 = 702; public static final String OBJ_X9_62_c2pnb368w1 = "1.2.840.10045.3.0.19"; public static final String SN_X9_62_c2tnb431r1 = "c2tnb431r1"; public static final short NID_X9_62_c2tnb431r1 = 703; public static final String OBJ_X9_62_c2tnb431r1 = "1.2.840.10045.3.0.20"; public static final String OBJ_X9_62_primeCurve = "1.2.840.10045.3.1"; public static final String SN_X9_62_prime192v1 = "prime192v1"; public static final short NID_X9_62_prime192v1 = 409; public static final String OBJ_X9_62_prime192v1 = "1.2.840.10045.3.1.1"; public static final String SN_X9_62_prime192v2 = "prime192v2"; public static final short NID_X9_62_prime192v2 = 410; public static final String OBJ_X9_62_prime192v2 = "1.2.840.10045.3.1.2"; public static final String SN_X9_62_prime192v3 = "prime192v3"; public static final short NID_X9_62_prime192v3 = 411; public static final String OBJ_X9_62_prime192v3 = "1.2.840.10045.3.1.3"; public static final String SN_X9_62_prime239v1 = "prime239v1"; public static final short NID_X9_62_prime239v1 = 412; public static final String OBJ_X9_62_prime239v1 = "1.2.840.10045.3.1.4"; public static final String SN_X9_62_prime239v2 = "prime239v2"; public static final short NID_X9_62_prime239v2 = 413; public static final String OBJ_X9_62_prime239v2 = "1.2.840.10045.3.1.5"; public static final String SN_X9_62_prime239v3 = "prime239v3"; public static final short NID_X9_62_prime239v3 = 414; public static final String OBJ_X9_62_prime239v3 = "1.2.840.10045.3.1.6"; public static final String SN_X9_62_prime256v1 = "prime256v1"; public static final short NID_X9_62_prime256v1 = 415; public static final String OBJ_X9_62_prime256v1 = "1.2.840.10045.3.1.7"; public static final String OBJ_X9_62_id_ecSigType = "1.2.840.10045.4"; public static final String SN_ecdsa_with_SHA1 = "ecdsa-with-SHA1"; public static final short NID_ecdsa_with_SHA1 = 416; public static final String OBJ_ecdsa_with_SHA1 = "1.2.840.10045.4.1"; public static final String SN_ecdsa_with_Recommended = "ecdsa-with-Recommended"; public static final short NID_ecdsa_with_Recommended = 791; public static final String OBJ_ecdsa_with_Recommended = "1.2.840.10045.4.2"; public static final String SN_ecdsa_with_Specified = "ecdsa-with-Specified"; public static final short NID_ecdsa_with_Specified = 792; public static final String OBJ_ecdsa_with_Specified = "1.2.840.10045.4.3"; public static final String SN_ecdsa_with_SHA224 = "ecdsa-with-SHA224"; public static final short NID_ecdsa_with_SHA224 = 793; public static final String OBJ_ecdsa_with_SHA224 = "1.2.840.10045.4.3.1"; public static final String SN_ecdsa_with_SHA256 = "ecdsa-with-SHA256"; public static final short NID_ecdsa_with_SHA256 = 794; public static final String OBJ_ecdsa_with_SHA256 = "1.2.840.10045.4.3.2"; public static final String SN_ecdsa_with_SHA384 = "ecdsa-with-SHA384"; public static final short NID_ecdsa_with_SHA384 = 795; public static final String OBJ_ecdsa_with_SHA384 = "1.2.840.10045.4.3.3"; public static final String SN_ecdsa_with_SHA512 = "ecdsa-with-SHA512"; public static final short NID_ecdsa_with_SHA512 = 796; public static final String OBJ_ecdsa_with_SHA512 = "1.2.840.10045.4.3.4"; public static final String OBJ_secg_ellipticCurve = "1.3.132.0"; public static final String SN_secp112r1 = "secp112r1"; public static final short NID_secp112r1 = 704; public static final String OBJ_secp112r1 = "1.3.132.0.6"; public static final String SN_secp112r2 = "secp112r2"; public static final short NID_secp112r2 = 705; public static final String OBJ_secp112r2 = "1.3.132.0.7"; public static final String SN_secp128r1 = "secp128r1"; public static final short NID_secp128r1 = 706; public static final String OBJ_secp128r1 = "1.3.132.0.28"; public static final String SN_secp128r2 = "secp128r2"; public static final short NID_secp128r2 = 707; public static final String OBJ_secp128r2 = "1.3.132.0.29"; public static final String SN_secp160k1 = "secp160k1"; public static final short NID_secp160k1 = 708; public static final String OBJ_secp160k1 = "1.3.132.0.9"; public static final String SN_secp160r1 = "secp160r1"; public static final short NID_secp160r1 = 709; public static final String OBJ_secp160r1 = "1.3.132.0.8"; public static final String SN_secp160r2 = "secp160r2"; public static final short NID_secp160r2 = 710; public static final String OBJ_secp160r2 = "1.3.132.0.30"; public static final String SN_secp192k1 = "secp192k1"; public static final short NID_secp192k1 = 711; public static final String OBJ_secp192k1 = "1.3.132.0.31"; public static final String SN_secp224k1 = "secp224k1"; public static final short NID_secp224k1 = 712; public static final String OBJ_secp224k1 = "1.3.132.0.32"; public static final String SN_secp224r1 = "secp224r1"; public static final short NID_secp224r1 = 713; public static final String OBJ_secp224r1 = "1.3.132.0.33"; public static final String SN_secp256k1 = "secp256k1"; public static final short NID_secp256k1 = 714; public static final String OBJ_secp256k1 = "1.3.132.0.10"; public static final String SN_secp384r1 = "secp384r1"; public static final short NID_secp384r1 = 715; public static final String OBJ_secp384r1 = "1.3.132.0.34"; public static final String SN_secp521r1 = "secp521r1"; public static final short NID_secp521r1 = 716; public static final String OBJ_secp521r1 = "1.3.132.0.35"; public static final String SN_sect113r1 = "sect113r1"; public static final short NID_sect113r1 = 717; public static final String OBJ_sect113r1 = "1.3.132.0.4"; public static final String SN_sect113r2 = "sect113r2"; public static final short NID_sect113r2 = 718; public static final String OBJ_sect113r2 = "1.3.132.0.5"; public static final String SN_sect131r1 = "sect131r1"; public static final short NID_sect131r1 = 719; public static final String OBJ_sect131r1 = "1.3.132.0.22"; public static final String SN_sect131r2 = "sect131r2"; public static final short NID_sect131r2 = 720; public static final String OBJ_sect131r2 = "1.3.132.0.23"; public static final String SN_sect163k1 = "sect163k1"; public static final short NID_sect163k1 = 721; public static final String OBJ_sect163k1 = "1.3.132.0.1"; public static final String SN_sect163r1 = "sect163r1"; public static final short NID_sect163r1 = 722; public static final String OBJ_sect163r1 = "1.3.132.0.2"; public static final String SN_sect163r2 = "sect163r2"; public static final short NID_sect163r2 = 723; public static final String OBJ_sect163r2 = "1.3.132.0.15"; public static final String SN_sect193r1 = "sect193r1"; public static final short NID_sect193r1 = 724; public static final String OBJ_sect193r1 = "1.3.132.0.24"; public static final String SN_sect193r2 = "sect193r2"; public static final short NID_sect193r2 = 725; public static final String OBJ_sect193r2 = "1.3.132.0.25"; public static final String SN_sect233k1 = "sect233k1"; public static final short NID_sect233k1 = 726; public static final String OBJ_sect233k1 = "1.3.132.0.26"; public static final String SN_sect233r1 = "sect233r1"; public static final short NID_sect233r1 = 727; public static final String OBJ_sect233r1 = "1.3.132.0.27"; public static final String SN_sect239k1 = "sect239k1"; public static final short NID_sect239k1 = 728; public static final String OBJ_sect239k1 = "1.3.132.0.3"; public static final String SN_sect283k1 = "sect283k1"; public static final short NID_sect283k1 = 729; public static final String OBJ_sect283k1 = "1.3.132.0.16"; public static final String SN_sect283r1 = "sect283r1"; public static final short NID_sect283r1 = 730; public static final String OBJ_sect283r1 = "1.3.132.0.17"; public static final String SN_sect409k1 = "sect409k1"; public static final short NID_sect409k1 = 731; public static final String OBJ_sect409k1 = "1.3.132.0.36"; public static final String SN_sect409r1 = "sect409r1"; public static final short NID_sect409r1 = 732; public static final String OBJ_sect409r1 = "1.3.132.0.37"; public static final String SN_sect571k1 = "sect571k1"; public static final short NID_sect571k1 = 733; public static final String OBJ_sect571k1 = "1.3.132.0.38"; public static final String SN_sect571r1 = "sect571r1"; public static final short NID_sect571r1 = 734; public static final String OBJ_sect571r1 = "1.3.132.0.39"; public static final String OBJ_wap_wsg_idm_ecid = "2.23.43.1.4"; public static final String SN_wap_wsg_idm_ecid_wtls1 = "wap-wsg-idm-ecid-wtls1"; public static final short NID_wap_wsg_idm_ecid_wtls1 = 735; public static final String OBJ_wap_wsg_idm_ecid_wtls1 = "2.23.43.1.4.1"; public static final String SN_wap_wsg_idm_ecid_wtls3 = "wap-wsg-idm-ecid-wtls3"; public static final short NID_wap_wsg_idm_ecid_wtls3 = 736; public static final String OBJ_wap_wsg_idm_ecid_wtls3 = "2.23.43.1.4.3"; public static final String SN_wap_wsg_idm_ecid_wtls4 = "wap-wsg-idm-ecid-wtls4"; public static final short NID_wap_wsg_idm_ecid_wtls4 = 737; public static final String OBJ_wap_wsg_idm_ecid_wtls4 = "2.23.43.1.4.4"; public static final String SN_wap_wsg_idm_ecid_wtls5 = "wap-wsg-idm-ecid-wtls5"; public static final short NID_wap_wsg_idm_ecid_wtls5 = 738; public static final String OBJ_wap_wsg_idm_ecid_wtls5 = "2.23.43.1.4.5"; public static final String SN_wap_wsg_idm_ecid_wtls6 = "wap-wsg-idm-ecid-wtls6"; public static final short NID_wap_wsg_idm_ecid_wtls6 = 739; public static final String OBJ_wap_wsg_idm_ecid_wtls6 = "2.23.43.1.4.6"; public static final String SN_wap_wsg_idm_ecid_wtls7 = "wap-wsg-idm-ecid-wtls7"; public static final short NID_wap_wsg_idm_ecid_wtls7 = 740; public static final String OBJ_wap_wsg_idm_ecid_wtls7 = "2.23.43.1.4.7"; public static final String SN_wap_wsg_idm_ecid_wtls8 = "wap-wsg-idm-ecid-wtls8"; public static final short NID_wap_wsg_idm_ecid_wtls8 = 741; public static final String OBJ_wap_wsg_idm_ecid_wtls8 = "2.23.43.1.4.8"; public static final String SN_wap_wsg_idm_ecid_wtls9 = "wap-wsg-idm-ecid-wtls9"; public static final short NID_wap_wsg_idm_ecid_wtls9 = 742; public static final String OBJ_wap_wsg_idm_ecid_wtls9 = "2.23.43.1.4.9"; public static final String SN_wap_wsg_idm_ecid_wtls10 = "wap-wsg-idm-ecid-wtls10"; public static final short NID_wap_wsg_idm_ecid_wtls10 = 743; public static final String OBJ_wap_wsg_idm_ecid_wtls10 = "2.23.43.1.4.10"; public static final String SN_wap_wsg_idm_ecid_wtls11 = "wap-wsg-idm-ecid-wtls11"; public static final short NID_wap_wsg_idm_ecid_wtls11 = 744; public static final String OBJ_wap_wsg_idm_ecid_wtls11 = "2.23.43.1.4.11"; public static final String SN_wap_wsg_idm_ecid_wtls12 = "wap-wsg-idm-ecid-wtls12"; public static final short NID_wap_wsg_idm_ecid_wtls12 = 745; public static final String OBJ_wap_wsg_idm_ecid_wtls12 = "2.23.43.1.4.12"; public static final String SN_cast5_cbc = "CAST5-CBC"; public static final String LN_cast5_cbc = "cast5-cbc"; public static final short NID_cast5_cbc = 108; public static final String OBJ_cast5_cbc = "1.2.840.113533.7.66.10"; public static final String SN_cast5_ecb = "CAST5-ECB"; public static final String LN_cast5_ecb = "cast5-ecb"; public static final short NID_cast5_ecb = 109; public static final String SN_cast5_cfb64 = "CAST5-CFB"; public static final String LN_cast5_cfb64 = "cast5-cfb"; public static final short NID_cast5_cfb64 = 110; public static final String SN_cast5_ofb64 = "CAST5-OFB"; public static final String LN_cast5_ofb64 = "cast5-ofb"; public static final short NID_cast5_ofb64 = 111; public static final String LN_pbeWithMD5AndCast5_CBC = "pbeWithMD5AndCast5CBC"; public static final short NID_pbeWithMD5AndCast5_CBC = 112; public static final String OBJ_pbeWithMD5AndCast5_CBC = "1.2.840.113533.7.66.12"; public static final String SN_id_PasswordBasedMAC = "id-PasswordBasedMAC"; public static final String LN_id_PasswordBasedMAC = "password based MAC"; public static final short NID_id_PasswordBasedMAC = 782; public static final String OBJ_id_PasswordBasedMAC = "1.2.840.113533.7.66.13"; public static final String SN_id_DHBasedMac = "id-DHBasedMac"; public static final String LN_id_DHBasedMac = "Diffie-Hellman based MAC"; public static final short NID_id_DHBasedMac = 783; public static final String OBJ_id_DHBasedMac = "1.2.840.113533.7.66.30"; public static final String SN_rsadsi = "rsadsi"; public static final String LN_rsadsi = "RSA Data Security, Inc."; public static final short NID_rsadsi = 1; public static final String OBJ_rsadsi = "1.2.840.113549"; public static final String SN_pkcs = "pkcs"; public static final String LN_pkcs = "RSA Data Security, Inc. PKCS"; public static final short NID_pkcs = 2; public static final String OBJ_pkcs = "1.2.840.113549.1"; public static final String SN_pkcs1 = "pkcs1"; public static final short NID_pkcs1 = 186; public static final String OBJ_pkcs1 = "1.2.840.113549.1.1"; public static final String LN_rsaEncryption = "rsaEncryption"; public static final short NID_rsaEncryption = 6; public static final String OBJ_rsaEncryption = "1.2.840.113549.1.1.1"; public static final String SN_md2WithRSAEncryption = "RSA-MD2"; public static final String LN_md2WithRSAEncryption = "md2WithRSAEncryption"; public static final short NID_md2WithRSAEncryption = 7; public static final String OBJ_md2WithRSAEncryption = "1.2.840.113549.1.1.2"; public static final String SN_md4WithRSAEncryption = "RSA-MD4"; public static final String LN_md4WithRSAEncryption = "md4WithRSAEncryption"; public static final short NID_md4WithRSAEncryption = 396; public static final String OBJ_md4WithRSAEncryption = "1.2.840.113549.1.1.3"; public static final String SN_md5WithRSAEncryption = "RSA-MD5"; public static final String LN_md5WithRSAEncryption = "md5WithRSAEncryption"; public static final short NID_md5WithRSAEncryption = 8; public static final String OBJ_md5WithRSAEncryption = "1.2.840.113549.1.1.4"; public static final String SN_sha1WithRSAEncryption = "RSA-SHA1"; public static final String LN_sha1WithRSAEncryption = "sha1WithRSAEncryption"; public static final short NID_sha1WithRSAEncryption = 65; public static final String OBJ_sha1WithRSAEncryption = "1.2.840.113549.1.1.5"; public static final String SN_rsaesOaep = "RSAES-OAEP"; public static final String LN_rsaesOaep = "rsaesOaep"; public static final short NID_rsaesOaep = 919; public static final String OBJ_rsaesOaep = "1.2.840.113549.1.1.7"; public static final String SN_mgf1 = "MGF1"; public static final String LN_mgf1 = "mgf1"; public static final short NID_mgf1 = 911; public static final String OBJ_mgf1 = "1.2.840.113549.1.1.8"; public static final String SN_pSpecified = "PSPECIFIED"; public static final String LN_pSpecified = "pSpecified"; public static final short NID_pSpecified = 935; public static final String OBJ_pSpecified = "1.2.840.113549.1.1.9"; public static final String SN_rsassaPss = "RSASSA-PSS"; public static final String LN_rsassaPss = "rsassaPss"; public static final short NID_rsassaPss = 912; public static final String OBJ_rsassaPss = "1.2.840.113549.1.1.10"; public static final String SN_sha256WithRSAEncryption = "RSA-SHA256"; public static final String LN_sha256WithRSAEncryption = "sha256WithRSAEncryption"; public static final short NID_sha256WithRSAEncryption = 668; public static final String OBJ_sha256WithRSAEncryption = "1.2.840.113549.1.1.11"; public static final String SN_sha384WithRSAEncryption = "RSA-SHA384"; public static final String LN_sha384WithRSAEncryption = "sha384WithRSAEncryption"; public static final short NID_sha384WithRSAEncryption = 669; public static final String OBJ_sha384WithRSAEncryption = "1.2.840.113549.1.1.12"; public static final String SN_sha512WithRSAEncryption = "RSA-SHA512"; public static final String LN_sha512WithRSAEncryption = "sha512WithRSAEncryption"; public static final short NID_sha512WithRSAEncryption = 670; public static final String OBJ_sha512WithRSAEncryption = "1.2.840.113549.1.1.13"; public static final String SN_sha224WithRSAEncryption = "RSA-SHA224"; public static final String LN_sha224WithRSAEncryption = "sha224WithRSAEncryption"; public static final short NID_sha224WithRSAEncryption = 671; public static final String OBJ_sha224WithRSAEncryption = "1.2.840.113549.1.1.14"; public static final String SN_pkcs3 = "pkcs3"; public static final short NID_pkcs3 = 27; public static final String OBJ_pkcs3 = "1.2.840.113549.1.3"; public static final String LN_dhKeyAgreement = "dhKeyAgreement"; public static final short NID_dhKeyAgreement = 28; public static final String OBJ_dhKeyAgreement = "1.2.840.113549.1.3.1"; public static final String SN_pkcs5 = "pkcs5"; public static final short NID_pkcs5 = 187; public static final String OBJ_pkcs5 = "1.2.840.113549.1.5"; public static final String SN_pbeWithMD2AndDES_CBC = "PBE-MD2-DES"; public static final String LN_pbeWithMD2AndDES_CBC = "pbeWithMD2AndDES-CBC"; public static final short NID_pbeWithMD2AndDES_CBC = 9; public static final String OBJ_pbeWithMD2AndDES_CBC = "1.2.840.113549.1.5.1"; public static final String SN_pbeWithMD5AndDES_CBC = "PBE-MD5-DES"; public static final String LN_pbeWithMD5AndDES_CBC = "pbeWithMD5AndDES-CBC"; public static final short NID_pbeWithMD5AndDES_CBC = 10; public static final String OBJ_pbeWithMD5AndDES_CBC = "1.2.840.113549.1.5.3"; public static final String SN_pbeWithMD2AndRC2_CBC = "PBE-MD2-RC2-64"; public static final String LN_pbeWithMD2AndRC2_CBC = "pbeWithMD2AndRC2-CBC"; public static final short NID_pbeWithMD2AndRC2_CBC = 168; public static final String OBJ_pbeWithMD2AndRC2_CBC = "1.2.840.113549.1.5.4"; public static final String SN_pbeWithMD5AndRC2_CBC = "PBE-MD5-RC2-64"; public static final String LN_pbeWithMD5AndRC2_CBC = "pbeWithMD5AndRC2-CBC"; public static final short NID_pbeWithMD5AndRC2_CBC = 169; public static final String OBJ_pbeWithMD5AndRC2_CBC = "1.2.840.113549.1.5.6"; public static final String SN_pbeWithSHA1AndDES_CBC = "PBE-SHA1-DES"; public static final String LN_pbeWithSHA1AndDES_CBC = "pbeWithSHA1AndDES-CBC"; public static final short NID_pbeWithSHA1AndDES_CBC = 170; public static final String OBJ_pbeWithSHA1AndDES_CBC = "1.2.840.113549.1.5.10"; public static final String SN_pbeWithSHA1AndRC2_CBC = "PBE-SHA1-RC2-64"; public static final String LN_pbeWithSHA1AndRC2_CBC = "pbeWithSHA1AndRC2-CBC"; public static final short NID_pbeWithSHA1AndRC2_CBC = 68; public static final String OBJ_pbeWithSHA1AndRC2_CBC = "1.2.840.113549.1.5.11"; public static final String LN_id_pbkdf2 = "PBKDF2"; public static final short NID_id_pbkdf2 = 69; public static final String OBJ_id_pbkdf2 = "1.2.840.113549.1.5.12"; public static final String LN_pbes2 = "PBES2"; public static final short NID_pbes2 = 161; public static final String OBJ_pbes2 = "1.2.840.113549.1.5.13"; public static final String LN_pbmac1 = "PBMAC1"; public static final short NID_pbmac1 = 162; public static final String OBJ_pbmac1 = "1.2.840.113549.1.5.14"; public static final String SN_pkcs7 = "pkcs7"; public static final short NID_pkcs7 = 20; public static final String OBJ_pkcs7 = "1.2.840.113549.1.7"; public static final String LN_pkcs7_data = "pkcs7-data"; public static final short NID_pkcs7_data = 21; public static final String OBJ_pkcs7_data = "1.2.840.113549.1.7.1"; public static final String LN_pkcs7_signed = "pkcs7-signedData"; public static final short NID_pkcs7_signed = 22; public static final String OBJ_pkcs7_signed = "1.2.840.113549.1.7.2"; public static final String LN_pkcs7_enveloped = "pkcs7-envelopedData"; public static final short NID_pkcs7_enveloped = 23; public static final String OBJ_pkcs7_enveloped = "1.2.840.113549.1.7.3"; public static final String LN_pkcs7_signedAndEnveloped = "pkcs7-signedAndEnvelopedData"; public static final short NID_pkcs7_signedAndEnveloped = 24; public static final String OBJ_pkcs7_signedAndEnveloped = "1.2.840.113549.1.7.4"; public static final String LN_pkcs7_digest = "pkcs7-digestData"; public static final short NID_pkcs7_digest = 25; public static final String OBJ_pkcs7_digest = "1.2.840.113549.1.7.5"; public static final String LN_pkcs7_encrypted = "pkcs7-encryptedData"; public static final short NID_pkcs7_encrypted = 26; public static final String OBJ_pkcs7_encrypted = "1.2.840.113549.1.7.6"; public static final String SN_pkcs9 = "pkcs9"; public static final short NID_pkcs9 = 47; public static final String OBJ_pkcs9 = "1.2.840.113549.1.9"; public static final String LN_pkcs9_emailAddress = "emailAddress"; public static final short NID_pkcs9_emailAddress = 48; public static final String OBJ_pkcs9_emailAddress = "1.2.840.113549.1.9.1"; public static final String LN_pkcs9_unstructuredName = "unstructuredName"; public static final short NID_pkcs9_unstructuredName = 49; public static final String OBJ_pkcs9_unstructuredName = "1.2.840.113549.1.9.2"; public static final String LN_pkcs9_contentType = "contentType"; public static final short NID_pkcs9_contentType = 50; public static final String OBJ_pkcs9_contentType = "1.2.840.113549.1.9.3"; public static final String LN_pkcs9_messageDigest = "messageDigest"; public static final short NID_pkcs9_messageDigest = 51; public static final String OBJ_pkcs9_messageDigest = "1.2.840.113549.1.9.4"; public static final String LN_pkcs9_signingTime = "signingTime"; public static final short NID_pkcs9_signingTime = 52; public static final String OBJ_pkcs9_signingTime = "1.2.840.113549.1.9.5"; public static final String LN_pkcs9_countersignature = "countersignature"; public static final short NID_pkcs9_countersignature = 53; public static final String OBJ_pkcs9_countersignature = "1.2.840.113549.1.9.6"; public static final String LN_pkcs9_challengePassword = "challengePassword"; public static final short NID_pkcs9_challengePassword = 54; public static final String OBJ_pkcs9_challengePassword = "1.2.840.113549.1.9.7"; public static final String LN_pkcs9_unstructuredAddress = "unstructuredAddress"; public static final short NID_pkcs9_unstructuredAddress = 55; public static final String OBJ_pkcs9_unstructuredAddress = "1.2.840.113549.1.9.8"; public static final String LN_pkcs9_extCertAttributes = "extendedCertificateAttributes"; public static final short NID_pkcs9_extCertAttributes = 56; public static final String OBJ_pkcs9_extCertAttributes = "1.2.840.113549.1.9.9"; public static final String SN_ext_req = "extReq"; public static final String LN_ext_req = "Extension Request"; public static final short NID_ext_req = 172; public static final String OBJ_ext_req = "1.2.840.113549.1.9.14"; public static final String SN_SMIMECapabilities = "SMIME-CAPS"; public static final String LN_SMIMECapabilities = "S/MIME Capabilities"; public static final short NID_SMIMECapabilities = 167; public static final String OBJ_SMIMECapabilities = "1.2.840.113549.1.9.15"; public static final String SN_SMIME = "SMIME"; public static final String LN_SMIME = "S/MIME"; public static final short NID_SMIME = 188; public static final String OBJ_SMIME = "1.2.840.113549.1.9.16"; public static final String SN_id_smime_mod = "id-smime-mod"; public static final short NID_id_smime_mod = 189; public static final String OBJ_id_smime_mod = "1.2.840.113549.1.9.16.0"; public static final String SN_id_smime_ct = "id-smime-ct"; public static final short NID_id_smime_ct = 190; public static final String OBJ_id_smime_ct = "1.2.840.113549.1.9.16.1"; public static final String SN_id_smime_aa = "id-smime-aa"; public static final short NID_id_smime_aa = 191; public static final String OBJ_id_smime_aa = "1.2.840.113549.1.9.16.2"; public static final String SN_id_smime_alg = "id-smime-alg"; public static final short NID_id_smime_alg = 192; public static final String OBJ_id_smime_alg = "1.2.840.113549.1.9.16.3"; public static final String SN_id_smime_cd = "id-smime-cd"; public static final short NID_id_smime_cd = 193; public static final String OBJ_id_smime_cd = "1.2.840.113549.1.9.16.4"; public static final String SN_id_smime_spq = "id-smime-spq"; public static final short NID_id_smime_spq = 194; public static final String OBJ_id_smime_spq = "1.2.840.113549.1.9.16.5"; public static final String SN_id_smime_cti = "id-smime-cti"; public static final short NID_id_smime_cti = 195; public static final String OBJ_id_smime_cti = "1.2.840.113549.1.9.16.6"; public static final String SN_id_smime_mod_cms = "id-smime-mod-cms"; public static final short NID_id_smime_mod_cms = 196; public static final String OBJ_id_smime_mod_cms = "1.2.840.113549.1.9.16.0.1"; public static final String SN_id_smime_mod_ess = "id-smime-mod-ess"; public static final short NID_id_smime_mod_ess = 197; public static final String OBJ_id_smime_mod_ess = "1.2.840.113549.1.9.16.0.2"; public static final String SN_id_smime_mod_oid = "id-smime-mod-oid"; public static final short NID_id_smime_mod_oid = 198; public static final String OBJ_id_smime_mod_oid = "1.2.840.113549.1.9.16.0.3"; public static final String SN_id_smime_mod_msg_v3 = "id-smime-mod-msg-v3"; public static final short NID_id_smime_mod_msg_v3 = 199; public static final String OBJ_id_smime_mod_msg_v3 = "1.2.840.113549.1.9.16.0.4"; public static final String SN_id_smime_mod_ets_eSignature_88 = "id-smime-mod-ets-eSignature-88"; public static final short NID_id_smime_mod_ets_eSignature_88 = 200; public static final String OBJ_id_smime_mod_ets_eSignature_88 = "1.2.840.113549.1.9.16.0.5"; public static final String SN_id_smime_mod_ets_eSignature_97 = "id-smime-mod-ets-eSignature-97"; public static final short NID_id_smime_mod_ets_eSignature_97 = 201; public static final String OBJ_id_smime_mod_ets_eSignature_97 = "1.2.840.113549.1.9.16.0.6"; public static final String SN_id_smime_mod_ets_eSigPolicy_88 = "id-smime-mod-ets-eSigPolicy-88"; public static final short NID_id_smime_mod_ets_eSigPolicy_88 = 202; public static final String OBJ_id_smime_mod_ets_eSigPolicy_88 = "1.2.840.113549.1.9.16.0.7"; public static final String SN_id_smime_mod_ets_eSigPolicy_97 = "id-smime-mod-ets-eSigPolicy-97"; public static final short NID_id_smime_mod_ets_eSigPolicy_97 = 203; public static final String OBJ_id_smime_mod_ets_eSigPolicy_97 = "1.2.840.113549.1.9.16.0.8"; public static final String SN_id_smime_ct_receipt = "id-smime-ct-receipt"; public static final short NID_id_smime_ct_receipt = 204; public static final String OBJ_id_smime_ct_receipt = "1.2.840.113549.1.9.16.1.1"; public static final String SN_id_smime_ct_authData = "id-smime-ct-authData"; public static final short NID_id_smime_ct_authData = 205; public static final String OBJ_id_smime_ct_authData = "1.2.840.113549.1.9.16.1.2"; public static final String SN_id_smime_ct_publishCert = "id-smime-ct-publishCert"; public static final short NID_id_smime_ct_publishCert = 206; public static final String OBJ_id_smime_ct_publishCert = "1.2.840.113549.1.9.16.1.3"; public static final String SN_id_smime_ct_TSTInfo = "id-smime-ct-TSTInfo"; public static final short NID_id_smime_ct_TSTInfo = 207; public static final String OBJ_id_smime_ct_TSTInfo = "1.2.840.113549.1.9.16.1.4"; public static final String SN_id_smime_ct_TDTInfo = "id-smime-ct-TDTInfo"; public static final short NID_id_smime_ct_TDTInfo = 208; public static final String OBJ_id_smime_ct_TDTInfo = "1.2.840.113549.1.9.16.1.5"; public static final String SN_id_smime_ct_contentInfo = "id-smime-ct-contentInfo"; public static final short NID_id_smime_ct_contentInfo = 209; public static final String OBJ_id_smime_ct_contentInfo = "1.2.840.113549.1.9.16.1.6"; public static final String SN_id_smime_ct_DVCSRequestData = "id-smime-ct-DVCSRequestData"; public static final short NID_id_smime_ct_DVCSRequestData = 210; public static final String OBJ_id_smime_ct_DVCSRequestData = "1.2.840.113549.1.9.16.1.7"; public static final String SN_id_smime_ct_DVCSResponseData = "id-smime-ct-DVCSResponseData"; public static final short NID_id_smime_ct_DVCSResponseData = 211; public static final String OBJ_id_smime_ct_DVCSResponseData = "1.2.840.113549.1.9.16.1.8"; public static final String SN_id_smime_ct_compressedData = "id-smime-ct-compressedData"; public static final short NID_id_smime_ct_compressedData = 786; public static final String OBJ_id_smime_ct_compressedData = "1.2.840.113549.1.9.16.1.9"; public static final String SN_id_ct_asciiTextWithCRLF = "id-ct-asciiTextWithCRLF"; public static final short NID_id_ct_asciiTextWithCRLF = 787; public static final String OBJ_id_ct_asciiTextWithCRLF = "1.2.840.113549.1.9.16.1.27"; public static final String SN_id_smime_aa_receiptRequest = "id-smime-aa-receiptRequest"; public static final short NID_id_smime_aa_receiptRequest = 212; public static final String OBJ_id_smime_aa_receiptRequest = "1.2.840.113549.1.9.16.2.1"; public static final String SN_id_smime_aa_securityLabel = "id-smime-aa-securityLabel"; public static final short NID_id_smime_aa_securityLabel = 213; public static final String OBJ_id_smime_aa_securityLabel = "1.2.840.113549.1.9.16.2.2"; public static final String SN_id_smime_aa_mlExpandHistory = "id-smime-aa-mlExpandHistory"; public static final short NID_id_smime_aa_mlExpandHistory = 214; public static final String OBJ_id_smime_aa_mlExpandHistory = "1.2.840.113549.1.9.16.2.3"; public static final String SN_id_smime_aa_contentHint = "id-smime-aa-contentHint"; public static final short NID_id_smime_aa_contentHint = 215; public static final String OBJ_id_smime_aa_contentHint = "1.2.840.113549.1.9.16.2.4"; public static final String SN_id_smime_aa_msgSigDigest = "id-smime-aa-msgSigDigest"; public static final short NID_id_smime_aa_msgSigDigest = 216; public static final String OBJ_id_smime_aa_msgSigDigest = "1.2.840.113549.1.9.16.2.5"; public static final String SN_id_smime_aa_encapContentType = "id-smime-aa-encapContentType"; public static final short NID_id_smime_aa_encapContentType = 217; public static final String OBJ_id_smime_aa_encapContentType = "1.2.840.113549.1.9.16.2.6"; public static final String SN_id_smime_aa_contentIdentifier = "id-smime-aa-contentIdentifier"; public static final short NID_id_smime_aa_contentIdentifier = 218; public static final String OBJ_id_smime_aa_contentIdentifier = "1.2.840.113549.1.9.16.2.7"; public static final String SN_id_smime_aa_macValue = "id-smime-aa-macValue"; public static final short NID_id_smime_aa_macValue = 219; public static final String OBJ_id_smime_aa_macValue = "1.2.840.113549.1.9.16.2.8"; public static final String SN_id_smime_aa_equivalentLabels = "id-smime-aa-equivalentLabels"; public static final short NID_id_smime_aa_equivalentLabels = 220; public static final String OBJ_id_smime_aa_equivalentLabels = "1.2.840.113549.1.9.16.2.9"; public static final String SN_id_smime_aa_contentReference = "id-smime-aa-contentReference"; public static final short NID_id_smime_aa_contentReference = 221; public static final String OBJ_id_smime_aa_contentReference = "1.2.840.113549.1.9.16.2.10"; public static final String SN_id_smime_aa_encrypKeyPref = "id-smime-aa-encrypKeyPref"; public static final short NID_id_smime_aa_encrypKeyPref = 222; public static final String OBJ_id_smime_aa_encrypKeyPref = "1.2.840.113549.1.9.16.2.11"; public static final String SN_id_smime_aa_signingCertificate = "id-smime-aa-signingCertificate"; public static final short NID_id_smime_aa_signingCertificate = 223; public static final String OBJ_id_smime_aa_signingCertificate = "1.2.840.113549.1.9.16.2.12"; public static final String SN_id_smime_aa_smimeEncryptCerts = "id-smime-aa-smimeEncryptCerts"; public static final short NID_id_smime_aa_smimeEncryptCerts = 224; public static final String OBJ_id_smime_aa_smimeEncryptCerts = "1.2.840.113549.1.9.16.2.13"; public static final String SN_id_smime_aa_timeStampToken = "id-smime-aa-timeStampToken"; public static final short NID_id_smime_aa_timeStampToken = 225; public static final String OBJ_id_smime_aa_timeStampToken = "1.2.840.113549.1.9.16.2.14"; public static final String SN_id_smime_aa_ets_sigPolicyId = "id-smime-aa-ets-sigPolicyId"; public static final short NID_id_smime_aa_ets_sigPolicyId = 226; public static final String OBJ_id_smime_aa_ets_sigPolicyId = "1.2.840.113549.1.9.16.2.15"; public static final String SN_id_smime_aa_ets_commitmentType = "id-smime-aa-ets-commitmentType"; public static final short NID_id_smime_aa_ets_commitmentType = 227; public static final String OBJ_id_smime_aa_ets_commitmentType = "1.2.840.113549.1.9.16.2.16"; public static final String SN_id_smime_aa_ets_signerLocation = "id-smime-aa-ets-signerLocation"; public static final short NID_id_smime_aa_ets_signerLocation = 228; public static final String OBJ_id_smime_aa_ets_signerLocation = "1.2.840.113549.1.9.16.2.17"; public static final String SN_id_smime_aa_ets_signerAttr = "id-smime-aa-ets-signerAttr"; public static final short NID_id_smime_aa_ets_signerAttr = 229; public static final String OBJ_id_smime_aa_ets_signerAttr = "1.2.840.113549.1.9.16.2.18"; public static final String SN_id_smime_aa_ets_otherSigCert = "id-smime-aa-ets-otherSigCert"; public static final short NID_id_smime_aa_ets_otherSigCert = 230; public static final String OBJ_id_smime_aa_ets_otherSigCert = "1.2.840.113549.1.9.16.2.19"; public static final String SN_id_smime_aa_ets_contentTimestamp = "id-smime-aa-ets-contentTimestamp"; public static final short NID_id_smime_aa_ets_contentTimestamp = 231; public static final String OBJ_id_smime_aa_ets_contentTimestamp = "1.2.840.113549.1.9.16.2.20"; public static final String SN_id_smime_aa_ets_CertificateRefs = "id-smime-aa-ets-CertificateRefs"; public static final short NID_id_smime_aa_ets_CertificateRefs = 232; public static final String OBJ_id_smime_aa_ets_CertificateRefs = "1.2.840.113549.1.9.16.2.21"; public static final String SN_id_smime_aa_ets_RevocationRefs = "id-smime-aa-ets-RevocationRefs"; public static final short NID_id_smime_aa_ets_RevocationRefs = 233; public static final String OBJ_id_smime_aa_ets_RevocationRefs = "1.2.840.113549.1.9.16.2.22"; public static final String SN_id_smime_aa_ets_certValues = "id-smime-aa-ets-certValues"; public static final short NID_id_smime_aa_ets_certValues = 234; public static final String OBJ_id_smime_aa_ets_certValues = "1.2.840.113549.1.9.16.2.23"; public static final String SN_id_smime_aa_ets_revocationValues = "id-smime-aa-ets-revocationValues"; public static final short NID_id_smime_aa_ets_revocationValues = 235; public static final String OBJ_id_smime_aa_ets_revocationValues = "1.2.840.113549.1.9.16.2.24"; public static final String SN_id_smime_aa_ets_escTimeStamp = "id-smime-aa-ets-escTimeStamp"; public static final short NID_id_smime_aa_ets_escTimeStamp = 236; public static final String OBJ_id_smime_aa_ets_escTimeStamp = "1.2.840.113549.1.9.16.2.25"; public static final String SN_id_smime_aa_ets_certCRLTimestamp = "id-smime-aa-ets-certCRLTimestamp"; public static final short NID_id_smime_aa_ets_certCRLTimestamp = 237; public static final String OBJ_id_smime_aa_ets_certCRLTimestamp = "1.2.840.113549.1.9.16.2.26"; public static final String SN_id_smime_aa_ets_archiveTimeStamp = "id-smime-aa-ets-archiveTimeStamp"; public static final short NID_id_smime_aa_ets_archiveTimeStamp = 238; public static final String OBJ_id_smime_aa_ets_archiveTimeStamp = "1.2.840.113549.1.9.16.2.27"; public static final String SN_id_smime_aa_signatureType = "id-smime-aa-signatureType"; public static final short NID_id_smime_aa_signatureType = 239; public static final String OBJ_id_smime_aa_signatureType = "1.2.840.113549.1.9.16.2.28"; public static final String SN_id_smime_aa_dvcs_dvc = "id-smime-aa-dvcs-dvc"; public static final short NID_id_smime_aa_dvcs_dvc = 240; public static final String OBJ_id_smime_aa_dvcs_dvc = "1.2.840.113549.1.9.16.2.29"; public static final String SN_id_smime_alg_ESDHwith3DES = "id-smime-alg-ESDHwith3DES"; public static final short NID_id_smime_alg_ESDHwith3DES = 241; public static final String OBJ_id_smime_alg_ESDHwith3DES = "1.2.840.113549.1.9.16.3.1"; public static final String SN_id_smime_alg_ESDHwithRC2 = "id-smime-alg-ESDHwithRC2"; public static final short NID_id_smime_alg_ESDHwithRC2 = 242; public static final String OBJ_id_smime_alg_ESDHwithRC2 = "1.2.840.113549.1.9.16.3.2"; public static final String SN_id_smime_alg_3DESwrap = "id-smime-alg-3DESwrap"; public static final short NID_id_smime_alg_3DESwrap = 243; public static final String OBJ_id_smime_alg_3DESwrap = "1.2.840.113549.1.9.16.3.3"; public static final String SN_id_smime_alg_RC2wrap = "id-smime-alg-RC2wrap"; public static final short NID_id_smime_alg_RC2wrap = 244; public static final String OBJ_id_smime_alg_RC2wrap = "1.2.840.113549.1.9.16.3.4"; public static final String SN_id_smime_alg_ESDH = "id-smime-alg-ESDH"; public static final short NID_id_smime_alg_ESDH = 245; public static final String OBJ_id_smime_alg_ESDH = "1.2.840.113549.1.9.16.3.5"; public static final String SN_id_smime_alg_CMS3DESwrap = "id-smime-alg-CMS3DESwrap"; public static final short NID_id_smime_alg_CMS3DESwrap = 246; public static final String OBJ_id_smime_alg_CMS3DESwrap = "1.2.840.113549.1.9.16.3.6"; public static final String SN_id_smime_alg_CMSRC2wrap = "id-smime-alg-CMSRC2wrap"; public static final short NID_id_smime_alg_CMSRC2wrap = 247; public static final String OBJ_id_smime_alg_CMSRC2wrap = "1.2.840.113549.1.9.16.3.7"; public static final String SN_id_alg_PWRI_KEK = "id-alg-PWRI-KEK"; public static final short NID_id_alg_PWRI_KEK = 893; public static final String OBJ_id_alg_PWRI_KEK = "1.2.840.113549.1.9.16.3.9"; public static final String SN_id_smime_cd_ldap = "id-smime-cd-ldap"; public static final short NID_id_smime_cd_ldap = 248; public static final String OBJ_id_smime_cd_ldap = "1.2.840.113549.1.9.16.4.1"; public static final String SN_id_smime_spq_ets_sqt_uri = "id-smime-spq-ets-sqt-uri"; public static final short NID_id_smime_spq_ets_sqt_uri = 249; public static final String OBJ_id_smime_spq_ets_sqt_uri = "1.2.840.113549.1.9.16.5.1"; public static final String SN_id_smime_spq_ets_sqt_unotice = "id-smime-spq-ets-sqt-unotice"; public static final short NID_id_smime_spq_ets_sqt_unotice = 250; public static final String OBJ_id_smime_spq_ets_sqt_unotice = "1.2.840.113549.1.9.16.5.2"; public static final String SN_id_smime_cti_ets_proofOfOrigin = "id-smime-cti-ets-proofOfOrigin"; public static final short NID_id_smime_cti_ets_proofOfOrigin = 251; public static final String OBJ_id_smime_cti_ets_proofOfOrigin = "1.2.840.113549.1.9.16.6.1"; public static final String SN_id_smime_cti_ets_proofOfReceipt = "id-smime-cti-ets-proofOfReceipt"; public static final short NID_id_smime_cti_ets_proofOfReceipt = 252; public static final String OBJ_id_smime_cti_ets_proofOfReceipt = "1.2.840.113549.1.9.16.6.2"; public static final String SN_id_smime_cti_ets_proofOfDelivery = "id-smime-cti-ets-proofOfDelivery"; public static final short NID_id_smime_cti_ets_proofOfDelivery = 253; public static final String OBJ_id_smime_cti_ets_proofOfDelivery = "1.2.840.113549.1.9.16.6.3"; public static final String SN_id_smime_cti_ets_proofOfSender = "id-smime-cti-ets-proofOfSender"; public static final short NID_id_smime_cti_ets_proofOfSender = 254; public static final String OBJ_id_smime_cti_ets_proofOfSender = "1.2.840.113549.1.9.16.6.4"; public static final String SN_id_smime_cti_ets_proofOfApproval = "id-smime-cti-ets-proofOfApproval"; public static final short NID_id_smime_cti_ets_proofOfApproval = 255; public static final String OBJ_id_smime_cti_ets_proofOfApproval = "1.2.840.113549.1.9.16.6.5"; public static final String SN_id_smime_cti_ets_proofOfCreation = "id-smime-cti-ets-proofOfCreation"; public static final short NID_id_smime_cti_ets_proofOfCreation = 256; public static final String OBJ_id_smime_cti_ets_proofOfCreation = "1.2.840.113549.1.9.16.6.6"; public static final String LN_friendlyName = "friendlyName"; public static final short NID_friendlyName = 156; public static final String OBJ_friendlyName = "1.2.840.113549.1.9.20"; public static final String LN_localKeyID = "localKeyID"; public static final short NID_localKeyID = 157; public static final String OBJ_localKeyID = "1.2.840.113549.1.9.21"; public static final String SN_ms_csp_name = "CSPName"; public static final String LN_ms_csp_name = "Microsoft CSP Name"; public static final short NID_ms_csp_name = 417; public static final String OBJ_ms_csp_name = "1.3.6.1.4.1.311.17.1"; public static final String SN_LocalKeySet = "LocalKeySet"; public static final String LN_LocalKeySet = "Microsoft Local Key set"; public static final short NID_LocalKeySet = 856; public static final String OBJ_LocalKeySet = "1.3.6.1.4.1.311.17.2"; public static final String OBJ_certTypes = "1.2.840.113549.1.9.22"; public static final String LN_x509Certificate = "x509Certificate"; public static final short NID_x509Certificate = 158; public static final String OBJ_x509Certificate = "1.2.840.113549.1.9.22.1"; public static final String LN_sdsiCertificate = "sdsiCertificate"; public static final short NID_sdsiCertificate = 159; public static final String OBJ_sdsiCertificate = "1.2.840.113549.1.9.22.2"; public static final String OBJ_crlTypes = "1.2.840.113549.1.9.23"; public static final String LN_x509Crl = "x509Crl"; public static final short NID_x509Crl = 160; public static final String OBJ_x509Crl = "1.2.840.113549.1.9.23.1"; public static final String OBJ_pkcs12 = "1.2.840.113549.1.12"; public static final String OBJ_pkcs12_pbeids = "1.2.840.113549.1.12.1"; public static final String SN_pbe_WithSHA1And128BitRC4 = "PBE-SHA1-RC4-128"; public static final String LN_pbe_WithSHA1And128BitRC4 = "pbeWithSHA1And128BitRC4"; public static final short NID_pbe_WithSHA1And128BitRC4 = 144; public static final String OBJ_pbe_WithSHA1And128BitRC4 = "1.2.840.113549.1.12.1.1"; public static final String SN_pbe_WithSHA1And40BitRC4 = "PBE-SHA1-RC4-40"; public static final String LN_pbe_WithSHA1And40BitRC4 = "pbeWithSHA1And40BitRC4"; public static final short NID_pbe_WithSHA1And40BitRC4 = 145; public static final String OBJ_pbe_WithSHA1And40BitRC4 = "1.2.840.113549.1.12.1.2"; public static final String SN_pbe_WithSHA1And3_Key_TripleDES_CBC = "PBE-SHA1-3DES"; public static final String LN_pbe_WithSHA1And3_Key_TripleDES_CBC = "pbeWithSHA1And3-KeyTripleDES-CBC"; public static final short NID_pbe_WithSHA1And3_Key_TripleDES_CBC = 146; public static final String OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC = "1.2.840.113549.1.12.1.3"; public static final String SN_pbe_WithSHA1And2_Key_TripleDES_CBC = "PBE-SHA1-2DES"; public static final String LN_pbe_WithSHA1And2_Key_TripleDES_CBC = "pbeWithSHA1And2-KeyTripleDES-CBC"; public static final short NID_pbe_WithSHA1And2_Key_TripleDES_CBC = 147; public static final String OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC = "1.2.840.113549.1.12.1.4"; public static final String SN_pbe_WithSHA1And128BitRC2_CBC = "PBE-SHA1-RC2-128"; public static final String LN_pbe_WithSHA1And128BitRC2_CBC = "pbeWithSHA1And128BitRC2-CBC"; public static final short NID_pbe_WithSHA1And128BitRC2_CBC = 148; public static final String OBJ_pbe_WithSHA1And128BitRC2_CBC = "1.2.840.113549.1.12.1.5"; public static final String SN_pbe_WithSHA1And40BitRC2_CBC = "PBE-SHA1-RC2-40"; public static final String LN_pbe_WithSHA1And40BitRC2_CBC = "pbeWithSHA1And40BitRC2-CBC"; public static final short NID_pbe_WithSHA1And40BitRC2_CBC = 149; public static final String OBJ_pbe_WithSHA1And40BitRC2_CBC = "1.2.840.113549.1.12.1.6"; public static final String OBJ_pkcs12_Version1 = "1.2.840.113549.1.12.10"; public static final String OBJ_pkcs12_BagIds = "1.2.840.113549.1.12.10.1"; public static final String LN_keyBag = "keyBag"; public static final short NID_keyBag = 150; public static final String OBJ_keyBag = "1.2.840.113549.1.12.10.1.1"; public static final String LN_pkcs8ShroudedKeyBag = "pkcs8ShroudedKeyBag"; public static final short NID_pkcs8ShroudedKeyBag = 151; public static final String OBJ_pkcs8ShroudedKeyBag = "1.2.840.113549.1.12.10.1.2"; public static final String LN_certBag = "certBag"; public static final short NID_certBag = 152; public static final String OBJ_certBag = "1.2.840.113549.1.12.10.1.3"; public static final String LN_crlBag = "crlBag"; public static final short NID_crlBag = 153; public static final String OBJ_crlBag = "1.2.840.113549.1.12.10.1.4"; public static final String LN_secretBag = "secretBag"; public static final short NID_secretBag = 154; public static final String OBJ_secretBag = "1.2.840.113549.1.12.10.1.5"; public static final String LN_safeContentsBag = "safeContentsBag"; public static final short NID_safeContentsBag = 155; public static final String OBJ_safeContentsBag = "1.2.840.113549.1.12.10.1.6"; public static final String SN_md2 = "MD2"; public static final String LN_md2 = "md2"; public static final short NID_md2 = 3; public static final String OBJ_md2 = "1.2.840.113549.2.2"; public static final String SN_md4 = "MD4"; public static final String LN_md4 = "md4"; public static final short NID_md4 = 257; public static final String OBJ_md4 = "1.2.840.113549.2.4"; public static final String SN_md5 = "MD5"; public static final String LN_md5 = "md5"; public static final short NID_md5 = 4; public static final String OBJ_md5 = "1.2.840.113549.2.5"; public static final String SN_md5_sha1 = "MD5-SHA1"; public static final String LN_md5_sha1 = "md5-sha1"; public static final short NID_md5_sha1 = 114; public static final String LN_hmacWithMD5 = "hmacWithMD5"; public static final short NID_hmacWithMD5 = 797; public static final String OBJ_hmacWithMD5 = "1.2.840.113549.2.6"; public static final String LN_hmacWithSHA1 = "hmacWithSHA1"; public static final short NID_hmacWithSHA1 = 163; public static final String OBJ_hmacWithSHA1 = "1.2.840.113549.2.7"; public static final String LN_hmacWithSHA224 = "hmacWithSHA224"; public static final short NID_hmacWithSHA224 = 798; public static final String OBJ_hmacWithSHA224 = "1.2.840.113549.2.8"; public static final String LN_hmacWithSHA256 = "hmacWithSHA256"; public static final short NID_hmacWithSHA256 = 799; public static final String OBJ_hmacWithSHA256 = "1.2.840.113549.2.9"; public static final String LN_hmacWithSHA384 = "hmacWithSHA384"; public static final short NID_hmacWithSHA384 = 800; public static final String OBJ_hmacWithSHA384 = "1.2.840.113549.2.10"; public static final String LN_hmacWithSHA512 = "hmacWithSHA512"; public static final short NID_hmacWithSHA512 = 801; public static final String OBJ_hmacWithSHA512 = "1.2.840.113549.2.11"; public static final String SN_rc2_cbc = "RC2-CBC"; public static final String LN_rc2_cbc = "rc2-cbc"; public static final short NID_rc2_cbc = 37; public static final String OBJ_rc2_cbc = "1.2.840.113549.3.2"; public static final String SN_rc2_ecb = "RC2-ECB"; public static final String LN_rc2_ecb = "rc2-ecb"; public static final short NID_rc2_ecb = 38; public static final String SN_rc2_cfb64 = "RC2-CFB"; public static final String LN_rc2_cfb64 = "rc2-cfb"; public static final short NID_rc2_cfb64 = 39; public static final String SN_rc2_ofb64 = "RC2-OFB"; public static final String LN_rc2_ofb64 = "rc2-ofb"; public static final short NID_rc2_ofb64 = 40; public static final String SN_rc2_40_cbc = "RC2-40-CBC"; public static final String LN_rc2_40_cbc = "rc2-40-cbc"; public static final short NID_rc2_40_cbc = 98; public static final String SN_rc2_64_cbc = "RC2-64-CBC"; public static final String LN_rc2_64_cbc = "rc2-64-cbc"; public static final short NID_rc2_64_cbc = 166; public static final String SN_rc4 = "RC4"; public static final String LN_rc4 = "rc4"; public static final short NID_rc4 = 5; public static final String OBJ_rc4 = "1.2.840.113549.3.4"; public static final String SN_rc4_40 = "RC4-40"; public static final String LN_rc4_40 = "rc4-40"; public static final short NID_rc4_40 = 97; public static final String SN_des_ede3_cbc = "DES-EDE3-CBC"; public static final String LN_des_ede3_cbc = "des-ede3-cbc"; public static final short NID_des_ede3_cbc = 44; public static final String OBJ_des_ede3_cbc = "1.2.840.113549.3.7"; public static final String SN_rc5_cbc = "RC5-CBC"; public static final String LN_rc5_cbc = "rc5-cbc"; public static final short NID_rc5_cbc = 120; public static final String OBJ_rc5_cbc = "1.2.840.113549.3.8"; public static final String SN_rc5_ecb = "RC5-ECB"; public static final String LN_rc5_ecb = "rc5-ecb"; public static final short NID_rc5_ecb = 121; public static final String SN_rc5_cfb64 = "RC5-CFB"; public static final String LN_rc5_cfb64 = "rc5-cfb"; public static final short NID_rc5_cfb64 = 122; public static final String SN_rc5_ofb64 = "RC5-OFB"; public static final String LN_rc5_ofb64 = "rc5-ofb"; public static final short NID_rc5_ofb64 = 123; public static final String SN_ms_ext_req = "msExtReq"; public static final String LN_ms_ext_req = "Microsoft Extension Request"; public static final short NID_ms_ext_req = 171; public static final String OBJ_ms_ext_req = "1.3.6.1.4.1.311.2.1.14"; public static final String SN_ms_code_ind = "msCodeInd"; public static final String LN_ms_code_ind = "Microsoft Individual Code Signing"; public static final short NID_ms_code_ind = 134; public static final String OBJ_ms_code_ind = "1.3.6.1.4.1.311.2.1.21"; public static final String SN_ms_code_com = "msCodeCom"; public static final String LN_ms_code_com = "Microsoft Commercial Code Signing"; public static final short NID_ms_code_com = 135; public static final String OBJ_ms_code_com = "1.3.6.1.4.1.311.2.1.22"; public static final String SN_ms_ctl_sign = "msCTLSign"; public static final String LN_ms_ctl_sign = "Microsoft Trust List Signing"; public static final short NID_ms_ctl_sign = 136; public static final String OBJ_ms_ctl_sign = "1.3.6.1.4.1.311.10.3.1"; public static final String SN_ms_sgc = "msSGC"; public static final String LN_ms_sgc = "Microsoft Server Gated Crypto"; public static final short NID_ms_sgc = 137; public static final String OBJ_ms_sgc = "1.3.6.1.4.1.311.10.3.3"; public static final String SN_ms_efs = "msEFS"; public static final String LN_ms_efs = "Microsoft Encrypted File System"; public static final short NID_ms_efs = 138; public static final String OBJ_ms_efs = "1.3.6.1.4.1.311.10.3.4"; public static final String SN_ms_smartcard_login = "msSmartcardLogin"; public static final String LN_ms_smartcard_login = "Microsoft Smartcardlogin"; public static final short NID_ms_smartcard_login = 648; public static final String OBJ_ms_smartcard_login = "1.3.6.1.4.1.311.20.2.2"; public static final String SN_ms_upn = "msUPN"; public static final String LN_ms_upn = "Microsoft Universal Principal Name"; public static final short NID_ms_upn = 649; public static final String OBJ_ms_upn = "1.3.6.1.4.1.311.20.2.3"; public static final String SN_idea_cbc = "IDEA-CBC"; public static final String LN_idea_cbc = "idea-cbc"; public static final short NID_idea_cbc = 34; public static final String OBJ_idea_cbc = "1.3.6.1.4.1.188.7.1.1.2"; public static final String SN_idea_ecb = "IDEA-ECB"; public static final String LN_idea_ecb = "idea-ecb"; public static final short NID_idea_ecb = 36; public static final String SN_idea_cfb64 = "IDEA-CFB"; public static final String LN_idea_cfb64 = "idea-cfb"; public static final short NID_idea_cfb64 = 35; public static final String SN_idea_ofb64 = "IDEA-OFB"; public static final String LN_idea_ofb64 = "idea-ofb"; public static final short NID_idea_ofb64 = 46; public static final String SN_bf_cbc = "BF-CBC"; public static final String LN_bf_cbc = "bf-cbc"; public static final short NID_bf_cbc = 91; public static final String OBJ_bf_cbc = "1.3.6.1.4.1.3029.1.2"; public static final String SN_bf_ecb = "BF-ECB"; public static final String LN_bf_ecb = "bf-ecb"; public static final short NID_bf_ecb = 92; public static final String SN_bf_cfb64 = "BF-CFB"; public static final String LN_bf_cfb64 = "bf-cfb"; public static final short NID_bf_cfb64 = 93; public static final String SN_bf_ofb64 = "BF-OFB"; public static final String LN_bf_ofb64 = "bf-ofb"; public static final short NID_bf_ofb64 = 94; public static final String SN_id_pkix = "PKIX"; public static final short NID_id_pkix = 127; public static final String OBJ_id_pkix = "1.3.6.1.5.5.7"; public static final String SN_id_pkix_mod = "id-pkix-mod"; public static final short NID_id_pkix_mod = 258; public static final String OBJ_id_pkix_mod = "1.3.6.1.5.5.7.0"; public static final String SN_id_pe = "id-pe"; public static final short NID_id_pe = 175; public static final String OBJ_id_pe = "1.3.6.1.5.5.7.1"; public static final String SN_id_qt = "id-qt"; public static final short NID_id_qt = 259; public static final String OBJ_id_qt = "1.3.6.1.5.5.7.2"; public static final String SN_id_kp = "id-kp"; public static final short NID_id_kp = 128; public static final String OBJ_id_kp = "1.3.6.1.5.5.7.3"; public static final String SN_id_it = "id-it"; public static final short NID_id_it = 260; public static final String OBJ_id_it = "1.3.6.1.5.5.7.4"; public static final String SN_id_pkip = "id-pkip"; public static final short NID_id_pkip = 261; public static final String OBJ_id_pkip = "1.3.6.1.5.5.7.5"; public static final String SN_id_alg = "id-alg"; public static final short NID_id_alg = 262; public static final String OBJ_id_alg = "1.3.6.1.5.5.7.6"; public static final String SN_id_cmc = "id-cmc"; public static final short NID_id_cmc = 263; public static final String OBJ_id_cmc = "1.3.6.1.5.5.7.7"; public static final String SN_id_on = "id-on"; public static final short NID_id_on = 264; public static final String OBJ_id_on = "1.3.6.1.5.5.7.8"; public static final String SN_id_pda = "id-pda"; public static final short NID_id_pda = 265; public static final String OBJ_id_pda = "1.3.6.1.5.5.7.9"; public static final String SN_id_aca = "id-aca"; public static final short NID_id_aca = 266; public static final String OBJ_id_aca = "1.3.6.1.5.5.7.10"; public static final String SN_id_qcs = "id-qcs"; public static final short NID_id_qcs = 267; public static final String OBJ_id_qcs = "1.3.6.1.5.5.7.11"; public static final String SN_id_cct = "id-cct"; public static final short NID_id_cct = 268; public static final String OBJ_id_cct = "1.3.6.1.5.5.7.12"; public static final String SN_id_ppl = "id-ppl"; public static final short NID_id_ppl = 662; public static final String OBJ_id_ppl = "1.3.6.1.5.5.7.21"; public static final String SN_id_ad = "id-ad"; public static final short NID_id_ad = 176; public static final String OBJ_id_ad = "1.3.6.1.5.5.7.48"; public static final String SN_id_pkix1_explicit_88 = "id-pkix1-explicit-88"; public static final short NID_id_pkix1_explicit_88 = 269; public static final String OBJ_id_pkix1_explicit_88 = "1.3.6.1.5.5.7.0.1"; public static final String SN_id_pkix1_implicit_88 = "id-pkix1-implicit-88"; public static final short NID_id_pkix1_implicit_88 = 270; public static final String OBJ_id_pkix1_implicit_88 = "1.3.6.1.5.5.7.0.2"; public static final String SN_id_pkix1_explicit_93 = "id-pkix1-explicit-93"; public static final short NID_id_pkix1_explicit_93 = 271; public static final String OBJ_id_pkix1_explicit_93 = "1.3.6.1.5.5.7.0.3"; public static final String SN_id_pkix1_implicit_93 = "id-pkix1-implicit-93"; public static final short NID_id_pkix1_implicit_93 = 272; public static final String OBJ_id_pkix1_implicit_93 = "1.3.6.1.5.5.7.0.4"; public static final String SN_id_mod_crmf = "id-mod-crmf"; public static final short NID_id_mod_crmf = 273; public static final String OBJ_id_mod_crmf = "1.3.6.1.5.5.7.0.5"; public static final String SN_id_mod_cmc = "id-mod-cmc"; public static final short NID_id_mod_cmc = 274; public static final String OBJ_id_mod_cmc = "1.3.6.1.5.5.7.0.6"; public static final String SN_id_mod_kea_profile_88 = "id-mod-kea-profile-88"; public static final short NID_id_mod_kea_profile_88 = 275; public static final String OBJ_id_mod_kea_profile_88 = "1.3.6.1.5.5.7.0.7"; public static final String SN_id_mod_kea_profile_93 = "id-mod-kea-profile-93"; public static final short NID_id_mod_kea_profile_93 = 276; public static final String OBJ_id_mod_kea_profile_93 = "1.3.6.1.5.5.7.0.8"; public static final String SN_id_mod_cmp = "id-mod-cmp"; public static final short NID_id_mod_cmp = 277; public static final String OBJ_id_mod_cmp = "1.3.6.1.5.5.7.0.9"; public static final String SN_id_mod_qualified_cert_88 = "id-mod-qualified-cert-88"; public static final short NID_id_mod_qualified_cert_88 = 278; public static final String OBJ_id_mod_qualified_cert_88 = "1.3.6.1.5.5.7.0.10"; public static final String SN_id_mod_qualified_cert_93 = "id-mod-qualified-cert-93"; public static final short NID_id_mod_qualified_cert_93 = 279; public static final String OBJ_id_mod_qualified_cert_93 = "1.3.6.1.5.5.7.0.11"; public static final String SN_id_mod_attribute_cert = "id-mod-attribute-cert"; public static final short NID_id_mod_attribute_cert = 280; public static final String OBJ_id_mod_attribute_cert = "1.3.6.1.5.5.7.0.12"; public static final String SN_id_mod_timestamp_protocol = "id-mod-timestamp-protocol"; public static final short NID_id_mod_timestamp_protocol = 281; public static final String OBJ_id_mod_timestamp_protocol = "1.3.6.1.5.5.7.0.13"; public static final String SN_id_mod_ocsp = "id-mod-ocsp"; public static final short NID_id_mod_ocsp = 282; public static final String OBJ_id_mod_ocsp = "1.3.6.1.5.5.7.0.14"; public static final String SN_id_mod_dvcs = "id-mod-dvcs"; public static final short NID_id_mod_dvcs = 283; public static final String OBJ_id_mod_dvcs = "1.3.6.1.5.5.7.0.15"; public static final String SN_id_mod_cmp2000 = "id-mod-cmp2000"; public static final short NID_id_mod_cmp2000 = 284; public static final String OBJ_id_mod_cmp2000 = "1.3.6.1.5.5.7.0.16"; public static final String SN_info_access = "authorityInfoAccess"; public static final String LN_info_access = "Authority Information Access"; public static final short NID_info_access = 177; public static final String OBJ_info_access = "1.3.6.1.5.5.7.1.1"; public static final String SN_biometricInfo = "biometricInfo"; public static final String LN_biometricInfo = "Biometric Info"; public static final short NID_biometricInfo = 285; public static final String OBJ_biometricInfo = "1.3.6.1.5.5.7.1.2"; public static final String SN_qcStatements = "qcStatements"; public static final short NID_qcStatements = 286; public static final String OBJ_qcStatements = "1.3.6.1.5.5.7.1.3"; public static final String SN_ac_auditEntity = "ac-auditEntity"; public static final short NID_ac_auditEntity = 287; public static final String OBJ_ac_auditEntity = "1.3.6.1.5.5.7.1.4"; public static final String SN_ac_targeting = "ac-targeting"; public static final short NID_ac_targeting = 288; public static final String OBJ_ac_targeting = "1.3.6.1.5.5.7.1.5"; public static final String SN_aaControls = "aaControls"; public static final short NID_aaControls = 289; public static final String OBJ_aaControls = "1.3.6.1.5.5.7.1.6"; public static final String SN_sbgp_ipAddrBlock = "sbgp-ipAddrBlock"; public static final short NID_sbgp_ipAddrBlock = 290; public static final String OBJ_sbgp_ipAddrBlock = "1.3.6.1.5.5.7.1.7"; public static final String SN_sbgp_autonomousSysNum = "sbgp-autonomousSysNum"; public static final short NID_sbgp_autonomousSysNum = 291; public static final String OBJ_sbgp_autonomousSysNum = "1.3.6.1.5.5.7.1.8"; public static final String SN_sbgp_routerIdentifier = "sbgp-routerIdentifier"; public static final short NID_sbgp_routerIdentifier = 292; public static final String OBJ_sbgp_routerIdentifier = "1.3.6.1.5.5.7.1.9"; public static final String SN_ac_proxying = "ac-proxying"; public static final short NID_ac_proxying = 397; public static final String OBJ_ac_proxying = "1.3.6.1.5.5.7.1.10"; public static final String SN_sinfo_access = "subjectInfoAccess"; public static final String LN_sinfo_access = "Subject Information Access"; public static final short NID_sinfo_access = 398; public static final String OBJ_sinfo_access = "1.3.6.1.5.5.7.1.11"; public static final String SN_proxyCertInfo = "proxyCertInfo"; public static final String LN_proxyCertInfo = "Proxy Certificate Information"; public static final short NID_proxyCertInfo = 663; public static final String OBJ_proxyCertInfo = "1.3.6.1.5.5.7.1.14"; public static final String SN_id_qt_cps = "id-qt-cps"; public static final String LN_id_qt_cps = "Policy Qualifier CPS"; public static final short NID_id_qt_cps = 164; public static final String OBJ_id_qt_cps = "1.3.6.1.5.5.7.2.1"; public static final String SN_id_qt_unotice = "id-qt-unotice"; public static final String LN_id_qt_unotice = "Policy Qualifier User Notice"; public static final short NID_id_qt_unotice = 165; public static final String OBJ_id_qt_unotice = "1.3.6.1.5.5.7.2.2"; public static final String SN_textNotice = "textNotice"; public static final short NID_textNotice = 293; public static final String OBJ_textNotice = "1.3.6.1.5.5.7.2.3"; public static final String SN_server_auth = "serverAuth"; public static final String LN_server_auth = "TLS Web Server Authentication"; public static final short NID_server_auth = 129; public static final String OBJ_server_auth = "1.3.6.1.5.5.7.3.1"; public static final String SN_client_auth = "clientAuth"; public static final String LN_client_auth = "TLS Web Client Authentication"; public static final short NID_client_auth = 130; public static final String OBJ_client_auth = "1.3.6.1.5.5.7.3.2"; public static final String SN_code_sign = "codeSigning"; public static final String LN_code_sign = "Code Signing"; public static final short NID_code_sign = 131; public static final String OBJ_code_sign = "1.3.6.1.5.5.7.3.3"; public static final String SN_email_protect = "emailProtection"; public static final String LN_email_protect = "E-mail Protection"; public static final short NID_email_protect = 132; public static final String OBJ_email_protect = "1.3.6.1.5.5.7.3.4"; public static final String SN_ipsecEndSystem = "ipsecEndSystem"; public static final String LN_ipsecEndSystem = "IPSec End System"; public static final short NID_ipsecEndSystem = 294; public static final String OBJ_ipsecEndSystem = "1.3.6.1.5.5.7.3.5"; public static final String SN_ipsecTunnel = "ipsecTunnel"; public static final String LN_ipsecTunnel = "IPSec Tunnel"; public static final short NID_ipsecTunnel = 295; public static final String OBJ_ipsecTunnel = "1.3.6.1.5.5.7.3.6"; public static final String SN_ipsecUser = "ipsecUser"; public static final String LN_ipsecUser = "IPSec User"; public static final short NID_ipsecUser = 296; public static final String OBJ_ipsecUser = "1.3.6.1.5.5.7.3.7"; public static final String SN_time_stamp = "timeStamping"; public static final String LN_time_stamp = "Time Stamping"; public static final short NID_time_stamp = 133; public static final String OBJ_time_stamp = "1.3.6.1.5.5.7.3.8"; public static final String SN_OCSP_sign = "OCSPSigning"; public static final String LN_OCSP_sign = "OCSP Signing"; public static final short NID_OCSP_sign = 180; public static final String OBJ_OCSP_sign = "1.3.6.1.5.5.7.3.9"; public static final String SN_dvcs = "DVCS"; public static final String LN_dvcs = "dvcs"; public static final short NID_dvcs = 297; public static final String OBJ_dvcs = "1.3.6.1.5.5.7.3.10"; public static final String SN_id_it_caProtEncCert = "id-it-caProtEncCert"; public static final short NID_id_it_caProtEncCert = 298; public static final String OBJ_id_it_caProtEncCert = "1.3.6.1.5.5.7.4.1"; public static final String SN_id_it_signKeyPairTypes = "id-it-signKeyPairTypes"; public static final short NID_id_it_signKeyPairTypes = 299; public static final String OBJ_id_it_signKeyPairTypes = "1.3.6.1.5.5.7.4.2"; public static final String SN_id_it_encKeyPairTypes = "id-it-encKeyPairTypes"; public static final short NID_id_it_encKeyPairTypes = 300; public static final String OBJ_id_it_encKeyPairTypes = "1.3.6.1.5.5.7.4.3"; public static final String SN_id_it_preferredSymmAlg = "id-it-preferredSymmAlg"; public static final short NID_id_it_preferredSymmAlg = 301; public static final String OBJ_id_it_preferredSymmAlg = "1.3.6.1.5.5.7.4.4"; public static final String SN_id_it_caKeyUpdateInfo = "id-it-caKeyUpdateInfo"; public static final short NID_id_it_caKeyUpdateInfo = 302; public static final String OBJ_id_it_caKeyUpdateInfo = "1.3.6.1.5.5.7.4.5"; public static final String SN_id_it_currentCRL = "id-it-currentCRL"; public static final short NID_id_it_currentCRL = 303; public static final String OBJ_id_it_currentCRL = "1.3.6.1.5.5.7.4.6"; public static final String SN_id_it_unsupportedOIDs = "id-it-unsupportedOIDs"; public static final short NID_id_it_unsupportedOIDs = 304; public static final String OBJ_id_it_unsupportedOIDs = "1.3.6.1.5.5.7.4.7"; public static final String SN_id_it_subscriptionRequest = "id-it-subscriptionRequest"; public static final short NID_id_it_subscriptionRequest = 305; public static final String OBJ_id_it_subscriptionRequest = "1.3.6.1.5.5.7.4.8"; public static final String SN_id_it_subscriptionResponse = "id-it-subscriptionResponse"; public static final short NID_id_it_subscriptionResponse = 306; public static final String OBJ_id_it_subscriptionResponse = "1.3.6.1.5.5.7.4.9"; public static final String SN_id_it_keyPairParamReq = "id-it-keyPairParamReq"; public static final short NID_id_it_keyPairParamReq = 307; public static final String OBJ_id_it_keyPairParamReq = "1.3.6.1.5.5.7.4.10"; public static final String SN_id_it_keyPairParamRep = "id-it-keyPairParamRep"; public static final short NID_id_it_keyPairParamRep = 308; public static final String OBJ_id_it_keyPairParamRep = "1.3.6.1.5.5.7.4.11"; public static final String SN_id_it_revPassphrase = "id-it-revPassphrase"; public static final short NID_id_it_revPassphrase = 309; public static final String OBJ_id_it_revPassphrase = "1.3.6.1.5.5.7.4.12"; public static final String SN_id_it_implicitConfirm = "id-it-implicitConfirm"; public static final short NID_id_it_implicitConfirm = 310; public static final String OBJ_id_it_implicitConfirm = "1.3.6.1.5.5.7.4.13"; public static final String SN_id_it_confirmWaitTime = "id-it-confirmWaitTime"; public static final short NID_id_it_confirmWaitTime = 311; public static final String OBJ_id_it_confirmWaitTime = "1.3.6.1.5.5.7.4.14"; public static final String SN_id_it_origPKIMessage = "id-it-origPKIMessage"; public static final short NID_id_it_origPKIMessage = 312; public static final String OBJ_id_it_origPKIMessage = "1.3.6.1.5.5.7.4.15"; public static final String SN_id_it_suppLangTags = "id-it-suppLangTags"; public static final short NID_id_it_suppLangTags = 784; public static final String OBJ_id_it_suppLangTags = "1.3.6.1.5.5.7.4.16"; public static final String SN_id_regCtrl = "id-regCtrl"; public static final short NID_id_regCtrl = 313; public static final String OBJ_id_regCtrl = "1.3.6.1.5.5.7.5.1"; public static final String SN_id_regInfo = "id-regInfo"; public static final short NID_id_regInfo = 314; public static final String OBJ_id_regInfo = "1.3.6.1.5.5.7.5.2"; public static final String SN_id_regCtrl_regToken = "id-regCtrl-regToken"; public static final short NID_id_regCtrl_regToken = 315; public static final String OBJ_id_regCtrl_regToken = "1.3.6.1.5.5.7.5.1.1"; public static final String SN_id_regCtrl_authenticator = "id-regCtrl-authenticator"; public static final short NID_id_regCtrl_authenticator = 316; public static final String OBJ_id_regCtrl_authenticator = "1.3.6.1.5.5.7.5.1.2"; public static final String SN_id_regCtrl_pkiPublicationInfo = "id-regCtrl-pkiPublicationInfo"; public static final short NID_id_regCtrl_pkiPublicationInfo = 317; public static final String OBJ_id_regCtrl_pkiPublicationInfo = "1.3.6.1.5.5.7.5.1.3"; public static final String SN_id_regCtrl_pkiArchiveOptions = "id-regCtrl-pkiArchiveOptions"; public static final short NID_id_regCtrl_pkiArchiveOptions = 318; public static final String OBJ_id_regCtrl_pkiArchiveOptions = "1.3.6.1.5.5.7.5.1.4"; public static final String SN_id_regCtrl_oldCertID = "id-regCtrl-oldCertID"; public static final short NID_id_regCtrl_oldCertID = 319; public static final String OBJ_id_regCtrl_oldCertID = "1.3.6.1.5.5.7.5.1.5"; public static final String SN_id_regCtrl_protocolEncrKey = "id-regCtrl-protocolEncrKey"; public static final short NID_id_regCtrl_protocolEncrKey = 320; public static final String OBJ_id_regCtrl_protocolEncrKey = "1.3.6.1.5.5.7.5.1.6"; public static final String SN_id_regInfo_utf8Pairs = "id-regInfo-utf8Pairs"; public static final short NID_id_regInfo_utf8Pairs = 321; public static final String OBJ_id_regInfo_utf8Pairs = "1.3.6.1.5.5.7.5.2.1"; public static final String SN_id_regInfo_certReq = "id-regInfo-certReq"; public static final short NID_id_regInfo_certReq = 322; public static final String OBJ_id_regInfo_certReq = "1.3.6.1.5.5.7.5.2.2"; public static final String SN_id_alg_des40 = "id-alg-des40"; public static final short NID_id_alg_des40 = 323; public static final String OBJ_id_alg_des40 = "1.3.6.1.5.5.7.6.1"; public static final String SN_id_alg_noSignature = "id-alg-noSignature"; public static final short NID_id_alg_noSignature = 324; public static final String OBJ_id_alg_noSignature = "1.3.6.1.5.5.7.6.2"; public static final String SN_id_alg_dh_sig_hmac_sha1 = "id-alg-dh-sig-hmac-sha1"; public static final short NID_id_alg_dh_sig_hmac_sha1 = 325; public static final String OBJ_id_alg_dh_sig_hmac_sha1 = "1.3.6.1.5.5.7.6.3"; public static final String SN_id_alg_dh_pop = "id-alg-dh-pop"; public static final short NID_id_alg_dh_pop = 326; public static final String OBJ_id_alg_dh_pop = "1.3.6.1.5.5.7.6.4"; public static final String SN_id_cmc_statusInfo = "id-cmc-statusInfo"; public static final short NID_id_cmc_statusInfo = 327; public static final String OBJ_id_cmc_statusInfo = "1.3.6.1.5.5.7.7.1"; public static final String SN_id_cmc_identification = "id-cmc-identification"; public static final short NID_id_cmc_identification = 328; public static final String OBJ_id_cmc_identification = "1.3.6.1.5.5.7.7.2"; public static final String SN_id_cmc_identityProof = "id-cmc-identityProof"; public static final short NID_id_cmc_identityProof = 329; public static final String OBJ_id_cmc_identityProof = "1.3.6.1.5.5.7.7.3"; public static final String SN_id_cmc_dataReturn = "id-cmc-dataReturn"; public static final short NID_id_cmc_dataReturn = 330; public static final String OBJ_id_cmc_dataReturn = "1.3.6.1.5.5.7.7.4"; public static final String SN_id_cmc_transactionId = "id-cmc-transactionId"; public static final short NID_id_cmc_transactionId = 331; public static final String OBJ_id_cmc_transactionId = "1.3.6.1.5.5.7.7.5"; public static final String SN_id_cmc_senderNonce = "id-cmc-senderNonce"; public static final short NID_id_cmc_senderNonce = 332; public static final String OBJ_id_cmc_senderNonce = "1.3.6.1.5.5.7.7.6"; public static final String SN_id_cmc_recipientNonce = "id-cmc-recipientNonce"; public static final short NID_id_cmc_recipientNonce = 333; public static final String OBJ_id_cmc_recipientNonce = "1.3.6.1.5.5.7.7.7"; public static final String SN_id_cmc_addExtensions = "id-cmc-addExtensions"; public static final short NID_id_cmc_addExtensions = 334; public static final String OBJ_id_cmc_addExtensions = "1.3.6.1.5.5.7.7.8"; public static final String SN_id_cmc_encryptedPOP = "id-cmc-encryptedPOP"; public static final short NID_id_cmc_encryptedPOP = 335; public static final String OBJ_id_cmc_encryptedPOP = "1.3.6.1.5.5.7.7.9"; public static final String SN_id_cmc_decryptedPOP = "id-cmc-decryptedPOP"; public static final short NID_id_cmc_decryptedPOP = 336; public static final String OBJ_id_cmc_decryptedPOP = "1.3.6.1.5.5.7.7.10"; public static final String SN_id_cmc_lraPOPWitness = "id-cmc-lraPOPWitness"; public static final short NID_id_cmc_lraPOPWitness = 337; public static final String OBJ_id_cmc_lraPOPWitness = "1.3.6.1.5.5.7.7.11"; public static final String SN_id_cmc_getCert = "id-cmc-getCert"; public static final short NID_id_cmc_getCert = 338; public static final String OBJ_id_cmc_getCert = "1.3.6.1.5.5.7.7.15"; public static final String SN_id_cmc_getCRL = "id-cmc-getCRL"; public static final short NID_id_cmc_getCRL = 339; public static final String OBJ_id_cmc_getCRL = "1.3.6.1.5.5.7.7.16"; public static final String SN_id_cmc_revokeRequest = "id-cmc-revokeRequest"; public static final short NID_id_cmc_revokeRequest = 340; public static final String OBJ_id_cmc_revokeRequest = "1.3.6.1.5.5.7.7.17"; public static final String SN_id_cmc_regInfo = "id-cmc-regInfo"; public static final short NID_id_cmc_regInfo = 341; public static final String OBJ_id_cmc_regInfo = "1.3.6.1.5.5.7.7.18"; public static final String SN_id_cmc_responseInfo = "id-cmc-responseInfo"; public static final short NID_id_cmc_responseInfo = 342; public static final String OBJ_id_cmc_responseInfo = "1.3.6.1.5.5.7.7.19"; public static final String SN_id_cmc_queryPending = "id-cmc-queryPending"; public static final short NID_id_cmc_queryPending = 343; public static final String OBJ_id_cmc_queryPending = "1.3.6.1.5.5.7.7.21"; public static final String SN_id_cmc_popLinkRandom = "id-cmc-popLinkRandom"; public static final short NID_id_cmc_popLinkRandom = 344; public static final String OBJ_id_cmc_popLinkRandom = "1.3.6.1.5.5.7.7.22"; public static final String SN_id_cmc_popLinkWitness = "id-cmc-popLinkWitness"; public static final short NID_id_cmc_popLinkWitness = 345; public static final String OBJ_id_cmc_popLinkWitness = "1.3.6.1.5.5.7.7.23"; public static final String SN_id_cmc_confirmCertAcceptance = "id-cmc-confirmCertAcceptance"; public static final short NID_id_cmc_confirmCertAcceptance = 346; public static final String OBJ_id_cmc_confirmCertAcceptance = "1.3.6.1.5.5.7.7.24"; public static final String SN_id_on_personalData = "id-on-personalData"; public static final short NID_id_on_personalData = 347; public static final String OBJ_id_on_personalData = "1.3.6.1.5.5.7.8.1"; public static final String SN_id_on_permanentIdentifier = "id-on-permanentIdentifier"; public static final String LN_id_on_permanentIdentifier = "Permanent Identifier"; public static final short NID_id_on_permanentIdentifier = 858; public static final String OBJ_id_on_permanentIdentifier = "1.3.6.1.5.5.7.8.3"; public static final String SN_id_pda_dateOfBirth = "id-pda-dateOfBirth"; public static final short NID_id_pda_dateOfBirth = 348; public static final String OBJ_id_pda_dateOfBirth = "1.3.6.1.5.5.7.9.1"; public static final String SN_id_pda_placeOfBirth = "id-pda-placeOfBirth"; public static final short NID_id_pda_placeOfBirth = 349; public static final String OBJ_id_pda_placeOfBirth = "1.3.6.1.5.5.7.9.2"; public static final String SN_id_pda_gender = "id-pda-gender"; public static final short NID_id_pda_gender = 351; public static final String OBJ_id_pda_gender = "1.3.6.1.5.5.7.9.3"; public static final String SN_id_pda_countryOfCitizenship = "id-pda-countryOfCitizenship"; public static final short NID_id_pda_countryOfCitizenship = 352; public static final String OBJ_id_pda_countryOfCitizenship = "1.3.6.1.5.5.7.9.4"; public static final String SN_id_pda_countryOfResidence = "id-pda-countryOfResidence"; public static final short NID_id_pda_countryOfResidence = 353; public static final String OBJ_id_pda_countryOfResidence = "1.3.6.1.5.5.7.9.5"; public static final String SN_id_aca_authenticationInfo = "id-aca-authenticationInfo"; public static final short NID_id_aca_authenticationInfo = 354; public static final String OBJ_id_aca_authenticationInfo = "1.3.6.1.5.5.7.10.1"; public static final String SN_id_aca_accessIdentity = "id-aca-accessIdentity"; public static final short NID_id_aca_accessIdentity = 355; public static final String OBJ_id_aca_accessIdentity = "1.3.6.1.5.5.7.10.2"; public static final String SN_id_aca_chargingIdentity = "id-aca-chargingIdentity"; public static final short NID_id_aca_chargingIdentity = 356; public static final String OBJ_id_aca_chargingIdentity = "1.3.6.1.5.5.7.10.3"; public static final String SN_id_aca_group = "id-aca-group"; public static final short NID_id_aca_group = 357; public static final String OBJ_id_aca_group = "1.3.6.1.5.5.7.10.4"; public static final String SN_id_aca_role = "id-aca-role"; public static final short NID_id_aca_role = 358; public static final String OBJ_id_aca_role = "1.3.6.1.5.5.7.10.5"; public static final String SN_id_aca_encAttrs = "id-aca-encAttrs"; public static final short NID_id_aca_encAttrs = 399; public static final String OBJ_id_aca_encAttrs = "1.3.6.1.5.5.7.10.6"; public static final String SN_id_qcs_pkixQCSyntax_v1 = "id-qcs-pkixQCSyntax-v1"; public static final short NID_id_qcs_pkixQCSyntax_v1 = 359; public static final String OBJ_id_qcs_pkixQCSyntax_v1 = "1.3.6.1.5.5.7.11.1"; public static final String SN_id_cct_crs = "id-cct-crs"; public static final short NID_id_cct_crs = 360; public static final String OBJ_id_cct_crs = "1.3.6.1.5.5.7.12.1"; public static final String SN_id_cct_PKIData = "id-cct-PKIData"; public static final short NID_id_cct_PKIData = 361; public static final String OBJ_id_cct_PKIData = "1.3.6.1.5.5.7.12.2"; public static final String SN_id_cct_PKIResponse = "id-cct-PKIResponse"; public static final short NID_id_cct_PKIResponse = 362; public static final String OBJ_id_cct_PKIResponse = "1.3.6.1.5.5.7.12.3"; public static final String SN_id_ppl_anyLanguage = "id-ppl-anyLanguage"; public static final String LN_id_ppl_anyLanguage = "Any language"; public static final short NID_id_ppl_anyLanguage = 664; public static final String OBJ_id_ppl_anyLanguage = "1.3.6.1.5.5.7.21.0"; public static final String SN_id_ppl_inheritAll = "id-ppl-inheritAll"; public static final String LN_id_ppl_inheritAll = "Inherit all"; public static final short NID_id_ppl_inheritAll = 665; public static final String OBJ_id_ppl_inheritAll = "1.3.6.1.5.5.7.21.1"; public static final String SN_Independent = "id-ppl-independent"; public static final String LN_Independent = "Independent"; public static final short NID_Independent = 667; public static final String OBJ_Independent = "1.3.6.1.5.5.7.21.2"; public static final String SN_ad_OCSP = "OCSP"; public static final String LN_ad_OCSP = "OCSP"; public static final short NID_ad_OCSP = 178; public static final String OBJ_ad_OCSP = "1.3.6.1.5.5.7.48.1"; public static final String SN_ad_ca_issuers = "caIssuers"; public static final String LN_ad_ca_issuers = "CA Issuers"; public static final short NID_ad_ca_issuers = 179; public static final String OBJ_ad_ca_issuers = "1.3.6.1.5.5.7.48.2"; public static final String SN_ad_timeStamping = "ad_timestamping"; public static final String LN_ad_timeStamping = "AD Time Stamping"; public static final short NID_ad_timeStamping = 363; public static final String OBJ_ad_timeStamping = "1.3.6.1.5.5.7.48.3"; public static final String SN_ad_dvcs = "AD_DVCS"; public static final String LN_ad_dvcs = "ad dvcs"; public static final short NID_ad_dvcs = 364; public static final String OBJ_ad_dvcs = "1.3.6.1.5.5.7.48.4"; public static final String SN_caRepository = "caRepository"; public static final String LN_caRepository = "CA Repository"; public static final short NID_caRepository = 785; public static final String OBJ_caRepository = "1.3.6.1.5.5.7.48.5"; public static final String OBJ_id_pkix_OCSP = "1.3.6.1.5.5.7.48.1"; public static final String SN_id_pkix_OCSP_basic = "basicOCSPResponse"; public static final String LN_id_pkix_OCSP_basic = "Basic OCSP Response"; public static final short NID_id_pkix_OCSP_basic = 365; public static final String OBJ_id_pkix_OCSP_basic = "1.3.6.1.5.5.7.48.1.1"; public static final String SN_id_pkix_OCSP_Nonce = "Nonce"; public static final String LN_id_pkix_OCSP_Nonce = "OCSP Nonce"; public static final short NID_id_pkix_OCSP_Nonce = 366; public static final String OBJ_id_pkix_OCSP_Nonce = "1.3.6.1.5.5.7.48.1.2"; public static final String SN_id_pkix_OCSP_CrlID = "CrlID"; public static final String LN_id_pkix_OCSP_CrlID = "OCSP CRL ID"; public static final short NID_id_pkix_OCSP_CrlID = 367; public static final String OBJ_id_pkix_OCSP_CrlID = "1.3.6.1.5.5.7.48.1.3"; public static final String SN_id_pkix_OCSP_acceptableResponses = "acceptableResponses"; public static final String LN_id_pkix_OCSP_acceptableResponses = "Acceptable OCSP Responses"; public static final short NID_id_pkix_OCSP_acceptableResponses = 368; public static final String OBJ_id_pkix_OCSP_acceptableResponses = "1.3.6.1.5.5.7.48.1.4"; public static final String SN_id_pkix_OCSP_noCheck = "noCheck"; public static final String LN_id_pkix_OCSP_noCheck = "OCSP No Check"; public static final short NID_id_pkix_OCSP_noCheck = 369; public static final String OBJ_id_pkix_OCSP_noCheck = "1.3.6.1.5.5.7.48.1.5"; public static final String SN_id_pkix_OCSP_archiveCutoff = "archiveCutoff"; public static final String LN_id_pkix_OCSP_archiveCutoff = "OCSP Archive Cutoff"; public static final short NID_id_pkix_OCSP_archiveCutoff = 370; public static final String OBJ_id_pkix_OCSP_archiveCutoff = "1.3.6.1.5.5.7.48.1.6"; public static final String SN_id_pkix_OCSP_serviceLocator = "serviceLocator"; public static final String LN_id_pkix_OCSP_serviceLocator = "OCSP Service Locator"; public static final short NID_id_pkix_OCSP_serviceLocator = 371; public static final String OBJ_id_pkix_OCSP_serviceLocator = "1.3.6.1.5.5.7.48.1.7"; public static final String SN_id_pkix_OCSP_extendedStatus = "extendedStatus"; public static final String LN_id_pkix_OCSP_extendedStatus = "Extended OCSP Status"; public static final short NID_id_pkix_OCSP_extendedStatus = 372; public static final String OBJ_id_pkix_OCSP_extendedStatus = "1.3.6.1.5.5.7.48.1.8"; public static final String SN_id_pkix_OCSP_valid = "valid"; public static final short NID_id_pkix_OCSP_valid = 373; public static final String OBJ_id_pkix_OCSP_valid = "1.3.6.1.5.5.7.48.1.9"; public static final String SN_id_pkix_OCSP_path = "path"; public static final short NID_id_pkix_OCSP_path = 374; public static final String OBJ_id_pkix_OCSP_path = "1.3.6.1.5.5.7.48.1.10"; public static final String SN_id_pkix_OCSP_trustRoot = "trustRoot"; public static final String LN_id_pkix_OCSP_trustRoot = "Trust Root"; public static final short NID_id_pkix_OCSP_trustRoot = 375; public static final String OBJ_id_pkix_OCSP_trustRoot = "1.3.6.1.5.5.7.48.1.11"; public static final String SN_algorithm = "algorithm"; public static final String LN_algorithm = "algorithm"; public static final short NID_algorithm = 376; public static final String OBJ_algorithm = "1.3.14.3.2"; public static final String SN_md5WithRSA = "RSA-NP-MD5"; public static final String LN_md5WithRSA = "md5WithRSA"; public static final short NID_md5WithRSA = 104; public static final String OBJ_md5WithRSA = "1.3.14.3.2.3"; public static final String SN_des_ecb = "DES-ECB"; public static final String LN_des_ecb = "des-ecb"; public static final short NID_des_ecb = 29; public static final String OBJ_des_ecb = "1.3.14.3.2.6"; public static final String SN_des_cbc = "DES-CBC"; public static final String LN_des_cbc = "des-cbc"; public static final short NID_des_cbc = 31; public static final String OBJ_des_cbc = "1.3.14.3.2.7"; public static final String SN_des_ofb64 = "DES-OFB"; public static final String LN_des_ofb64 = "des-ofb"; public static final short NID_des_ofb64 = 45; public static final String OBJ_des_ofb64 = "1.3.14.3.2.8"; public static final String SN_des_cfb64 = "DES-CFB"; public static final String LN_des_cfb64 = "des-cfb"; public static final short NID_des_cfb64 = 30; public static final String OBJ_des_cfb64 = "1.3.14.3.2.9"; public static final String SN_rsaSignature = "rsaSignature"; public static final short NID_rsaSignature = 377; public static final String OBJ_rsaSignature = "1.3.14.3.2.11"; public static final String SN_dsa_2 = "DSA-old"; public static final String LN_dsa_2 = "dsaEncryption-old"; public static final short NID_dsa_2 = 67; public static final String OBJ_dsa_2 = "1.3.14.3.2.12"; public static final String SN_dsaWithSHA = "DSA-SHA"; public static final String LN_dsaWithSHA = "dsaWithSHA"; public static final short NID_dsaWithSHA = 66; public static final String OBJ_dsaWithSHA = "1.3.14.3.2.13"; public static final String SN_shaWithRSAEncryption = "RSA-SHA"; public static final String LN_shaWithRSAEncryption = "shaWithRSAEncryption"; public static final short NID_shaWithRSAEncryption = 42; public static final String OBJ_shaWithRSAEncryption = "1.3.14.3.2.15"; public static final String SN_des_ede_ecb = "DES-EDE"; public static final String LN_des_ede_ecb = "des-ede"; public static final short NID_des_ede_ecb = 32; public static final String OBJ_des_ede_ecb = "1.3.14.3.2.17"; public static final String SN_des_ede3_ecb = "DES-EDE3"; public static final String LN_des_ede3_ecb = "des-ede3"; public static final short NID_des_ede3_ecb = 33; public static final String SN_des_ede_cbc = "DES-EDE-CBC"; public static final String LN_des_ede_cbc = "des-ede-cbc"; public static final short NID_des_ede_cbc = 43; public static final String SN_des_ede_cfb64 = "DES-EDE-CFB"; public static final String LN_des_ede_cfb64 = "des-ede-cfb"; public static final short NID_des_ede_cfb64 = 60; public static final String SN_des_ede3_cfb64 = "DES-EDE3-CFB"; public static final String LN_des_ede3_cfb64 = "des-ede3-cfb"; public static final short NID_des_ede3_cfb64 = 61; public static final String SN_des_ede_ofb64 = "DES-EDE-OFB"; public static final String LN_des_ede_ofb64 = "des-ede-ofb"; public static final short NID_des_ede_ofb64 = 62; public static final String SN_des_ede3_ofb64 = "DES-EDE3-OFB"; public static final String LN_des_ede3_ofb64 = "des-ede3-ofb"; public static final short NID_des_ede3_ofb64 = 63; public static final String SN_desx_cbc = "DESX-CBC"; public static final String LN_desx_cbc = "desx-cbc"; public static final short NID_desx_cbc = 80; public static final String SN_sha = "SHA"; public static final String LN_sha = "sha"; public static final short NID_sha = 41; public static final String OBJ_sha = "1.3.14.3.2.18"; public static final String SN_sha1 = "SHA1"; public static final String LN_sha1 = "sha1"; public static final short NID_sha1 = 64; public static final String OBJ_sha1 = "1.3.14.3.2.26"; public static final String SN_dsaWithSHA1_2 = "DSA-SHA1-old"; public static final String LN_dsaWithSHA1_2 = "dsaWithSHA1-old"; public static final short NID_dsaWithSHA1_2 = 70; public static final String OBJ_dsaWithSHA1_2 = "1.3.14.3.2.27"; public static final String SN_sha1WithRSA = "RSA-SHA1-2"; public static final String LN_sha1WithRSA = "sha1WithRSA"; public static final short NID_sha1WithRSA = 115; public static final String OBJ_sha1WithRSA = "1.3.14.3.2.29"; public static final String SN_ripemd160 = "RIPEMD160"; public static final String LN_ripemd160 = "ripemd160"; public static final short NID_ripemd160 = 117; public static final String OBJ_ripemd160 = "1.3.36.3.2.1"; public static final String SN_ripemd160WithRSA = "RSA-RIPEMD160"; public static final String LN_ripemd160WithRSA = "ripemd160WithRSA"; public static final short NID_ripemd160WithRSA = 119; public static final String OBJ_ripemd160WithRSA = "1.3.36.3.3.1.2"; public static final String SN_sxnet = "SXNetID"; public static final String LN_sxnet = "Strong Extranet ID"; public static final short NID_sxnet = 143; public static final String OBJ_sxnet = "1.3.101.1.4.1"; public static final String SN_X500 = "X500"; public static final String LN_X500 = "directory services (X.500)"; public static final short NID_X500 = 11; public static final String OBJ_X500 = "2.5"; public static final String SN_X509 = "X509"; public static final short NID_X509 = 12; public static final String OBJ_X509 = "2.5.4"; public static final String SN_commonName = "CN"; public static final String LN_commonName = "commonName"; public static final short NID_commonName = 13; public static final String OBJ_commonName = "2.5.4.3"; public static final String SN_surname = "SN"; public static final String LN_surname = "surname"; public static final short NID_surname = 100; public static final String OBJ_surname = "2.5.4.4"; public static final String LN_serialNumber = "serialNumber"; public static final short NID_serialNumber = 105; public static final String OBJ_serialNumber = "2.5.4.5"; public static final String SN_countryName = "C"; public static final String LN_countryName = "countryName"; public static final short NID_countryName = 14; public static final String OBJ_countryName = "2.5.4.6"; public static final String SN_localityName = "L"; public static final String LN_localityName = "localityName"; public static final short NID_localityName = 15; public static final String OBJ_localityName = "2.5.4.7"; public static final String SN_stateOrProvinceName = "ST"; public static final String LN_stateOrProvinceName = "stateOrProvinceName"; public static final short NID_stateOrProvinceName = 16; public static final String OBJ_stateOrProvinceName = "2.5.4.8"; public static final String SN_streetAddress = "street"; public static final String LN_streetAddress = "streetAddress"; public static final short NID_streetAddress = 660; public static final String OBJ_streetAddress = "2.5.4.9"; public static final String SN_organizationName = "O"; public static final String LN_organizationName = "organizationName"; public static final short NID_organizationName = 17; public static final String OBJ_organizationName = "2.5.4.10"; public static final String SN_organizationalUnitName = "OU"; public static final String LN_organizationalUnitName = "organizationalUnitName"; public static final short NID_organizationalUnitName = 18; public static final String OBJ_organizationalUnitName = "2.5.4.11"; public static final String SN_title = "title"; public static final String LN_title = "title"; public static final short NID_title = 106; public static final String OBJ_title = "2.5.4.12"; public static final String LN_description = "description"; public static final short NID_description = 107; public static final String OBJ_description = "2.5.4.13"; public static final String LN_searchGuide = "searchGuide"; public static final short NID_searchGuide = 859; public static final String OBJ_searchGuide = "2.5.4.14"; public static final String LN_businessCategory = "businessCategory"; public static final short NID_businessCategory = 860; public static final String OBJ_businessCategory = "2.5.4.15"; public static final String LN_postalAddress = "postalAddress"; public static final short NID_postalAddress = 861; public static final String OBJ_postalAddress = "2.5.4.16"; public static final String LN_postalCode = "postalCode"; public static final short NID_postalCode = 661; public static final String OBJ_postalCode = "2.5.4.17"; public static final String LN_postOfficeBox = "postOfficeBox"; public static final short NID_postOfficeBox = 862; public static final String OBJ_postOfficeBox = "2.5.4.18"; public static final String LN_physicalDeliveryOfficeName = "physicalDeliveryOfficeName"; public static final short NID_physicalDeliveryOfficeName = 863; public static final String OBJ_physicalDeliveryOfficeName = "2.5.4.19"; public static final String LN_telephoneNumber = "telephoneNumber"; public static final short NID_telephoneNumber = 864; public static final String OBJ_telephoneNumber = "2.5.4.20"; public static final String LN_telexNumber = "telexNumber"; public static final short NID_telexNumber = 865; public static final String OBJ_telexNumber = "2.5.4.21"; public static final String LN_teletexTerminalIdentifier = "teletexTerminalIdentifier"; public static final short NID_teletexTerminalIdentifier = 866; public static final String OBJ_teletexTerminalIdentifier = "2.5.4.22"; public static final String LN_facsimileTelephoneNumber = "facsimileTelephoneNumber"; public static final short NID_facsimileTelephoneNumber = 867; public static final String OBJ_facsimileTelephoneNumber = "2.5.4.23"; public static final String LN_x121Address = "x121Address"; public static final short NID_x121Address = 868; public static final String OBJ_x121Address = "2.5.4.24"; public static final String LN_internationaliSDNNumber = "internationaliSDNNumber"; public static final short NID_internationaliSDNNumber = 869; public static final String OBJ_internationaliSDNNumber = "2.5.4.25"; public static final String LN_registeredAddress = "registeredAddress"; public static final short NID_registeredAddress = 870; public static final String OBJ_registeredAddress = "2.5.4.26"; public static final String LN_destinationIndicator = "destinationIndicator"; public static final short NID_destinationIndicator = 871; public static final String OBJ_destinationIndicator = "2.5.4.27"; public static final String LN_preferredDeliveryMethod = "preferredDeliveryMethod"; public static final short NID_preferredDeliveryMethod = 872; public static final String OBJ_preferredDeliveryMethod = "2.5.4.28"; public static final String LN_presentationAddress = "presentationAddress"; public static final short NID_presentationAddress = 873; public static final String OBJ_presentationAddress = "2.5.4.29"; public static final String LN_supportedApplicationContext = "supportedApplicationContext"; public static final short NID_supportedApplicationContext = 874; public static final String OBJ_supportedApplicationContext = "2.5.4.30"; public static final String SN_member = "member"; public static final short NID_member = 875; public static final String OBJ_member = "2.5.4.31"; public static final String SN_owner = "owner"; public static final short NID_owner = 876; public static final String OBJ_owner = "2.5.4.32"; public static final String LN_roleOccupant = "roleOccupant"; public static final short NID_roleOccupant = 877; public static final String OBJ_roleOccupant = "2.5.4.33"; public static final String SN_seeAlso = "seeAlso"; public static final short NID_seeAlso = 878; public static final String OBJ_seeAlso = "2.5.4.34"; public static final String LN_userPassword = "userPassword"; public static final short NID_userPassword = 879; public static final String OBJ_userPassword = "2.5.4.35"; public static final String LN_userCertificate = "userCertificate"; public static final short NID_userCertificate = 880; public static final String OBJ_userCertificate = "2.5.4.36"; public static final String LN_cACertificate = "cACertificate"; public static final short NID_cACertificate = 881; public static final String OBJ_cACertificate = "2.5.4.37"; public static final String LN_authorityRevocationList = "authorityRevocationList"; public static final short NID_authorityRevocationList = 882; public static final String OBJ_authorityRevocationList = "2.5.4.38"; public static final String LN_certificateRevocationList = "certificateRevocationList"; public static final short NID_certificateRevocationList = 883; public static final String OBJ_certificateRevocationList = "2.5.4.39"; public static final String LN_crossCertificatePair = "crossCertificatePair"; public static final short NID_crossCertificatePair = 884; public static final String OBJ_crossCertificatePair = "2.5.4.40"; public static final String SN_name = "name"; public static final String LN_name = "name"; public static final short NID_name = 173; public static final String OBJ_name = "2.5.4.41"; public static final String SN_givenName = "GN"; public static final String LN_givenName = "givenName"; public static final short NID_givenName = 99; public static final String OBJ_givenName = "2.5.4.42"; public static final String SN_initials = "initials"; public static final String LN_initials = "initials"; public static final short NID_initials = 101; public static final String OBJ_initials = "2.5.4.43"; public static final String LN_generationQualifier = "generationQualifier"; public static final short NID_generationQualifier = 509; public static final String OBJ_generationQualifier = "2.5.4.44"; public static final String LN_x500UniqueIdentifier = "x500UniqueIdentifier"; public static final short NID_x500UniqueIdentifier = 503; public static final String OBJ_x500UniqueIdentifier = "2.5.4.45"; public static final String SN_dnQualifier = "dnQualifier"; public static final String LN_dnQualifier = "dnQualifier"; public static final short NID_dnQualifier = 174; public static final String OBJ_dnQualifier = "2.5.4.46"; public static final String LN_enhancedSearchGuide = "enhancedSearchGuide"; public static final short NID_enhancedSearchGuide = 885; public static final String OBJ_enhancedSearchGuide = "2.5.4.47"; public static final String LN_protocolInformation = "protocolInformation"; public static final short NID_protocolInformation = 886; public static final String OBJ_protocolInformation = "2.5.4.48"; public static final String LN_distinguishedName = "distinguishedName"; public static final short NID_distinguishedName = 887; public static final String OBJ_distinguishedName = "2.5.4.49"; public static final String LN_uniqueMember = "uniqueMember"; public static final short NID_uniqueMember = 888; public static final String OBJ_uniqueMember = "2.5.4.50"; public static final String LN_houseIdentifier = "houseIdentifier"; public static final short NID_houseIdentifier = 889; public static final String OBJ_houseIdentifier = "2.5.4.51"; public static final String LN_supportedAlgorithms = "supportedAlgorithms"; public static final short NID_supportedAlgorithms = 890; public static final String OBJ_supportedAlgorithms = "2.5.4.52"; public static final String LN_deltaRevocationList = "deltaRevocationList"; public static final short NID_deltaRevocationList = 891; public static final String OBJ_deltaRevocationList = "2.5.4.53"; public static final String SN_dmdName = "dmdName"; public static final short NID_dmdName = 892; public static final String OBJ_dmdName = "2.5.4.54"; public static final String LN_pseudonym = "pseudonym"; public static final short NID_pseudonym = 510; public static final String OBJ_pseudonym = "2.5.4.65"; public static final String SN_role = "role"; public static final String LN_role = "role"; public static final short NID_role = 400; public static final String OBJ_role = "2.5.4.72"; public static final String SN_X500algorithms = "X500algorithms"; public static final String LN_X500algorithms = "directory services - algorithms"; public static final short NID_X500algorithms = 378; public static final String OBJ_X500algorithms = "2.5.8"; public static final String SN_rsa = "RSA"; public static final String LN_rsa = "rsa"; public static final short NID_rsa = 19; public static final String OBJ_rsa = "2.5.8.1.1"; public static final String SN_mdc2WithRSA = "RSA-MDC2"; public static final String LN_mdc2WithRSA = "mdc2WithRSA"; public static final short NID_mdc2WithRSA = 96; public static final String OBJ_mdc2WithRSA = "2.5.8.3.100"; public static final String SN_mdc2 = "MDC2"; public static final String LN_mdc2 = "mdc2"; public static final short NID_mdc2 = 95; public static final String OBJ_mdc2 = "2.5.8.3.101"; public static final String SN_id_ce = "id-ce"; public static final short NID_id_ce = 81; public static final String OBJ_id_ce = "2.5.29"; public static final String SN_subject_directory_attributes = "subjectDirectoryAttributes"; public static final String LN_subject_directory_attributes = "X509v3 Subject Directory Attributes"; public static final short NID_subject_directory_attributes = 769; public static final String OBJ_subject_directory_attributes = "2.5.29.9"; public static final String SN_subject_key_identifier = "subjectKeyIdentifier"; public static final String LN_subject_key_identifier = "X509v3 Subject Key Identifier"; public static final short NID_subject_key_identifier = 82; public static final String OBJ_subject_key_identifier = "2.5.29.14"; public static final String SN_key_usage = "keyUsage"; public static final String LN_key_usage = "X509v3 Key Usage"; public static final short NID_key_usage = 83; public static final String OBJ_key_usage = "2.5.29.15"; public static final String SN_private_key_usage_period = "privateKeyUsagePeriod"; public static final String LN_private_key_usage_period = "X509v3 Private Key Usage Period"; public static final short NID_private_key_usage_period = 84; public static final String OBJ_private_key_usage_period = "2.5.29.16"; public static final String SN_subject_alt_name = "subjectAltName"; public static final String LN_subject_alt_name = "X509v3 Subject Alternative Name"; public static final short NID_subject_alt_name = 85; public static final String OBJ_subject_alt_name = "2.5.29.17"; public static final String SN_issuer_alt_name = "issuerAltName"; public static final String LN_issuer_alt_name = "X509v3 Issuer Alternative Name"; public static final short NID_issuer_alt_name = 86; public static final String OBJ_issuer_alt_name = "2.5.29.18"; public static final String SN_basic_constraints = "basicConstraints"; public static final String LN_basic_constraints = "X509v3 Basic Constraints"; public static final short NID_basic_constraints = 87; public static final String OBJ_basic_constraints = "2.5.29.19"; public static final String SN_crl_number = "crlNumber"; public static final String LN_crl_number = "X509v3 CRL Number"; public static final short NID_crl_number = 88; public static final String OBJ_crl_number = "2.5.29.20"; public static final String SN_crl_reason = "CRLReason"; public static final String LN_crl_reason = "X509v3 CRL Reason Code"; public static final short NID_crl_reason = 141; public static final String OBJ_crl_reason = "2.5.29.21"; public static final String SN_invalidity_date = "invalidityDate"; public static final String LN_invalidity_date = "Invalidity Date"; public static final short NID_invalidity_date = 142; public static final String OBJ_invalidity_date = "2.5.29.24"; public static final String SN_delta_crl = "deltaCRL"; public static final String LN_delta_crl = "X509v3 Delta CRL Indicator"; public static final short NID_delta_crl = 140; public static final String OBJ_delta_crl = "2.5.29.27"; public static final String SN_issuing_distribution_point = "issuingDistributionPoint"; public static final String LN_issuing_distribution_point = "X509v3 Issuing Distrubution Point"; public static final short NID_issuing_distribution_point = 770; public static final String OBJ_issuing_distribution_point = "2.5.29.28"; public static final String SN_certificate_issuer = "certificateIssuer"; public static final String LN_certificate_issuer = "X509v3 Certificate Issuer"; public static final short NID_certificate_issuer = 771; public static final String OBJ_certificate_issuer = "2.5.29.29"; public static final String SN_name_constraints = "nameConstraints"; public static final String LN_name_constraints = "X509v3 Name Constraints"; public static final short NID_name_constraints = 666; public static final String OBJ_name_constraints = "2.5.29.30"; public static final String SN_crl_distribution_points = "crlDistributionPoints"; public static final String LN_crl_distribution_points = "X509v3 CRL Distribution Points"; public static final short NID_crl_distribution_points = 103; public static final String OBJ_crl_distribution_points = "2.5.29.31"; public static final String SN_certificate_policies = "certificatePolicies"; public static final String LN_certificate_policies = "X509v3 Certificate Policies"; public static final short NID_certificate_policies = 89; public static final String OBJ_certificate_policies = "2.5.29.32"; public static final String SN_any_policy = "anyPolicy"; public static final String LN_any_policy = "X509v3 Any Policy"; public static final short NID_any_policy = 746; public static final String OBJ_any_policy = "2.5.29.32.0"; public static final String SN_policy_mappings = "policyMappings"; public static final String LN_policy_mappings = "X509v3 Policy Mappings"; public static final short NID_policy_mappings = 747; public static final String OBJ_policy_mappings = "2.5.29.33"; public static final String SN_authority_key_identifier = "authorityKeyIdentifier"; public static final String LN_authority_key_identifier = "X509v3 Authority Key Identifier"; public static final short NID_authority_key_identifier = 90; public static final String OBJ_authority_key_identifier = "2.5.29.35"; public static final String SN_policy_constraints = "policyConstraints"; public static final String LN_policy_constraints = "X509v3 Policy Constraints"; public static final short NID_policy_constraints = 401; public static final String OBJ_policy_constraints = "2.5.29.36"; public static final String SN_ext_key_usage = "extendedKeyUsage"; public static final String LN_ext_key_usage = "X509v3 Extended Key Usage"; public static final short NID_ext_key_usage = 126; public static final String OBJ_ext_key_usage = "2.5.29.37"; public static final String SN_freshest_crl = "freshestCRL"; public static final String LN_freshest_crl = "X509v3 Freshest CRL"; public static final short NID_freshest_crl = 857; public static final String OBJ_freshest_crl = "2.5.29.46"; public static final String SN_inhibit_any_policy = "inhibitAnyPolicy"; public static final String LN_inhibit_any_policy = "X509v3 Inhibit Any Policy"; public static final short NID_inhibit_any_policy = 748; public static final String OBJ_inhibit_any_policy = "2.5.29.54"; public static final String SN_target_information = "targetInformation"; public static final String LN_target_information = "X509v3 AC Targeting"; public static final short NID_target_information = 402; public static final String OBJ_target_information = "2.5.29.55"; public static final String SN_no_rev_avail = "noRevAvail"; public static final String LN_no_rev_avail = "X509v3 No Revocation Available"; public static final short NID_no_rev_avail = 403; public static final String OBJ_no_rev_avail = "2.5.29.56"; public static final String SN_anyExtendedKeyUsage = "anyExtendedKeyUsage"; public static final String LN_anyExtendedKeyUsage = "Any Extended Key Usage"; public static final short NID_anyExtendedKeyUsage = 910; public static final String OBJ_anyExtendedKeyUsage = "2.5.29.37.0"; public static final String SN_netscape = "Netscape"; public static final String LN_netscape = "Netscape Communications Corp."; public static final short NID_netscape = 57; public static final String OBJ_netscape = "2.16.840.1.113730"; public static final String SN_netscape_cert_extension = "nsCertExt"; public static final String LN_netscape_cert_extension = "Netscape Certificate Extension"; public static final short NID_netscape_cert_extension = 58; public static final String OBJ_netscape_cert_extension = "2.16.840.1.113730.1"; public static final String SN_netscape_data_type = "nsDataType"; public static final String LN_netscape_data_type = "Netscape Data Type"; public static final short NID_netscape_data_type = 59; public static final String OBJ_netscape_data_type = "2.16.840.1.113730.2"; public static final String SN_netscape_cert_type = "nsCertType"; public static final String LN_netscape_cert_type = "Netscape Cert Type"; public static final short NID_netscape_cert_type = 71; public static final String OBJ_netscape_cert_type = "2.16.840.1.113730.1.1"; public static final String SN_netscape_base_url = "nsBaseUrl"; public static final String LN_netscape_base_url = "Netscape Base Url"; public static final short NID_netscape_base_url = 72; public static final String OBJ_netscape_base_url = "2.16.840.1.113730.1.2"; public static final String SN_netscape_revocation_url = "nsRevocationUrl"; public static final String LN_netscape_revocation_url = "Netscape Revocation Url"; public static final short NID_netscape_revocation_url = 73; public static final String OBJ_netscape_revocation_url = "2.16.840.1.113730.1.3"; public static final String SN_netscape_ca_revocation_url = "nsCaRevocationUrl"; public static final String LN_netscape_ca_revocation_url = "Netscape CA Revocation Url"; public static final short NID_netscape_ca_revocation_url = 74; public static final String OBJ_netscape_ca_revocation_url = "2.16.840.1.113730.1.4"; public static final String SN_netscape_renewal_url = "nsRenewalUrl"; public static final String LN_netscape_renewal_url = "Netscape Renewal Url"; public static final short NID_netscape_renewal_url = 75; public static final String OBJ_netscape_renewal_url = "2.16.840.1.113730.1.7"; public static final String SN_netscape_ca_policy_url = "nsCaPolicyUrl"; public static final String LN_netscape_ca_policy_url = "Netscape CA Policy Url"; public static final short NID_netscape_ca_policy_url = 76; public static final String OBJ_netscape_ca_policy_url = "2.16.840.1.113730.1.8"; public static final String SN_netscape_ssl_server_name = "nsSslServerName"; public static final String LN_netscape_ssl_server_name = "Netscape SSL Server Name"; public static final short NID_netscape_ssl_server_name = 77; public static final String OBJ_netscape_ssl_server_name = "2.16.840.1.113730.1.12"; public static final String SN_netscape_comment = "nsComment"; public static final String LN_netscape_comment = "Netscape Comment"; public static final short NID_netscape_comment = 78; public static final String OBJ_netscape_comment = "2.16.840.1.113730.1.13"; public static final String SN_netscape_cert_sequence = "nsCertSequence"; public static final String LN_netscape_cert_sequence = "Netscape Certificate Sequence"; public static final short NID_netscape_cert_sequence = 79; public static final String OBJ_netscape_cert_sequence = "2.16.840.1.113730.2.5"; public static final String SN_ns_sgc = "nsSGC"; public static final String LN_ns_sgc = "Netscape Server Gated Crypto"; public static final short NID_ns_sgc = 139; public static final String OBJ_ns_sgc = "2.16.840.1.113730.4.1"; public static final String SN_org = "ORG"; public static final String LN_org = "org"; public static final short NID_org = 379; public static final String OBJ_org = "1.3"; public static final String SN_dod = "DOD"; public static final String LN_dod = "dod"; public static final short NID_dod = 380; public static final String OBJ_dod = "1.3.6"; public static final String SN_iana = "IANA"; public static final String LN_iana = "iana"; public static final short NID_iana = 381; public static final String OBJ_iana = "1.3.6.1"; public static final String OBJ_internet = "1.3.6.1"; public static final String SN_Directory = "directory"; public static final String LN_Directory = "Directory"; public static final short NID_Directory = 382; public static final String OBJ_Directory = "1.3.6.1.1"; public static final String SN_Management = "mgmt"; public static final String LN_Management = "Management"; public static final short NID_Management = 383; public static final String OBJ_Management = "1.3.6.1.2"; public static final String SN_Experimental = "experimental"; public static final String LN_Experimental = "Experimental"; public static final short NID_Experimental = 384; public static final String OBJ_Experimental = "1.3.6.1.3"; public static final String SN_Private = "private"; public static final String LN_Private = "Private"; public static final short NID_Private = 385; public static final String OBJ_Private = "1.3.6.1.4"; public static final String SN_Security = "security"; public static final String LN_Security = "Security"; public static final short NID_Security = 386; public static final String OBJ_Security = "1.3.6.1.5"; public static final String SN_SNMPv2 = "snmpv2"; public static final String LN_SNMPv2 = "SNMPv2"; public static final short NID_SNMPv2 = 387; public static final String OBJ_SNMPv2 = "1.3.6.1.6"; public static final String LN_Mail = "Mail"; public static final short NID_Mail = 388; public static final String OBJ_Mail = "1.3.6.1.7"; public static final String SN_Enterprises = "enterprises"; public static final String LN_Enterprises = "Enterprises"; public static final short NID_Enterprises = 389; public static final String OBJ_Enterprises = "1.3.6.1.4.1"; public static final String SN_dcObject = "dcobject"; public static final String LN_dcObject = "dcObject"; public static final short NID_dcObject = 390; public static final String OBJ_dcObject = "1.3.6.1.4.1.1466.344"; public static final String SN_mime_mhs = "mime-mhs"; public static final String LN_mime_mhs = "MIME MHS"; public static final short NID_mime_mhs = 504; public static final String OBJ_mime_mhs = "1.3.6.1.7.1"; public static final String SN_mime_mhs_headings = "mime-mhs-headings"; public static final String LN_mime_mhs_headings = "mime-mhs-headings"; public static final short NID_mime_mhs_headings = 505; public static final String OBJ_mime_mhs_headings = "1.3.6.1.7.1.1"; public static final String SN_mime_mhs_bodies = "mime-mhs-bodies"; public static final String LN_mime_mhs_bodies = "mime-mhs-bodies"; public static final short NID_mime_mhs_bodies = 506; public static final String OBJ_mime_mhs_bodies = "1.3.6.1.7.1.2"; public static final String SN_id_hex_partial_message = "id-hex-partial-message"; public static final String LN_id_hex_partial_message = "id-hex-partial-message"; public static final short NID_id_hex_partial_message = 507; public static final String OBJ_id_hex_partial_message = "1.3.6.1.7.1.1.1"; public static final String SN_id_hex_multipart_message = "id-hex-multipart-message"; public static final String LN_id_hex_multipart_message = "id-hex-multipart-message"; public static final short NID_id_hex_multipart_message = 508; public static final String OBJ_id_hex_multipart_message = "1.3.6.1.7.1.1.2"; public static final String SN_rle_compression = "RLE"; public static final String LN_rle_compression = "run length compression"; public static final short NID_rle_compression = 124; public static final String OBJ_rle_compression = "1.1.1.1.666.1"; public static final String SN_zlib_compression = "ZLIB"; public static final String LN_zlib_compression = "zlib compression"; public static final short NID_zlib_compression = 125; public static final String OBJ_zlib_compression = "1.2.840.113549.1.9.16.3.8"; public static final String OBJ_csor = "2.16.840.1.101.3"; public static final String OBJ_nistAlgorithms = "2.16.840.1.101.3.4"; public static final String OBJ_aes = "2.16.840.1.101.3.4.1"; public static final String SN_aes_128_ecb = "AES-128-ECB"; public static final String LN_aes_128_ecb = "aes-128-ecb"; public static final short NID_aes_128_ecb = 418; public static final String OBJ_aes_128_ecb = "2.16.840.1.101.3.4.1.1"; public static final String SN_aes_128_cbc = "AES-128-CBC"; public static final String LN_aes_128_cbc = "aes-128-cbc"; public static final short NID_aes_128_cbc = 419; public static final String OBJ_aes_128_cbc = "2.16.840.1.101.3.4.1.2"; public static final String SN_aes_128_ofb128 = "AES-128-OFB"; public static final String LN_aes_128_ofb128 = "aes-128-ofb"; public static final short NID_aes_128_ofb128 = 420; public static final String OBJ_aes_128_ofb128 = "2.16.840.1.101.3.4.1.3"; public static final String SN_aes_128_cfb128 = "AES-128-CFB"; public static final String LN_aes_128_cfb128 = "aes-128-cfb"; public static final short NID_aes_128_cfb128 = 421; public static final String OBJ_aes_128_cfb128 = "2.16.840.1.101.3.4.1.4"; public static final String SN_id_aes128_wrap = "id-aes128-wrap"; public static final short NID_id_aes128_wrap = 788; public static final String OBJ_id_aes128_wrap = "2.16.840.1.101.3.4.1.5"; public static final String SN_aes_128_gcm = "id-aes128-GCM"; public static final String LN_aes_128_gcm = "aes-128-gcm"; public static final short NID_aes_128_gcm = 895; public static final String OBJ_aes_128_gcm = "2.16.840.1.101.3.4.1.6"; public static final String SN_aes_128_ccm = "id-aes128-CCM"; public static final String LN_aes_128_ccm = "aes-128-ccm"; public static final short NID_aes_128_ccm = 896; public static final String OBJ_aes_128_ccm = "2.16.840.1.101.3.4.1.7"; public static final String SN_id_aes128_wrap_pad = "id-aes128-wrap-pad"; public static final short NID_id_aes128_wrap_pad = 897; public static final String OBJ_id_aes128_wrap_pad = "2.16.840.1.101.3.4.1.8"; public static final String SN_aes_192_ecb = "AES-192-ECB"; public static final String LN_aes_192_ecb = "aes-192-ecb"; public static final short NID_aes_192_ecb = 422; public static final String OBJ_aes_192_ecb = "2.16.840.1.101.3.4.1.21"; public static final String SN_aes_192_cbc = "AES-192-CBC"; public static final String LN_aes_192_cbc = "aes-192-cbc"; public static final short NID_aes_192_cbc = 423; public static final String OBJ_aes_192_cbc = "2.16.840.1.101.3.4.1.22"; public static final String SN_aes_192_ofb128 = "AES-192-OFB"; public static final String LN_aes_192_ofb128 = "aes-192-ofb"; public static final short NID_aes_192_ofb128 = 424; public static final String OBJ_aes_192_ofb128 = "2.16.840.1.101.3.4.1.23"; public static final String SN_aes_192_cfb128 = "AES-192-CFB"; public static final String LN_aes_192_cfb128 = "aes-192-cfb"; public static final short NID_aes_192_cfb128 = 425; public static final String OBJ_aes_192_cfb128 = "2.16.840.1.101.3.4.1.24"; public static final String SN_id_aes192_wrap = "id-aes192-wrap"; public static final short NID_id_aes192_wrap = 789; public static final String OBJ_id_aes192_wrap = "2.16.840.1.101.3.4.1.25"; public static final String SN_aes_192_gcm = "id-aes192-GCM"; public static final String LN_aes_192_gcm = "aes-192-gcm"; public static final short NID_aes_192_gcm = 898; public static final String OBJ_aes_192_gcm = "2.16.840.1.101.3.4.1.26"; public static final String SN_aes_192_ccm = "id-aes192-CCM"; public static final String LN_aes_192_ccm = "aes-192-ccm"; public static final short NID_aes_192_ccm = 899; public static final String OBJ_aes_192_ccm = "2.16.840.1.101.3.4.1.27"; public static final String SN_id_aes192_wrap_pad = "id-aes192-wrap-pad"; public static final short NID_id_aes192_wrap_pad = 900; public static final String OBJ_id_aes192_wrap_pad = "2.16.840.1.101.3.4.1.28"; public static final String SN_aes_256_ecb = "AES-256-ECB"; public static final String LN_aes_256_ecb = "aes-256-ecb"; public static final short NID_aes_256_ecb = 426; public static final String OBJ_aes_256_ecb = "2.16.840.1.101.3.4.1.41"; public static final String SN_aes_256_cbc = "AES-256-CBC"; public static final String LN_aes_256_cbc = "aes-256-cbc"; public static final short NID_aes_256_cbc = 427; public static final String OBJ_aes_256_cbc = "2.16.840.1.101.3.4.1.42"; public static final String SN_aes_256_ofb128 = "AES-256-OFB"; public static final String LN_aes_256_ofb128 = "aes-256-ofb"; public static final short NID_aes_256_ofb128 = 428; public static final String OBJ_aes_256_ofb128 = "2.16.840.1.101.3.4.1.43"; public static final String SN_aes_256_cfb128 = "AES-256-CFB"; public static final String LN_aes_256_cfb128 = "aes-256-cfb"; public static final short NID_aes_256_cfb128 = 429; public static final String OBJ_aes_256_cfb128 = "2.16.840.1.101.3.4.1.44"; public static final String SN_id_aes256_wrap = "id-aes256-wrap"; public static final short NID_id_aes256_wrap = 790; public static final String OBJ_id_aes256_wrap = "2.16.840.1.101.3.4.1.45"; public static final String SN_aes_256_gcm = "id-aes256-GCM"; public static final String LN_aes_256_gcm = "aes-256-gcm"; public static final short NID_aes_256_gcm = 901; public static final String OBJ_aes_256_gcm = "2.16.840.1.101.3.4.1.46"; public static final String SN_aes_256_ccm = "id-aes256-CCM"; public static final String LN_aes_256_ccm = "aes-256-ccm"; public static final short NID_aes_256_ccm = 902; public static final String OBJ_aes_256_ccm = "2.16.840.1.101.3.4.1.47"; public static final String SN_id_aes256_wrap_pad = "id-aes256-wrap-pad"; public static final short NID_id_aes256_wrap_pad = 903; public static final String OBJ_id_aes256_wrap_pad = "2.16.840.1.101.3.4.1.48"; public static final String SN_aes_128_cfb1 = "AES-128-CFB1"; public static final String LN_aes_128_cfb1 = "aes-128-cfb1"; public static final short NID_aes_128_cfb1 = 650; public static final String SN_aes_192_cfb1 = "AES-192-CFB1"; public static final String LN_aes_192_cfb1 = "aes-192-cfb1"; public static final short NID_aes_192_cfb1 = 651; public static final String SN_aes_256_cfb1 = "AES-256-CFB1"; public static final String LN_aes_256_cfb1 = "aes-256-cfb1"; public static final short NID_aes_256_cfb1 = 652; public static final String SN_aes_128_cfb8 = "AES-128-CFB8"; public static final String LN_aes_128_cfb8 = "aes-128-cfb8"; public static final short NID_aes_128_cfb8 = 653; public static final String SN_aes_192_cfb8 = "AES-192-CFB8"; public static final String LN_aes_192_cfb8 = "aes-192-cfb8"; public static final short NID_aes_192_cfb8 = 654; public static final String SN_aes_256_cfb8 = "AES-256-CFB8"; public static final String LN_aes_256_cfb8 = "aes-256-cfb8"; public static final short NID_aes_256_cfb8 = 655; public static final String SN_aes_128_ctr = "AES-128-CTR"; public static final String LN_aes_128_ctr = "aes-128-ctr"; public static final short NID_aes_128_ctr = 904; public static final String SN_aes_192_ctr = "AES-192-CTR"; public static final String LN_aes_192_ctr = "aes-192-ctr"; public static final short NID_aes_192_ctr = 905; public static final String SN_aes_256_ctr = "AES-256-CTR"; public static final String LN_aes_256_ctr = "aes-256-ctr"; public static final short NID_aes_256_ctr = 906; public static final String SN_aes_128_xts = "AES-128-XTS"; public static final String LN_aes_128_xts = "aes-128-xts"; public static final short NID_aes_128_xts = 913; public static final String SN_aes_256_xts = "AES-256-XTS"; public static final String LN_aes_256_xts = "aes-256-xts"; public static final short NID_aes_256_xts = 914; public static final String SN_des_cfb1 = "DES-CFB1"; public static final String LN_des_cfb1 = "des-cfb1"; public static final short NID_des_cfb1 = 656; public static final String SN_des_cfb8 = "DES-CFB8"; public static final String LN_des_cfb8 = "des-cfb8"; public static final short NID_des_cfb8 = 657; public static final String SN_des_ede3_cfb1 = "DES-EDE3-CFB1"; public static final String LN_des_ede3_cfb1 = "des-ede3-cfb1"; public static final short NID_des_ede3_cfb1 = 658; public static final String SN_des_ede3_cfb8 = "DES-EDE3-CFB8"; public static final String LN_des_ede3_cfb8 = "des-ede3-cfb8"; public static final short NID_des_ede3_cfb8 = 659; public static final String OBJ_nist_hashalgs = "2.16.840.1.101.3.4.2"; public static final String SN_sha256 = "SHA256"; public static final String LN_sha256 = "sha256"; public static final short NID_sha256 = 672; public static final String OBJ_sha256 = "2.16.840.1.101.3.4.2.1"; public static final String SN_sha384 = "SHA384"; public static final String LN_sha384 = "sha384"; public static final short NID_sha384 = 673; public static final String OBJ_sha384 = "2.16.840.1.101.3.4.2.2"; public static final String SN_sha512 = "SHA512"; public static final String LN_sha512 = "sha512"; public static final short NID_sha512 = 674; public static final String OBJ_sha512 = "2.16.840.1.101.3.4.2.3"; public static final String SN_sha224 = "SHA224"; public static final String LN_sha224 = "sha224"; public static final short NID_sha224 = 675; public static final String OBJ_sha224 = "2.16.840.1.101.3.4.2.4"; public static final String OBJ_dsa_with_sha2 = "2.16.840.1.101.3.4.3"; public static final String SN_dsa_with_SHA224 = "dsa_with_SHA224"; public static final short NID_dsa_with_SHA224 = 802; public static final String OBJ_dsa_with_SHA224 = "2.16.840.1.101.3.4.3.1"; public static final String SN_dsa_with_SHA256 = "dsa_with_SHA256"; public static final short NID_dsa_with_SHA256 = 803; public static final String OBJ_dsa_with_SHA256 = "2.16.840.1.101.3.4.3.2"; public static final String SN_hold_instruction_code = "holdInstructionCode"; public static final String LN_hold_instruction_code = "Hold Instruction Code"; public static final short NID_hold_instruction_code = 430; public static final String OBJ_hold_instruction_code = "2.5.29.23"; public static final String OBJ_holdInstruction = "1.2.840.10040.2"; public static final String SN_hold_instruction_none = "holdInstructionNone"; public static final String LN_hold_instruction_none = "Hold Instruction None"; public static final short NID_hold_instruction_none = 431; public static final String OBJ_hold_instruction_none = "1.2.840.10040.2.1"; public static final String SN_hold_instruction_call_issuer = "holdInstructionCallIssuer"; public static final String LN_hold_instruction_call_issuer = "Hold Instruction Call Issuer"; public static final short NID_hold_instruction_call_issuer = 432; public static final String OBJ_hold_instruction_call_issuer = "1.2.840.10040.2.2"; public static final String SN_hold_instruction_reject = "holdInstructionReject"; public static final String LN_hold_instruction_reject = "Hold Instruction Reject"; public static final short NID_hold_instruction_reject = 433; public static final String OBJ_hold_instruction_reject = "1.2.840.10040.2.3"; public static final String SN_data = "data"; public static final short NID_data = 434; public static final String OBJ_data = "0.9"; public static final String SN_pss = "pss"; public static final short NID_pss = 435; public static final String OBJ_pss = "0.9.2342"; public static final String SN_ucl = "ucl"; public static final short NID_ucl = 436; public static final String OBJ_ucl = "0.9.2342.19200300"; public static final String SN_pilot = "pilot"; public static final short NID_pilot = 437; public static final String OBJ_pilot = "0.9.2342.19200300.100"; public static final String LN_pilotAttributeType = "pilotAttributeType"; public static final short NID_pilotAttributeType = 438; public static final String OBJ_pilotAttributeType = "0.9.2342.19200300.100.1"; public static final String LN_pilotAttributeSyntax = "pilotAttributeSyntax"; public static final short NID_pilotAttributeSyntax = 439; public static final String OBJ_pilotAttributeSyntax = "0.9.2342.19200300.100.3"; public static final String LN_pilotObjectClass = "pilotObjectClass"; public static final short NID_pilotObjectClass = 440; public static final String OBJ_pilotObjectClass = "0.9.2342.19200300.100.4"; public static final String LN_pilotGroups = "pilotGroups"; public static final short NID_pilotGroups = 441; public static final String OBJ_pilotGroups = "0.9.2342.19200300.100.10"; public static final String LN_iA5StringSyntax = "iA5StringSyntax"; public static final short NID_iA5StringSyntax = 442; public static final String OBJ_iA5StringSyntax = "0.9.2342.19200300.100.3.4"; public static final String LN_caseIgnoreIA5StringSyntax = "caseIgnoreIA5StringSyntax"; public static final short NID_caseIgnoreIA5StringSyntax = 443; public static final String OBJ_caseIgnoreIA5StringSyntax = "0.9.2342.19200300.100.3.5"; public static final String LN_pilotObject = "pilotObject"; public static final short NID_pilotObject = 444; public static final String OBJ_pilotObject = "0.9.2342.19200300.100.4.3"; public static final String LN_pilotPerson = "pilotPerson"; public static final short NID_pilotPerson = 445; public static final String OBJ_pilotPerson = "0.9.2342.19200300.100.4.4"; public static final String SN_account = "account"; public static final short NID_account = 446; public static final String OBJ_account = "0.9.2342.19200300.100.4.5"; public static final String SN_document = "document"; public static final short NID_document = 447; public static final String OBJ_document = "0.9.2342.19200300.100.4.6"; public static final String SN_room = "room"; public static final short NID_room = 448; public static final String OBJ_room = "0.9.2342.19200300.100.4.7"; public static final String LN_documentSeries = "documentSeries"; public static final short NID_documentSeries = 449; public static final String OBJ_documentSeries = "0.9.2342.19200300.100.4.9"; public static final String SN_Domain = "domain"; public static final String LN_Domain = "Domain"; public static final short NID_Domain = 392; public static final String OBJ_Domain = "0.9.2342.19200300.100.4.13"; public static final String LN_rFC822localPart = "rFC822localPart"; public static final short NID_rFC822localPart = 450; public static final String OBJ_rFC822localPart = "0.9.2342.19200300.100.4.14"; public static final String LN_dNSDomain = "dNSDomain"; public static final short NID_dNSDomain = 451; public static final String OBJ_dNSDomain = "0.9.2342.19200300.100.4.15"; public static final String LN_domainRelatedObject = "domainRelatedObject"; public static final short NID_domainRelatedObject = 452; public static final String OBJ_domainRelatedObject = "0.9.2342.19200300.100.4.17"; public static final String LN_friendlyCountry = "friendlyCountry"; public static final short NID_friendlyCountry = 453; public static final String OBJ_friendlyCountry = "0.9.2342.19200300.100.4.18"; public static final String LN_simpleSecurityObject = "simpleSecurityObject"; public static final short NID_simpleSecurityObject = 454; public static final String OBJ_simpleSecurityObject = "0.9.2342.19200300.100.4.19"; public static final String LN_pilotOrganization = "pilotOrganization"; public static final short NID_pilotOrganization = 455; public static final String OBJ_pilotOrganization = "0.9.2342.19200300.100.4.20"; public static final String LN_pilotDSA = "pilotDSA"; public static final short NID_pilotDSA = 456; public static final String OBJ_pilotDSA = "0.9.2342.19200300.100.4.21"; public static final String LN_qualityLabelledData = "qualityLabelledData"; public static final short NID_qualityLabelledData = 457; public static final String OBJ_qualityLabelledData = "0.9.2342.19200300.100.4.22"; public static final String SN_userId = "UID"; public static final String LN_userId = "userId"; public static final short NID_userId = 458; public static final String OBJ_userId = "0.9.2342.19200300.100.1.1"; public static final String LN_textEncodedORAddress = "textEncodedORAddress"; public static final short NID_textEncodedORAddress = 459; public static final String OBJ_textEncodedORAddress = "0.9.2342.19200300.100.1.2"; public static final String SN_rfc822Mailbox = "mail"; public static final String LN_rfc822Mailbox = "rfc822Mailbox"; public static final short NID_rfc822Mailbox = 460; public static final String OBJ_rfc822Mailbox = "0.9.2342.19200300.100.1.3"; public static final String SN_info = "info"; public static final short NID_info = 461; public static final String OBJ_info = "0.9.2342.19200300.100.1.4"; public static final String LN_favouriteDrink = "favouriteDrink"; public static final short NID_favouriteDrink = 462; public static final String OBJ_favouriteDrink = "0.9.2342.19200300.100.1.5"; public static final String LN_roomNumber = "roomNumber"; public static final short NID_roomNumber = 463; public static final String OBJ_roomNumber = "0.9.2342.19200300.100.1.6"; public static final String SN_photo = "photo"; public static final short NID_photo = 464; public static final String OBJ_photo = "0.9.2342.19200300.100.1.7"; public static final String LN_userClass = "userClass"; public static final short NID_userClass = 465; public static final String OBJ_userClass = "0.9.2342.19200300.100.1.8"; public static final String SN_host = "host"; public static final short NID_host = 466; public static final String OBJ_host = "0.9.2342.19200300.100.1.9"; public static final String SN_manager = "manager"; public static final short NID_manager = 467; public static final String OBJ_manager = "0.9.2342.19200300.100.1.10"; public static final String LN_documentIdentifier = "documentIdentifier"; public static final short NID_documentIdentifier = 468; public static final String OBJ_documentIdentifier = "0.9.2342.19200300.100.1.11"; public static final String LN_documentTitle = "documentTitle"; public static final short NID_documentTitle = 469; public static final String OBJ_documentTitle = "0.9.2342.19200300.100.1.12"; public static final String LN_documentVersion = "documentVersion"; public static final short NID_documentVersion = 470; public static final String OBJ_documentVersion = "0.9.2342.19200300.100.1.13"; public static final String LN_documentAuthor = "documentAuthor"; public static final short NID_documentAuthor = 471; public static final String OBJ_documentAuthor = "0.9.2342.19200300.100.1.14"; public static final String LN_documentLocation = "documentLocation"; public static final short NID_documentLocation = 472; public static final String OBJ_documentLocation = "0.9.2342.19200300.100.1.15"; public static final String LN_homeTelephoneNumber = "homeTelephoneNumber"; public static final short NID_homeTelephoneNumber = 473; public static final String OBJ_homeTelephoneNumber = "0.9.2342.19200300.100.1.20"; public static final String SN_secretary = "secretary"; public static final short NID_secretary = 474; public static final String OBJ_secretary = "0.9.2342.19200300.100.1.21"; public static final String LN_otherMailbox = "otherMailbox"; public static final short NID_otherMailbox = 475; public static final String OBJ_otherMailbox = "0.9.2342.19200300.100.1.22"; public static final String LN_lastModifiedTime = "lastModifiedTime"; public static final short NID_lastModifiedTime = 476; public static final String OBJ_lastModifiedTime = "0.9.2342.19200300.100.1.23"; public static final String LN_lastModifiedBy = "lastModifiedBy"; public static final short NID_lastModifiedBy = 477; public static final String OBJ_lastModifiedBy = "0.9.2342.19200300.100.1.24"; public static final String SN_domainComponent = "DC"; public static final String LN_domainComponent = "domainComponent"; public static final short NID_domainComponent = 391; public static final String OBJ_domainComponent = "0.9.2342.19200300.100.1.25"; public static final String LN_aRecord = "aRecord"; public static final short NID_aRecord = 478; public static final String OBJ_aRecord = "0.9.2342.19200300.100.1.26"; public static final String LN_pilotAttributeType27 = "pilotAttributeType27"; public static final short NID_pilotAttributeType27 = 479; public static final String OBJ_pilotAttributeType27 = "0.9.2342.19200300.100.1.27"; public static final String LN_mXRecord = "mXRecord"; public static final short NID_mXRecord = 480; public static final String OBJ_mXRecord = "0.9.2342.19200300.100.1.28"; public static final String LN_nSRecord = "nSRecord"; public static final short NID_nSRecord = 481; public static final String OBJ_nSRecord = "0.9.2342.19200300.100.1.29"; public static final String LN_sOARecord = "sOARecord"; public static final short NID_sOARecord = 482; public static final String OBJ_sOARecord = "0.9.2342.19200300.100.1.30"; public static final String LN_cNAMERecord = "cNAMERecord"; public static final short NID_cNAMERecord = 483; public static final String OBJ_cNAMERecord = "0.9.2342.19200300.100.1.31"; public static final String LN_associatedDomain = "associatedDomain"; public static final short NID_associatedDomain = 484; public static final String OBJ_associatedDomain = "0.9.2342.19200300.100.1.37"; public static final String LN_associatedName = "associatedName"; public static final short NID_associatedName = 485; public static final String OBJ_associatedName = "0.9.2342.19200300.100.1.38"; public static final String LN_homePostalAddress = "homePostalAddress"; public static final short NID_homePostalAddress = 486; public static final String OBJ_homePostalAddress = "0.9.2342.19200300.100.1.39"; public static final String LN_personalTitle = "personalTitle"; public static final short NID_personalTitle = 487; public static final String OBJ_personalTitle = "0.9.2342.19200300.100.1.40"; public static final String LN_mobileTelephoneNumber = "mobileTelephoneNumber"; public static final short NID_mobileTelephoneNumber = 488; public static final String OBJ_mobileTelephoneNumber = "0.9.2342.19200300.100.1.41"; public static final String LN_pagerTelephoneNumber = "pagerTelephoneNumber"; public static final short NID_pagerTelephoneNumber = 489; public static final String OBJ_pagerTelephoneNumber = "0.9.2342.19200300.100.1.42"; public static final String LN_friendlyCountryName = "friendlyCountryName"; public static final short NID_friendlyCountryName = 490; public static final String OBJ_friendlyCountryName = "0.9.2342.19200300.100.1.43"; public static final String LN_organizationalStatus = "organizationalStatus"; public static final short NID_organizationalStatus = 491; public static final String OBJ_organizationalStatus = "0.9.2342.19200300.100.1.45"; public static final String LN_janetMailbox = "janetMailbox"; public static final short NID_janetMailbox = 492; public static final String OBJ_janetMailbox = "0.9.2342.19200300.100.1.46"; public static final String LN_mailPreferenceOption = "mailPreferenceOption"; public static final short NID_mailPreferenceOption = 493; public static final String OBJ_mailPreferenceOption = "0.9.2342.19200300.100.1.47"; public static final String LN_buildingName = "buildingName"; public static final short NID_buildingName = 494; public static final String OBJ_buildingName = "0.9.2342.19200300.100.1.48"; public static final String LN_dSAQuality = "dSAQuality"; public static final short NID_dSAQuality = 495; public static final String OBJ_dSAQuality = "0.9.2342.19200300.100.1.49"; public static final String LN_singleLevelQuality = "singleLevelQuality"; public static final short NID_singleLevelQuality = 496; public static final String OBJ_singleLevelQuality = "0.9.2342.19200300.100.1.50"; public static final String LN_subtreeMinimumQuality = "subtreeMinimumQuality"; public static final short NID_subtreeMinimumQuality = 497; public static final String OBJ_subtreeMinimumQuality = "0.9.2342.19200300.100.1.51"; public static final String LN_subtreeMaximumQuality = "subtreeMaximumQuality"; public static final short NID_subtreeMaximumQuality = 498; public static final String OBJ_subtreeMaximumQuality = "0.9.2342.19200300.100.1.52"; public static final String LN_personalSignature = "personalSignature"; public static final short NID_personalSignature = 499; public static final String OBJ_personalSignature = "0.9.2342.19200300.100.1.53"; public static final String LN_dITRedirect = "dITRedirect"; public static final short NID_dITRedirect = 500; public static final String OBJ_dITRedirect = "0.9.2342.19200300.100.1.54"; public static final String SN_audio = "audio"; public static final short NID_audio = 501; public static final String OBJ_audio = "0.9.2342.19200300.100.1.55"; public static final String LN_documentPublisher = "documentPublisher"; public static final short NID_documentPublisher = 502; public static final String OBJ_documentPublisher = "0.9.2342.19200300.100.1.56"; public static final String SN_id_set = "id-set"; public static final String LN_id_set = "Secure Electronic Transactions"; public static final short NID_id_set = 512; public static final String OBJ_id_set = "2.23.42"; public static final String SN_set_ctype = "set-ctype"; public static final String LN_set_ctype = "content types"; public static final short NID_set_ctype = 513; public static final String OBJ_set_ctype = "2.23.42.0"; public static final String SN_set_msgExt = "set-msgExt"; public static final String LN_set_msgExt = "message extensions"; public static final short NID_set_msgExt = 514; public static final String OBJ_set_msgExt = "2.23.42.1"; public static final String SN_set_attr = "set-attr"; public static final short NID_set_attr = 515; public static final String OBJ_set_attr = "2.23.42.3"; public static final String SN_set_policy = "set-policy"; public static final short NID_set_policy = 516; public static final String OBJ_set_policy = "2.23.42.5"; public static final String SN_set_certExt = "set-certExt"; public static final String LN_set_certExt = "certificate extensions"; public static final short NID_set_certExt = 517; public static final String OBJ_set_certExt = "2.23.42.7"; public static final String SN_set_brand = "set-brand"; public static final short NID_set_brand = 518; public static final String OBJ_set_brand = "2.23.42.8"; public static final String SN_setct_PANData = "setct-PANData"; public static final short NID_setct_PANData = 519; public static final String OBJ_setct_PANData = "2.23.42.0.0"; public static final String SN_setct_PANToken = "setct-PANToken"; public static final short NID_setct_PANToken = 520; public static final String OBJ_setct_PANToken = "2.23.42.0.1"; public static final String SN_setct_PANOnly = "setct-PANOnly"; public static final short NID_setct_PANOnly = 521; public static final String OBJ_setct_PANOnly = "2.23.42.0.2"; public static final String SN_setct_OIData = "setct-OIData"; public static final short NID_setct_OIData = 522; public static final String OBJ_setct_OIData = "2.23.42.0.3"; public static final String SN_setct_PI = "setct-PI"; public static final short NID_setct_PI = 523; public static final String OBJ_setct_PI = "2.23.42.0.4"; public static final String SN_setct_PIData = "setct-PIData"; public static final short NID_setct_PIData = 524; public static final String OBJ_setct_PIData = "2.23.42.0.5"; public static final String SN_setct_PIDataUnsigned = "setct-PIDataUnsigned"; public static final short NID_setct_PIDataUnsigned = 525; public static final String OBJ_setct_PIDataUnsigned = "2.23.42.0.6"; public static final String SN_setct_HODInput = "setct-HODInput"; public static final short NID_setct_HODInput = 526; public static final String OBJ_setct_HODInput = "2.23.42.0.7"; public static final String SN_setct_AuthResBaggage = "setct-AuthResBaggage"; public static final short NID_setct_AuthResBaggage = 527; public static final String OBJ_setct_AuthResBaggage = "2.23.42.0.8"; public static final String SN_setct_AuthRevReqBaggage = "setct-AuthRevReqBaggage"; public static final short NID_setct_AuthRevReqBaggage = 528; public static final String OBJ_setct_AuthRevReqBaggage = "2.23.42.0.9"; public static final String SN_setct_AuthRevResBaggage = "setct-AuthRevResBaggage"; public static final short NID_setct_AuthRevResBaggage = 529; public static final String OBJ_setct_AuthRevResBaggage = "2.23.42.0.10"; public static final String SN_setct_CapTokenSeq = "setct-CapTokenSeq"; public static final short NID_setct_CapTokenSeq = 530; public static final String OBJ_setct_CapTokenSeq = "2.23.42.0.11"; public static final String SN_setct_PInitResData = "setct-PInitResData"; public static final short NID_setct_PInitResData = 531; public static final String OBJ_setct_PInitResData = "2.23.42.0.12"; public static final String SN_setct_PI_TBS = "setct-PI-TBS"; public static final short NID_setct_PI_TBS = 532; public static final String OBJ_setct_PI_TBS = "2.23.42.0.13"; public static final String SN_setct_PResData = "setct-PResData"; public static final short NID_setct_PResData = 533; public static final String OBJ_setct_PResData = "2.23.42.0.14"; public static final String SN_setct_AuthReqTBS = "setct-AuthReqTBS"; public static final short NID_setct_AuthReqTBS = 534; public static final String OBJ_setct_AuthReqTBS = "2.23.42.0.16"; public static final String SN_setct_AuthResTBS = "setct-AuthResTBS"; public static final short NID_setct_AuthResTBS = 535; public static final String OBJ_setct_AuthResTBS = "2.23.42.0.17"; public static final String SN_setct_AuthResTBSX = "setct-AuthResTBSX"; public static final short NID_setct_AuthResTBSX = 536; public static final String OBJ_setct_AuthResTBSX = "2.23.42.0.18"; public static final String SN_setct_AuthTokenTBS = "setct-AuthTokenTBS"; public static final short NID_setct_AuthTokenTBS = 537; public static final String OBJ_setct_AuthTokenTBS = "2.23.42.0.19"; public static final String SN_setct_CapTokenData = "setct-CapTokenData"; public static final short NID_setct_CapTokenData = 538; public static final String OBJ_setct_CapTokenData = "2.23.42.0.20"; public static final String SN_setct_CapTokenTBS = "setct-CapTokenTBS"; public static final short NID_setct_CapTokenTBS = 539; public static final String OBJ_setct_CapTokenTBS = "2.23.42.0.21"; public static final String SN_setct_AcqCardCodeMsg = "setct-AcqCardCodeMsg"; public static final short NID_setct_AcqCardCodeMsg = 540; public static final String OBJ_setct_AcqCardCodeMsg = "2.23.42.0.22"; public static final String SN_setct_AuthRevReqTBS = "setct-AuthRevReqTBS"; public static final short NID_setct_AuthRevReqTBS = 541; public static final String OBJ_setct_AuthRevReqTBS = "2.23.42.0.23"; public static final String SN_setct_AuthRevResData = "setct-AuthRevResData"; public static final short NID_setct_AuthRevResData = 542; public static final String OBJ_setct_AuthRevResData = "2.23.42.0.24"; public static final String SN_setct_AuthRevResTBS = "setct-AuthRevResTBS"; public static final short NID_setct_AuthRevResTBS = 543; public static final String OBJ_setct_AuthRevResTBS = "2.23.42.0.25"; public static final String SN_setct_CapReqTBS = "setct-CapReqTBS"; public static final short NID_setct_CapReqTBS = 544; public static final String OBJ_setct_CapReqTBS = "2.23.42.0.26"; public static final String SN_setct_CapReqTBSX = "setct-CapReqTBSX"; public static final short NID_setct_CapReqTBSX = 545; public static final String OBJ_setct_CapReqTBSX = "2.23.42.0.27"; public static final String SN_setct_CapResData = "setct-CapResData"; public static final short NID_setct_CapResData = 546; public static final String OBJ_setct_CapResData = "2.23.42.0.28"; public static final String SN_setct_CapRevReqTBS = "setct-CapRevReqTBS"; public static final short NID_setct_CapRevReqTBS = 547; public static final String OBJ_setct_CapRevReqTBS = "2.23.42.0.29"; public static final String SN_setct_CapRevReqTBSX = "setct-CapRevReqTBSX"; public static final short NID_setct_CapRevReqTBSX = 548; public static final String OBJ_setct_CapRevReqTBSX = "2.23.42.0.30"; public static final String SN_setct_CapRevResData = "setct-CapRevResData"; public static final short NID_setct_CapRevResData = 549; public static final String OBJ_setct_CapRevResData = "2.23.42.0.31"; public static final String SN_setct_CredReqTBS = "setct-CredReqTBS"; public static final short NID_setct_CredReqTBS = 550; public static final String OBJ_setct_CredReqTBS = "2.23.42.0.32"; public static final String SN_setct_CredReqTBSX = "setct-CredReqTBSX"; public static final short NID_setct_CredReqTBSX = 551; public static final String OBJ_setct_CredReqTBSX = "2.23.42.0.33"; public static final String SN_setct_CredResData = "setct-CredResData"; public static final short NID_setct_CredResData = 552; public static final String OBJ_setct_CredResData = "2.23.42.0.34"; public static final String SN_setct_CredRevReqTBS = "setct-CredRevReqTBS"; public static final short NID_setct_CredRevReqTBS = 553; public static final String OBJ_setct_CredRevReqTBS = "2.23.42.0.35"; public static final String SN_setct_CredRevReqTBSX = "setct-CredRevReqTBSX"; public static final short NID_setct_CredRevReqTBSX = 554; public static final String OBJ_setct_CredRevReqTBSX = "2.23.42.0.36"; public static final String SN_setct_CredRevResData = "setct-CredRevResData"; public static final short NID_setct_CredRevResData = 555; public static final String OBJ_setct_CredRevResData = "2.23.42.0.37"; public static final String SN_setct_PCertReqData = "setct-PCertReqData"; public static final short NID_setct_PCertReqData = 556; public static final String OBJ_setct_PCertReqData = "2.23.42.0.38"; public static final String SN_setct_PCertResTBS = "setct-PCertResTBS"; public static final short NID_setct_PCertResTBS = 557; public static final String OBJ_setct_PCertResTBS = "2.23.42.0.39"; public static final String SN_setct_BatchAdminReqData = "setct-BatchAdminReqData"; public static final short NID_setct_BatchAdminReqData = 558; public static final String OBJ_setct_BatchAdminReqData = "2.23.42.0.40"; public static final String SN_setct_BatchAdminResData = "setct-BatchAdminResData"; public static final short NID_setct_BatchAdminResData = 559; public static final String OBJ_setct_BatchAdminResData = "2.23.42.0.41"; public static final String SN_setct_CardCInitResTBS = "setct-CardCInitResTBS"; public static final short NID_setct_CardCInitResTBS = 560; public static final String OBJ_setct_CardCInitResTBS = "2.23.42.0.42"; public static final String SN_setct_MeAqCInitResTBS = "setct-MeAqCInitResTBS"; public static final short NID_setct_MeAqCInitResTBS = 561; public static final String OBJ_setct_MeAqCInitResTBS = "2.23.42.0.43"; public static final String SN_setct_RegFormResTBS = "setct-RegFormResTBS"; public static final short NID_setct_RegFormResTBS = 562; public static final String OBJ_setct_RegFormResTBS = "2.23.42.0.44"; public static final String SN_setct_CertReqData = "setct-CertReqData"; public static final short NID_setct_CertReqData = 563; public static final String OBJ_setct_CertReqData = "2.23.42.0.45"; public static final String SN_setct_CertReqTBS = "setct-CertReqTBS"; public static final short NID_setct_CertReqTBS = 564; public static final String OBJ_setct_CertReqTBS = "2.23.42.0.46"; public static final String SN_setct_CertResData = "setct-CertResData"; public static final short NID_setct_CertResData = 565; public static final String OBJ_setct_CertResData = "2.23.42.0.47"; public static final String SN_setct_CertInqReqTBS = "setct-CertInqReqTBS"; public static final short NID_setct_CertInqReqTBS = 566; public static final String OBJ_setct_CertInqReqTBS = "2.23.42.0.48"; public static final String SN_setct_ErrorTBS = "setct-ErrorTBS"; public static final short NID_setct_ErrorTBS = 567; public static final String OBJ_setct_ErrorTBS = "2.23.42.0.49"; public static final String SN_setct_PIDualSignedTBE = "setct-PIDualSignedTBE"; public static final short NID_setct_PIDualSignedTBE = 568; public static final String OBJ_setct_PIDualSignedTBE = "2.23.42.0.50"; public static final String SN_setct_PIUnsignedTBE = "setct-PIUnsignedTBE"; public static final short NID_setct_PIUnsignedTBE = 569; public static final String OBJ_setct_PIUnsignedTBE = "2.23.42.0.51"; public static final String SN_setct_AuthReqTBE = "setct-AuthReqTBE"; public static final short NID_setct_AuthReqTBE = 570; public static final String OBJ_setct_AuthReqTBE = "2.23.42.0.52"; public static final String SN_setct_AuthResTBE = "setct-AuthResTBE"; public static final short NID_setct_AuthResTBE = 571; public static final String OBJ_setct_AuthResTBE = "2.23.42.0.53"; public static final String SN_setct_AuthResTBEX = "setct-AuthResTBEX"; public static final short NID_setct_AuthResTBEX = 572; public static final String OBJ_setct_AuthResTBEX = "2.23.42.0.54"; public static final String SN_setct_AuthTokenTBE = "setct-AuthTokenTBE"; public static final short NID_setct_AuthTokenTBE = 573; public static final String OBJ_setct_AuthTokenTBE = "2.23.42.0.55"; public static final String SN_setct_CapTokenTBE = "setct-CapTokenTBE"; public static final short NID_setct_CapTokenTBE = 574; public static final String OBJ_setct_CapTokenTBE = "2.23.42.0.56"; public static final String SN_setct_CapTokenTBEX = "setct-CapTokenTBEX"; public static final short NID_setct_CapTokenTBEX = 575; public static final String OBJ_setct_CapTokenTBEX = "2.23.42.0.57"; public static final String SN_setct_AcqCardCodeMsgTBE = "setct-AcqCardCodeMsgTBE"; public static final short NID_setct_AcqCardCodeMsgTBE = 576; public static final String OBJ_setct_AcqCardCodeMsgTBE = "2.23.42.0.58"; public static final String SN_setct_AuthRevReqTBE = "setct-AuthRevReqTBE"; public static final short NID_setct_AuthRevReqTBE = 577; public static final String OBJ_setct_AuthRevReqTBE = "2.23.42.0.59"; public static final String SN_setct_AuthRevResTBE = "setct-AuthRevResTBE"; public static final short NID_setct_AuthRevResTBE = 578; public static final String OBJ_setct_AuthRevResTBE = "2.23.42.0.60"; public static final String SN_setct_AuthRevResTBEB = "setct-AuthRevResTBEB"; public static final short NID_setct_AuthRevResTBEB = 579; public static final String OBJ_setct_AuthRevResTBEB = "2.23.42.0.61"; public static final String SN_setct_CapReqTBE = "setct-CapReqTBE"; public static final short NID_setct_CapReqTBE = 580; public static final String OBJ_setct_CapReqTBE = "2.23.42.0.62"; public static final String SN_setct_CapReqTBEX = "setct-CapReqTBEX"; public static final short NID_setct_CapReqTBEX = 581; public static final String OBJ_setct_CapReqTBEX = "2.23.42.0.63"; public static final String SN_setct_CapResTBE = "setct-CapResTBE"; public static final short NID_setct_CapResTBE = 582; public static final String OBJ_setct_CapResTBE = "2.23.42.0.64"; public static final String SN_setct_CapRevReqTBE = "setct-CapRevReqTBE"; public static final short NID_setct_CapRevReqTBE = 583; public static final String OBJ_setct_CapRevReqTBE = "2.23.42.0.65"; public static final String SN_setct_CapRevReqTBEX = "setct-CapRevReqTBEX"; public static final short NID_setct_CapRevReqTBEX = 584; public static final String OBJ_setct_CapRevReqTBEX = "2.23.42.0.66"; public static final String SN_setct_CapRevResTBE = "setct-CapRevResTBE"; public static final short NID_setct_CapRevResTBE = 585; public static final String OBJ_setct_CapRevResTBE = "2.23.42.0.67"; public static final String SN_setct_CredReqTBE = "setct-CredReqTBE"; public static final short NID_setct_CredReqTBE = 586; public static final String OBJ_setct_CredReqTBE = "2.23.42.0.68"; public static final String SN_setct_CredReqTBEX = "setct-CredReqTBEX"; public static final short NID_setct_CredReqTBEX = 587; public static final String OBJ_setct_CredReqTBEX = "2.23.42.0.69"; public static final String SN_setct_CredResTBE = "setct-CredResTBE"; public static final short NID_setct_CredResTBE = 588; public static final String OBJ_setct_CredResTBE = "2.23.42.0.70"; public static final String SN_setct_CredRevReqTBE = "setct-CredRevReqTBE"; public static final short NID_setct_CredRevReqTBE = 589; public static final String OBJ_setct_CredRevReqTBE = "2.23.42.0.71"; public static final String SN_setct_CredRevReqTBEX = "setct-CredRevReqTBEX"; public static final short NID_setct_CredRevReqTBEX = 590; public static final String OBJ_setct_CredRevReqTBEX = "2.23.42.0.72"; public static final String SN_setct_CredRevResTBE = "setct-CredRevResTBE"; public static final short NID_setct_CredRevResTBE = 591; public static final String OBJ_setct_CredRevResTBE = "2.23.42.0.73"; public static final String SN_setct_BatchAdminReqTBE = "setct-BatchAdminReqTBE"; public static final short NID_setct_BatchAdminReqTBE = 592; public static final String OBJ_setct_BatchAdminReqTBE = "2.23.42.0.74"; public static final String SN_setct_BatchAdminResTBE = "setct-BatchAdminResTBE"; public static final short NID_setct_BatchAdminResTBE = 593; public static final String OBJ_setct_BatchAdminResTBE = "2.23.42.0.75"; public static final String SN_setct_RegFormReqTBE = "setct-RegFormReqTBE"; public static final short NID_setct_RegFormReqTBE = 594; public static final String OBJ_setct_RegFormReqTBE = "2.23.42.0.76"; public static final String SN_setct_CertReqTBE = "setct-CertReqTBE"; public static final short NID_setct_CertReqTBE = 595; public static final String OBJ_setct_CertReqTBE = "2.23.42.0.77"; public static final String SN_setct_CertReqTBEX = "setct-CertReqTBEX"; public static final short NID_setct_CertReqTBEX = 596; public static final String OBJ_setct_CertReqTBEX = "2.23.42.0.78"; public static final String SN_setct_CertResTBE = "setct-CertResTBE"; public static final short NID_setct_CertResTBE = 597; public static final String OBJ_setct_CertResTBE = "2.23.42.0.79"; public static final String SN_setct_CRLNotificationTBS = "setct-CRLNotificationTBS"; public static final short NID_setct_CRLNotificationTBS = 598; public static final String OBJ_setct_CRLNotificationTBS = "2.23.42.0.80"; public static final String SN_setct_CRLNotificationResTBS = "setct-CRLNotificationResTBS"; public static final short NID_setct_CRLNotificationResTBS = 599; public static final String OBJ_setct_CRLNotificationResTBS = "2.23.42.0.81"; public static final String SN_setct_BCIDistributionTBS = "setct-BCIDistributionTBS"; public static final short NID_setct_BCIDistributionTBS = 600; public static final String OBJ_setct_BCIDistributionTBS = "2.23.42.0.82"; public static final String SN_setext_genCrypt = "setext-genCrypt"; public static final String LN_setext_genCrypt = "generic cryptogram"; public static final short NID_setext_genCrypt = 601; public static final String OBJ_setext_genCrypt = "2.23.42.1.1"; public static final String SN_setext_miAuth = "setext-miAuth"; public static final String LN_setext_miAuth = "merchant initiated auth"; public static final short NID_setext_miAuth = 602; public static final String OBJ_setext_miAuth = "2.23.42.1.3"; public static final String SN_setext_pinSecure = "setext-pinSecure"; public static final short NID_setext_pinSecure = 603; public static final String OBJ_setext_pinSecure = "2.23.42.1.4"; public static final String SN_setext_pinAny = "setext-pinAny"; public static final short NID_setext_pinAny = 604; public static final String OBJ_setext_pinAny = "2.23.42.1.5"; public static final String SN_setext_track2 = "setext-track2"; public static final short NID_setext_track2 = 605; public static final String OBJ_setext_track2 = "2.23.42.1.7"; public static final String SN_setext_cv = "setext-cv"; public static final String LN_setext_cv = "additional verification"; public static final short NID_setext_cv = 606; public static final String OBJ_setext_cv = "2.23.42.1.8"; public static final String SN_set_policy_root = "set-policy-root"; public static final short NID_set_policy_root = 607; public static final String OBJ_set_policy_root = "2.23.42.5.0"; public static final String SN_setCext_hashedRoot = "setCext-hashedRoot"; public static final short NID_setCext_hashedRoot = 608; public static final String OBJ_setCext_hashedRoot = "2.23.42.7.0"; public static final String SN_setCext_certType = "setCext-certType"; public static final short NID_setCext_certType = 609; public static final String OBJ_setCext_certType = "2.23.42.7.1"; public static final String SN_setCext_merchData = "setCext-merchData"; public static final short NID_setCext_merchData = 610; public static final String OBJ_setCext_merchData = "2.23.42.7.2"; public static final String SN_setCext_cCertRequired = "setCext-cCertRequired"; public static final short NID_setCext_cCertRequired = 611; public static final String OBJ_setCext_cCertRequired = "2.23.42.7.3"; public static final String SN_setCext_tunneling = "setCext-tunneling"; public static final short NID_setCext_tunneling = 612; public static final String OBJ_setCext_tunneling = "2.23.42.7.4"; public static final String SN_setCext_setExt = "setCext-setExt"; public static final short NID_setCext_setExt = 613; public static final String OBJ_setCext_setExt = "2.23.42.7.5"; public static final String SN_setCext_setQualf = "setCext-setQualf"; public static final short NID_setCext_setQualf = 614; public static final String OBJ_setCext_setQualf = "2.23.42.7.6"; public static final String SN_setCext_PGWYcapabilities = "setCext-PGWYcapabilities"; public static final short NID_setCext_PGWYcapabilities = 615; public static final String OBJ_setCext_PGWYcapabilities = "2.23.42.7.7"; public static final String SN_setCext_TokenIdentifier = "setCext-TokenIdentifier"; public static final short NID_setCext_TokenIdentifier = 616; public static final String OBJ_setCext_TokenIdentifier = "2.23.42.7.8"; public static final String SN_setCext_Track2Data = "setCext-Track2Data"; public static final short NID_setCext_Track2Data = 617; public static final String OBJ_setCext_Track2Data = "2.23.42.7.9"; public static final String SN_setCext_TokenType = "setCext-TokenType"; public static final short NID_setCext_TokenType = 618; public static final String OBJ_setCext_TokenType = "2.23.42.7.10"; public static final String SN_setCext_IssuerCapabilities = "setCext-IssuerCapabilities"; public static final short NID_setCext_IssuerCapabilities = 619; public static final String OBJ_setCext_IssuerCapabilities = "2.23.42.7.11"; public static final String SN_setAttr_Cert = "setAttr-Cert"; public static final short NID_setAttr_Cert = 620; public static final String OBJ_setAttr_Cert = "2.23.42.3.0"; public static final String SN_setAttr_PGWYcap = "setAttr-PGWYcap"; public static final String LN_setAttr_PGWYcap = "payment gateway capabilities"; public static final short NID_setAttr_PGWYcap = 621; public static final String OBJ_setAttr_PGWYcap = "2.23.42.3.1"; public static final String SN_setAttr_TokenType = "setAttr-TokenType"; public static final short NID_setAttr_TokenType = 622; public static final String OBJ_setAttr_TokenType = "2.23.42.3.2"; public static final String SN_setAttr_IssCap = "setAttr-IssCap"; public static final String LN_setAttr_IssCap = "issuer capabilities"; public static final short NID_setAttr_IssCap = 623; public static final String OBJ_setAttr_IssCap = "2.23.42.3.3"; public static final String SN_set_rootKeyThumb = "set-rootKeyThumb"; public static final short NID_set_rootKeyThumb = 624; public static final String OBJ_set_rootKeyThumb = "2.23.42.3.0.0"; public static final String SN_set_addPolicy = "set-addPolicy"; public static final short NID_set_addPolicy = 625; public static final String OBJ_set_addPolicy = "2.23.42.3.0.1"; public static final String SN_setAttr_Token_EMV = "setAttr-Token-EMV"; public static final short NID_setAttr_Token_EMV = 626; public static final String OBJ_setAttr_Token_EMV = "2.23.42.3.2.1"; public static final String SN_setAttr_Token_B0Prime = "setAttr-Token-B0Prime"; public static final short NID_setAttr_Token_B0Prime = 627; public static final String OBJ_setAttr_Token_B0Prime = "2.23.42.3.2.2"; public static final String SN_setAttr_IssCap_CVM = "setAttr-IssCap-CVM"; public static final short NID_setAttr_IssCap_CVM = 628; public static final String OBJ_setAttr_IssCap_CVM = "2.23.42.3.3.3"; public static final String SN_setAttr_IssCap_T2 = "setAttr-IssCap-T2"; public static final short NID_setAttr_IssCap_T2 = 629; public static final String OBJ_setAttr_IssCap_T2 = "2.23.42.3.3.4"; public static final String SN_setAttr_IssCap_Sig = "setAttr-IssCap-Sig"; public static final short NID_setAttr_IssCap_Sig = 630; public static final String OBJ_setAttr_IssCap_Sig = "2.23.42.3.3.5"; public static final String SN_setAttr_GenCryptgrm = "setAttr-GenCryptgrm"; public static final String LN_setAttr_GenCryptgrm = "generate cryptogram"; public static final short NID_setAttr_GenCryptgrm = 631; public static final String OBJ_setAttr_GenCryptgrm = "2.23.42.3.3.3.1"; public static final String SN_setAttr_T2Enc = "setAttr-T2Enc"; public static final String LN_setAttr_T2Enc = "encrypted track 2"; public static final short NID_setAttr_T2Enc = 632; public static final String OBJ_setAttr_T2Enc = "2.23.42.3.3.4.1"; public static final String SN_setAttr_T2cleartxt = "setAttr-T2cleartxt"; public static final String LN_setAttr_T2cleartxt = "cleartext track 2"; public static final short NID_setAttr_T2cleartxt = 633; public static final String OBJ_setAttr_T2cleartxt = "2.23.42.3.3.4.2"; public static final String SN_setAttr_TokICCsig = "setAttr-TokICCsig"; public static final String LN_setAttr_TokICCsig = "ICC or token signature"; public static final short NID_setAttr_TokICCsig = 634; public static final String OBJ_setAttr_TokICCsig = "2.23.42.3.3.5.1"; public static final String SN_setAttr_SecDevSig = "setAttr-SecDevSig"; public static final String LN_setAttr_SecDevSig = "secure device signature"; public static final short NID_setAttr_SecDevSig = 635; public static final String OBJ_setAttr_SecDevSig = "2.23.42.3.3.5.2"; public static final String SN_set_brand_IATA_ATA = "set-brand-IATA-ATA"; public static final short NID_set_brand_IATA_ATA = 636; public static final String OBJ_set_brand_IATA_ATA = "2.23.42.8.1"; public static final String SN_set_brand_Diners = "set-brand-Diners"; public static final short NID_set_brand_Diners = 637; public static final String OBJ_set_brand_Diners = "2.23.42.8.30"; public static final String SN_set_brand_AmericanExpress = "set-brand-AmericanExpress"; public static final short NID_set_brand_AmericanExpress = 638; public static final String OBJ_set_brand_AmericanExpress = "2.23.42.8.34"; public static final String SN_set_brand_JCB = "set-brand-JCB"; public static final short NID_set_brand_JCB = 639; public static final String OBJ_set_brand_JCB = "2.23.42.8.35"; public static final String SN_set_brand_Visa = "set-brand-Visa"; public static final short NID_set_brand_Visa = 640; public static final String OBJ_set_brand_Visa = "2.23.42.8.4"; public static final String SN_set_brand_MasterCard = "set-brand-MasterCard"; public static final short NID_set_brand_MasterCard = 641; public static final String OBJ_set_brand_MasterCard = "2.23.42.8.5"; public static final String SN_set_brand_Novus = "set-brand-Novus"; public static final short NID_set_brand_Novus = 642; public static final String OBJ_set_brand_Novus = "2.23.42.8.6011"; public static final String SN_des_cdmf = "DES-CDMF"; public static final String LN_des_cdmf = "des-cdmf"; public static final short NID_des_cdmf = 643; public static final String OBJ_des_cdmf = "1.2.840.113549.3.10"; public static final String SN_rsaOAEPEncryptionSET = "rsaOAEPEncryptionSET"; public static final short NID_rsaOAEPEncryptionSET = 644; public static final String OBJ_rsaOAEPEncryptionSET = "1.2.840.113549.1.1.6"; public static final String SN_ipsec3 = "Oakley-EC2N-3"; public static final String LN_ipsec3 = "ipsec3"; public static final short NID_ipsec3 = 749; public static final String SN_ipsec4 = "Oakley-EC2N-4"; public static final String LN_ipsec4 = "ipsec4"; public static final short NID_ipsec4 = 750; public static final String SN_whirlpool = "whirlpool"; public static final short NID_whirlpool = 804; public static final String OBJ_whirlpool = "1.0.10118.3.0.55"; public static final String SN_cryptopro = "cryptopro"; public static final short NID_cryptopro = 805; public static final String OBJ_cryptopro = "1.2.643.2.2"; public static final String SN_cryptocom = "cryptocom"; public static final short NID_cryptocom = 806; public static final String OBJ_cryptocom = "1.2.643.2.9"; public static final String SN_id_GostR3411_94_with_GostR3410_2001 = "id-GostR3411-94-with-GostR3410-2001"; public static final String LN_id_GostR3411_94_with_GostR3410_2001 = "GOST R 34.11-94 with GOST R 34.10-2001"; public static final short NID_id_GostR3411_94_with_GostR3410_2001 = 807; public static final String OBJ_id_GostR3411_94_with_GostR3410_2001 = "1.2.643.2.2.3"; public static final String SN_id_GostR3411_94_with_GostR3410_94 = "id-GostR3411-94-with-GostR3410-94"; public static final String LN_id_GostR3411_94_with_GostR3410_94 = "GOST R 34.11-94 with GOST R 34.10-94"; public static final short NID_id_GostR3411_94_with_GostR3410_94 = 808; public static final String OBJ_id_GostR3411_94_with_GostR3410_94 = "1.2.643.2.2.4"; public static final String SN_id_GostR3411_94 = "md_gost94"; public static final String LN_id_GostR3411_94 = "GOST R 34.11-94"; public static final short NID_id_GostR3411_94 = 809; public static final String OBJ_id_GostR3411_94 = "1.2.643.2.2.9"; public static final String SN_id_HMACGostR3411_94 = "id-HMACGostR3411-94"; public static final String LN_id_HMACGostR3411_94 = "HMAC GOST 34.11-94"; public static final short NID_id_HMACGostR3411_94 = 810; public static final String OBJ_id_HMACGostR3411_94 = "1.2.643.2.2.10"; public static final String SN_id_GostR3410_2001 = "gost2001"; public static final String LN_id_GostR3410_2001 = "GOST R 34.10-2001"; public static final short NID_id_GostR3410_2001 = 811; public static final String OBJ_id_GostR3410_2001 = "1.2.643.2.2.19"; public static final String SN_id_GostR3410_94 = "gost94"; public static final String LN_id_GostR3410_94 = "GOST R 34.10-94"; public static final short NID_id_GostR3410_94 = 812; public static final String OBJ_id_GostR3410_94 = "1.2.643.2.2.20"; public static final String SN_id_Gost28147_89 = "gost89"; public static final String LN_id_Gost28147_89 = "GOST 28147-89"; public static final short NID_id_Gost28147_89 = 813; public static final String OBJ_id_Gost28147_89 = "1.2.643.2.2.21"; public static final String SN_gost89_cnt = "gost89-cnt"; public static final short NID_gost89_cnt = 814; public static final String SN_id_Gost28147_89_MAC = "gost-mac"; public static final String LN_id_Gost28147_89_MAC = "GOST 28147-89 MAC"; public static final short NID_id_Gost28147_89_MAC = 815; public static final String OBJ_id_Gost28147_89_MAC = "1.2.643.2.2.22"; public static final String SN_id_GostR3411_94_prf = "prf-gostr3411-94"; public static final String LN_id_GostR3411_94_prf = "GOST R 34.11-94 PRF"; public static final short NID_id_GostR3411_94_prf = 816; public static final String OBJ_id_GostR3411_94_prf = "1.2.643.2.2.23"; public static final String SN_id_GostR3410_2001DH = "id-GostR3410-2001DH"; public static final String LN_id_GostR3410_2001DH = "GOST R 34.10-2001 DH"; public static final short NID_id_GostR3410_2001DH = 817; public static final String OBJ_id_GostR3410_2001DH = "1.2.643.2.2.98"; public static final String SN_id_GostR3410_94DH = "id-GostR3410-94DH"; public static final String LN_id_GostR3410_94DH = "GOST R 34.10-94 DH"; public static final short NID_id_GostR3410_94DH = 818; public static final String OBJ_id_GostR3410_94DH = "1.2.643.2.2.99"; public static final String SN_id_Gost28147_89_CryptoPro_KeyMeshing = "id-Gost28147-89-CryptoPro-KeyMeshing"; public static final short NID_id_Gost28147_89_CryptoPro_KeyMeshing = 819; public static final String OBJ_id_Gost28147_89_CryptoPro_KeyMeshing = "1.2.643.2.2.14.1"; public static final String SN_id_Gost28147_89_None_KeyMeshing = "id-Gost28147-89-None-KeyMeshing"; public static final short NID_id_Gost28147_89_None_KeyMeshing = 820; public static final String OBJ_id_Gost28147_89_None_KeyMeshing = "1.2.643.2.2.14.0"; public static final String SN_id_GostR3411_94_TestParamSet = "id-GostR3411-94-TestParamSet"; public static final short NID_id_GostR3411_94_TestParamSet = 821; public static final String OBJ_id_GostR3411_94_TestParamSet = "1.2.643.2.2.30.0"; public static final String SN_id_GostR3411_94_CryptoProParamSet = "id-GostR3411-94-CryptoProParamSet"; public static final short NID_id_GostR3411_94_CryptoProParamSet = 822; public static final String OBJ_id_GostR3411_94_CryptoProParamSet = "1.2.643.2.2.30.1"; public static final String SN_id_Gost28147_89_TestParamSet = "id-Gost28147-89-TestParamSet"; public static final short NID_id_Gost28147_89_TestParamSet = 823; public static final String OBJ_id_Gost28147_89_TestParamSet = "1.2.643.2.2.31.0"; public static final String SN_id_Gost28147_89_CryptoPro_A_ParamSet = "id-Gost28147-89-CryptoPro-A-ParamSet"; public static final short NID_id_Gost28147_89_CryptoPro_A_ParamSet = 824; public static final String OBJ_id_Gost28147_89_CryptoPro_A_ParamSet = "1.2.643.2.2.31.1"; public static final String SN_id_Gost28147_89_CryptoPro_B_ParamSet = "id-Gost28147-89-CryptoPro-B-ParamSet"; public static final short NID_id_Gost28147_89_CryptoPro_B_ParamSet = 825; public static final String OBJ_id_Gost28147_89_CryptoPro_B_ParamSet = "1.2.643.2.2.31.2"; public static final String SN_id_Gost28147_89_CryptoPro_C_ParamSet = "id-Gost28147-89-CryptoPro-C-ParamSet"; public static final short NID_id_Gost28147_89_CryptoPro_C_ParamSet = 826; public static final String OBJ_id_Gost28147_89_CryptoPro_C_ParamSet = "1.2.643.2.2.31.3"; public static final String SN_id_Gost28147_89_CryptoPro_D_ParamSet = "id-Gost28147-89-CryptoPro-D-ParamSet"; public static final short NID_id_Gost28147_89_CryptoPro_D_ParamSet = 827; public static final String OBJ_id_Gost28147_89_CryptoPro_D_ParamSet = "1.2.643.2.2.31.4"; public static final String SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet = "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"; public static final short NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet = 828; public static final String OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet = "1.2.643.2.2.31.5"; public static final String SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet = "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"; public static final short NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet = 829; public static final String OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet = "1.2.643.2.2.31.6"; public static final String SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet = "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"; public static final short NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet = 830; public static final String OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet = "1.2.643.2.2.31.7"; public static final String SN_id_GostR3410_94_TestParamSet = "id-GostR3410-94-TestParamSet"; public static final short NID_id_GostR3410_94_TestParamSet = 831; public static final String OBJ_id_GostR3410_94_TestParamSet = "1.2.643.2.2.32.0"; public static final String SN_id_GostR3410_94_CryptoPro_A_ParamSet = "id-GostR3410-94-CryptoPro-A-ParamSet"; public static final short NID_id_GostR3410_94_CryptoPro_A_ParamSet = 832; public static final String OBJ_id_GostR3410_94_CryptoPro_A_ParamSet = "1.2.643.2.2.32.2"; public static final String SN_id_GostR3410_94_CryptoPro_B_ParamSet = "id-GostR3410-94-CryptoPro-B-ParamSet"; public static final short NID_id_GostR3410_94_CryptoPro_B_ParamSet = 833; public static final String OBJ_id_GostR3410_94_CryptoPro_B_ParamSet = "1.2.643.2.2.32.3"; public static final String SN_id_GostR3410_94_CryptoPro_C_ParamSet = "id-GostR3410-94-CryptoPro-C-ParamSet"; public static final short NID_id_GostR3410_94_CryptoPro_C_ParamSet = 834; public static final String OBJ_id_GostR3410_94_CryptoPro_C_ParamSet = "1.2.643.2.2.32.4"; public static final String SN_id_GostR3410_94_CryptoPro_D_ParamSet = "id-GostR3410-94-CryptoPro-D-ParamSet"; public static final short NID_id_GostR3410_94_CryptoPro_D_ParamSet = 835; public static final String OBJ_id_GostR3410_94_CryptoPro_D_ParamSet = "1.2.643.2.2.32.5"; public static final String SN_id_GostR3410_94_CryptoPro_XchA_ParamSet = "id-GostR3410-94-CryptoPro-XchA-ParamSet"; public static final short NID_id_GostR3410_94_CryptoPro_XchA_ParamSet = 836; public static final String OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet = "1.2.643.2.2.33.1"; public static final String SN_id_GostR3410_94_CryptoPro_XchB_ParamSet = "id-GostR3410-94-CryptoPro-XchB-ParamSet"; public static final short NID_id_GostR3410_94_CryptoPro_XchB_ParamSet = 837; public static final String OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet = "1.2.643.2.2.33.2"; public static final String SN_id_GostR3410_94_CryptoPro_XchC_ParamSet = "id-GostR3410-94-CryptoPro-XchC-ParamSet"; public static final short NID_id_GostR3410_94_CryptoPro_XchC_ParamSet = 838; public static final String OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet = "1.2.643.2.2.33.3"; public static final String SN_id_GostR3410_2001_TestParamSet = "id-GostR3410-2001-TestParamSet"; public static final short NID_id_GostR3410_2001_TestParamSet = 839; public static final String OBJ_id_GostR3410_2001_TestParamSet = "1.2.643.2.2.35.0"; public static final String SN_id_GostR3410_2001_CryptoPro_A_ParamSet = "id-GostR3410-2001-CryptoPro-A-ParamSet"; public static final short NID_id_GostR3410_2001_CryptoPro_A_ParamSet = 840; public static final String OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet = "1.2.643.2.2.35.1"; public static final String SN_id_GostR3410_2001_CryptoPro_B_ParamSet = "id-GostR3410-2001-CryptoPro-B-ParamSet"; public static final short NID_id_GostR3410_2001_CryptoPro_B_ParamSet = 841; public static final String OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet = "1.2.643.2.2.35.2"; public static final String SN_id_GostR3410_2001_CryptoPro_C_ParamSet = "id-GostR3410-2001-CryptoPro-C-ParamSet"; public static final short NID_id_GostR3410_2001_CryptoPro_C_ParamSet = 842; public static final String OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet = "1.2.643.2.2.35.3"; public static final String SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet = "id-GostR3410-2001-CryptoPro-XchA-ParamSet"; public static final short NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet = 843; public static final String OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet = "1.2.643.2.2.36.0"; public static final String SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet = "id-GostR3410-2001-CryptoPro-XchB-ParamSet"; public static final short NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet = 844; public static final String OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet = "1.2.643.2.2.36.1"; public static final String SN_id_GostR3410_94_a = "id-GostR3410-94-a"; public static final short NID_id_GostR3410_94_a = 845; public static final String OBJ_id_GostR3410_94_a = "1.2.643.2.2.20.1"; public static final String SN_id_GostR3410_94_aBis = "id-GostR3410-94-aBis"; public static final short NID_id_GostR3410_94_aBis = 846; public static final String OBJ_id_GostR3410_94_aBis = "1.2.643.2.2.20.2"; public static final String SN_id_GostR3410_94_b = "id-GostR3410-94-b"; public static final short NID_id_GostR3410_94_b = 847; public static final String OBJ_id_GostR3410_94_b = "1.2.643.2.2.20.3"; public static final String SN_id_GostR3410_94_bBis = "id-GostR3410-94-bBis"; public static final short NID_id_GostR3410_94_bBis = 848; public static final String OBJ_id_GostR3410_94_bBis = "1.2.643.2.2.20.4"; public static final String SN_id_Gost28147_89_cc = "id-Gost28147-89-cc"; public static final String LN_id_Gost28147_89_cc = "GOST 28147-89 Cryptocom ParamSet"; public static final short NID_id_Gost28147_89_cc = 849; public static final String OBJ_id_Gost28147_89_cc = "1.2.643.2.9.1.6.1"; public static final String SN_id_GostR3410_94_cc = "gost94cc"; public static final String LN_id_GostR3410_94_cc = "GOST 34.10-94 Cryptocom"; public static final short NID_id_GostR3410_94_cc = 850; public static final String OBJ_id_GostR3410_94_cc = "1.2.643.2.9.1.5.3"; public static final String SN_id_GostR3410_2001_cc = "gost2001cc"; public static final String LN_id_GostR3410_2001_cc = "GOST 34.10-2001 Cryptocom"; public static final short NID_id_GostR3410_2001_cc = 851; public static final String OBJ_id_GostR3410_2001_cc = "1.2.643.2.9.1.5.4"; public static final String SN_id_GostR3411_94_with_GostR3410_94_cc = "id-GostR3411-94-with-GostR3410-94-cc"; public static final String LN_id_GostR3411_94_with_GostR3410_94_cc = "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"; public static final short NID_id_GostR3411_94_with_GostR3410_94_cc = 852; public static final String OBJ_id_GostR3411_94_with_GostR3410_94_cc = "1.2.643.2.9.1.3.3"; public static final String SN_id_GostR3411_94_with_GostR3410_2001_cc = "id-GostR3411-94-with-GostR3410-2001-cc"; public static final String LN_id_GostR3411_94_with_GostR3410_2001_cc = "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"; public static final short NID_id_GostR3411_94_with_GostR3410_2001_cc = 853; public static final String OBJ_id_GostR3411_94_with_GostR3410_2001_cc = "1.2.643.2.9.1.3.4"; public static final String SN_id_GostR3410_2001_ParamSet_cc = "id-GostR3410-2001-ParamSet-cc"; public static final String LN_id_GostR3410_2001_ParamSet_cc = "GOST R 3410-2001 Parameter Set Cryptocom"; public static final short NID_id_GostR3410_2001_ParamSet_cc = 854; public static final String OBJ_id_GostR3410_2001_ParamSet_cc = "1.2.643.2.9.1.8.1"; public static final String SN_camellia_128_cbc = "CAMELLIA-128-CBC"; public static final String LN_camellia_128_cbc = "camellia-128-cbc"; public static final short NID_camellia_128_cbc = 751; public static final String OBJ_camellia_128_cbc = "1.2.392.200011.61.1.1.1.2"; public static final String SN_camellia_192_cbc = "CAMELLIA-192-CBC"; public static final String LN_camellia_192_cbc = "camellia-192-cbc"; public static final short NID_camellia_192_cbc = 752; public static final String OBJ_camellia_192_cbc = "1.2.392.200011.61.1.1.1.3"; public static final String SN_camellia_256_cbc = "CAMELLIA-256-CBC"; public static final String LN_camellia_256_cbc = "camellia-256-cbc"; public static final short NID_camellia_256_cbc = 753; public static final String OBJ_camellia_256_cbc = "1.2.392.200011.61.1.1.1.4"; public static final String SN_id_camellia128_wrap = "id-camellia128-wrap"; public static final short NID_id_camellia128_wrap = 907; public static final String OBJ_id_camellia128_wrap = "1.2.392.200011.61.1.1.3.2"; public static final String SN_id_camellia192_wrap = "id-camellia192-wrap"; public static final short NID_id_camellia192_wrap = 908; public static final String OBJ_id_camellia192_wrap = "1.2.392.200011.61.1.1.3.3"; public static final String SN_id_camellia256_wrap = "id-camellia256-wrap"; public static final short NID_id_camellia256_wrap = 909; public static final String OBJ_id_camellia256_wrap = "1.2.392.200011.61.1.1.3.4"; public static final String OBJ_ntt_ds = "0.3.4401.5"; public static final String OBJ_camellia = "0.3.4401.5.3.1.9"; public static final String SN_camellia_128_ecb = "CAMELLIA-128-ECB"; public static final String LN_camellia_128_ecb = "camellia-128-ecb"; public static final short NID_camellia_128_ecb = 754; public static final String OBJ_camellia_128_ecb = "0.3.4401.5.3.1.9.1"; public static final String SN_camellia_128_ofb128 = "CAMELLIA-128-OFB"; public static final String LN_camellia_128_ofb128 = "camellia-128-ofb"; public static final short NID_camellia_128_ofb128 = 766; public static final String OBJ_camellia_128_ofb128 = "0.3.4401.5.3.1.9.3"; public static final String SN_camellia_128_cfb128 = "CAMELLIA-128-CFB"; public static final String LN_camellia_128_cfb128 = "camellia-128-cfb"; public static final short NID_camellia_128_cfb128 = 757; public static final String OBJ_camellia_128_cfb128 = "0.3.4401.5.3.1.9.4"; public static final String SN_camellia_192_ecb = "CAMELLIA-192-ECB"; public static final String LN_camellia_192_ecb = "camellia-192-ecb"; public static final short NID_camellia_192_ecb = 755; public static final String OBJ_camellia_192_ecb = "0.3.4401.5.3.1.9.21"; public static final String SN_camellia_192_ofb128 = "CAMELLIA-192-OFB"; public static final String LN_camellia_192_ofb128 = "camellia-192-ofb"; public static final short NID_camellia_192_ofb128 = 767; public static final String OBJ_camellia_192_ofb128 = "0.3.4401.5.3.1.9.23"; public static final String SN_camellia_192_cfb128 = "CAMELLIA-192-CFB"; public static final String LN_camellia_192_cfb128 = "camellia-192-cfb"; public static final short NID_camellia_192_cfb128 = 758; public static final String OBJ_camellia_192_cfb128 = "0.3.4401.5.3.1.9.24"; public static final String SN_camellia_256_ecb = "CAMELLIA-256-ECB"; public static final String LN_camellia_256_ecb = "camellia-256-ecb"; public static final short NID_camellia_256_ecb = 756; public static final String OBJ_camellia_256_ecb = "0.3.4401.5.3.1.9.41"; public static final String SN_camellia_256_ofb128 = "CAMELLIA-256-OFB"; public static final String LN_camellia_256_ofb128 = "camellia-256-ofb"; public static final short NID_camellia_256_ofb128 = 768; public static final String OBJ_camellia_256_ofb128 = "0.3.4401.5.3.1.9.43"; public static final String SN_camellia_256_cfb128 = "CAMELLIA-256-CFB"; public static final String LN_camellia_256_cfb128 = "camellia-256-cfb"; public static final short NID_camellia_256_cfb128 = 759; public static final String OBJ_camellia_256_cfb128 = "0.3.4401.5.3.1.9.44"; public static final String SN_camellia_128_cfb1 = "CAMELLIA-128-CFB1"; public static final String LN_camellia_128_cfb1 = "camellia-128-cfb1"; public static final short NID_camellia_128_cfb1 = 760; public static final String SN_camellia_192_cfb1 = "CAMELLIA-192-CFB1"; public static final String LN_camellia_192_cfb1 = "camellia-192-cfb1"; public static final short NID_camellia_192_cfb1 = 761; public static final String SN_camellia_256_cfb1 = "CAMELLIA-256-CFB1"; public static final String LN_camellia_256_cfb1 = "camellia-256-cfb1"; public static final short NID_camellia_256_cfb1 = 762; public static final String SN_camellia_128_cfb8 = "CAMELLIA-128-CFB8"; public static final String LN_camellia_128_cfb8 = "camellia-128-cfb8"; public static final short NID_camellia_128_cfb8 = 763; public static final String SN_camellia_192_cfb8 = "CAMELLIA-192-CFB8"; public static final String LN_camellia_192_cfb8 = "camellia-192-cfb8"; public static final short NID_camellia_192_cfb8 = 764; public static final String SN_camellia_256_cfb8 = "CAMELLIA-256-CFB8"; public static final String LN_camellia_256_cfb8 = "camellia-256-cfb8"; public static final short NID_camellia_256_cfb8 = 765; public static final String SN_kisa = "KISA"; public static final String LN_kisa = "kisa"; public static final short NID_kisa = 773; public static final String OBJ_kisa = "1.2.410.200004"; public static final String SN_seed_ecb = "SEED-ECB"; public static final String LN_seed_ecb = "seed-ecb"; public static final short NID_seed_ecb = 776; public static final String OBJ_seed_ecb = "1.2.410.200004.1.3"; public static final String SN_seed_cbc = "SEED-CBC"; public static final String LN_seed_cbc = "seed-cbc"; public static final short NID_seed_cbc = 777; public static final String OBJ_seed_cbc = "1.2.410.200004.1.4"; public static final String SN_seed_cfb128 = "SEED-CFB"; public static final String LN_seed_cfb128 = "seed-cfb"; public static final short NID_seed_cfb128 = 779; public static final String OBJ_seed_cfb128 = "1.2.410.200004.1.5"; public static final String SN_seed_ofb128 = "SEED-OFB"; public static final String LN_seed_ofb128 = "seed-ofb"; public static final short NID_seed_ofb128 = 778; public static final String OBJ_seed_ofb128 = "1.2.410.200004.1.6"; public static final String SN_hmac = "HMAC"; public static final String LN_hmac = "hmac"; public static final short NID_hmac = 855; public static final String SN_cmac = "CMAC"; public static final String LN_cmac = "cmac"; public static final short NID_cmac = 894; public static final String SN_rc4_hmac_md5 = "RC4-HMAC-MD5"; public static final String LN_rc4_hmac_md5 = "rc4-hmac-md5"; public static final short NID_rc4_hmac_md5 = 915; public static final String SN_aes_128_cbc_hmac_sha1 = "AES-128-CBC-HMAC-SHA1"; public static final String LN_aes_128_cbc_hmac_sha1 = "aes-128-cbc-hmac-sha1"; public static final short NID_aes_128_cbc_hmac_sha1 = 916; public static final String SN_aes_192_cbc_hmac_sha1 = "AES-192-CBC-HMAC-SHA1"; public static final String LN_aes_192_cbc_hmac_sha1 = "aes-192-cbc-hmac-sha1"; public static final short NID_aes_192_cbc_hmac_sha1 = 917; public static final String SN_aes_256_cbc_hmac_sha1 = "AES-256-CBC-HMAC-SHA1"; public static final String LN_aes_256_cbc_hmac_sha1 = "aes-256-cbc-hmac-sha1"; public static final short NID_aes_256_cbc_hmac_sha1 = 918; public static final String SN_aes_128_cbc_hmac_sha256 = "AES-128-CBC-HMAC-SHA256"; public static final String LN_aes_128_cbc_hmac_sha256 = "aes-128-cbc-hmac-sha256"; public static final short NID_aes_128_cbc_hmac_sha256 = 948; public static final String SN_aes_192_cbc_hmac_sha256 = "AES-192-CBC-HMAC-SHA256"; public static final String LN_aes_192_cbc_hmac_sha256 = "aes-192-cbc-hmac-sha256"; public static final short NID_aes_192_cbc_hmac_sha256 = 949; public static final String SN_aes_256_cbc_hmac_sha256 = "AES-256-CBC-HMAC-SHA256"; public static final String LN_aes_256_cbc_hmac_sha256 = "aes-256-cbc-hmac-sha256"; public static final short NID_aes_256_cbc_hmac_sha256 = 950; public static final String SN_dhpublicnumber = "dhpublicnumber"; public static final String LN_dhpublicnumber = "X9.42 DH"; public static final short NID_dhpublicnumber = 920; public static final String OBJ_dhpublicnumber = "1.2.840.10046.2.1"; public static final String SN_brainpoolP160r1 = "brainpoolP160r1"; public static final short NID_brainpoolP160r1 = 921; public static final String OBJ_brainpoolP160r1 = "1.3.36.3.3.2.8.1.1.1"; public static final String SN_brainpoolP160t1 = "brainpoolP160t1"; public static final short NID_brainpoolP160t1 = 922; public static final String OBJ_brainpoolP160t1 = "1.3.36.3.3.2.8.1.1.2"; public static final String SN_brainpoolP192r1 = "brainpoolP192r1"; public static final short NID_brainpoolP192r1 = 923; public static final String OBJ_brainpoolP192r1 = "1.3.36.3.3.2.8.1.1.3"; public static final String SN_brainpoolP192t1 = "brainpoolP192t1"; public static final short NID_brainpoolP192t1 = 924; public static final String OBJ_brainpoolP192t1 = "1.3.36.3.3.2.8.1.1.4"; public static final String SN_brainpoolP224r1 = "brainpoolP224r1"; public static final short NID_brainpoolP224r1 = 925; public static final String OBJ_brainpoolP224r1 = "1.3.36.3.3.2.8.1.1.5"; public static final String SN_brainpoolP224t1 = "brainpoolP224t1"; public static final short NID_brainpoolP224t1 = 926; public static final String OBJ_brainpoolP224t1 = "1.3.36.3.3.2.8.1.1.6"; public static final String SN_brainpoolP256r1 = "brainpoolP256r1"; public static final short NID_brainpoolP256r1 = 927; public static final String OBJ_brainpoolP256r1 = "1.3.36.3.3.2.8.1.1.7"; public static final String SN_brainpoolP256t1 = "brainpoolP256t1"; public static final short NID_brainpoolP256t1 = 928; public static final String OBJ_brainpoolP256t1 = "1.3.36.3.3.2.8.1.1.8"; public static final String SN_brainpoolP320r1 = "brainpoolP320r1"; public static final short NID_brainpoolP320r1 = 929; public static final String OBJ_brainpoolP320r1 = "1.3.36.3.3.2.8.1.1.9"; public static final String SN_brainpoolP320t1 = "brainpoolP320t1"; public static final short NID_brainpoolP320t1 = 930; public static final String OBJ_brainpoolP320t1 = "1.3.36.3.3.2.8.1.1.10"; public static final String SN_brainpoolP384r1 = "brainpoolP384r1"; public static final short NID_brainpoolP384r1 = 931; public static final String OBJ_brainpoolP384r1 = "1.3.36.3.3.2.8.1.1.11"; public static final String SN_brainpoolP384t1 = "brainpoolP384t1"; public static final short NID_brainpoolP384t1 = 932; public static final String OBJ_brainpoolP384t1 = "1.3.36.3.3.2.8.1.1.12"; public static final String SN_brainpoolP512r1 = "brainpoolP512r1"; public static final short NID_brainpoolP512r1 = 933; public static final String OBJ_brainpoolP512r1 = "1.3.36.3.3.2.8.1.1.13"; public static final String SN_brainpoolP512t1 = "brainpoolP512t1"; public static final short NID_brainpoolP512t1 = 934; public static final String OBJ_brainpoolP512t1 = "1.3.36.3.3.2.8.1.1.14"; public static final String OBJ_x9_63_scheme = "1.3.133.16.840.63.0"; public static final String OBJ_secg_scheme = "1.3.132.1"; public static final String SN_dhSinglePass_stdDH_sha1kdf_scheme = "dhSinglePass-stdDH-sha1kdf-scheme"; public static final short NID_dhSinglePass_stdDH_sha1kdf_scheme = 936; public static final String OBJ_dhSinglePass_stdDH_sha1kdf_scheme = "1.3.133.16.840.63.0.2"; public static final String SN_dhSinglePass_stdDH_sha224kdf_scheme = "dhSinglePass-stdDH-sha224kdf-scheme"; public static final short NID_dhSinglePass_stdDH_sha224kdf_scheme = 937; public static final String OBJ_dhSinglePass_stdDH_sha224kdf_scheme = "1.3.132.1.11.0"; public static final String SN_dhSinglePass_stdDH_sha256kdf_scheme = "dhSinglePass-stdDH-sha256kdf-scheme"; public static final short NID_dhSinglePass_stdDH_sha256kdf_scheme = 938; public static final String OBJ_dhSinglePass_stdDH_sha256kdf_scheme = "1.3.132.1.11.1"; public static final String SN_dhSinglePass_stdDH_sha384kdf_scheme = "dhSinglePass-stdDH-sha384kdf-scheme"; public static final short NID_dhSinglePass_stdDH_sha384kdf_scheme = 939; public static final String OBJ_dhSinglePass_stdDH_sha384kdf_scheme = "1.3.132.1.11.2"; public static final String SN_dhSinglePass_stdDH_sha512kdf_scheme = "dhSinglePass-stdDH-sha512kdf-scheme"; public static final short NID_dhSinglePass_stdDH_sha512kdf_scheme = 940; public static final String OBJ_dhSinglePass_stdDH_sha512kdf_scheme = "1.3.132.1.11.3"; public static final String SN_dhSinglePass_cofactorDH_sha1kdf_scheme = "dhSinglePass-cofactorDH-sha1kdf-scheme"; public static final short NID_dhSinglePass_cofactorDH_sha1kdf_scheme = 941; public static final String OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme = "1.3.133.16.840.63.0.3"; public static final String SN_dhSinglePass_cofactorDH_sha224kdf_scheme = "dhSinglePass-cofactorDH-sha224kdf-scheme"; public static final short NID_dhSinglePass_cofactorDH_sha224kdf_scheme = 942; public static final String OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme = "1.3.132.1.14.0"; public static final String SN_dhSinglePass_cofactorDH_sha256kdf_scheme = "dhSinglePass-cofactorDH-sha256kdf-scheme"; public static final short NID_dhSinglePass_cofactorDH_sha256kdf_scheme = 943; public static final String OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme = "1.3.132.1.14.1"; public static final String SN_dhSinglePass_cofactorDH_sha384kdf_scheme = "dhSinglePass-cofactorDH-sha384kdf-scheme"; public static final short NID_dhSinglePass_cofactorDH_sha384kdf_scheme = 944; public static final String OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme = "1.3.132.1.14.2"; public static final String SN_dhSinglePass_cofactorDH_sha512kdf_scheme = "dhSinglePass-cofactorDH-sha512kdf-scheme"; public static final short NID_dhSinglePass_cofactorDH_sha512kdf_scheme = 945; public static final String OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme = "1.3.132.1.14.3"; public static final String SN_dh_std_kdf = "dh-std-kdf"; public static final short NID_dh_std_kdf = 946; public static final String SN_dh_cofactor_kdf = "dh-cofactor-kdf"; public static final short NID_dh_cofactor_kdf = 947; public static final String SN_ct_precert_scts = "ct_precert_scts"; public static final String LN_ct_precert_scts = "CT Precertificate SCTs"; public static final short NID_ct_precert_scts = 951; public static final String OBJ_ct_precert_scts = "1.3.6.1.4.1.11129.2.4.2"; public static final String SN_ct_precert_poison = "ct_precert_poison"; public static final String LN_ct_precert_poison = "CT Precertificate Poison"; public static final short NID_ct_precert_poison = 952; public static final String OBJ_ct_precert_poison = "1.3.6.1.4.1.11129.2.4.3"; public static final String SN_ct_precert_signer = "ct_precert_signer"; public static final String LN_ct_precert_signer = "CT Precertificate Signer"; public static final short NID_ct_precert_signer = 953; public static final String OBJ_ct_precert_signer = "1.3.6.1.4.1.11129.2.4.4"; public static final String SN_ct_cert_scts = "ct_cert_scts"; public static final String LN_ct_cert_scts = "CT Certificate SCTs"; public static final short NID_ct_cert_scts = 954; public static final String OBJ_ct_cert_scts = "1.3.6.1.4.1.11129.2.4.5"; public static final String SN_jurisdictionLocalityName = "jurisdictionL"; public static final String LN_jurisdictionLocalityName = "jurisdictionLocalityName"; public static final short NID_jurisdictionLocalityName = 955; public static final String OBJ_jurisdictionLocalityName = "1.3.6.1.4.1.311.60.2.1.1"; public static final String SN_jurisdictionStateOrProvinceName = "jurisdictionST"; public static final String LN_jurisdictionStateOrProvinceName = "jurisdictionStateOrProvinceName"; public static final short NID_jurisdictionStateOrProvinceName = 956; public static final String OBJ_jurisdictionStateOrProvinceName = "1.3.6.1.4.1.311.60.2.1.2"; public static final String SN_jurisdictionCountryName = "jurisdictionC"; public static final String LN_jurisdictionCountryName = "jurisdictionCountryName"; public static final short NID_jurisdictionCountryName = 957; public static final String OBJ_jurisdictionCountryName = "1.3.6.1.4.1.311.60.2.1.3"; private static final HashMap SYM_TO_OID = new HashMap(1284, 1); // if ( sn != null ) SYM_TO_OID.put(sn.toLowerCase(), oid); // if ( ln != null ) SYM_TO_OID.put(ln.toLowerCase(), oid); static { SYM_TO_OID.put( SN_undef.toLowerCase(), OBJ_undef ); SYM_TO_OID.put( LN_undef.toLowerCase(), OBJ_undef ); SYM_TO_OID.put( SN_itu_t.toLowerCase(), OBJ_itu_t ); SYM_TO_OID.put( LN_itu_t.toLowerCase(), OBJ_itu_t ); SYM_TO_OID.put( SN_iso.toLowerCase(), OBJ_iso ); SYM_TO_OID.put( LN_iso.toLowerCase(), OBJ_iso ); SYM_TO_OID.put( SN_joint_iso_itu_t.toLowerCase(), OBJ_joint_iso_itu_t ); SYM_TO_OID.put( LN_joint_iso_itu_t.toLowerCase(), OBJ_joint_iso_itu_t ); SYM_TO_OID.put( SN_member_body.toLowerCase(), OBJ_member_body ); SYM_TO_OID.put( LN_member_body.toLowerCase(), OBJ_member_body ); SYM_TO_OID.put( SN_identified_organization.toLowerCase(), OBJ_identified_organization ); SYM_TO_OID.put( SN_hmac_md5.toLowerCase(), OBJ_hmac_md5 ); SYM_TO_OID.put( LN_hmac_md5.toLowerCase(), OBJ_hmac_md5 ); SYM_TO_OID.put( SN_hmac_sha1.toLowerCase(), OBJ_hmac_sha1 ); SYM_TO_OID.put( LN_hmac_sha1.toLowerCase(), OBJ_hmac_sha1 ); SYM_TO_OID.put( SN_certicom_arc.toLowerCase(), OBJ_certicom_arc ); SYM_TO_OID.put( SN_international_organizations.toLowerCase(), OBJ_international_organizations ); SYM_TO_OID.put( LN_international_organizations.toLowerCase(), OBJ_international_organizations ); SYM_TO_OID.put( SN_wap.toLowerCase(), OBJ_wap ); SYM_TO_OID.put( SN_wap_wsg.toLowerCase(), OBJ_wap_wsg ); SYM_TO_OID.put( SN_selected_attribute_types.toLowerCase(), OBJ_selected_attribute_types ); SYM_TO_OID.put( LN_selected_attribute_types.toLowerCase(), OBJ_selected_attribute_types ); SYM_TO_OID.put( SN_clearance.toLowerCase(), OBJ_clearance ); SYM_TO_OID.put( SN_ISO_US.toLowerCase(), OBJ_ISO_US ); SYM_TO_OID.put( LN_ISO_US.toLowerCase(), OBJ_ISO_US ); SYM_TO_OID.put( SN_X9_57.toLowerCase(), OBJ_X9_57 ); SYM_TO_OID.put( LN_X9_57.toLowerCase(), OBJ_X9_57 ); SYM_TO_OID.put( SN_X9cm.toLowerCase(), OBJ_X9cm ); SYM_TO_OID.put( LN_X9cm.toLowerCase(), OBJ_X9cm ); SYM_TO_OID.put( SN_dsa.toLowerCase(), OBJ_dsa ); SYM_TO_OID.put( LN_dsa.toLowerCase(), OBJ_dsa ); SYM_TO_OID.put( SN_dsaWithSHA1.toLowerCase(), OBJ_dsaWithSHA1 ); SYM_TO_OID.put( LN_dsaWithSHA1.toLowerCase(), OBJ_dsaWithSHA1 ); SYM_TO_OID.put( SN_ansi_X9_62.toLowerCase(), OBJ_ansi_X9_62 ); SYM_TO_OID.put( LN_ansi_X9_62.toLowerCase(), OBJ_ansi_X9_62 ); SYM_TO_OID.put( SN_X9_62_prime_field.toLowerCase(), OBJ_X9_62_prime_field ); SYM_TO_OID.put( SN_X9_62_characteristic_two_field.toLowerCase(), OBJ_X9_62_characteristic_two_field ); SYM_TO_OID.put( SN_X9_62_id_characteristic_two_basis.toLowerCase(), OBJ_X9_62_id_characteristic_two_basis ); SYM_TO_OID.put( SN_X9_62_onBasis.toLowerCase(), OBJ_X9_62_onBasis ); SYM_TO_OID.put( SN_X9_62_tpBasis.toLowerCase(), OBJ_X9_62_tpBasis ); SYM_TO_OID.put( SN_X9_62_ppBasis.toLowerCase(), OBJ_X9_62_ppBasis ); SYM_TO_OID.put( SN_X9_62_id_ecPublicKey.toLowerCase(), OBJ_X9_62_id_ecPublicKey ); SYM_TO_OID.put( SN_X9_62_c2pnb163v1.toLowerCase(), OBJ_X9_62_c2pnb163v1 ); SYM_TO_OID.put( SN_X9_62_c2pnb163v2.toLowerCase(), OBJ_X9_62_c2pnb163v2 ); SYM_TO_OID.put( SN_X9_62_c2pnb163v3.toLowerCase(), OBJ_X9_62_c2pnb163v3 ); SYM_TO_OID.put( SN_X9_62_c2pnb176v1.toLowerCase(), OBJ_X9_62_c2pnb176v1 ); SYM_TO_OID.put( SN_X9_62_c2tnb191v1.toLowerCase(), OBJ_X9_62_c2tnb191v1 ); SYM_TO_OID.put( SN_X9_62_c2tnb191v2.toLowerCase(), OBJ_X9_62_c2tnb191v2 ); SYM_TO_OID.put( SN_X9_62_c2tnb191v3.toLowerCase(), OBJ_X9_62_c2tnb191v3 ); SYM_TO_OID.put( SN_X9_62_c2onb191v4.toLowerCase(), OBJ_X9_62_c2onb191v4 ); SYM_TO_OID.put( SN_X9_62_c2onb191v5.toLowerCase(), OBJ_X9_62_c2onb191v5 ); SYM_TO_OID.put( SN_X9_62_c2pnb208w1.toLowerCase(), OBJ_X9_62_c2pnb208w1 ); SYM_TO_OID.put( SN_X9_62_c2tnb239v1.toLowerCase(), OBJ_X9_62_c2tnb239v1 ); SYM_TO_OID.put( SN_X9_62_c2tnb239v2.toLowerCase(), OBJ_X9_62_c2tnb239v2 ); SYM_TO_OID.put( SN_X9_62_c2tnb239v3.toLowerCase(), OBJ_X9_62_c2tnb239v3 ); SYM_TO_OID.put( SN_X9_62_c2onb239v4.toLowerCase(), OBJ_X9_62_c2onb239v4 ); SYM_TO_OID.put( SN_X9_62_c2onb239v5.toLowerCase(), OBJ_X9_62_c2onb239v5 ); SYM_TO_OID.put( SN_X9_62_c2pnb272w1.toLowerCase(), OBJ_X9_62_c2pnb272w1 ); SYM_TO_OID.put( SN_X9_62_c2pnb304w1.toLowerCase(), OBJ_X9_62_c2pnb304w1 ); SYM_TO_OID.put( SN_X9_62_c2tnb359v1.toLowerCase(), OBJ_X9_62_c2tnb359v1 ); SYM_TO_OID.put( SN_X9_62_c2pnb368w1.toLowerCase(), OBJ_X9_62_c2pnb368w1 ); SYM_TO_OID.put( SN_X9_62_c2tnb431r1.toLowerCase(), OBJ_X9_62_c2tnb431r1 ); SYM_TO_OID.put( SN_X9_62_prime192v1.toLowerCase(), OBJ_X9_62_prime192v1 ); SYM_TO_OID.put( SN_X9_62_prime192v2.toLowerCase(), OBJ_X9_62_prime192v2 ); SYM_TO_OID.put( SN_X9_62_prime192v3.toLowerCase(), OBJ_X9_62_prime192v3 ); SYM_TO_OID.put( SN_X9_62_prime239v1.toLowerCase(), OBJ_X9_62_prime239v1 ); SYM_TO_OID.put( SN_X9_62_prime239v2.toLowerCase(), OBJ_X9_62_prime239v2 ); SYM_TO_OID.put( SN_X9_62_prime239v3.toLowerCase(), OBJ_X9_62_prime239v3 ); SYM_TO_OID.put( SN_X9_62_prime256v1.toLowerCase(), OBJ_X9_62_prime256v1 ); SYM_TO_OID.put( SN_ecdsa_with_SHA1.toLowerCase(), OBJ_ecdsa_with_SHA1 ); SYM_TO_OID.put( SN_ecdsa_with_Recommended.toLowerCase(), OBJ_ecdsa_with_Recommended ); SYM_TO_OID.put( SN_ecdsa_with_Specified.toLowerCase(), OBJ_ecdsa_with_Specified ); SYM_TO_OID.put( SN_ecdsa_with_SHA224.toLowerCase(), OBJ_ecdsa_with_SHA224 ); SYM_TO_OID.put( SN_ecdsa_with_SHA256.toLowerCase(), OBJ_ecdsa_with_SHA256 ); SYM_TO_OID.put( SN_ecdsa_with_SHA384.toLowerCase(), OBJ_ecdsa_with_SHA384 ); SYM_TO_OID.put( SN_ecdsa_with_SHA512.toLowerCase(), OBJ_ecdsa_with_SHA512 ); SYM_TO_OID.put( SN_secp112r1.toLowerCase(), OBJ_secp112r1 ); SYM_TO_OID.put( SN_secp112r2.toLowerCase(), OBJ_secp112r2 ); SYM_TO_OID.put( SN_secp128r1.toLowerCase(), OBJ_secp128r1 ); SYM_TO_OID.put( SN_secp128r2.toLowerCase(), OBJ_secp128r2 ); SYM_TO_OID.put( SN_secp160k1.toLowerCase(), OBJ_secp160k1 ); SYM_TO_OID.put( SN_secp160r1.toLowerCase(), OBJ_secp160r1 ); SYM_TO_OID.put( SN_secp160r2.toLowerCase(), OBJ_secp160r2 ); SYM_TO_OID.put( SN_secp192k1.toLowerCase(), OBJ_secp192k1 ); SYM_TO_OID.put( SN_secp224k1.toLowerCase(), OBJ_secp224k1 ); SYM_TO_OID.put( SN_secp224r1.toLowerCase(), OBJ_secp224r1 ); SYM_TO_OID.put( SN_secp256k1.toLowerCase(), OBJ_secp256k1 ); SYM_TO_OID.put( SN_secp384r1.toLowerCase(), OBJ_secp384r1 ); SYM_TO_OID.put( SN_secp521r1.toLowerCase(), OBJ_secp521r1 ); SYM_TO_OID.put( SN_sect113r1.toLowerCase(), OBJ_sect113r1 ); SYM_TO_OID.put( SN_sect113r2.toLowerCase(), OBJ_sect113r2 ); SYM_TO_OID.put( SN_sect131r1.toLowerCase(), OBJ_sect131r1 ); SYM_TO_OID.put( SN_sect131r2.toLowerCase(), OBJ_sect131r2 ); SYM_TO_OID.put( SN_sect163k1.toLowerCase(), OBJ_sect163k1 ); SYM_TO_OID.put( SN_sect163r1.toLowerCase(), OBJ_sect163r1 ); SYM_TO_OID.put( SN_sect163r2.toLowerCase(), OBJ_sect163r2 ); SYM_TO_OID.put( SN_sect193r1.toLowerCase(), OBJ_sect193r1 ); SYM_TO_OID.put( SN_sect193r2.toLowerCase(), OBJ_sect193r2 ); SYM_TO_OID.put( SN_sect233k1.toLowerCase(), OBJ_sect233k1 ); SYM_TO_OID.put( SN_sect233r1.toLowerCase(), OBJ_sect233r1 ); SYM_TO_OID.put( SN_sect239k1.toLowerCase(), OBJ_sect239k1 ); SYM_TO_OID.put( SN_sect283k1.toLowerCase(), OBJ_sect283k1 ); SYM_TO_OID.put( SN_sect283r1.toLowerCase(), OBJ_sect283r1 ); SYM_TO_OID.put( SN_sect409k1.toLowerCase(), OBJ_sect409k1 ); SYM_TO_OID.put( SN_sect409r1.toLowerCase(), OBJ_sect409r1 ); SYM_TO_OID.put( SN_sect571k1.toLowerCase(), OBJ_sect571k1 ); SYM_TO_OID.put( SN_sect571r1.toLowerCase(), OBJ_sect571r1 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls1.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls1 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls3.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls3 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls4.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls4 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls5.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls5 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls6.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls6 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls7.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls7 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls8.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls8 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls9.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls9 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls10.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls10 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls11.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls11 ); SYM_TO_OID.put( SN_wap_wsg_idm_ecid_wtls12.toLowerCase(), OBJ_wap_wsg_idm_ecid_wtls12 ); SYM_TO_OID.put( SN_cast5_cbc.toLowerCase(), OBJ_cast5_cbc ); SYM_TO_OID.put( LN_cast5_cbc.toLowerCase(), OBJ_cast5_cbc ); SYM_TO_OID.put( LN_pbeWithMD5AndCast5_CBC.toLowerCase(), OBJ_pbeWithMD5AndCast5_CBC ); SYM_TO_OID.put( SN_id_PasswordBasedMAC.toLowerCase(), OBJ_id_PasswordBasedMAC ); SYM_TO_OID.put( LN_id_PasswordBasedMAC.toLowerCase(), OBJ_id_PasswordBasedMAC ); SYM_TO_OID.put( SN_id_DHBasedMac.toLowerCase(), OBJ_id_DHBasedMac ); SYM_TO_OID.put( LN_id_DHBasedMac.toLowerCase(), OBJ_id_DHBasedMac ); SYM_TO_OID.put( SN_rsadsi.toLowerCase(), OBJ_rsadsi ); SYM_TO_OID.put( LN_rsadsi.toLowerCase(), OBJ_rsadsi ); SYM_TO_OID.put( SN_pkcs.toLowerCase(), OBJ_pkcs ); SYM_TO_OID.put( LN_pkcs.toLowerCase(), OBJ_pkcs ); SYM_TO_OID.put( SN_pkcs1.toLowerCase(), OBJ_pkcs1 ); SYM_TO_OID.put( LN_rsaEncryption.toLowerCase(), OBJ_rsaEncryption ); SYM_TO_OID.put( SN_md2WithRSAEncryption.toLowerCase(), OBJ_md2WithRSAEncryption ); SYM_TO_OID.put( LN_md2WithRSAEncryption.toLowerCase(), OBJ_md2WithRSAEncryption ); SYM_TO_OID.put( SN_md4WithRSAEncryption.toLowerCase(), OBJ_md4WithRSAEncryption ); SYM_TO_OID.put( LN_md4WithRSAEncryption.toLowerCase(), OBJ_md4WithRSAEncryption ); SYM_TO_OID.put( SN_md5WithRSAEncryption.toLowerCase(), OBJ_md5WithRSAEncryption ); SYM_TO_OID.put( LN_md5WithRSAEncryption.toLowerCase(), OBJ_md5WithRSAEncryption ); SYM_TO_OID.put( SN_sha1WithRSAEncryption.toLowerCase(), OBJ_sha1WithRSAEncryption ); SYM_TO_OID.put( LN_sha1WithRSAEncryption.toLowerCase(), OBJ_sha1WithRSAEncryption ); SYM_TO_OID.put( SN_rsaesOaep.toLowerCase(), OBJ_rsaesOaep ); SYM_TO_OID.put( LN_rsaesOaep.toLowerCase(), OBJ_rsaesOaep ); SYM_TO_OID.put( SN_mgf1.toLowerCase(), OBJ_mgf1 ); SYM_TO_OID.put( LN_mgf1.toLowerCase(), OBJ_mgf1 ); SYM_TO_OID.put( SN_pSpecified.toLowerCase(), OBJ_pSpecified ); SYM_TO_OID.put( LN_pSpecified.toLowerCase(), OBJ_pSpecified ); SYM_TO_OID.put( SN_rsassaPss.toLowerCase(), OBJ_rsassaPss ); SYM_TO_OID.put( LN_rsassaPss.toLowerCase(), OBJ_rsassaPss ); SYM_TO_OID.put( SN_sha256WithRSAEncryption.toLowerCase(), OBJ_sha256WithRSAEncryption ); SYM_TO_OID.put( LN_sha256WithRSAEncryption.toLowerCase(), OBJ_sha256WithRSAEncryption ); SYM_TO_OID.put( SN_sha384WithRSAEncryption.toLowerCase(), OBJ_sha384WithRSAEncryption ); SYM_TO_OID.put( LN_sha384WithRSAEncryption.toLowerCase(), OBJ_sha384WithRSAEncryption ); SYM_TO_OID.put( SN_sha512WithRSAEncryption.toLowerCase(), OBJ_sha512WithRSAEncryption ); SYM_TO_OID.put( LN_sha512WithRSAEncryption.toLowerCase(), OBJ_sha512WithRSAEncryption ); SYM_TO_OID.put( SN_sha224WithRSAEncryption.toLowerCase(), OBJ_sha224WithRSAEncryption ); SYM_TO_OID.put( LN_sha224WithRSAEncryption.toLowerCase(), OBJ_sha224WithRSAEncryption ); SYM_TO_OID.put( SN_pkcs3.toLowerCase(), OBJ_pkcs3 ); SYM_TO_OID.put( LN_dhKeyAgreement.toLowerCase(), OBJ_dhKeyAgreement ); SYM_TO_OID.put( SN_pkcs5.toLowerCase(), OBJ_pkcs5 ); SYM_TO_OID.put( SN_pbeWithMD2AndDES_CBC.toLowerCase(), OBJ_pbeWithMD2AndDES_CBC ); SYM_TO_OID.put( LN_pbeWithMD2AndDES_CBC.toLowerCase(), OBJ_pbeWithMD2AndDES_CBC ); SYM_TO_OID.put( SN_pbeWithMD5AndDES_CBC.toLowerCase(), OBJ_pbeWithMD5AndDES_CBC ); SYM_TO_OID.put( LN_pbeWithMD5AndDES_CBC.toLowerCase(), OBJ_pbeWithMD5AndDES_CBC ); SYM_TO_OID.put( SN_pbeWithMD2AndRC2_CBC.toLowerCase(), OBJ_pbeWithMD2AndRC2_CBC ); SYM_TO_OID.put( LN_pbeWithMD2AndRC2_CBC.toLowerCase(), OBJ_pbeWithMD2AndRC2_CBC ); SYM_TO_OID.put( SN_pbeWithMD5AndRC2_CBC.toLowerCase(), OBJ_pbeWithMD5AndRC2_CBC ); SYM_TO_OID.put( LN_pbeWithMD5AndRC2_CBC.toLowerCase(), OBJ_pbeWithMD5AndRC2_CBC ); SYM_TO_OID.put( SN_pbeWithSHA1AndDES_CBC.toLowerCase(), OBJ_pbeWithSHA1AndDES_CBC ); SYM_TO_OID.put( LN_pbeWithSHA1AndDES_CBC.toLowerCase(), OBJ_pbeWithSHA1AndDES_CBC ); SYM_TO_OID.put( SN_pbeWithSHA1AndRC2_CBC.toLowerCase(), OBJ_pbeWithSHA1AndRC2_CBC ); SYM_TO_OID.put( LN_pbeWithSHA1AndRC2_CBC.toLowerCase(), OBJ_pbeWithSHA1AndRC2_CBC ); SYM_TO_OID.put( LN_id_pbkdf2.toLowerCase(), OBJ_id_pbkdf2 ); SYM_TO_OID.put( LN_pbes2.toLowerCase(), OBJ_pbes2 ); SYM_TO_OID.put( LN_pbmac1.toLowerCase(), OBJ_pbmac1 ); SYM_TO_OID.put( SN_pkcs7.toLowerCase(), OBJ_pkcs7 ); SYM_TO_OID.put( LN_pkcs7_data.toLowerCase(), OBJ_pkcs7_data ); SYM_TO_OID.put( LN_pkcs7_signed.toLowerCase(), OBJ_pkcs7_signed ); SYM_TO_OID.put( LN_pkcs7_enveloped.toLowerCase(), OBJ_pkcs7_enveloped ); SYM_TO_OID.put( LN_pkcs7_signedAndEnveloped.toLowerCase(), OBJ_pkcs7_signedAndEnveloped ); SYM_TO_OID.put( LN_pkcs7_digest.toLowerCase(), OBJ_pkcs7_digest ); SYM_TO_OID.put( LN_pkcs7_encrypted.toLowerCase(), OBJ_pkcs7_encrypted ); SYM_TO_OID.put( SN_pkcs9.toLowerCase(), OBJ_pkcs9 ); SYM_TO_OID.put( LN_pkcs9_emailAddress.toLowerCase(), OBJ_pkcs9_emailAddress ); SYM_TO_OID.put( LN_pkcs9_unstructuredName.toLowerCase(), OBJ_pkcs9_unstructuredName ); SYM_TO_OID.put( LN_pkcs9_contentType.toLowerCase(), OBJ_pkcs9_contentType ); SYM_TO_OID.put( LN_pkcs9_messageDigest.toLowerCase(), OBJ_pkcs9_messageDigest ); SYM_TO_OID.put( LN_pkcs9_signingTime.toLowerCase(), OBJ_pkcs9_signingTime ); SYM_TO_OID.put( LN_pkcs9_countersignature.toLowerCase(), OBJ_pkcs9_countersignature ); SYM_TO_OID.put( LN_pkcs9_challengePassword.toLowerCase(), OBJ_pkcs9_challengePassword ); SYM_TO_OID.put( LN_pkcs9_unstructuredAddress.toLowerCase(), OBJ_pkcs9_unstructuredAddress ); SYM_TO_OID.put( LN_pkcs9_extCertAttributes.toLowerCase(), OBJ_pkcs9_extCertAttributes ); SYM_TO_OID.put( SN_ext_req.toLowerCase(), OBJ_ext_req ); SYM_TO_OID.put( LN_ext_req.toLowerCase(), OBJ_ext_req ); SYM_TO_OID.put( SN_SMIMECapabilities.toLowerCase(), OBJ_SMIMECapabilities ); SYM_TO_OID.put( LN_SMIMECapabilities.toLowerCase(), OBJ_SMIMECapabilities ); SYM_TO_OID.put( SN_SMIME.toLowerCase(), OBJ_SMIME ); SYM_TO_OID.put( LN_SMIME.toLowerCase(), OBJ_SMIME ); SYM_TO_OID.put( SN_id_smime_mod.toLowerCase(), OBJ_id_smime_mod ); SYM_TO_OID.put( SN_id_smime_ct.toLowerCase(), OBJ_id_smime_ct ); SYM_TO_OID.put( SN_id_smime_aa.toLowerCase(), OBJ_id_smime_aa ); SYM_TO_OID.put( SN_id_smime_alg.toLowerCase(), OBJ_id_smime_alg ); SYM_TO_OID.put( SN_id_smime_cd.toLowerCase(), OBJ_id_smime_cd ); SYM_TO_OID.put( SN_id_smime_spq.toLowerCase(), OBJ_id_smime_spq ); SYM_TO_OID.put( SN_id_smime_cti.toLowerCase(), OBJ_id_smime_cti ); SYM_TO_OID.put( SN_id_smime_mod_cms.toLowerCase(), OBJ_id_smime_mod_cms ); SYM_TO_OID.put( SN_id_smime_mod_ess.toLowerCase(), OBJ_id_smime_mod_ess ); SYM_TO_OID.put( SN_id_smime_mod_oid.toLowerCase(), OBJ_id_smime_mod_oid ); SYM_TO_OID.put( SN_id_smime_mod_msg_v3.toLowerCase(), OBJ_id_smime_mod_msg_v3 ); SYM_TO_OID.put( SN_id_smime_mod_ets_eSignature_88.toLowerCase(), OBJ_id_smime_mod_ets_eSignature_88 ); SYM_TO_OID.put( SN_id_smime_mod_ets_eSignature_97.toLowerCase(), OBJ_id_smime_mod_ets_eSignature_97 ); SYM_TO_OID.put( SN_id_smime_mod_ets_eSigPolicy_88.toLowerCase(), OBJ_id_smime_mod_ets_eSigPolicy_88 ); SYM_TO_OID.put( SN_id_smime_mod_ets_eSigPolicy_97.toLowerCase(), OBJ_id_smime_mod_ets_eSigPolicy_97 ); SYM_TO_OID.put( SN_id_smime_ct_receipt.toLowerCase(), OBJ_id_smime_ct_receipt ); SYM_TO_OID.put( SN_id_smime_ct_authData.toLowerCase(), OBJ_id_smime_ct_authData ); SYM_TO_OID.put( SN_id_smime_ct_publishCert.toLowerCase(), OBJ_id_smime_ct_publishCert ); SYM_TO_OID.put( SN_id_smime_ct_TSTInfo.toLowerCase(), OBJ_id_smime_ct_TSTInfo ); SYM_TO_OID.put( SN_id_smime_ct_TDTInfo.toLowerCase(), OBJ_id_smime_ct_TDTInfo ); SYM_TO_OID.put( SN_id_smime_ct_contentInfo.toLowerCase(), OBJ_id_smime_ct_contentInfo ); SYM_TO_OID.put( SN_id_smime_ct_DVCSRequestData.toLowerCase(), OBJ_id_smime_ct_DVCSRequestData ); SYM_TO_OID.put( SN_id_smime_ct_DVCSResponseData.toLowerCase(), OBJ_id_smime_ct_DVCSResponseData ); SYM_TO_OID.put( SN_id_smime_ct_compressedData.toLowerCase(), OBJ_id_smime_ct_compressedData ); SYM_TO_OID.put( SN_id_ct_asciiTextWithCRLF.toLowerCase(), OBJ_id_ct_asciiTextWithCRLF ); SYM_TO_OID.put( SN_id_smime_aa_receiptRequest.toLowerCase(), OBJ_id_smime_aa_receiptRequest ); SYM_TO_OID.put( SN_id_smime_aa_securityLabel.toLowerCase(), OBJ_id_smime_aa_securityLabel ); SYM_TO_OID.put( SN_id_smime_aa_mlExpandHistory.toLowerCase(), OBJ_id_smime_aa_mlExpandHistory ); SYM_TO_OID.put( SN_id_smime_aa_contentHint.toLowerCase(), OBJ_id_smime_aa_contentHint ); SYM_TO_OID.put( SN_id_smime_aa_msgSigDigest.toLowerCase(), OBJ_id_smime_aa_msgSigDigest ); SYM_TO_OID.put( SN_id_smime_aa_encapContentType.toLowerCase(), OBJ_id_smime_aa_encapContentType ); SYM_TO_OID.put( SN_id_smime_aa_contentIdentifier.toLowerCase(), OBJ_id_smime_aa_contentIdentifier ); SYM_TO_OID.put( SN_id_smime_aa_macValue.toLowerCase(), OBJ_id_smime_aa_macValue ); SYM_TO_OID.put( SN_id_smime_aa_equivalentLabels.toLowerCase(), OBJ_id_smime_aa_equivalentLabels ); SYM_TO_OID.put( SN_id_smime_aa_contentReference.toLowerCase(), OBJ_id_smime_aa_contentReference ); SYM_TO_OID.put( SN_id_smime_aa_encrypKeyPref.toLowerCase(), OBJ_id_smime_aa_encrypKeyPref ); SYM_TO_OID.put( SN_id_smime_aa_signingCertificate.toLowerCase(), OBJ_id_smime_aa_signingCertificate ); SYM_TO_OID.put( SN_id_smime_aa_smimeEncryptCerts.toLowerCase(), OBJ_id_smime_aa_smimeEncryptCerts ); SYM_TO_OID.put( SN_id_smime_aa_timeStampToken.toLowerCase(), OBJ_id_smime_aa_timeStampToken ); SYM_TO_OID.put( SN_id_smime_aa_ets_sigPolicyId.toLowerCase(), OBJ_id_smime_aa_ets_sigPolicyId ); SYM_TO_OID.put( SN_id_smime_aa_ets_commitmentType.toLowerCase(), OBJ_id_smime_aa_ets_commitmentType ); SYM_TO_OID.put( SN_id_smime_aa_ets_signerLocation.toLowerCase(), OBJ_id_smime_aa_ets_signerLocation ); SYM_TO_OID.put( SN_id_smime_aa_ets_signerAttr.toLowerCase(), OBJ_id_smime_aa_ets_signerAttr ); SYM_TO_OID.put( SN_id_smime_aa_ets_otherSigCert.toLowerCase(), OBJ_id_smime_aa_ets_otherSigCert ); SYM_TO_OID.put( SN_id_smime_aa_ets_contentTimestamp.toLowerCase(), OBJ_id_smime_aa_ets_contentTimestamp ); SYM_TO_OID.put( SN_id_smime_aa_ets_CertificateRefs.toLowerCase(), OBJ_id_smime_aa_ets_CertificateRefs ); SYM_TO_OID.put( SN_id_smime_aa_ets_RevocationRefs.toLowerCase(), OBJ_id_smime_aa_ets_RevocationRefs ); SYM_TO_OID.put( SN_id_smime_aa_ets_certValues.toLowerCase(), OBJ_id_smime_aa_ets_certValues ); SYM_TO_OID.put( SN_id_smime_aa_ets_revocationValues.toLowerCase(), OBJ_id_smime_aa_ets_revocationValues ); SYM_TO_OID.put( SN_id_smime_aa_ets_escTimeStamp.toLowerCase(), OBJ_id_smime_aa_ets_escTimeStamp ); SYM_TO_OID.put( SN_id_smime_aa_ets_certCRLTimestamp.toLowerCase(), OBJ_id_smime_aa_ets_certCRLTimestamp ); SYM_TO_OID.put( SN_id_smime_aa_ets_archiveTimeStamp.toLowerCase(), OBJ_id_smime_aa_ets_archiveTimeStamp ); SYM_TO_OID.put( SN_id_smime_aa_signatureType.toLowerCase(), OBJ_id_smime_aa_signatureType ); SYM_TO_OID.put( SN_id_smime_aa_dvcs_dvc.toLowerCase(), OBJ_id_smime_aa_dvcs_dvc ); SYM_TO_OID.put( SN_id_smime_alg_ESDHwith3DES.toLowerCase(), OBJ_id_smime_alg_ESDHwith3DES ); SYM_TO_OID.put( SN_id_smime_alg_ESDHwithRC2.toLowerCase(), OBJ_id_smime_alg_ESDHwithRC2 ); SYM_TO_OID.put( SN_id_smime_alg_3DESwrap.toLowerCase(), OBJ_id_smime_alg_3DESwrap ); SYM_TO_OID.put( SN_id_smime_alg_RC2wrap.toLowerCase(), OBJ_id_smime_alg_RC2wrap ); SYM_TO_OID.put( SN_id_smime_alg_ESDH.toLowerCase(), OBJ_id_smime_alg_ESDH ); SYM_TO_OID.put( SN_id_smime_alg_CMS3DESwrap.toLowerCase(), OBJ_id_smime_alg_CMS3DESwrap ); SYM_TO_OID.put( SN_id_smime_alg_CMSRC2wrap.toLowerCase(), OBJ_id_smime_alg_CMSRC2wrap ); SYM_TO_OID.put( SN_id_alg_PWRI_KEK.toLowerCase(), OBJ_id_alg_PWRI_KEK ); SYM_TO_OID.put( SN_id_smime_cd_ldap.toLowerCase(), OBJ_id_smime_cd_ldap ); SYM_TO_OID.put( SN_id_smime_spq_ets_sqt_uri.toLowerCase(), OBJ_id_smime_spq_ets_sqt_uri ); SYM_TO_OID.put( SN_id_smime_spq_ets_sqt_unotice.toLowerCase(), OBJ_id_smime_spq_ets_sqt_unotice ); SYM_TO_OID.put( SN_id_smime_cti_ets_proofOfOrigin.toLowerCase(), OBJ_id_smime_cti_ets_proofOfOrigin ); SYM_TO_OID.put( SN_id_smime_cti_ets_proofOfReceipt.toLowerCase(), OBJ_id_smime_cti_ets_proofOfReceipt ); SYM_TO_OID.put( SN_id_smime_cti_ets_proofOfDelivery.toLowerCase(), OBJ_id_smime_cti_ets_proofOfDelivery ); SYM_TO_OID.put( SN_id_smime_cti_ets_proofOfSender.toLowerCase(), OBJ_id_smime_cti_ets_proofOfSender ); SYM_TO_OID.put( SN_id_smime_cti_ets_proofOfApproval.toLowerCase(), OBJ_id_smime_cti_ets_proofOfApproval ); SYM_TO_OID.put( SN_id_smime_cti_ets_proofOfCreation.toLowerCase(), OBJ_id_smime_cti_ets_proofOfCreation ); SYM_TO_OID.put( LN_friendlyName.toLowerCase(), OBJ_friendlyName ); SYM_TO_OID.put( LN_localKeyID.toLowerCase(), OBJ_localKeyID ); SYM_TO_OID.put( SN_ms_csp_name.toLowerCase(), OBJ_ms_csp_name ); SYM_TO_OID.put( LN_ms_csp_name.toLowerCase(), OBJ_ms_csp_name ); SYM_TO_OID.put( SN_LocalKeySet.toLowerCase(), OBJ_LocalKeySet ); SYM_TO_OID.put( LN_LocalKeySet.toLowerCase(), OBJ_LocalKeySet ); SYM_TO_OID.put( LN_x509Certificate.toLowerCase(), OBJ_x509Certificate ); SYM_TO_OID.put( LN_sdsiCertificate.toLowerCase(), OBJ_sdsiCertificate ); SYM_TO_OID.put( LN_x509Crl.toLowerCase(), OBJ_x509Crl ); SYM_TO_OID.put( SN_pbe_WithSHA1And128BitRC4.toLowerCase(), OBJ_pbe_WithSHA1And128BitRC4 ); SYM_TO_OID.put( LN_pbe_WithSHA1And128BitRC4.toLowerCase(), OBJ_pbe_WithSHA1And128BitRC4 ); SYM_TO_OID.put( SN_pbe_WithSHA1And40BitRC4.toLowerCase(), OBJ_pbe_WithSHA1And40BitRC4 ); SYM_TO_OID.put( LN_pbe_WithSHA1And40BitRC4.toLowerCase(), OBJ_pbe_WithSHA1And40BitRC4 ); SYM_TO_OID.put( SN_pbe_WithSHA1And3_Key_TripleDES_CBC.toLowerCase(), OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC ); SYM_TO_OID.put( LN_pbe_WithSHA1And3_Key_TripleDES_CBC.toLowerCase(), OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC ); SYM_TO_OID.put( SN_pbe_WithSHA1And2_Key_TripleDES_CBC.toLowerCase(), OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC ); SYM_TO_OID.put( LN_pbe_WithSHA1And2_Key_TripleDES_CBC.toLowerCase(), OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC ); SYM_TO_OID.put( SN_pbe_WithSHA1And128BitRC2_CBC.toLowerCase(), OBJ_pbe_WithSHA1And128BitRC2_CBC ); SYM_TO_OID.put( LN_pbe_WithSHA1And128BitRC2_CBC.toLowerCase(), OBJ_pbe_WithSHA1And128BitRC2_CBC ); SYM_TO_OID.put( SN_pbe_WithSHA1And40BitRC2_CBC.toLowerCase(), OBJ_pbe_WithSHA1And40BitRC2_CBC ); SYM_TO_OID.put( LN_pbe_WithSHA1And40BitRC2_CBC.toLowerCase(), OBJ_pbe_WithSHA1And40BitRC2_CBC ); SYM_TO_OID.put( LN_keyBag.toLowerCase(), OBJ_keyBag ); SYM_TO_OID.put( LN_pkcs8ShroudedKeyBag.toLowerCase(), OBJ_pkcs8ShroudedKeyBag ); SYM_TO_OID.put( LN_certBag.toLowerCase(), OBJ_certBag ); SYM_TO_OID.put( LN_crlBag.toLowerCase(), OBJ_crlBag ); SYM_TO_OID.put( LN_secretBag.toLowerCase(), OBJ_secretBag ); SYM_TO_OID.put( LN_safeContentsBag.toLowerCase(), OBJ_safeContentsBag ); SYM_TO_OID.put( SN_md2.toLowerCase(), OBJ_md2 ); SYM_TO_OID.put( LN_md2.toLowerCase(), OBJ_md2 ); SYM_TO_OID.put( SN_md4.toLowerCase(), OBJ_md4 ); SYM_TO_OID.put( LN_md4.toLowerCase(), OBJ_md4 ); SYM_TO_OID.put( SN_md5.toLowerCase(), OBJ_md5 ); SYM_TO_OID.put( LN_md5.toLowerCase(), OBJ_md5 ); SYM_TO_OID.put( LN_hmacWithMD5.toLowerCase(), OBJ_hmacWithMD5 ); SYM_TO_OID.put( LN_hmacWithSHA1.toLowerCase(), OBJ_hmacWithSHA1 ); SYM_TO_OID.put( LN_hmacWithSHA224.toLowerCase(), OBJ_hmacWithSHA224 ); SYM_TO_OID.put( LN_hmacWithSHA256.toLowerCase(), OBJ_hmacWithSHA256 ); SYM_TO_OID.put( LN_hmacWithSHA384.toLowerCase(), OBJ_hmacWithSHA384 ); SYM_TO_OID.put( LN_hmacWithSHA512.toLowerCase(), OBJ_hmacWithSHA512 ); SYM_TO_OID.put( SN_rc2_cbc.toLowerCase(), OBJ_rc2_cbc ); SYM_TO_OID.put( LN_rc2_cbc.toLowerCase(), OBJ_rc2_cbc ); SYM_TO_OID.put( SN_rc4.toLowerCase(), OBJ_rc4 ); SYM_TO_OID.put( LN_rc4.toLowerCase(), OBJ_rc4 ); SYM_TO_OID.put( SN_des_ede3_cbc.toLowerCase(), OBJ_des_ede3_cbc ); SYM_TO_OID.put( LN_des_ede3_cbc.toLowerCase(), OBJ_des_ede3_cbc ); SYM_TO_OID.put( SN_rc5_cbc.toLowerCase(), OBJ_rc5_cbc ); SYM_TO_OID.put( LN_rc5_cbc.toLowerCase(), OBJ_rc5_cbc ); SYM_TO_OID.put( SN_ms_ext_req.toLowerCase(), OBJ_ms_ext_req ); SYM_TO_OID.put( LN_ms_ext_req.toLowerCase(), OBJ_ms_ext_req ); SYM_TO_OID.put( SN_ms_code_ind.toLowerCase(), OBJ_ms_code_ind ); SYM_TO_OID.put( LN_ms_code_ind.toLowerCase(), OBJ_ms_code_ind ); SYM_TO_OID.put( SN_ms_code_com.toLowerCase(), OBJ_ms_code_com ); SYM_TO_OID.put( LN_ms_code_com.toLowerCase(), OBJ_ms_code_com ); SYM_TO_OID.put( SN_ms_ctl_sign.toLowerCase(), OBJ_ms_ctl_sign ); SYM_TO_OID.put( LN_ms_ctl_sign.toLowerCase(), OBJ_ms_ctl_sign ); SYM_TO_OID.put( SN_ms_sgc.toLowerCase(), OBJ_ms_sgc ); SYM_TO_OID.put( LN_ms_sgc.toLowerCase(), OBJ_ms_sgc ); SYM_TO_OID.put( SN_ms_efs.toLowerCase(), OBJ_ms_efs ); SYM_TO_OID.put( LN_ms_efs.toLowerCase(), OBJ_ms_efs ); SYM_TO_OID.put( SN_ms_smartcard_login.toLowerCase(), OBJ_ms_smartcard_login ); SYM_TO_OID.put( LN_ms_smartcard_login.toLowerCase(), OBJ_ms_smartcard_login ); SYM_TO_OID.put( SN_ms_upn.toLowerCase(), OBJ_ms_upn ); SYM_TO_OID.put( LN_ms_upn.toLowerCase(), OBJ_ms_upn ); SYM_TO_OID.put( SN_idea_cbc.toLowerCase(), OBJ_idea_cbc ); SYM_TO_OID.put( LN_idea_cbc.toLowerCase(), OBJ_idea_cbc ); SYM_TO_OID.put( SN_bf_cbc.toLowerCase(), OBJ_bf_cbc ); SYM_TO_OID.put( LN_bf_cbc.toLowerCase(), OBJ_bf_cbc ); SYM_TO_OID.put( SN_id_pkix.toLowerCase(), OBJ_id_pkix ); SYM_TO_OID.put( SN_id_pkix_mod.toLowerCase(), OBJ_id_pkix_mod ); SYM_TO_OID.put( SN_id_pe.toLowerCase(), OBJ_id_pe ); SYM_TO_OID.put( SN_id_qt.toLowerCase(), OBJ_id_qt ); SYM_TO_OID.put( SN_id_kp.toLowerCase(), OBJ_id_kp ); SYM_TO_OID.put( SN_id_it.toLowerCase(), OBJ_id_it ); SYM_TO_OID.put( SN_id_pkip.toLowerCase(), OBJ_id_pkip ); SYM_TO_OID.put( SN_id_alg.toLowerCase(), OBJ_id_alg ); SYM_TO_OID.put( SN_id_cmc.toLowerCase(), OBJ_id_cmc ); SYM_TO_OID.put( SN_id_on.toLowerCase(), OBJ_id_on ); SYM_TO_OID.put( SN_id_pda.toLowerCase(), OBJ_id_pda ); SYM_TO_OID.put( SN_id_aca.toLowerCase(), OBJ_id_aca ); SYM_TO_OID.put( SN_id_qcs.toLowerCase(), OBJ_id_qcs ); SYM_TO_OID.put( SN_id_cct.toLowerCase(), OBJ_id_cct ); SYM_TO_OID.put( SN_id_ppl.toLowerCase(), OBJ_id_ppl ); SYM_TO_OID.put( SN_id_ad.toLowerCase(), OBJ_id_ad ); SYM_TO_OID.put( SN_id_pkix1_explicit_88.toLowerCase(), OBJ_id_pkix1_explicit_88 ); SYM_TO_OID.put( SN_id_pkix1_implicit_88.toLowerCase(), OBJ_id_pkix1_implicit_88 ); SYM_TO_OID.put( SN_id_pkix1_explicit_93.toLowerCase(), OBJ_id_pkix1_explicit_93 ); SYM_TO_OID.put( SN_id_pkix1_implicit_93.toLowerCase(), OBJ_id_pkix1_implicit_93 ); SYM_TO_OID.put( SN_id_mod_crmf.toLowerCase(), OBJ_id_mod_crmf ); SYM_TO_OID.put( SN_id_mod_cmc.toLowerCase(), OBJ_id_mod_cmc ); SYM_TO_OID.put( SN_id_mod_kea_profile_88.toLowerCase(), OBJ_id_mod_kea_profile_88 ); SYM_TO_OID.put( SN_id_mod_kea_profile_93.toLowerCase(), OBJ_id_mod_kea_profile_93 ); SYM_TO_OID.put( SN_id_mod_cmp.toLowerCase(), OBJ_id_mod_cmp ); SYM_TO_OID.put( SN_id_mod_qualified_cert_88.toLowerCase(), OBJ_id_mod_qualified_cert_88 ); SYM_TO_OID.put( SN_id_mod_qualified_cert_93.toLowerCase(), OBJ_id_mod_qualified_cert_93 ); SYM_TO_OID.put( SN_id_mod_attribute_cert.toLowerCase(), OBJ_id_mod_attribute_cert ); SYM_TO_OID.put( SN_id_mod_timestamp_protocol.toLowerCase(), OBJ_id_mod_timestamp_protocol ); SYM_TO_OID.put( SN_id_mod_ocsp.toLowerCase(), OBJ_id_mod_ocsp ); SYM_TO_OID.put( SN_id_mod_dvcs.toLowerCase(), OBJ_id_mod_dvcs ); SYM_TO_OID.put( SN_id_mod_cmp2000.toLowerCase(), OBJ_id_mod_cmp2000 ); SYM_TO_OID.put( SN_info_access.toLowerCase(), OBJ_info_access ); SYM_TO_OID.put( LN_info_access.toLowerCase(), OBJ_info_access ); SYM_TO_OID.put( SN_biometricInfo.toLowerCase(), OBJ_biometricInfo ); SYM_TO_OID.put( LN_biometricInfo.toLowerCase(), OBJ_biometricInfo ); SYM_TO_OID.put( SN_qcStatements.toLowerCase(), OBJ_qcStatements ); SYM_TO_OID.put( SN_ac_auditEntity.toLowerCase(), OBJ_ac_auditEntity ); SYM_TO_OID.put( SN_ac_targeting.toLowerCase(), OBJ_ac_targeting ); SYM_TO_OID.put( SN_aaControls.toLowerCase(), OBJ_aaControls ); SYM_TO_OID.put( SN_sbgp_ipAddrBlock.toLowerCase(), OBJ_sbgp_ipAddrBlock ); SYM_TO_OID.put( SN_sbgp_autonomousSysNum.toLowerCase(), OBJ_sbgp_autonomousSysNum ); SYM_TO_OID.put( SN_sbgp_routerIdentifier.toLowerCase(), OBJ_sbgp_routerIdentifier ); SYM_TO_OID.put( SN_ac_proxying.toLowerCase(), OBJ_ac_proxying ); SYM_TO_OID.put( SN_sinfo_access.toLowerCase(), OBJ_sinfo_access ); SYM_TO_OID.put( LN_sinfo_access.toLowerCase(), OBJ_sinfo_access ); SYM_TO_OID.put( SN_proxyCertInfo.toLowerCase(), OBJ_proxyCertInfo ); SYM_TO_OID.put( LN_proxyCertInfo.toLowerCase(), OBJ_proxyCertInfo ); SYM_TO_OID.put( SN_id_qt_cps.toLowerCase(), OBJ_id_qt_cps ); SYM_TO_OID.put( LN_id_qt_cps.toLowerCase(), OBJ_id_qt_cps ); SYM_TO_OID.put( SN_id_qt_unotice.toLowerCase(), OBJ_id_qt_unotice ); SYM_TO_OID.put( LN_id_qt_unotice.toLowerCase(), OBJ_id_qt_unotice ); SYM_TO_OID.put( SN_textNotice.toLowerCase(), OBJ_textNotice ); SYM_TO_OID.put( SN_server_auth.toLowerCase(), OBJ_server_auth ); SYM_TO_OID.put( LN_server_auth.toLowerCase(), OBJ_server_auth ); SYM_TO_OID.put( SN_client_auth.toLowerCase(), OBJ_client_auth ); SYM_TO_OID.put( LN_client_auth.toLowerCase(), OBJ_client_auth ); SYM_TO_OID.put( SN_code_sign.toLowerCase(), OBJ_code_sign ); SYM_TO_OID.put( LN_code_sign.toLowerCase(), OBJ_code_sign ); SYM_TO_OID.put( SN_email_protect.toLowerCase(), OBJ_email_protect ); SYM_TO_OID.put( LN_email_protect.toLowerCase(), OBJ_email_protect ); SYM_TO_OID.put( SN_ipsecEndSystem.toLowerCase(), OBJ_ipsecEndSystem ); SYM_TO_OID.put( LN_ipsecEndSystem.toLowerCase(), OBJ_ipsecEndSystem ); SYM_TO_OID.put( SN_ipsecTunnel.toLowerCase(), OBJ_ipsecTunnel ); SYM_TO_OID.put( LN_ipsecTunnel.toLowerCase(), OBJ_ipsecTunnel ); SYM_TO_OID.put( SN_ipsecUser.toLowerCase(), OBJ_ipsecUser ); SYM_TO_OID.put( LN_ipsecUser.toLowerCase(), OBJ_ipsecUser ); SYM_TO_OID.put( SN_time_stamp.toLowerCase(), OBJ_time_stamp ); SYM_TO_OID.put( LN_time_stamp.toLowerCase(), OBJ_time_stamp ); SYM_TO_OID.put( SN_OCSP_sign.toLowerCase(), OBJ_OCSP_sign ); SYM_TO_OID.put( LN_OCSP_sign.toLowerCase(), OBJ_OCSP_sign ); SYM_TO_OID.put( SN_dvcs.toLowerCase(), OBJ_dvcs ); SYM_TO_OID.put( LN_dvcs.toLowerCase(), OBJ_dvcs ); SYM_TO_OID.put( SN_id_it_caProtEncCert.toLowerCase(), OBJ_id_it_caProtEncCert ); SYM_TO_OID.put( SN_id_it_signKeyPairTypes.toLowerCase(), OBJ_id_it_signKeyPairTypes ); SYM_TO_OID.put( SN_id_it_encKeyPairTypes.toLowerCase(), OBJ_id_it_encKeyPairTypes ); SYM_TO_OID.put( SN_id_it_preferredSymmAlg.toLowerCase(), OBJ_id_it_preferredSymmAlg ); SYM_TO_OID.put( SN_id_it_caKeyUpdateInfo.toLowerCase(), OBJ_id_it_caKeyUpdateInfo ); SYM_TO_OID.put( SN_id_it_currentCRL.toLowerCase(), OBJ_id_it_currentCRL ); SYM_TO_OID.put( SN_id_it_unsupportedOIDs.toLowerCase(), OBJ_id_it_unsupportedOIDs ); SYM_TO_OID.put( SN_id_it_subscriptionRequest.toLowerCase(), OBJ_id_it_subscriptionRequest ); SYM_TO_OID.put( SN_id_it_subscriptionResponse.toLowerCase(), OBJ_id_it_subscriptionResponse ); SYM_TO_OID.put( SN_id_it_keyPairParamReq.toLowerCase(), OBJ_id_it_keyPairParamReq ); SYM_TO_OID.put( SN_id_it_keyPairParamRep.toLowerCase(), OBJ_id_it_keyPairParamRep ); SYM_TO_OID.put( SN_id_it_revPassphrase.toLowerCase(), OBJ_id_it_revPassphrase ); SYM_TO_OID.put( SN_id_it_implicitConfirm.toLowerCase(), OBJ_id_it_implicitConfirm ); SYM_TO_OID.put( SN_id_it_confirmWaitTime.toLowerCase(), OBJ_id_it_confirmWaitTime ); SYM_TO_OID.put( SN_id_it_origPKIMessage.toLowerCase(), OBJ_id_it_origPKIMessage ); SYM_TO_OID.put( SN_id_it_suppLangTags.toLowerCase(), OBJ_id_it_suppLangTags ); SYM_TO_OID.put( SN_id_regCtrl.toLowerCase(), OBJ_id_regCtrl ); SYM_TO_OID.put( SN_id_regInfo.toLowerCase(), OBJ_id_regInfo ); SYM_TO_OID.put( SN_id_regCtrl_regToken.toLowerCase(), OBJ_id_regCtrl_regToken ); SYM_TO_OID.put( SN_id_regCtrl_authenticator.toLowerCase(), OBJ_id_regCtrl_authenticator ); SYM_TO_OID.put( SN_id_regCtrl_pkiPublicationInfo.toLowerCase(), OBJ_id_regCtrl_pkiPublicationInfo ); SYM_TO_OID.put( SN_id_regCtrl_pkiArchiveOptions.toLowerCase(), OBJ_id_regCtrl_pkiArchiveOptions ); SYM_TO_OID.put( SN_id_regCtrl_oldCertID.toLowerCase(), OBJ_id_regCtrl_oldCertID ); SYM_TO_OID.put( SN_id_regCtrl_protocolEncrKey.toLowerCase(), OBJ_id_regCtrl_protocolEncrKey ); SYM_TO_OID.put( SN_id_regInfo_utf8Pairs.toLowerCase(), OBJ_id_regInfo_utf8Pairs ); SYM_TO_OID.put( SN_id_regInfo_certReq.toLowerCase(), OBJ_id_regInfo_certReq ); SYM_TO_OID.put( SN_id_alg_des40.toLowerCase(), OBJ_id_alg_des40 ); SYM_TO_OID.put( SN_id_alg_noSignature.toLowerCase(), OBJ_id_alg_noSignature ); SYM_TO_OID.put( SN_id_alg_dh_sig_hmac_sha1.toLowerCase(), OBJ_id_alg_dh_sig_hmac_sha1 ); SYM_TO_OID.put( SN_id_alg_dh_pop.toLowerCase(), OBJ_id_alg_dh_pop ); SYM_TO_OID.put( SN_id_cmc_statusInfo.toLowerCase(), OBJ_id_cmc_statusInfo ); SYM_TO_OID.put( SN_id_cmc_identification.toLowerCase(), OBJ_id_cmc_identification ); SYM_TO_OID.put( SN_id_cmc_identityProof.toLowerCase(), OBJ_id_cmc_identityProof ); SYM_TO_OID.put( SN_id_cmc_dataReturn.toLowerCase(), OBJ_id_cmc_dataReturn ); SYM_TO_OID.put( SN_id_cmc_transactionId.toLowerCase(), OBJ_id_cmc_transactionId ); SYM_TO_OID.put( SN_id_cmc_senderNonce.toLowerCase(), OBJ_id_cmc_senderNonce ); SYM_TO_OID.put( SN_id_cmc_recipientNonce.toLowerCase(), OBJ_id_cmc_recipientNonce ); SYM_TO_OID.put( SN_id_cmc_addExtensions.toLowerCase(), OBJ_id_cmc_addExtensions ); SYM_TO_OID.put( SN_id_cmc_encryptedPOP.toLowerCase(), OBJ_id_cmc_encryptedPOP ); SYM_TO_OID.put( SN_id_cmc_decryptedPOP.toLowerCase(), OBJ_id_cmc_decryptedPOP ); SYM_TO_OID.put( SN_id_cmc_lraPOPWitness.toLowerCase(), OBJ_id_cmc_lraPOPWitness ); SYM_TO_OID.put( SN_id_cmc_getCert.toLowerCase(), OBJ_id_cmc_getCert ); SYM_TO_OID.put( SN_id_cmc_getCRL.toLowerCase(), OBJ_id_cmc_getCRL ); SYM_TO_OID.put( SN_id_cmc_revokeRequest.toLowerCase(), OBJ_id_cmc_revokeRequest ); SYM_TO_OID.put( SN_id_cmc_regInfo.toLowerCase(), OBJ_id_cmc_regInfo ); SYM_TO_OID.put( SN_id_cmc_responseInfo.toLowerCase(), OBJ_id_cmc_responseInfo ); SYM_TO_OID.put( SN_id_cmc_queryPending.toLowerCase(), OBJ_id_cmc_queryPending ); SYM_TO_OID.put( SN_id_cmc_popLinkRandom.toLowerCase(), OBJ_id_cmc_popLinkRandom ); SYM_TO_OID.put( SN_id_cmc_popLinkWitness.toLowerCase(), OBJ_id_cmc_popLinkWitness ); SYM_TO_OID.put( SN_id_cmc_confirmCertAcceptance.toLowerCase(), OBJ_id_cmc_confirmCertAcceptance ); SYM_TO_OID.put( SN_id_on_personalData.toLowerCase(), OBJ_id_on_personalData ); SYM_TO_OID.put( SN_id_on_permanentIdentifier.toLowerCase(), OBJ_id_on_permanentIdentifier ); SYM_TO_OID.put( LN_id_on_permanentIdentifier.toLowerCase(), OBJ_id_on_permanentIdentifier ); SYM_TO_OID.put( SN_id_pda_dateOfBirth.toLowerCase(), OBJ_id_pda_dateOfBirth ); SYM_TO_OID.put( SN_id_pda_placeOfBirth.toLowerCase(), OBJ_id_pda_placeOfBirth ); SYM_TO_OID.put( SN_id_pda_gender.toLowerCase(), OBJ_id_pda_gender ); SYM_TO_OID.put( SN_id_pda_countryOfCitizenship.toLowerCase(), OBJ_id_pda_countryOfCitizenship ); SYM_TO_OID.put( SN_id_pda_countryOfResidence.toLowerCase(), OBJ_id_pda_countryOfResidence ); SYM_TO_OID.put( SN_id_aca_authenticationInfo.toLowerCase(), OBJ_id_aca_authenticationInfo ); SYM_TO_OID.put( SN_id_aca_accessIdentity.toLowerCase(), OBJ_id_aca_accessIdentity ); SYM_TO_OID.put( SN_id_aca_chargingIdentity.toLowerCase(), OBJ_id_aca_chargingIdentity ); SYM_TO_OID.put( SN_id_aca_group.toLowerCase(), OBJ_id_aca_group ); SYM_TO_OID.put( SN_id_aca_role.toLowerCase(), OBJ_id_aca_role ); SYM_TO_OID.put( SN_id_aca_encAttrs.toLowerCase(), OBJ_id_aca_encAttrs ); SYM_TO_OID.put( SN_id_qcs_pkixQCSyntax_v1.toLowerCase(), OBJ_id_qcs_pkixQCSyntax_v1 ); SYM_TO_OID.put( SN_id_cct_crs.toLowerCase(), OBJ_id_cct_crs ); SYM_TO_OID.put( SN_id_cct_PKIData.toLowerCase(), OBJ_id_cct_PKIData ); SYM_TO_OID.put( SN_id_cct_PKIResponse.toLowerCase(), OBJ_id_cct_PKIResponse ); SYM_TO_OID.put( SN_id_ppl_anyLanguage.toLowerCase(), OBJ_id_ppl_anyLanguage ); SYM_TO_OID.put( LN_id_ppl_anyLanguage.toLowerCase(), OBJ_id_ppl_anyLanguage ); SYM_TO_OID.put( SN_id_ppl_inheritAll.toLowerCase(), OBJ_id_ppl_inheritAll ); SYM_TO_OID.put( LN_id_ppl_inheritAll.toLowerCase(), OBJ_id_ppl_inheritAll ); SYM_TO_OID.put( SN_Independent.toLowerCase(), OBJ_Independent ); SYM_TO_OID.put( LN_Independent.toLowerCase(), OBJ_Independent ); SYM_TO_OID.put( SN_ad_OCSP.toLowerCase(), OBJ_ad_OCSP ); SYM_TO_OID.put( LN_ad_OCSP.toLowerCase(), OBJ_ad_OCSP ); SYM_TO_OID.put( SN_ad_ca_issuers.toLowerCase(), OBJ_ad_ca_issuers ); SYM_TO_OID.put( LN_ad_ca_issuers.toLowerCase(), OBJ_ad_ca_issuers ); SYM_TO_OID.put( SN_ad_timeStamping.toLowerCase(), OBJ_ad_timeStamping ); SYM_TO_OID.put( LN_ad_timeStamping.toLowerCase(), OBJ_ad_timeStamping ); SYM_TO_OID.put( SN_ad_dvcs.toLowerCase(), OBJ_ad_dvcs ); SYM_TO_OID.put( LN_ad_dvcs.toLowerCase(), OBJ_ad_dvcs ); SYM_TO_OID.put( SN_caRepository.toLowerCase(), OBJ_caRepository ); SYM_TO_OID.put( LN_caRepository.toLowerCase(), OBJ_caRepository ); SYM_TO_OID.put( SN_id_pkix_OCSP_basic.toLowerCase(), OBJ_id_pkix_OCSP_basic ); SYM_TO_OID.put( LN_id_pkix_OCSP_basic.toLowerCase(), OBJ_id_pkix_OCSP_basic ); SYM_TO_OID.put( SN_id_pkix_OCSP_Nonce.toLowerCase(), OBJ_id_pkix_OCSP_Nonce ); SYM_TO_OID.put( LN_id_pkix_OCSP_Nonce.toLowerCase(), OBJ_id_pkix_OCSP_Nonce ); SYM_TO_OID.put( SN_id_pkix_OCSP_CrlID.toLowerCase(), OBJ_id_pkix_OCSP_CrlID ); SYM_TO_OID.put( LN_id_pkix_OCSP_CrlID.toLowerCase(), OBJ_id_pkix_OCSP_CrlID ); SYM_TO_OID.put( SN_id_pkix_OCSP_acceptableResponses.toLowerCase(), OBJ_id_pkix_OCSP_acceptableResponses ); SYM_TO_OID.put( LN_id_pkix_OCSP_acceptableResponses.toLowerCase(), OBJ_id_pkix_OCSP_acceptableResponses ); SYM_TO_OID.put( SN_id_pkix_OCSP_noCheck.toLowerCase(), OBJ_id_pkix_OCSP_noCheck ); SYM_TO_OID.put( LN_id_pkix_OCSP_noCheck.toLowerCase(), OBJ_id_pkix_OCSP_noCheck ); SYM_TO_OID.put( SN_id_pkix_OCSP_archiveCutoff.toLowerCase(), OBJ_id_pkix_OCSP_archiveCutoff ); SYM_TO_OID.put( LN_id_pkix_OCSP_archiveCutoff.toLowerCase(), OBJ_id_pkix_OCSP_archiveCutoff ); SYM_TO_OID.put( SN_id_pkix_OCSP_serviceLocator.toLowerCase(), OBJ_id_pkix_OCSP_serviceLocator ); SYM_TO_OID.put( LN_id_pkix_OCSP_serviceLocator.toLowerCase(), OBJ_id_pkix_OCSP_serviceLocator ); SYM_TO_OID.put( SN_id_pkix_OCSP_extendedStatus.toLowerCase(), OBJ_id_pkix_OCSP_extendedStatus ); SYM_TO_OID.put( LN_id_pkix_OCSP_extendedStatus.toLowerCase(), OBJ_id_pkix_OCSP_extendedStatus ); SYM_TO_OID.put( SN_id_pkix_OCSP_valid.toLowerCase(), OBJ_id_pkix_OCSP_valid ); SYM_TO_OID.put( SN_id_pkix_OCSP_path.toLowerCase(), OBJ_id_pkix_OCSP_path ); SYM_TO_OID.put( SN_id_pkix_OCSP_trustRoot.toLowerCase(), OBJ_id_pkix_OCSP_trustRoot ); SYM_TO_OID.put( LN_id_pkix_OCSP_trustRoot.toLowerCase(), OBJ_id_pkix_OCSP_trustRoot ); SYM_TO_OID.put( SN_algorithm.toLowerCase(), OBJ_algorithm ); SYM_TO_OID.put( LN_algorithm.toLowerCase(), OBJ_algorithm ); SYM_TO_OID.put( SN_md5WithRSA.toLowerCase(), OBJ_md5WithRSA ); SYM_TO_OID.put( LN_md5WithRSA.toLowerCase(), OBJ_md5WithRSA ); SYM_TO_OID.put( SN_des_ecb.toLowerCase(), OBJ_des_ecb ); SYM_TO_OID.put( LN_des_ecb.toLowerCase(), OBJ_des_ecb ); SYM_TO_OID.put( SN_des_cbc.toLowerCase(), OBJ_des_cbc ); SYM_TO_OID.put( LN_des_cbc.toLowerCase(), OBJ_des_cbc ); SYM_TO_OID.put( SN_des_ofb64.toLowerCase(), OBJ_des_ofb64 ); SYM_TO_OID.put( LN_des_ofb64.toLowerCase(), OBJ_des_ofb64 ); SYM_TO_OID.put( SN_des_cfb64.toLowerCase(), OBJ_des_cfb64 ); SYM_TO_OID.put( LN_des_cfb64.toLowerCase(), OBJ_des_cfb64 ); SYM_TO_OID.put( SN_rsaSignature.toLowerCase(), OBJ_rsaSignature ); SYM_TO_OID.put( SN_dsa_2.toLowerCase(), OBJ_dsa_2 ); SYM_TO_OID.put( LN_dsa_2.toLowerCase(), OBJ_dsa_2 ); SYM_TO_OID.put( SN_dsaWithSHA.toLowerCase(), OBJ_dsaWithSHA ); SYM_TO_OID.put( LN_dsaWithSHA.toLowerCase(), OBJ_dsaWithSHA ); SYM_TO_OID.put( SN_shaWithRSAEncryption.toLowerCase(), OBJ_shaWithRSAEncryption ); SYM_TO_OID.put( LN_shaWithRSAEncryption.toLowerCase(), OBJ_shaWithRSAEncryption ); SYM_TO_OID.put( SN_des_ede_ecb.toLowerCase(), OBJ_des_ede_ecb ); SYM_TO_OID.put( LN_des_ede_ecb.toLowerCase(), OBJ_des_ede_ecb ); SYM_TO_OID.put( SN_sha.toLowerCase(), OBJ_sha ); SYM_TO_OID.put( LN_sha.toLowerCase(), OBJ_sha ); SYM_TO_OID.put( SN_sha1.toLowerCase(), OBJ_sha1 ); SYM_TO_OID.put( LN_sha1.toLowerCase(), OBJ_sha1 ); SYM_TO_OID.put( SN_dsaWithSHA1_2.toLowerCase(), OBJ_dsaWithSHA1_2 ); SYM_TO_OID.put( LN_dsaWithSHA1_2.toLowerCase(), OBJ_dsaWithSHA1_2 ); SYM_TO_OID.put( SN_sha1WithRSA.toLowerCase(), OBJ_sha1WithRSA ); SYM_TO_OID.put( LN_sha1WithRSA.toLowerCase(), OBJ_sha1WithRSA ); SYM_TO_OID.put( SN_ripemd160.toLowerCase(), OBJ_ripemd160 ); SYM_TO_OID.put( LN_ripemd160.toLowerCase(), OBJ_ripemd160 ); SYM_TO_OID.put( SN_ripemd160WithRSA.toLowerCase(), OBJ_ripemd160WithRSA ); SYM_TO_OID.put( LN_ripemd160WithRSA.toLowerCase(), OBJ_ripemd160WithRSA ); SYM_TO_OID.put( SN_sxnet.toLowerCase(), OBJ_sxnet ); SYM_TO_OID.put( LN_sxnet.toLowerCase(), OBJ_sxnet ); SYM_TO_OID.put( SN_X500.toLowerCase(), OBJ_X500 ); SYM_TO_OID.put( LN_X500.toLowerCase(), OBJ_X500 ); SYM_TO_OID.put( SN_X509.toLowerCase(), OBJ_X509 ); SYM_TO_OID.put( SN_commonName.toLowerCase(), OBJ_commonName ); SYM_TO_OID.put( LN_commonName.toLowerCase(), OBJ_commonName ); SYM_TO_OID.put( SN_surname.toLowerCase(), OBJ_surname ); SYM_TO_OID.put( LN_surname.toLowerCase(), OBJ_surname ); SYM_TO_OID.put( LN_serialNumber.toLowerCase(), OBJ_serialNumber ); SYM_TO_OID.put( SN_countryName.toLowerCase(), OBJ_countryName ); SYM_TO_OID.put( LN_countryName.toLowerCase(), OBJ_countryName ); SYM_TO_OID.put( SN_localityName.toLowerCase(), OBJ_localityName ); SYM_TO_OID.put( LN_localityName.toLowerCase(), OBJ_localityName ); SYM_TO_OID.put( SN_stateOrProvinceName.toLowerCase(), OBJ_stateOrProvinceName ); SYM_TO_OID.put( LN_stateOrProvinceName.toLowerCase(), OBJ_stateOrProvinceName ); SYM_TO_OID.put( SN_streetAddress.toLowerCase(), OBJ_streetAddress ); SYM_TO_OID.put( LN_streetAddress.toLowerCase(), OBJ_streetAddress ); SYM_TO_OID.put( SN_organizationName.toLowerCase(), OBJ_organizationName ); SYM_TO_OID.put( LN_organizationName.toLowerCase(), OBJ_organizationName ); SYM_TO_OID.put( SN_organizationalUnitName.toLowerCase(), OBJ_organizationalUnitName ); SYM_TO_OID.put( LN_organizationalUnitName.toLowerCase(), OBJ_organizationalUnitName ); SYM_TO_OID.put( SN_title.toLowerCase(), OBJ_title ); SYM_TO_OID.put( LN_title.toLowerCase(), OBJ_title ); SYM_TO_OID.put( LN_description.toLowerCase(), OBJ_description ); SYM_TO_OID.put( LN_searchGuide.toLowerCase(), OBJ_searchGuide ); SYM_TO_OID.put( LN_businessCategory.toLowerCase(), OBJ_businessCategory ); SYM_TO_OID.put( LN_postalAddress.toLowerCase(), OBJ_postalAddress ); SYM_TO_OID.put( LN_postalCode.toLowerCase(), OBJ_postalCode ); SYM_TO_OID.put( LN_postOfficeBox.toLowerCase(), OBJ_postOfficeBox ); SYM_TO_OID.put( LN_physicalDeliveryOfficeName.toLowerCase(), OBJ_physicalDeliveryOfficeName ); SYM_TO_OID.put( LN_telephoneNumber.toLowerCase(), OBJ_telephoneNumber ); SYM_TO_OID.put( LN_telexNumber.toLowerCase(), OBJ_telexNumber ); SYM_TO_OID.put( LN_teletexTerminalIdentifier.toLowerCase(), OBJ_teletexTerminalIdentifier ); SYM_TO_OID.put( LN_facsimileTelephoneNumber.toLowerCase(), OBJ_facsimileTelephoneNumber ); SYM_TO_OID.put( LN_x121Address.toLowerCase(), OBJ_x121Address ); SYM_TO_OID.put( LN_internationaliSDNNumber.toLowerCase(), OBJ_internationaliSDNNumber ); SYM_TO_OID.put( LN_registeredAddress.toLowerCase(), OBJ_registeredAddress ); SYM_TO_OID.put( LN_destinationIndicator.toLowerCase(), OBJ_destinationIndicator ); SYM_TO_OID.put( LN_preferredDeliveryMethod.toLowerCase(), OBJ_preferredDeliveryMethod ); SYM_TO_OID.put( LN_presentationAddress.toLowerCase(), OBJ_presentationAddress ); SYM_TO_OID.put( LN_supportedApplicationContext.toLowerCase(), OBJ_supportedApplicationContext ); SYM_TO_OID.put( SN_member.toLowerCase(), OBJ_member ); SYM_TO_OID.put( SN_owner.toLowerCase(), OBJ_owner ); SYM_TO_OID.put( LN_roleOccupant.toLowerCase(), OBJ_roleOccupant ); SYM_TO_OID.put( SN_seeAlso.toLowerCase(), OBJ_seeAlso ); SYM_TO_OID.put( LN_userPassword.toLowerCase(), OBJ_userPassword ); SYM_TO_OID.put( LN_userCertificate.toLowerCase(), OBJ_userCertificate ); SYM_TO_OID.put( LN_cACertificate.toLowerCase(), OBJ_cACertificate ); SYM_TO_OID.put( LN_authorityRevocationList.toLowerCase(), OBJ_authorityRevocationList ); SYM_TO_OID.put( LN_certificateRevocationList.toLowerCase(), OBJ_certificateRevocationList ); SYM_TO_OID.put( LN_crossCertificatePair.toLowerCase(), OBJ_crossCertificatePair ); SYM_TO_OID.put( SN_name.toLowerCase(), OBJ_name ); SYM_TO_OID.put( LN_name.toLowerCase(), OBJ_name ); SYM_TO_OID.put( SN_givenName.toLowerCase(), OBJ_givenName ); SYM_TO_OID.put( LN_givenName.toLowerCase(), OBJ_givenName ); SYM_TO_OID.put( SN_initials.toLowerCase(), OBJ_initials ); SYM_TO_OID.put( LN_initials.toLowerCase(), OBJ_initials ); SYM_TO_OID.put( LN_generationQualifier.toLowerCase(), OBJ_generationQualifier ); SYM_TO_OID.put( LN_x500UniqueIdentifier.toLowerCase(), OBJ_x500UniqueIdentifier ); SYM_TO_OID.put( SN_dnQualifier.toLowerCase(), OBJ_dnQualifier ); SYM_TO_OID.put( LN_dnQualifier.toLowerCase(), OBJ_dnQualifier ); SYM_TO_OID.put( LN_enhancedSearchGuide.toLowerCase(), OBJ_enhancedSearchGuide ); SYM_TO_OID.put( LN_protocolInformation.toLowerCase(), OBJ_protocolInformation ); SYM_TO_OID.put( LN_distinguishedName.toLowerCase(), OBJ_distinguishedName ); SYM_TO_OID.put( LN_uniqueMember.toLowerCase(), OBJ_uniqueMember ); SYM_TO_OID.put( LN_houseIdentifier.toLowerCase(), OBJ_houseIdentifier ); SYM_TO_OID.put( LN_supportedAlgorithms.toLowerCase(), OBJ_supportedAlgorithms ); SYM_TO_OID.put( LN_deltaRevocationList.toLowerCase(), OBJ_deltaRevocationList ); SYM_TO_OID.put( SN_dmdName.toLowerCase(), OBJ_dmdName ); SYM_TO_OID.put( LN_pseudonym.toLowerCase(), OBJ_pseudonym ); SYM_TO_OID.put( SN_role.toLowerCase(), OBJ_role ); SYM_TO_OID.put( LN_role.toLowerCase(), OBJ_role ); SYM_TO_OID.put( SN_X500algorithms.toLowerCase(), OBJ_X500algorithms ); SYM_TO_OID.put( LN_X500algorithms.toLowerCase(), OBJ_X500algorithms ); SYM_TO_OID.put( SN_rsa.toLowerCase(), OBJ_rsa ); SYM_TO_OID.put( LN_rsa.toLowerCase(), OBJ_rsa ); SYM_TO_OID.put( SN_mdc2WithRSA.toLowerCase(), OBJ_mdc2WithRSA ); SYM_TO_OID.put( LN_mdc2WithRSA.toLowerCase(), OBJ_mdc2WithRSA ); SYM_TO_OID.put( SN_mdc2.toLowerCase(), OBJ_mdc2 ); SYM_TO_OID.put( LN_mdc2.toLowerCase(), OBJ_mdc2 ); SYM_TO_OID.put( SN_id_ce.toLowerCase(), OBJ_id_ce ); SYM_TO_OID.put( SN_subject_directory_attributes.toLowerCase(), OBJ_subject_directory_attributes ); SYM_TO_OID.put( LN_subject_directory_attributes.toLowerCase(), OBJ_subject_directory_attributes ); SYM_TO_OID.put( SN_subject_key_identifier.toLowerCase(), OBJ_subject_key_identifier ); SYM_TO_OID.put( LN_subject_key_identifier.toLowerCase(), OBJ_subject_key_identifier ); SYM_TO_OID.put( SN_key_usage.toLowerCase(), OBJ_key_usage ); SYM_TO_OID.put( LN_key_usage.toLowerCase(), OBJ_key_usage ); SYM_TO_OID.put( SN_private_key_usage_period.toLowerCase(), OBJ_private_key_usage_period ); SYM_TO_OID.put( LN_private_key_usage_period.toLowerCase(), OBJ_private_key_usage_period ); SYM_TO_OID.put( SN_subject_alt_name.toLowerCase(), OBJ_subject_alt_name ); SYM_TO_OID.put( LN_subject_alt_name.toLowerCase(), OBJ_subject_alt_name ); SYM_TO_OID.put( SN_issuer_alt_name.toLowerCase(), OBJ_issuer_alt_name ); SYM_TO_OID.put( LN_issuer_alt_name.toLowerCase(), OBJ_issuer_alt_name ); SYM_TO_OID.put( SN_basic_constraints.toLowerCase(), OBJ_basic_constraints ); SYM_TO_OID.put( LN_basic_constraints.toLowerCase(), OBJ_basic_constraints ); SYM_TO_OID.put( SN_crl_number.toLowerCase(), OBJ_crl_number ); SYM_TO_OID.put( LN_crl_number.toLowerCase(), OBJ_crl_number ); SYM_TO_OID.put( SN_crl_reason.toLowerCase(), OBJ_crl_reason ); SYM_TO_OID.put( LN_crl_reason.toLowerCase(), OBJ_crl_reason ); SYM_TO_OID.put( SN_invalidity_date.toLowerCase(), OBJ_invalidity_date ); SYM_TO_OID.put( LN_invalidity_date.toLowerCase(), OBJ_invalidity_date ); SYM_TO_OID.put( SN_delta_crl.toLowerCase(), OBJ_delta_crl ); SYM_TO_OID.put( LN_delta_crl.toLowerCase(), OBJ_delta_crl ); SYM_TO_OID.put( SN_issuing_distribution_point.toLowerCase(), OBJ_issuing_distribution_point ); SYM_TO_OID.put( LN_issuing_distribution_point.toLowerCase(), OBJ_issuing_distribution_point ); SYM_TO_OID.put( SN_certificate_issuer.toLowerCase(), OBJ_certificate_issuer ); SYM_TO_OID.put( LN_certificate_issuer.toLowerCase(), OBJ_certificate_issuer ); SYM_TO_OID.put( SN_name_constraints.toLowerCase(), OBJ_name_constraints ); SYM_TO_OID.put( LN_name_constraints.toLowerCase(), OBJ_name_constraints ); SYM_TO_OID.put( SN_crl_distribution_points.toLowerCase(), OBJ_crl_distribution_points ); SYM_TO_OID.put( LN_crl_distribution_points.toLowerCase(), OBJ_crl_distribution_points ); SYM_TO_OID.put( SN_certificate_policies.toLowerCase(), OBJ_certificate_policies ); SYM_TO_OID.put( LN_certificate_policies.toLowerCase(), OBJ_certificate_policies ); SYM_TO_OID.put( SN_any_policy.toLowerCase(), OBJ_any_policy ); SYM_TO_OID.put( LN_any_policy.toLowerCase(), OBJ_any_policy ); SYM_TO_OID.put( SN_policy_mappings.toLowerCase(), OBJ_policy_mappings ); SYM_TO_OID.put( LN_policy_mappings.toLowerCase(), OBJ_policy_mappings ); SYM_TO_OID.put( SN_authority_key_identifier.toLowerCase(), OBJ_authority_key_identifier ); SYM_TO_OID.put( LN_authority_key_identifier.toLowerCase(), OBJ_authority_key_identifier ); SYM_TO_OID.put( SN_policy_constraints.toLowerCase(), OBJ_policy_constraints ); SYM_TO_OID.put( LN_policy_constraints.toLowerCase(), OBJ_policy_constraints ); SYM_TO_OID.put( SN_ext_key_usage.toLowerCase(), OBJ_ext_key_usage ); SYM_TO_OID.put( LN_ext_key_usage.toLowerCase(), OBJ_ext_key_usage ); SYM_TO_OID.put( SN_freshest_crl.toLowerCase(), OBJ_freshest_crl ); SYM_TO_OID.put( LN_freshest_crl.toLowerCase(), OBJ_freshest_crl ); SYM_TO_OID.put( SN_inhibit_any_policy.toLowerCase(), OBJ_inhibit_any_policy ); SYM_TO_OID.put( LN_inhibit_any_policy.toLowerCase(), OBJ_inhibit_any_policy ); SYM_TO_OID.put( SN_target_information.toLowerCase(), OBJ_target_information ); SYM_TO_OID.put( LN_target_information.toLowerCase(), OBJ_target_information ); SYM_TO_OID.put( SN_no_rev_avail.toLowerCase(), OBJ_no_rev_avail ); SYM_TO_OID.put( LN_no_rev_avail.toLowerCase(), OBJ_no_rev_avail ); SYM_TO_OID.put( SN_anyExtendedKeyUsage.toLowerCase(), OBJ_anyExtendedKeyUsage ); SYM_TO_OID.put( LN_anyExtendedKeyUsage.toLowerCase(), OBJ_anyExtendedKeyUsage ); SYM_TO_OID.put( SN_netscape.toLowerCase(), OBJ_netscape ); SYM_TO_OID.put( LN_netscape.toLowerCase(), OBJ_netscape ); SYM_TO_OID.put( SN_netscape_cert_extension.toLowerCase(), OBJ_netscape_cert_extension ); SYM_TO_OID.put( LN_netscape_cert_extension.toLowerCase(), OBJ_netscape_cert_extension ); SYM_TO_OID.put( SN_netscape_data_type.toLowerCase(), OBJ_netscape_data_type ); SYM_TO_OID.put( LN_netscape_data_type.toLowerCase(), OBJ_netscape_data_type ); SYM_TO_OID.put( SN_netscape_cert_type.toLowerCase(), OBJ_netscape_cert_type ); SYM_TO_OID.put( LN_netscape_cert_type.toLowerCase(), OBJ_netscape_cert_type ); SYM_TO_OID.put( SN_netscape_base_url.toLowerCase(), OBJ_netscape_base_url ); SYM_TO_OID.put( LN_netscape_base_url.toLowerCase(), OBJ_netscape_base_url ); SYM_TO_OID.put( SN_netscape_revocation_url.toLowerCase(), OBJ_netscape_revocation_url ); SYM_TO_OID.put( LN_netscape_revocation_url.toLowerCase(), OBJ_netscape_revocation_url ); SYM_TO_OID.put( SN_netscape_ca_revocation_url.toLowerCase(), OBJ_netscape_ca_revocation_url ); SYM_TO_OID.put( LN_netscape_ca_revocation_url.toLowerCase(), OBJ_netscape_ca_revocation_url ); SYM_TO_OID.put( SN_netscape_renewal_url.toLowerCase(), OBJ_netscape_renewal_url ); SYM_TO_OID.put( LN_netscape_renewal_url.toLowerCase(), OBJ_netscape_renewal_url ); SYM_TO_OID.put( SN_netscape_ca_policy_url.toLowerCase(), OBJ_netscape_ca_policy_url ); SYM_TO_OID.put( LN_netscape_ca_policy_url.toLowerCase(), OBJ_netscape_ca_policy_url ); SYM_TO_OID.put( SN_netscape_ssl_server_name.toLowerCase(), OBJ_netscape_ssl_server_name ); SYM_TO_OID.put( LN_netscape_ssl_server_name.toLowerCase(), OBJ_netscape_ssl_server_name ); SYM_TO_OID.put( SN_netscape_comment.toLowerCase(), OBJ_netscape_comment ); SYM_TO_OID.put( LN_netscape_comment.toLowerCase(), OBJ_netscape_comment ); SYM_TO_OID.put( SN_netscape_cert_sequence.toLowerCase(), OBJ_netscape_cert_sequence ); SYM_TO_OID.put( LN_netscape_cert_sequence.toLowerCase(), OBJ_netscape_cert_sequence ); SYM_TO_OID.put( SN_ns_sgc.toLowerCase(), OBJ_ns_sgc ); SYM_TO_OID.put( LN_ns_sgc.toLowerCase(), OBJ_ns_sgc ); SYM_TO_OID.put( SN_org.toLowerCase(), OBJ_org ); SYM_TO_OID.put( LN_org.toLowerCase(), OBJ_org ); SYM_TO_OID.put( SN_dod.toLowerCase(), OBJ_dod ); SYM_TO_OID.put( LN_dod.toLowerCase(), OBJ_dod ); SYM_TO_OID.put( SN_iana.toLowerCase(), OBJ_iana ); SYM_TO_OID.put( LN_iana.toLowerCase(), OBJ_iana ); SYM_TO_OID.put( SN_Directory.toLowerCase(), OBJ_Directory ); SYM_TO_OID.put( LN_Directory.toLowerCase(), OBJ_Directory ); SYM_TO_OID.put( SN_Management.toLowerCase(), OBJ_Management ); SYM_TO_OID.put( LN_Management.toLowerCase(), OBJ_Management ); SYM_TO_OID.put( SN_Experimental.toLowerCase(), OBJ_Experimental ); SYM_TO_OID.put( LN_Experimental.toLowerCase(), OBJ_Experimental ); SYM_TO_OID.put( SN_Private.toLowerCase(), OBJ_Private ); SYM_TO_OID.put( LN_Private.toLowerCase(), OBJ_Private ); SYM_TO_OID.put( SN_Security.toLowerCase(), OBJ_Security ); SYM_TO_OID.put( LN_Security.toLowerCase(), OBJ_Security ); SYM_TO_OID.put( SN_SNMPv2.toLowerCase(), OBJ_SNMPv2 ); SYM_TO_OID.put( LN_SNMPv2.toLowerCase(), OBJ_SNMPv2 ); SYM_TO_OID.put( LN_Mail.toLowerCase(), OBJ_Mail ); SYM_TO_OID.put( SN_Enterprises.toLowerCase(), OBJ_Enterprises ); SYM_TO_OID.put( LN_Enterprises.toLowerCase(), OBJ_Enterprises ); SYM_TO_OID.put( SN_dcObject.toLowerCase(), OBJ_dcObject ); SYM_TO_OID.put( LN_dcObject.toLowerCase(), OBJ_dcObject ); SYM_TO_OID.put( SN_mime_mhs.toLowerCase(), OBJ_mime_mhs ); SYM_TO_OID.put( LN_mime_mhs.toLowerCase(), OBJ_mime_mhs ); SYM_TO_OID.put( SN_mime_mhs_headings.toLowerCase(), OBJ_mime_mhs_headings ); SYM_TO_OID.put( LN_mime_mhs_headings.toLowerCase(), OBJ_mime_mhs_headings ); SYM_TO_OID.put( SN_mime_mhs_bodies.toLowerCase(), OBJ_mime_mhs_bodies ); SYM_TO_OID.put( LN_mime_mhs_bodies.toLowerCase(), OBJ_mime_mhs_bodies ); SYM_TO_OID.put( SN_id_hex_partial_message.toLowerCase(), OBJ_id_hex_partial_message ); SYM_TO_OID.put( LN_id_hex_partial_message.toLowerCase(), OBJ_id_hex_partial_message ); SYM_TO_OID.put( SN_id_hex_multipart_message.toLowerCase(), OBJ_id_hex_multipart_message ); SYM_TO_OID.put( LN_id_hex_multipart_message.toLowerCase(), OBJ_id_hex_multipart_message ); SYM_TO_OID.put( SN_rle_compression.toLowerCase(), OBJ_rle_compression ); SYM_TO_OID.put( LN_rle_compression.toLowerCase(), OBJ_rle_compression ); SYM_TO_OID.put( SN_zlib_compression.toLowerCase(), OBJ_zlib_compression ); SYM_TO_OID.put( LN_zlib_compression.toLowerCase(), OBJ_zlib_compression ); SYM_TO_OID.put( SN_aes_128_ecb.toLowerCase(), OBJ_aes_128_ecb ); SYM_TO_OID.put( LN_aes_128_ecb.toLowerCase(), OBJ_aes_128_ecb ); SYM_TO_OID.put( SN_aes_128_cbc.toLowerCase(), OBJ_aes_128_cbc ); SYM_TO_OID.put( LN_aes_128_cbc.toLowerCase(), OBJ_aes_128_cbc ); SYM_TO_OID.put( SN_aes_128_ofb128.toLowerCase(), OBJ_aes_128_ofb128 ); SYM_TO_OID.put( LN_aes_128_ofb128.toLowerCase(), OBJ_aes_128_ofb128 ); SYM_TO_OID.put( SN_aes_128_cfb128.toLowerCase(), OBJ_aes_128_cfb128 ); SYM_TO_OID.put( LN_aes_128_cfb128.toLowerCase(), OBJ_aes_128_cfb128 ); SYM_TO_OID.put( SN_id_aes128_wrap.toLowerCase(), OBJ_id_aes128_wrap ); SYM_TO_OID.put( SN_aes_128_gcm.toLowerCase(), OBJ_aes_128_gcm ); SYM_TO_OID.put( LN_aes_128_gcm.toLowerCase(), OBJ_aes_128_gcm ); SYM_TO_OID.put( SN_aes_128_ccm.toLowerCase(), OBJ_aes_128_ccm ); SYM_TO_OID.put( LN_aes_128_ccm.toLowerCase(), OBJ_aes_128_ccm ); SYM_TO_OID.put( SN_id_aes128_wrap_pad.toLowerCase(), OBJ_id_aes128_wrap_pad ); SYM_TO_OID.put( SN_aes_192_ecb.toLowerCase(), OBJ_aes_192_ecb ); SYM_TO_OID.put( LN_aes_192_ecb.toLowerCase(), OBJ_aes_192_ecb ); SYM_TO_OID.put( SN_aes_192_cbc.toLowerCase(), OBJ_aes_192_cbc ); SYM_TO_OID.put( LN_aes_192_cbc.toLowerCase(), OBJ_aes_192_cbc ); SYM_TO_OID.put( SN_aes_192_ofb128.toLowerCase(), OBJ_aes_192_ofb128 ); SYM_TO_OID.put( LN_aes_192_ofb128.toLowerCase(), OBJ_aes_192_ofb128 ); SYM_TO_OID.put( SN_aes_192_cfb128.toLowerCase(), OBJ_aes_192_cfb128 ); SYM_TO_OID.put( LN_aes_192_cfb128.toLowerCase(), OBJ_aes_192_cfb128 ); SYM_TO_OID.put( SN_id_aes192_wrap.toLowerCase(), OBJ_id_aes192_wrap ); SYM_TO_OID.put( SN_aes_192_gcm.toLowerCase(), OBJ_aes_192_gcm ); SYM_TO_OID.put( LN_aes_192_gcm.toLowerCase(), OBJ_aes_192_gcm ); SYM_TO_OID.put( SN_aes_192_ccm.toLowerCase(), OBJ_aes_192_ccm ); SYM_TO_OID.put( LN_aes_192_ccm.toLowerCase(), OBJ_aes_192_ccm ); SYM_TO_OID.put( SN_id_aes192_wrap_pad.toLowerCase(), OBJ_id_aes192_wrap_pad ); SYM_TO_OID.put( SN_aes_256_ecb.toLowerCase(), OBJ_aes_256_ecb ); SYM_TO_OID.put( LN_aes_256_ecb.toLowerCase(), OBJ_aes_256_ecb ); SYM_TO_OID.put( SN_aes_256_cbc.toLowerCase(), OBJ_aes_256_cbc ); SYM_TO_OID.put( LN_aes_256_cbc.toLowerCase(), OBJ_aes_256_cbc ); SYM_TO_OID.put( SN_aes_256_ofb128.toLowerCase(), OBJ_aes_256_ofb128 ); SYM_TO_OID.put( LN_aes_256_ofb128.toLowerCase(), OBJ_aes_256_ofb128 ); SYM_TO_OID.put( SN_aes_256_cfb128.toLowerCase(), OBJ_aes_256_cfb128 ); SYM_TO_OID.put( LN_aes_256_cfb128.toLowerCase(), OBJ_aes_256_cfb128 ); SYM_TO_OID.put( SN_id_aes256_wrap.toLowerCase(), OBJ_id_aes256_wrap ); SYM_TO_OID.put( SN_aes_256_gcm.toLowerCase(), OBJ_aes_256_gcm ); SYM_TO_OID.put( LN_aes_256_gcm.toLowerCase(), OBJ_aes_256_gcm ); SYM_TO_OID.put( SN_aes_256_ccm.toLowerCase(), OBJ_aes_256_ccm ); SYM_TO_OID.put( LN_aes_256_ccm.toLowerCase(), OBJ_aes_256_ccm ); SYM_TO_OID.put( SN_id_aes256_wrap_pad.toLowerCase(), OBJ_id_aes256_wrap_pad ); SYM_TO_OID.put( SN_sha256.toLowerCase(), OBJ_sha256 ); SYM_TO_OID.put( LN_sha256.toLowerCase(), OBJ_sha256 ); SYM_TO_OID.put( SN_sha384.toLowerCase(), OBJ_sha384 ); SYM_TO_OID.put( LN_sha384.toLowerCase(), OBJ_sha384 ); SYM_TO_OID.put( SN_sha512.toLowerCase(), OBJ_sha512 ); SYM_TO_OID.put( LN_sha512.toLowerCase(), OBJ_sha512 ); SYM_TO_OID.put( SN_sha224.toLowerCase(), OBJ_sha224 ); SYM_TO_OID.put( LN_sha224.toLowerCase(), OBJ_sha224 ); SYM_TO_OID.put( SN_dsa_with_SHA224.toLowerCase(), OBJ_dsa_with_SHA224 ); SYM_TO_OID.put( SN_dsa_with_SHA256.toLowerCase(), OBJ_dsa_with_SHA256 ); SYM_TO_OID.put( SN_hold_instruction_code.toLowerCase(), OBJ_hold_instruction_code ); SYM_TO_OID.put( LN_hold_instruction_code.toLowerCase(), OBJ_hold_instruction_code ); SYM_TO_OID.put( SN_hold_instruction_none.toLowerCase(), OBJ_hold_instruction_none ); SYM_TO_OID.put( LN_hold_instruction_none.toLowerCase(), OBJ_hold_instruction_none ); SYM_TO_OID.put( SN_hold_instruction_call_issuer.toLowerCase(), OBJ_hold_instruction_call_issuer ); SYM_TO_OID.put( LN_hold_instruction_call_issuer.toLowerCase(), OBJ_hold_instruction_call_issuer ); SYM_TO_OID.put( SN_hold_instruction_reject.toLowerCase(), OBJ_hold_instruction_reject ); SYM_TO_OID.put( LN_hold_instruction_reject.toLowerCase(), OBJ_hold_instruction_reject ); SYM_TO_OID.put( SN_data.toLowerCase(), OBJ_data ); SYM_TO_OID.put( SN_pss.toLowerCase(), OBJ_pss ); SYM_TO_OID.put( SN_ucl.toLowerCase(), OBJ_ucl ); SYM_TO_OID.put( SN_pilot.toLowerCase(), OBJ_pilot ); SYM_TO_OID.put( LN_pilotAttributeType.toLowerCase(), OBJ_pilotAttributeType ); SYM_TO_OID.put( LN_pilotAttributeSyntax.toLowerCase(), OBJ_pilotAttributeSyntax ); SYM_TO_OID.put( LN_pilotObjectClass.toLowerCase(), OBJ_pilotObjectClass ); SYM_TO_OID.put( LN_pilotGroups.toLowerCase(), OBJ_pilotGroups ); SYM_TO_OID.put( LN_iA5StringSyntax.toLowerCase(), OBJ_iA5StringSyntax ); SYM_TO_OID.put( LN_caseIgnoreIA5StringSyntax.toLowerCase(), OBJ_caseIgnoreIA5StringSyntax ); SYM_TO_OID.put( LN_pilotObject.toLowerCase(), OBJ_pilotObject ); SYM_TO_OID.put( LN_pilotPerson.toLowerCase(), OBJ_pilotPerson ); SYM_TO_OID.put( SN_account.toLowerCase(), OBJ_account ); SYM_TO_OID.put( SN_document.toLowerCase(), OBJ_document ); SYM_TO_OID.put( SN_room.toLowerCase(), OBJ_room ); SYM_TO_OID.put( LN_documentSeries.toLowerCase(), OBJ_documentSeries ); SYM_TO_OID.put( SN_Domain.toLowerCase(), OBJ_Domain ); SYM_TO_OID.put( LN_Domain.toLowerCase(), OBJ_Domain ); SYM_TO_OID.put( LN_rFC822localPart.toLowerCase(), OBJ_rFC822localPart ); SYM_TO_OID.put( LN_dNSDomain.toLowerCase(), OBJ_dNSDomain ); SYM_TO_OID.put( LN_domainRelatedObject.toLowerCase(), OBJ_domainRelatedObject ); SYM_TO_OID.put( LN_friendlyCountry.toLowerCase(), OBJ_friendlyCountry ); SYM_TO_OID.put( LN_simpleSecurityObject.toLowerCase(), OBJ_simpleSecurityObject ); SYM_TO_OID.put( LN_pilotOrganization.toLowerCase(), OBJ_pilotOrganization ); SYM_TO_OID.put( LN_pilotDSA.toLowerCase(), OBJ_pilotDSA ); SYM_TO_OID.put( LN_qualityLabelledData.toLowerCase(), OBJ_qualityLabelledData ); SYM_TO_OID.put( SN_userId.toLowerCase(), OBJ_userId ); SYM_TO_OID.put( LN_userId.toLowerCase(), OBJ_userId ); SYM_TO_OID.put( LN_textEncodedORAddress.toLowerCase(), OBJ_textEncodedORAddress ); SYM_TO_OID.put( SN_rfc822Mailbox.toLowerCase(), OBJ_rfc822Mailbox ); SYM_TO_OID.put( LN_rfc822Mailbox.toLowerCase(), OBJ_rfc822Mailbox ); SYM_TO_OID.put( SN_info.toLowerCase(), OBJ_info ); SYM_TO_OID.put( LN_favouriteDrink.toLowerCase(), OBJ_favouriteDrink ); SYM_TO_OID.put( LN_roomNumber.toLowerCase(), OBJ_roomNumber ); SYM_TO_OID.put( SN_photo.toLowerCase(), OBJ_photo ); SYM_TO_OID.put( LN_userClass.toLowerCase(), OBJ_userClass ); SYM_TO_OID.put( SN_host.toLowerCase(), OBJ_host ); SYM_TO_OID.put( SN_manager.toLowerCase(), OBJ_manager ); SYM_TO_OID.put( LN_documentIdentifier.toLowerCase(), OBJ_documentIdentifier ); SYM_TO_OID.put( LN_documentTitle.toLowerCase(), OBJ_documentTitle ); SYM_TO_OID.put( LN_documentVersion.toLowerCase(), OBJ_documentVersion ); SYM_TO_OID.put( LN_documentAuthor.toLowerCase(), OBJ_documentAuthor ); SYM_TO_OID.put( LN_documentLocation.toLowerCase(), OBJ_documentLocation ); SYM_TO_OID.put( LN_homeTelephoneNumber.toLowerCase(), OBJ_homeTelephoneNumber ); SYM_TO_OID.put( SN_secretary.toLowerCase(), OBJ_secretary ); SYM_TO_OID.put( LN_otherMailbox.toLowerCase(), OBJ_otherMailbox ); SYM_TO_OID.put( LN_lastModifiedTime.toLowerCase(), OBJ_lastModifiedTime ); SYM_TO_OID.put( LN_lastModifiedBy.toLowerCase(), OBJ_lastModifiedBy ); SYM_TO_OID.put( SN_domainComponent.toLowerCase(), OBJ_domainComponent ); SYM_TO_OID.put( LN_domainComponent.toLowerCase(), OBJ_domainComponent ); SYM_TO_OID.put( LN_aRecord.toLowerCase(), OBJ_aRecord ); SYM_TO_OID.put( LN_pilotAttributeType27.toLowerCase(), OBJ_pilotAttributeType27 ); SYM_TO_OID.put( LN_mXRecord.toLowerCase(), OBJ_mXRecord ); SYM_TO_OID.put( LN_nSRecord.toLowerCase(), OBJ_nSRecord ); SYM_TO_OID.put( LN_sOARecord.toLowerCase(), OBJ_sOARecord ); SYM_TO_OID.put( LN_cNAMERecord.toLowerCase(), OBJ_cNAMERecord ); SYM_TO_OID.put( LN_associatedDomain.toLowerCase(), OBJ_associatedDomain ); SYM_TO_OID.put( LN_associatedName.toLowerCase(), OBJ_associatedName ); SYM_TO_OID.put( LN_homePostalAddress.toLowerCase(), OBJ_homePostalAddress ); SYM_TO_OID.put( LN_personalTitle.toLowerCase(), OBJ_personalTitle ); SYM_TO_OID.put( LN_mobileTelephoneNumber.toLowerCase(), OBJ_mobileTelephoneNumber ); SYM_TO_OID.put( LN_pagerTelephoneNumber.toLowerCase(), OBJ_pagerTelephoneNumber ); SYM_TO_OID.put( LN_friendlyCountryName.toLowerCase(), OBJ_friendlyCountryName ); SYM_TO_OID.put( LN_organizationalStatus.toLowerCase(), OBJ_organizationalStatus ); SYM_TO_OID.put( LN_janetMailbox.toLowerCase(), OBJ_janetMailbox ); SYM_TO_OID.put( LN_mailPreferenceOption.toLowerCase(), OBJ_mailPreferenceOption ); SYM_TO_OID.put( LN_buildingName.toLowerCase(), OBJ_buildingName ); SYM_TO_OID.put( LN_dSAQuality.toLowerCase(), OBJ_dSAQuality ); SYM_TO_OID.put( LN_singleLevelQuality.toLowerCase(), OBJ_singleLevelQuality ); SYM_TO_OID.put( LN_subtreeMinimumQuality.toLowerCase(), OBJ_subtreeMinimumQuality ); SYM_TO_OID.put( LN_subtreeMaximumQuality.toLowerCase(), OBJ_subtreeMaximumQuality ); SYM_TO_OID.put( LN_personalSignature.toLowerCase(), OBJ_personalSignature ); SYM_TO_OID.put( LN_dITRedirect.toLowerCase(), OBJ_dITRedirect ); SYM_TO_OID.put( SN_audio.toLowerCase(), OBJ_audio ); SYM_TO_OID.put( LN_documentPublisher.toLowerCase(), OBJ_documentPublisher ); SYM_TO_OID.put( SN_id_set.toLowerCase(), OBJ_id_set ); SYM_TO_OID.put( LN_id_set.toLowerCase(), OBJ_id_set ); SYM_TO_OID.put( SN_set_ctype.toLowerCase(), OBJ_set_ctype ); SYM_TO_OID.put( LN_set_ctype.toLowerCase(), OBJ_set_ctype ); SYM_TO_OID.put( SN_set_msgExt.toLowerCase(), OBJ_set_msgExt ); SYM_TO_OID.put( LN_set_msgExt.toLowerCase(), OBJ_set_msgExt ); SYM_TO_OID.put( SN_set_attr.toLowerCase(), OBJ_set_attr ); SYM_TO_OID.put( SN_set_policy.toLowerCase(), OBJ_set_policy ); SYM_TO_OID.put( SN_set_certExt.toLowerCase(), OBJ_set_certExt ); SYM_TO_OID.put( LN_set_certExt.toLowerCase(), OBJ_set_certExt ); SYM_TO_OID.put( SN_set_brand.toLowerCase(), OBJ_set_brand ); SYM_TO_OID.put( SN_setct_PANData.toLowerCase(), OBJ_setct_PANData ); SYM_TO_OID.put( SN_setct_PANToken.toLowerCase(), OBJ_setct_PANToken ); SYM_TO_OID.put( SN_setct_PANOnly.toLowerCase(), OBJ_setct_PANOnly ); SYM_TO_OID.put( SN_setct_OIData.toLowerCase(), OBJ_setct_OIData ); SYM_TO_OID.put( SN_setct_PI.toLowerCase(), OBJ_setct_PI ); SYM_TO_OID.put( SN_setct_PIData.toLowerCase(), OBJ_setct_PIData ); SYM_TO_OID.put( SN_setct_PIDataUnsigned.toLowerCase(), OBJ_setct_PIDataUnsigned ); SYM_TO_OID.put( SN_setct_HODInput.toLowerCase(), OBJ_setct_HODInput ); SYM_TO_OID.put( SN_setct_AuthResBaggage.toLowerCase(), OBJ_setct_AuthResBaggage ); SYM_TO_OID.put( SN_setct_AuthRevReqBaggage.toLowerCase(), OBJ_setct_AuthRevReqBaggage ); SYM_TO_OID.put( SN_setct_AuthRevResBaggage.toLowerCase(), OBJ_setct_AuthRevResBaggage ); SYM_TO_OID.put( SN_setct_CapTokenSeq.toLowerCase(), OBJ_setct_CapTokenSeq ); SYM_TO_OID.put( SN_setct_PInitResData.toLowerCase(), OBJ_setct_PInitResData ); SYM_TO_OID.put( SN_setct_PI_TBS.toLowerCase(), OBJ_setct_PI_TBS ); SYM_TO_OID.put( SN_setct_PResData.toLowerCase(), OBJ_setct_PResData ); SYM_TO_OID.put( SN_setct_AuthReqTBS.toLowerCase(), OBJ_setct_AuthReqTBS ); SYM_TO_OID.put( SN_setct_AuthResTBS.toLowerCase(), OBJ_setct_AuthResTBS ); SYM_TO_OID.put( SN_setct_AuthResTBSX.toLowerCase(), OBJ_setct_AuthResTBSX ); SYM_TO_OID.put( SN_setct_AuthTokenTBS.toLowerCase(), OBJ_setct_AuthTokenTBS ); SYM_TO_OID.put( SN_setct_CapTokenData.toLowerCase(), OBJ_setct_CapTokenData ); SYM_TO_OID.put( SN_setct_CapTokenTBS.toLowerCase(), OBJ_setct_CapTokenTBS ); SYM_TO_OID.put( SN_setct_AcqCardCodeMsg.toLowerCase(), OBJ_setct_AcqCardCodeMsg ); SYM_TO_OID.put( SN_setct_AuthRevReqTBS.toLowerCase(), OBJ_setct_AuthRevReqTBS ); SYM_TO_OID.put( SN_setct_AuthRevResData.toLowerCase(), OBJ_setct_AuthRevResData ); SYM_TO_OID.put( SN_setct_AuthRevResTBS.toLowerCase(), OBJ_setct_AuthRevResTBS ); SYM_TO_OID.put( SN_setct_CapReqTBS.toLowerCase(), OBJ_setct_CapReqTBS ); SYM_TO_OID.put( SN_setct_CapReqTBSX.toLowerCase(), OBJ_setct_CapReqTBSX ); SYM_TO_OID.put( SN_setct_CapResData.toLowerCase(), OBJ_setct_CapResData ); SYM_TO_OID.put( SN_setct_CapRevReqTBS.toLowerCase(), OBJ_setct_CapRevReqTBS ); SYM_TO_OID.put( SN_setct_CapRevReqTBSX.toLowerCase(), OBJ_setct_CapRevReqTBSX ); SYM_TO_OID.put( SN_setct_CapRevResData.toLowerCase(), OBJ_setct_CapRevResData ); SYM_TO_OID.put( SN_setct_CredReqTBS.toLowerCase(), OBJ_setct_CredReqTBS ); SYM_TO_OID.put( SN_setct_CredReqTBSX.toLowerCase(), OBJ_setct_CredReqTBSX ); SYM_TO_OID.put( SN_setct_CredResData.toLowerCase(), OBJ_setct_CredResData ); SYM_TO_OID.put( SN_setct_CredRevReqTBS.toLowerCase(), OBJ_setct_CredRevReqTBS ); SYM_TO_OID.put( SN_setct_CredRevReqTBSX.toLowerCase(), OBJ_setct_CredRevReqTBSX ); SYM_TO_OID.put( SN_setct_CredRevResData.toLowerCase(), OBJ_setct_CredRevResData ); SYM_TO_OID.put( SN_setct_PCertReqData.toLowerCase(), OBJ_setct_PCertReqData ); SYM_TO_OID.put( SN_setct_PCertResTBS.toLowerCase(), OBJ_setct_PCertResTBS ); SYM_TO_OID.put( SN_setct_BatchAdminReqData.toLowerCase(), OBJ_setct_BatchAdminReqData ); SYM_TO_OID.put( SN_setct_BatchAdminResData.toLowerCase(), OBJ_setct_BatchAdminResData ); SYM_TO_OID.put( SN_setct_CardCInitResTBS.toLowerCase(), OBJ_setct_CardCInitResTBS ); SYM_TO_OID.put( SN_setct_MeAqCInitResTBS.toLowerCase(), OBJ_setct_MeAqCInitResTBS ); SYM_TO_OID.put( SN_setct_RegFormResTBS.toLowerCase(), OBJ_setct_RegFormResTBS ); SYM_TO_OID.put( SN_setct_CertReqData.toLowerCase(), OBJ_setct_CertReqData ); SYM_TO_OID.put( SN_setct_CertReqTBS.toLowerCase(), OBJ_setct_CertReqTBS ); SYM_TO_OID.put( SN_setct_CertResData.toLowerCase(), OBJ_setct_CertResData ); SYM_TO_OID.put( SN_setct_CertInqReqTBS.toLowerCase(), OBJ_setct_CertInqReqTBS ); SYM_TO_OID.put( SN_setct_ErrorTBS.toLowerCase(), OBJ_setct_ErrorTBS ); SYM_TO_OID.put( SN_setct_PIDualSignedTBE.toLowerCase(), OBJ_setct_PIDualSignedTBE ); SYM_TO_OID.put( SN_setct_PIUnsignedTBE.toLowerCase(), OBJ_setct_PIUnsignedTBE ); SYM_TO_OID.put( SN_setct_AuthReqTBE.toLowerCase(), OBJ_setct_AuthReqTBE ); SYM_TO_OID.put( SN_setct_AuthResTBE.toLowerCase(), OBJ_setct_AuthResTBE ); SYM_TO_OID.put( SN_setct_AuthResTBEX.toLowerCase(), OBJ_setct_AuthResTBEX ); SYM_TO_OID.put( SN_setct_AuthTokenTBE.toLowerCase(), OBJ_setct_AuthTokenTBE ); SYM_TO_OID.put( SN_setct_CapTokenTBE.toLowerCase(), OBJ_setct_CapTokenTBE ); SYM_TO_OID.put( SN_setct_CapTokenTBEX.toLowerCase(), OBJ_setct_CapTokenTBEX ); SYM_TO_OID.put( SN_setct_AcqCardCodeMsgTBE.toLowerCase(), OBJ_setct_AcqCardCodeMsgTBE ); SYM_TO_OID.put( SN_setct_AuthRevReqTBE.toLowerCase(), OBJ_setct_AuthRevReqTBE ); SYM_TO_OID.put( SN_setct_AuthRevResTBE.toLowerCase(), OBJ_setct_AuthRevResTBE ); SYM_TO_OID.put( SN_setct_AuthRevResTBEB.toLowerCase(), OBJ_setct_AuthRevResTBEB ); SYM_TO_OID.put( SN_setct_CapReqTBE.toLowerCase(), OBJ_setct_CapReqTBE ); SYM_TO_OID.put( SN_setct_CapReqTBEX.toLowerCase(), OBJ_setct_CapReqTBEX ); SYM_TO_OID.put( SN_setct_CapResTBE.toLowerCase(), OBJ_setct_CapResTBE ); SYM_TO_OID.put( SN_setct_CapRevReqTBE.toLowerCase(), OBJ_setct_CapRevReqTBE ); SYM_TO_OID.put( SN_setct_CapRevReqTBEX.toLowerCase(), OBJ_setct_CapRevReqTBEX ); SYM_TO_OID.put( SN_setct_CapRevResTBE.toLowerCase(), OBJ_setct_CapRevResTBE ); SYM_TO_OID.put( SN_setct_CredReqTBE.toLowerCase(), OBJ_setct_CredReqTBE ); SYM_TO_OID.put( SN_setct_CredReqTBEX.toLowerCase(), OBJ_setct_CredReqTBEX ); SYM_TO_OID.put( SN_setct_CredResTBE.toLowerCase(), OBJ_setct_CredResTBE ); SYM_TO_OID.put( SN_setct_CredRevReqTBE.toLowerCase(), OBJ_setct_CredRevReqTBE ); SYM_TO_OID.put( SN_setct_CredRevReqTBEX.toLowerCase(), OBJ_setct_CredRevReqTBEX ); SYM_TO_OID.put( SN_setct_CredRevResTBE.toLowerCase(), OBJ_setct_CredRevResTBE ); SYM_TO_OID.put( SN_setct_BatchAdminReqTBE.toLowerCase(), OBJ_setct_BatchAdminReqTBE ); SYM_TO_OID.put( SN_setct_BatchAdminResTBE.toLowerCase(), OBJ_setct_BatchAdminResTBE ); SYM_TO_OID.put( SN_setct_RegFormReqTBE.toLowerCase(), OBJ_setct_RegFormReqTBE ); SYM_TO_OID.put( SN_setct_CertReqTBE.toLowerCase(), OBJ_setct_CertReqTBE ); SYM_TO_OID.put( SN_setct_CertReqTBEX.toLowerCase(), OBJ_setct_CertReqTBEX ); SYM_TO_OID.put( SN_setct_CertResTBE.toLowerCase(), OBJ_setct_CertResTBE ); SYM_TO_OID.put( SN_setct_CRLNotificationTBS.toLowerCase(), OBJ_setct_CRLNotificationTBS ); SYM_TO_OID.put( SN_setct_CRLNotificationResTBS.toLowerCase(), OBJ_setct_CRLNotificationResTBS ); SYM_TO_OID.put( SN_setct_BCIDistributionTBS.toLowerCase(), OBJ_setct_BCIDistributionTBS ); SYM_TO_OID.put( SN_setext_genCrypt.toLowerCase(), OBJ_setext_genCrypt ); SYM_TO_OID.put( LN_setext_genCrypt.toLowerCase(), OBJ_setext_genCrypt ); SYM_TO_OID.put( SN_setext_miAuth.toLowerCase(), OBJ_setext_miAuth ); SYM_TO_OID.put( LN_setext_miAuth.toLowerCase(), OBJ_setext_miAuth ); SYM_TO_OID.put( SN_setext_pinSecure.toLowerCase(), OBJ_setext_pinSecure ); SYM_TO_OID.put( SN_setext_pinAny.toLowerCase(), OBJ_setext_pinAny ); SYM_TO_OID.put( SN_setext_track2.toLowerCase(), OBJ_setext_track2 ); SYM_TO_OID.put( SN_setext_cv.toLowerCase(), OBJ_setext_cv ); SYM_TO_OID.put( LN_setext_cv.toLowerCase(), OBJ_setext_cv ); SYM_TO_OID.put( SN_set_policy_root.toLowerCase(), OBJ_set_policy_root ); SYM_TO_OID.put( SN_setCext_hashedRoot.toLowerCase(), OBJ_setCext_hashedRoot ); SYM_TO_OID.put( SN_setCext_certType.toLowerCase(), OBJ_setCext_certType ); SYM_TO_OID.put( SN_setCext_merchData.toLowerCase(), OBJ_setCext_merchData ); SYM_TO_OID.put( SN_setCext_cCertRequired.toLowerCase(), OBJ_setCext_cCertRequired ); SYM_TO_OID.put( SN_setCext_tunneling.toLowerCase(), OBJ_setCext_tunneling ); SYM_TO_OID.put( SN_setCext_setExt.toLowerCase(), OBJ_setCext_setExt ); SYM_TO_OID.put( SN_setCext_setQualf.toLowerCase(), OBJ_setCext_setQualf ); SYM_TO_OID.put( SN_setCext_PGWYcapabilities.toLowerCase(), OBJ_setCext_PGWYcapabilities ); SYM_TO_OID.put( SN_setCext_TokenIdentifier.toLowerCase(), OBJ_setCext_TokenIdentifier ); SYM_TO_OID.put( SN_setCext_Track2Data.toLowerCase(), OBJ_setCext_Track2Data ); SYM_TO_OID.put( SN_setCext_TokenType.toLowerCase(), OBJ_setCext_TokenType ); SYM_TO_OID.put( SN_setCext_IssuerCapabilities.toLowerCase(), OBJ_setCext_IssuerCapabilities ); SYM_TO_OID.put( SN_setAttr_Cert.toLowerCase(), OBJ_setAttr_Cert ); SYM_TO_OID.put( SN_setAttr_PGWYcap.toLowerCase(), OBJ_setAttr_PGWYcap ); SYM_TO_OID.put( LN_setAttr_PGWYcap.toLowerCase(), OBJ_setAttr_PGWYcap ); SYM_TO_OID.put( SN_setAttr_TokenType.toLowerCase(), OBJ_setAttr_TokenType ); SYM_TO_OID.put( SN_setAttr_IssCap.toLowerCase(), OBJ_setAttr_IssCap ); SYM_TO_OID.put( LN_setAttr_IssCap.toLowerCase(), OBJ_setAttr_IssCap ); SYM_TO_OID.put( SN_set_rootKeyThumb.toLowerCase(), OBJ_set_rootKeyThumb ); SYM_TO_OID.put( SN_set_addPolicy.toLowerCase(), OBJ_set_addPolicy ); SYM_TO_OID.put( SN_setAttr_Token_EMV.toLowerCase(), OBJ_setAttr_Token_EMV ); SYM_TO_OID.put( SN_setAttr_Token_B0Prime.toLowerCase(), OBJ_setAttr_Token_B0Prime ); SYM_TO_OID.put( SN_setAttr_IssCap_CVM.toLowerCase(), OBJ_setAttr_IssCap_CVM ); SYM_TO_OID.put( SN_setAttr_IssCap_T2.toLowerCase(), OBJ_setAttr_IssCap_T2 ); SYM_TO_OID.put( SN_setAttr_IssCap_Sig.toLowerCase(), OBJ_setAttr_IssCap_Sig ); SYM_TO_OID.put( SN_setAttr_GenCryptgrm.toLowerCase(), OBJ_setAttr_GenCryptgrm ); SYM_TO_OID.put( LN_setAttr_GenCryptgrm.toLowerCase(), OBJ_setAttr_GenCryptgrm ); SYM_TO_OID.put( SN_setAttr_T2Enc.toLowerCase(), OBJ_setAttr_T2Enc ); SYM_TO_OID.put( LN_setAttr_T2Enc.toLowerCase(), OBJ_setAttr_T2Enc ); SYM_TO_OID.put( SN_setAttr_T2cleartxt.toLowerCase(), OBJ_setAttr_T2cleartxt ); SYM_TO_OID.put( LN_setAttr_T2cleartxt.toLowerCase(), OBJ_setAttr_T2cleartxt ); SYM_TO_OID.put( SN_setAttr_TokICCsig.toLowerCase(), OBJ_setAttr_TokICCsig ); SYM_TO_OID.put( LN_setAttr_TokICCsig.toLowerCase(), OBJ_setAttr_TokICCsig ); SYM_TO_OID.put( SN_setAttr_SecDevSig.toLowerCase(), OBJ_setAttr_SecDevSig ); SYM_TO_OID.put( LN_setAttr_SecDevSig.toLowerCase(), OBJ_setAttr_SecDevSig ); SYM_TO_OID.put( SN_set_brand_IATA_ATA.toLowerCase(), OBJ_set_brand_IATA_ATA ); SYM_TO_OID.put( SN_set_brand_Diners.toLowerCase(), OBJ_set_brand_Diners ); SYM_TO_OID.put( SN_set_brand_AmericanExpress.toLowerCase(), OBJ_set_brand_AmericanExpress ); SYM_TO_OID.put( SN_set_brand_JCB.toLowerCase(), OBJ_set_brand_JCB ); SYM_TO_OID.put( SN_set_brand_Visa.toLowerCase(), OBJ_set_brand_Visa ); SYM_TO_OID.put( SN_set_brand_MasterCard.toLowerCase(), OBJ_set_brand_MasterCard ); SYM_TO_OID.put( SN_set_brand_Novus.toLowerCase(), OBJ_set_brand_Novus ); SYM_TO_OID.put( SN_des_cdmf.toLowerCase(), OBJ_des_cdmf ); SYM_TO_OID.put( LN_des_cdmf.toLowerCase(), OBJ_des_cdmf ); SYM_TO_OID.put( SN_rsaOAEPEncryptionSET.toLowerCase(), OBJ_rsaOAEPEncryptionSET ); SYM_TO_OID.put( SN_whirlpool.toLowerCase(), OBJ_whirlpool ); SYM_TO_OID.put( SN_cryptopro.toLowerCase(), OBJ_cryptopro ); SYM_TO_OID.put( SN_cryptocom.toLowerCase(), OBJ_cryptocom ); SYM_TO_OID.put( SN_id_GostR3411_94_with_GostR3410_2001.toLowerCase(), OBJ_id_GostR3411_94_with_GostR3410_2001 ); SYM_TO_OID.put( LN_id_GostR3411_94_with_GostR3410_2001.toLowerCase(), OBJ_id_GostR3411_94_with_GostR3410_2001 ); SYM_TO_OID.put( SN_id_GostR3411_94_with_GostR3410_94.toLowerCase(), OBJ_id_GostR3411_94_with_GostR3410_94 ); SYM_TO_OID.put( LN_id_GostR3411_94_with_GostR3410_94.toLowerCase(), OBJ_id_GostR3411_94_with_GostR3410_94 ); SYM_TO_OID.put( SN_id_GostR3411_94.toLowerCase(), OBJ_id_GostR3411_94 ); SYM_TO_OID.put( LN_id_GostR3411_94.toLowerCase(), OBJ_id_GostR3411_94 ); SYM_TO_OID.put( SN_id_HMACGostR3411_94.toLowerCase(), OBJ_id_HMACGostR3411_94 ); SYM_TO_OID.put( LN_id_HMACGostR3411_94.toLowerCase(), OBJ_id_HMACGostR3411_94 ); SYM_TO_OID.put( SN_id_GostR3410_2001.toLowerCase(), OBJ_id_GostR3410_2001 ); SYM_TO_OID.put( LN_id_GostR3410_2001.toLowerCase(), OBJ_id_GostR3410_2001 ); SYM_TO_OID.put( SN_id_GostR3410_94.toLowerCase(), OBJ_id_GostR3410_94 ); SYM_TO_OID.put( LN_id_GostR3410_94.toLowerCase(), OBJ_id_GostR3410_94 ); SYM_TO_OID.put( SN_id_Gost28147_89.toLowerCase(), OBJ_id_Gost28147_89 ); SYM_TO_OID.put( LN_id_Gost28147_89.toLowerCase(), OBJ_id_Gost28147_89 ); SYM_TO_OID.put( SN_id_Gost28147_89_MAC.toLowerCase(), OBJ_id_Gost28147_89_MAC ); SYM_TO_OID.put( LN_id_Gost28147_89_MAC.toLowerCase(), OBJ_id_Gost28147_89_MAC ); SYM_TO_OID.put( SN_id_GostR3411_94_prf.toLowerCase(), OBJ_id_GostR3411_94_prf ); SYM_TO_OID.put( LN_id_GostR3411_94_prf.toLowerCase(), OBJ_id_GostR3411_94_prf ); SYM_TO_OID.put( SN_id_GostR3410_2001DH.toLowerCase(), OBJ_id_GostR3410_2001DH ); SYM_TO_OID.put( LN_id_GostR3410_2001DH.toLowerCase(), OBJ_id_GostR3410_2001DH ); SYM_TO_OID.put( SN_id_GostR3410_94DH.toLowerCase(), OBJ_id_GostR3410_94DH ); SYM_TO_OID.put( LN_id_GostR3410_94DH.toLowerCase(), OBJ_id_GostR3410_94DH ); SYM_TO_OID.put( SN_id_Gost28147_89_CryptoPro_KeyMeshing.toLowerCase(), OBJ_id_Gost28147_89_CryptoPro_KeyMeshing ); SYM_TO_OID.put( SN_id_Gost28147_89_None_KeyMeshing.toLowerCase(), OBJ_id_Gost28147_89_None_KeyMeshing ); SYM_TO_OID.put( SN_id_GostR3411_94_TestParamSet.toLowerCase(), OBJ_id_GostR3411_94_TestParamSet ); SYM_TO_OID.put( SN_id_GostR3411_94_CryptoProParamSet.toLowerCase(), OBJ_id_GostR3411_94_CryptoProParamSet ); SYM_TO_OID.put( SN_id_Gost28147_89_TestParamSet.toLowerCase(), OBJ_id_Gost28147_89_TestParamSet ); SYM_TO_OID.put( SN_id_Gost28147_89_CryptoPro_A_ParamSet.toLowerCase(), OBJ_id_Gost28147_89_CryptoPro_A_ParamSet ); SYM_TO_OID.put( SN_id_Gost28147_89_CryptoPro_B_ParamSet.toLowerCase(), OBJ_id_Gost28147_89_CryptoPro_B_ParamSet ); SYM_TO_OID.put( SN_id_Gost28147_89_CryptoPro_C_ParamSet.toLowerCase(), OBJ_id_Gost28147_89_CryptoPro_C_ParamSet ); SYM_TO_OID.put( SN_id_Gost28147_89_CryptoPro_D_ParamSet.toLowerCase(), OBJ_id_Gost28147_89_CryptoPro_D_ParamSet ); SYM_TO_OID.put( SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet.toLowerCase(), OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet ); SYM_TO_OID.put( SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet.toLowerCase(), OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet ); SYM_TO_OID.put( SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet.toLowerCase(), OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_TestParamSet.toLowerCase(), OBJ_id_GostR3410_94_TestParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_CryptoPro_A_ParamSet.toLowerCase(), OBJ_id_GostR3410_94_CryptoPro_A_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_CryptoPro_B_ParamSet.toLowerCase(), OBJ_id_GostR3410_94_CryptoPro_B_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_CryptoPro_C_ParamSet.toLowerCase(), OBJ_id_GostR3410_94_CryptoPro_C_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_CryptoPro_D_ParamSet.toLowerCase(), OBJ_id_GostR3410_94_CryptoPro_D_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_CryptoPro_XchA_ParamSet.toLowerCase(), OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_CryptoPro_XchB_ParamSet.toLowerCase(), OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_CryptoPro_XchC_ParamSet.toLowerCase(), OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_2001_TestParamSet.toLowerCase(), OBJ_id_GostR3410_2001_TestParamSet ); SYM_TO_OID.put( SN_id_GostR3410_2001_CryptoPro_A_ParamSet.toLowerCase(), OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_2001_CryptoPro_B_ParamSet.toLowerCase(), OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_2001_CryptoPro_C_ParamSet.toLowerCase(), OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet.toLowerCase(), OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet.toLowerCase(), OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet ); SYM_TO_OID.put( SN_id_GostR3410_94_a.toLowerCase(), OBJ_id_GostR3410_94_a ); SYM_TO_OID.put( SN_id_GostR3410_94_aBis.toLowerCase(), OBJ_id_GostR3410_94_aBis ); SYM_TO_OID.put( SN_id_GostR3410_94_b.toLowerCase(), OBJ_id_GostR3410_94_b ); SYM_TO_OID.put( SN_id_GostR3410_94_bBis.toLowerCase(), OBJ_id_GostR3410_94_bBis ); SYM_TO_OID.put( SN_id_Gost28147_89_cc.toLowerCase(), OBJ_id_Gost28147_89_cc ); SYM_TO_OID.put( LN_id_Gost28147_89_cc.toLowerCase(), OBJ_id_Gost28147_89_cc ); SYM_TO_OID.put( SN_id_GostR3410_94_cc.toLowerCase(), OBJ_id_GostR3410_94_cc ); SYM_TO_OID.put( LN_id_GostR3410_94_cc.toLowerCase(), OBJ_id_GostR3410_94_cc ); SYM_TO_OID.put( SN_id_GostR3410_2001_cc.toLowerCase(), OBJ_id_GostR3410_2001_cc ); SYM_TO_OID.put( LN_id_GostR3410_2001_cc.toLowerCase(), OBJ_id_GostR3410_2001_cc ); SYM_TO_OID.put( SN_id_GostR3411_94_with_GostR3410_94_cc.toLowerCase(), OBJ_id_GostR3411_94_with_GostR3410_94_cc ); SYM_TO_OID.put( LN_id_GostR3411_94_with_GostR3410_94_cc.toLowerCase(), OBJ_id_GostR3411_94_with_GostR3410_94_cc ); SYM_TO_OID.put( SN_id_GostR3411_94_with_GostR3410_2001_cc.toLowerCase(), OBJ_id_GostR3411_94_with_GostR3410_2001_cc ); SYM_TO_OID.put( LN_id_GostR3411_94_with_GostR3410_2001_cc.toLowerCase(), OBJ_id_GostR3411_94_with_GostR3410_2001_cc ); SYM_TO_OID.put( SN_id_GostR3410_2001_ParamSet_cc.toLowerCase(), OBJ_id_GostR3410_2001_ParamSet_cc ); SYM_TO_OID.put( LN_id_GostR3410_2001_ParamSet_cc.toLowerCase(), OBJ_id_GostR3410_2001_ParamSet_cc ); SYM_TO_OID.put( SN_camellia_128_cbc.toLowerCase(), OBJ_camellia_128_cbc ); SYM_TO_OID.put( LN_camellia_128_cbc.toLowerCase(), OBJ_camellia_128_cbc ); SYM_TO_OID.put( SN_camellia_192_cbc.toLowerCase(), OBJ_camellia_192_cbc ); SYM_TO_OID.put( LN_camellia_192_cbc.toLowerCase(), OBJ_camellia_192_cbc ); SYM_TO_OID.put( SN_camellia_256_cbc.toLowerCase(), OBJ_camellia_256_cbc ); SYM_TO_OID.put( LN_camellia_256_cbc.toLowerCase(), OBJ_camellia_256_cbc ); SYM_TO_OID.put( SN_id_camellia128_wrap.toLowerCase(), OBJ_id_camellia128_wrap ); SYM_TO_OID.put( SN_id_camellia192_wrap.toLowerCase(), OBJ_id_camellia192_wrap ); SYM_TO_OID.put( SN_id_camellia256_wrap.toLowerCase(), OBJ_id_camellia256_wrap ); SYM_TO_OID.put( SN_camellia_128_ecb.toLowerCase(), OBJ_camellia_128_ecb ); SYM_TO_OID.put( LN_camellia_128_ecb.toLowerCase(), OBJ_camellia_128_ecb ); SYM_TO_OID.put( SN_camellia_128_ofb128.toLowerCase(), OBJ_camellia_128_ofb128 ); SYM_TO_OID.put( LN_camellia_128_ofb128.toLowerCase(), OBJ_camellia_128_ofb128 ); SYM_TO_OID.put( SN_camellia_128_cfb128.toLowerCase(), OBJ_camellia_128_cfb128 ); SYM_TO_OID.put( LN_camellia_128_cfb128.toLowerCase(), OBJ_camellia_128_cfb128 ); SYM_TO_OID.put( SN_camellia_192_ecb.toLowerCase(), OBJ_camellia_192_ecb ); SYM_TO_OID.put( LN_camellia_192_ecb.toLowerCase(), OBJ_camellia_192_ecb ); SYM_TO_OID.put( SN_camellia_192_ofb128.toLowerCase(), OBJ_camellia_192_ofb128 ); SYM_TO_OID.put( LN_camellia_192_ofb128.toLowerCase(), OBJ_camellia_192_ofb128 ); SYM_TO_OID.put( SN_camellia_192_cfb128.toLowerCase(), OBJ_camellia_192_cfb128 ); SYM_TO_OID.put( LN_camellia_192_cfb128.toLowerCase(), OBJ_camellia_192_cfb128 ); SYM_TO_OID.put( SN_camellia_256_ecb.toLowerCase(), OBJ_camellia_256_ecb ); SYM_TO_OID.put( LN_camellia_256_ecb.toLowerCase(), OBJ_camellia_256_ecb ); SYM_TO_OID.put( SN_camellia_256_ofb128.toLowerCase(), OBJ_camellia_256_ofb128 ); SYM_TO_OID.put( LN_camellia_256_ofb128.toLowerCase(), OBJ_camellia_256_ofb128 ); SYM_TO_OID.put( SN_camellia_256_cfb128.toLowerCase(), OBJ_camellia_256_cfb128 ); SYM_TO_OID.put( LN_camellia_256_cfb128.toLowerCase(), OBJ_camellia_256_cfb128 ); SYM_TO_OID.put( SN_kisa.toLowerCase(), OBJ_kisa ); SYM_TO_OID.put( LN_kisa.toLowerCase(), OBJ_kisa ); SYM_TO_OID.put( SN_seed_ecb.toLowerCase(), OBJ_seed_ecb ); SYM_TO_OID.put( LN_seed_ecb.toLowerCase(), OBJ_seed_ecb ); SYM_TO_OID.put( SN_seed_cbc.toLowerCase(), OBJ_seed_cbc ); SYM_TO_OID.put( LN_seed_cbc.toLowerCase(), OBJ_seed_cbc ); SYM_TO_OID.put( SN_seed_cfb128.toLowerCase(), OBJ_seed_cfb128 ); SYM_TO_OID.put( LN_seed_cfb128.toLowerCase(), OBJ_seed_cfb128 ); SYM_TO_OID.put( SN_seed_ofb128.toLowerCase(), OBJ_seed_ofb128 ); SYM_TO_OID.put( LN_seed_ofb128.toLowerCase(), OBJ_seed_ofb128 ); SYM_TO_OID.put( SN_dhpublicnumber.toLowerCase(), OBJ_dhpublicnumber ); SYM_TO_OID.put( LN_dhpublicnumber.toLowerCase(), OBJ_dhpublicnumber ); SYM_TO_OID.put( SN_brainpoolP160r1.toLowerCase(), OBJ_brainpoolP160r1 ); SYM_TO_OID.put( SN_brainpoolP160t1.toLowerCase(), OBJ_brainpoolP160t1 ); SYM_TO_OID.put( SN_brainpoolP192r1.toLowerCase(), OBJ_brainpoolP192r1 ); SYM_TO_OID.put( SN_brainpoolP192t1.toLowerCase(), OBJ_brainpoolP192t1 ); SYM_TO_OID.put( SN_brainpoolP224r1.toLowerCase(), OBJ_brainpoolP224r1 ); SYM_TO_OID.put( SN_brainpoolP224t1.toLowerCase(), OBJ_brainpoolP224t1 ); SYM_TO_OID.put( SN_brainpoolP256r1.toLowerCase(), OBJ_brainpoolP256r1 ); SYM_TO_OID.put( SN_brainpoolP256t1.toLowerCase(), OBJ_brainpoolP256t1 ); SYM_TO_OID.put( SN_brainpoolP320r1.toLowerCase(), OBJ_brainpoolP320r1 ); SYM_TO_OID.put( SN_brainpoolP320t1.toLowerCase(), OBJ_brainpoolP320t1 ); SYM_TO_OID.put( SN_brainpoolP384r1.toLowerCase(), OBJ_brainpoolP384r1 ); SYM_TO_OID.put( SN_brainpoolP384t1.toLowerCase(), OBJ_brainpoolP384t1 ); SYM_TO_OID.put( SN_brainpoolP512r1.toLowerCase(), OBJ_brainpoolP512r1 ); SYM_TO_OID.put( SN_brainpoolP512t1.toLowerCase(), OBJ_brainpoolP512t1 ); SYM_TO_OID.put( SN_dhSinglePass_stdDH_sha1kdf_scheme.toLowerCase(), OBJ_dhSinglePass_stdDH_sha1kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_stdDH_sha224kdf_scheme.toLowerCase(), OBJ_dhSinglePass_stdDH_sha224kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_stdDH_sha256kdf_scheme.toLowerCase(), OBJ_dhSinglePass_stdDH_sha256kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_stdDH_sha384kdf_scheme.toLowerCase(), OBJ_dhSinglePass_stdDH_sha384kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_stdDH_sha512kdf_scheme.toLowerCase(), OBJ_dhSinglePass_stdDH_sha512kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_cofactorDH_sha1kdf_scheme.toLowerCase(), OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_cofactorDH_sha224kdf_scheme.toLowerCase(), OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_cofactorDH_sha256kdf_scheme.toLowerCase(), OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_cofactorDH_sha384kdf_scheme.toLowerCase(), OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme ); SYM_TO_OID.put( SN_dhSinglePass_cofactorDH_sha512kdf_scheme.toLowerCase(), OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme ); SYM_TO_OID.put( SN_ct_precert_scts.toLowerCase(), OBJ_ct_precert_scts ); SYM_TO_OID.put( LN_ct_precert_scts.toLowerCase(), OBJ_ct_precert_scts ); SYM_TO_OID.put( SN_ct_precert_poison.toLowerCase(), OBJ_ct_precert_poison ); SYM_TO_OID.put( LN_ct_precert_poison.toLowerCase(), OBJ_ct_precert_poison ); SYM_TO_OID.put( SN_ct_precert_signer.toLowerCase(), OBJ_ct_precert_signer ); SYM_TO_OID.put( LN_ct_precert_signer.toLowerCase(), OBJ_ct_precert_signer ); SYM_TO_OID.put( SN_ct_cert_scts.toLowerCase(), OBJ_ct_cert_scts ); SYM_TO_OID.put( LN_ct_cert_scts.toLowerCase(), OBJ_ct_cert_scts ); SYM_TO_OID.put( SN_jurisdictionLocalityName.toLowerCase(), OBJ_jurisdictionLocalityName ); SYM_TO_OID.put( LN_jurisdictionLocalityName.toLowerCase(), OBJ_jurisdictionLocalityName ); SYM_TO_OID.put( SN_jurisdictionStateOrProvinceName.toLowerCase(), OBJ_jurisdictionStateOrProvinceName ); SYM_TO_OID.put( LN_jurisdictionStateOrProvinceName.toLowerCase(), OBJ_jurisdictionStateOrProvinceName ); SYM_TO_OID.put( SN_jurisdictionCountryName.toLowerCase(), OBJ_jurisdictionCountryName ); SYM_TO_OID.put( LN_jurisdictionCountryName.toLowerCase(), OBJ_jurisdictionCountryName ); } private static final HashMap OID_TO_SYM = new HashMap(1052, 1); // OID_TO_SYM.put(oid, sn == null ? ln : sn) static { OID_TO_SYM.put( OBJ_undef, SN_undef ); OID_TO_SYM.put( OBJ_itu_t, SN_itu_t ); OID_TO_SYM.put( OBJ_iso, SN_iso ); OID_TO_SYM.put( OBJ_joint_iso_itu_t, SN_joint_iso_itu_t ); OID_TO_SYM.put( OBJ_member_body, SN_member_body ); OID_TO_SYM.put( OBJ_hmac_md5, SN_hmac_md5 ); OID_TO_SYM.put( OBJ_hmac_sha1, SN_hmac_sha1 ); OID_TO_SYM.put( OBJ_international_organizations, SN_international_organizations ); OID_TO_SYM.put( OBJ_selected_attribute_types, SN_selected_attribute_types ); OID_TO_SYM.put( OBJ_ISO_US, SN_ISO_US ); OID_TO_SYM.put( OBJ_X9_57, SN_X9_57 ); OID_TO_SYM.put( OBJ_X9cm, SN_X9cm ); OID_TO_SYM.put( OBJ_dsa, SN_dsa ); OID_TO_SYM.put( OBJ_dsaWithSHA1, SN_dsaWithSHA1 ); OID_TO_SYM.put( OBJ_ansi_X9_62, SN_ansi_X9_62 ); OID_TO_SYM.put( OBJ_cast5_cbc, SN_cast5_cbc ); OID_TO_SYM.put( OBJ_pbeWithMD5AndCast5_CBC, LN_pbeWithMD5AndCast5_CBC ); OID_TO_SYM.put( OBJ_id_PasswordBasedMAC, SN_id_PasswordBasedMAC ); OID_TO_SYM.put( OBJ_id_DHBasedMac, SN_id_DHBasedMac ); OID_TO_SYM.put( OBJ_rsadsi, SN_rsadsi ); OID_TO_SYM.put( OBJ_pkcs, SN_pkcs ); OID_TO_SYM.put( OBJ_rsaEncryption, LN_rsaEncryption ); OID_TO_SYM.put( OBJ_md2WithRSAEncryption, SN_md2WithRSAEncryption ); OID_TO_SYM.put( OBJ_md4WithRSAEncryption, SN_md4WithRSAEncryption ); OID_TO_SYM.put( OBJ_md5WithRSAEncryption, SN_md5WithRSAEncryption ); OID_TO_SYM.put( OBJ_sha1WithRSAEncryption, SN_sha1WithRSAEncryption ); OID_TO_SYM.put( OBJ_rsaesOaep, SN_rsaesOaep ); OID_TO_SYM.put( OBJ_mgf1, SN_mgf1 ); OID_TO_SYM.put( OBJ_pSpecified, SN_pSpecified ); OID_TO_SYM.put( OBJ_rsassaPss, SN_rsassaPss ); OID_TO_SYM.put( OBJ_sha256WithRSAEncryption, SN_sha256WithRSAEncryption ); OID_TO_SYM.put( OBJ_sha384WithRSAEncryption, SN_sha384WithRSAEncryption ); OID_TO_SYM.put( OBJ_sha512WithRSAEncryption, SN_sha512WithRSAEncryption ); OID_TO_SYM.put( OBJ_sha224WithRSAEncryption, SN_sha224WithRSAEncryption ); OID_TO_SYM.put( OBJ_dhKeyAgreement, LN_dhKeyAgreement ); OID_TO_SYM.put( OBJ_pbeWithMD2AndDES_CBC, SN_pbeWithMD2AndDES_CBC ); OID_TO_SYM.put( OBJ_pbeWithMD5AndDES_CBC, SN_pbeWithMD5AndDES_CBC ); OID_TO_SYM.put( OBJ_pbeWithMD2AndRC2_CBC, SN_pbeWithMD2AndRC2_CBC ); OID_TO_SYM.put( OBJ_pbeWithMD5AndRC2_CBC, SN_pbeWithMD5AndRC2_CBC ); OID_TO_SYM.put( OBJ_pbeWithSHA1AndDES_CBC, SN_pbeWithSHA1AndDES_CBC ); OID_TO_SYM.put( OBJ_pbeWithSHA1AndRC2_CBC, SN_pbeWithSHA1AndRC2_CBC ); OID_TO_SYM.put( OBJ_id_pbkdf2, LN_id_pbkdf2 ); OID_TO_SYM.put( OBJ_pbes2, LN_pbes2 ); OID_TO_SYM.put( OBJ_pbmac1, LN_pbmac1 ); OID_TO_SYM.put( OBJ_pkcs7_data, LN_pkcs7_data ); OID_TO_SYM.put( OBJ_pkcs7_signed, LN_pkcs7_signed ); OID_TO_SYM.put( OBJ_pkcs7_enveloped, LN_pkcs7_enveloped ); OID_TO_SYM.put( OBJ_pkcs7_signedAndEnveloped, LN_pkcs7_signedAndEnveloped ); OID_TO_SYM.put( OBJ_pkcs7_digest, LN_pkcs7_digest ); OID_TO_SYM.put( OBJ_pkcs7_encrypted, LN_pkcs7_encrypted ); OID_TO_SYM.put( OBJ_pkcs9_emailAddress, LN_pkcs9_emailAddress ); OID_TO_SYM.put( OBJ_pkcs9_unstructuredName, LN_pkcs9_unstructuredName ); OID_TO_SYM.put( OBJ_pkcs9_contentType, LN_pkcs9_contentType ); OID_TO_SYM.put( OBJ_pkcs9_messageDigest, LN_pkcs9_messageDigest ); OID_TO_SYM.put( OBJ_pkcs9_signingTime, LN_pkcs9_signingTime ); OID_TO_SYM.put( OBJ_pkcs9_countersignature, LN_pkcs9_countersignature ); OID_TO_SYM.put( OBJ_pkcs9_challengePassword, LN_pkcs9_challengePassword ); OID_TO_SYM.put( OBJ_pkcs9_unstructuredAddress, LN_pkcs9_unstructuredAddress ); OID_TO_SYM.put( OBJ_pkcs9_extCertAttributes, LN_pkcs9_extCertAttributes ); OID_TO_SYM.put( OBJ_ext_req, SN_ext_req ); OID_TO_SYM.put( OBJ_SMIMECapabilities, SN_SMIMECapabilities ); OID_TO_SYM.put( OBJ_SMIME, SN_SMIME ); OID_TO_SYM.put( OBJ_friendlyName, LN_friendlyName ); OID_TO_SYM.put( OBJ_localKeyID, LN_localKeyID ); OID_TO_SYM.put( OBJ_ms_csp_name, SN_ms_csp_name ); OID_TO_SYM.put( OBJ_LocalKeySet, SN_LocalKeySet ); OID_TO_SYM.put( OBJ_x509Certificate, LN_x509Certificate ); OID_TO_SYM.put( OBJ_sdsiCertificate, LN_sdsiCertificate ); OID_TO_SYM.put( OBJ_x509Crl, LN_x509Crl ); OID_TO_SYM.put( OBJ_pbe_WithSHA1And128BitRC4, SN_pbe_WithSHA1And128BitRC4 ); OID_TO_SYM.put( OBJ_pbe_WithSHA1And40BitRC4, SN_pbe_WithSHA1And40BitRC4 ); OID_TO_SYM.put( OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC, SN_pbe_WithSHA1And3_Key_TripleDES_CBC ); OID_TO_SYM.put( OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC, SN_pbe_WithSHA1And2_Key_TripleDES_CBC ); OID_TO_SYM.put( OBJ_pbe_WithSHA1And128BitRC2_CBC, SN_pbe_WithSHA1And128BitRC2_CBC ); OID_TO_SYM.put( OBJ_pbe_WithSHA1And40BitRC2_CBC, SN_pbe_WithSHA1And40BitRC2_CBC ); OID_TO_SYM.put( OBJ_keyBag, LN_keyBag ); OID_TO_SYM.put( OBJ_pkcs8ShroudedKeyBag, LN_pkcs8ShroudedKeyBag ); OID_TO_SYM.put( OBJ_certBag, LN_certBag ); OID_TO_SYM.put( OBJ_crlBag, LN_crlBag ); OID_TO_SYM.put( OBJ_secretBag, LN_secretBag ); OID_TO_SYM.put( OBJ_safeContentsBag, LN_safeContentsBag ); OID_TO_SYM.put( OBJ_md2, SN_md2 ); OID_TO_SYM.put( OBJ_md4, SN_md4 ); OID_TO_SYM.put( OBJ_md5, SN_md5 ); OID_TO_SYM.put( OBJ_hmacWithMD5, LN_hmacWithMD5 ); OID_TO_SYM.put( OBJ_hmacWithSHA1, LN_hmacWithSHA1 ); OID_TO_SYM.put( OBJ_hmacWithSHA224, LN_hmacWithSHA224 ); OID_TO_SYM.put( OBJ_hmacWithSHA256, LN_hmacWithSHA256 ); OID_TO_SYM.put( OBJ_hmacWithSHA384, LN_hmacWithSHA384 ); OID_TO_SYM.put( OBJ_hmacWithSHA512, LN_hmacWithSHA512 ); OID_TO_SYM.put( OBJ_rc2_cbc, SN_rc2_cbc ); OID_TO_SYM.put( OBJ_rc4, SN_rc4 ); OID_TO_SYM.put( OBJ_des_ede3_cbc, SN_des_ede3_cbc ); OID_TO_SYM.put( OBJ_rc5_cbc, SN_rc5_cbc ); OID_TO_SYM.put( OBJ_ms_ext_req, SN_ms_ext_req ); OID_TO_SYM.put( OBJ_ms_code_ind, SN_ms_code_ind ); OID_TO_SYM.put( OBJ_ms_code_com, SN_ms_code_com ); OID_TO_SYM.put( OBJ_ms_ctl_sign, SN_ms_ctl_sign ); OID_TO_SYM.put( OBJ_ms_sgc, SN_ms_sgc ); OID_TO_SYM.put( OBJ_ms_efs, SN_ms_efs ); OID_TO_SYM.put( OBJ_ms_smartcard_login, SN_ms_smartcard_login ); OID_TO_SYM.put( OBJ_ms_upn, SN_ms_upn ); OID_TO_SYM.put( OBJ_idea_cbc, SN_idea_cbc ); OID_TO_SYM.put( OBJ_bf_cbc, SN_bf_cbc ); OID_TO_SYM.put( OBJ_info_access, SN_info_access ); OID_TO_SYM.put( OBJ_biometricInfo, SN_biometricInfo ); OID_TO_SYM.put( OBJ_sinfo_access, SN_sinfo_access ); OID_TO_SYM.put( OBJ_proxyCertInfo, SN_proxyCertInfo ); OID_TO_SYM.put( OBJ_id_qt_cps, SN_id_qt_cps ); OID_TO_SYM.put( OBJ_id_qt_unotice, SN_id_qt_unotice ); OID_TO_SYM.put( OBJ_server_auth, SN_server_auth ); OID_TO_SYM.put( OBJ_client_auth, SN_client_auth ); OID_TO_SYM.put( OBJ_code_sign, SN_code_sign ); OID_TO_SYM.put( OBJ_email_protect, SN_email_protect ); OID_TO_SYM.put( OBJ_ipsecEndSystem, SN_ipsecEndSystem ); OID_TO_SYM.put( OBJ_ipsecTunnel, SN_ipsecTunnel ); OID_TO_SYM.put( OBJ_ipsecUser, SN_ipsecUser ); OID_TO_SYM.put( OBJ_time_stamp, SN_time_stamp ); OID_TO_SYM.put( OBJ_OCSP_sign, SN_OCSP_sign ); OID_TO_SYM.put( OBJ_dvcs, SN_dvcs ); OID_TO_SYM.put( OBJ_id_on_permanentIdentifier, SN_id_on_permanentIdentifier ); OID_TO_SYM.put( OBJ_id_ppl_anyLanguage, SN_id_ppl_anyLanguage ); OID_TO_SYM.put( OBJ_id_ppl_inheritAll, SN_id_ppl_inheritAll ); OID_TO_SYM.put( OBJ_Independent, SN_Independent ); OID_TO_SYM.put( OBJ_ad_OCSP, SN_ad_OCSP ); OID_TO_SYM.put( OBJ_ad_ca_issuers, SN_ad_ca_issuers ); OID_TO_SYM.put( OBJ_ad_timeStamping, SN_ad_timeStamping ); OID_TO_SYM.put( OBJ_ad_dvcs, SN_ad_dvcs ); OID_TO_SYM.put( OBJ_caRepository, SN_caRepository ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_basic, SN_id_pkix_OCSP_basic ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_Nonce, SN_id_pkix_OCSP_Nonce ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_CrlID, SN_id_pkix_OCSP_CrlID ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_acceptableResponses, SN_id_pkix_OCSP_acceptableResponses ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_noCheck, SN_id_pkix_OCSP_noCheck ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_archiveCutoff, SN_id_pkix_OCSP_archiveCutoff ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_serviceLocator, SN_id_pkix_OCSP_serviceLocator ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_extendedStatus, SN_id_pkix_OCSP_extendedStatus ); OID_TO_SYM.put( OBJ_id_pkix_OCSP_trustRoot, SN_id_pkix_OCSP_trustRoot ); OID_TO_SYM.put( OBJ_algorithm, SN_algorithm ); OID_TO_SYM.put( OBJ_md5WithRSA, SN_md5WithRSA ); OID_TO_SYM.put( OBJ_des_ecb, SN_des_ecb ); OID_TO_SYM.put( OBJ_des_cbc, SN_des_cbc ); OID_TO_SYM.put( OBJ_des_ofb64, SN_des_ofb64 ); OID_TO_SYM.put( OBJ_des_cfb64, SN_des_cfb64 ); OID_TO_SYM.put( OBJ_dsa_2, SN_dsa_2 ); OID_TO_SYM.put( OBJ_dsaWithSHA, SN_dsaWithSHA ); OID_TO_SYM.put( OBJ_shaWithRSAEncryption, SN_shaWithRSAEncryption ); OID_TO_SYM.put( OBJ_des_ede_ecb, SN_des_ede_ecb ); OID_TO_SYM.put( OBJ_sha, SN_sha ); OID_TO_SYM.put( OBJ_sha1, SN_sha1 ); OID_TO_SYM.put( OBJ_dsaWithSHA1_2, SN_dsaWithSHA1_2 ); OID_TO_SYM.put( OBJ_sha1WithRSA, SN_sha1WithRSA ); OID_TO_SYM.put( OBJ_ripemd160, SN_ripemd160 ); OID_TO_SYM.put( OBJ_ripemd160WithRSA, SN_ripemd160WithRSA ); OID_TO_SYM.put( OBJ_sxnet, SN_sxnet ); OID_TO_SYM.put( OBJ_X500, SN_X500 ); OID_TO_SYM.put( OBJ_commonName, SN_commonName ); OID_TO_SYM.put( OBJ_surname, SN_surname ); OID_TO_SYM.put( OBJ_serialNumber, LN_serialNumber ); OID_TO_SYM.put( OBJ_countryName, SN_countryName ); OID_TO_SYM.put( OBJ_localityName, SN_localityName ); OID_TO_SYM.put( OBJ_stateOrProvinceName, SN_stateOrProvinceName ); OID_TO_SYM.put( OBJ_streetAddress, SN_streetAddress ); OID_TO_SYM.put( OBJ_organizationName, SN_organizationName ); OID_TO_SYM.put( OBJ_organizationalUnitName, SN_organizationalUnitName ); OID_TO_SYM.put( OBJ_title, SN_title ); OID_TO_SYM.put( OBJ_description, LN_description ); OID_TO_SYM.put( OBJ_searchGuide, LN_searchGuide ); OID_TO_SYM.put( OBJ_businessCategory, LN_businessCategory ); OID_TO_SYM.put( OBJ_postalAddress, LN_postalAddress ); OID_TO_SYM.put( OBJ_postalCode, LN_postalCode ); OID_TO_SYM.put( OBJ_postOfficeBox, LN_postOfficeBox ); OID_TO_SYM.put( OBJ_physicalDeliveryOfficeName, LN_physicalDeliveryOfficeName ); OID_TO_SYM.put( OBJ_telephoneNumber, LN_telephoneNumber ); OID_TO_SYM.put( OBJ_telexNumber, LN_telexNumber ); OID_TO_SYM.put( OBJ_teletexTerminalIdentifier, LN_teletexTerminalIdentifier ); OID_TO_SYM.put( OBJ_facsimileTelephoneNumber, LN_facsimileTelephoneNumber ); OID_TO_SYM.put( OBJ_x121Address, LN_x121Address ); OID_TO_SYM.put( OBJ_internationaliSDNNumber, LN_internationaliSDNNumber ); OID_TO_SYM.put( OBJ_registeredAddress, LN_registeredAddress ); OID_TO_SYM.put( OBJ_destinationIndicator, LN_destinationIndicator ); OID_TO_SYM.put( OBJ_preferredDeliveryMethod, LN_preferredDeliveryMethod ); OID_TO_SYM.put( OBJ_presentationAddress, LN_presentationAddress ); OID_TO_SYM.put( OBJ_supportedApplicationContext, LN_supportedApplicationContext ); OID_TO_SYM.put( OBJ_roleOccupant, LN_roleOccupant ); OID_TO_SYM.put( OBJ_userPassword, LN_userPassword ); OID_TO_SYM.put( OBJ_userCertificate, LN_userCertificate ); OID_TO_SYM.put( OBJ_cACertificate, LN_cACertificate ); OID_TO_SYM.put( OBJ_authorityRevocationList, LN_authorityRevocationList ); OID_TO_SYM.put( OBJ_certificateRevocationList, LN_certificateRevocationList ); OID_TO_SYM.put( OBJ_crossCertificatePair, LN_crossCertificatePair ); OID_TO_SYM.put( OBJ_name, SN_name ); OID_TO_SYM.put( OBJ_givenName, SN_givenName ); OID_TO_SYM.put( OBJ_initials, SN_initials ); OID_TO_SYM.put( OBJ_generationQualifier, LN_generationQualifier ); OID_TO_SYM.put( OBJ_x500UniqueIdentifier, LN_x500UniqueIdentifier ); OID_TO_SYM.put( OBJ_dnQualifier, SN_dnQualifier ); OID_TO_SYM.put( OBJ_enhancedSearchGuide, LN_enhancedSearchGuide ); OID_TO_SYM.put( OBJ_protocolInformation, LN_protocolInformation ); OID_TO_SYM.put( OBJ_distinguishedName, LN_distinguishedName ); OID_TO_SYM.put( OBJ_uniqueMember, LN_uniqueMember ); OID_TO_SYM.put( OBJ_houseIdentifier, LN_houseIdentifier ); OID_TO_SYM.put( OBJ_supportedAlgorithms, LN_supportedAlgorithms ); OID_TO_SYM.put( OBJ_deltaRevocationList, LN_deltaRevocationList ); OID_TO_SYM.put( OBJ_pseudonym, LN_pseudonym ); OID_TO_SYM.put( OBJ_role, SN_role ); OID_TO_SYM.put( OBJ_X500algorithms, SN_X500algorithms ); OID_TO_SYM.put( OBJ_rsa, SN_rsa ); OID_TO_SYM.put( OBJ_mdc2WithRSA, SN_mdc2WithRSA ); OID_TO_SYM.put( OBJ_mdc2, SN_mdc2 ); OID_TO_SYM.put( OBJ_subject_directory_attributes, SN_subject_directory_attributes ); OID_TO_SYM.put( OBJ_subject_key_identifier, SN_subject_key_identifier ); OID_TO_SYM.put( OBJ_key_usage, SN_key_usage ); OID_TO_SYM.put( OBJ_private_key_usage_period, SN_private_key_usage_period ); OID_TO_SYM.put( OBJ_subject_alt_name, SN_subject_alt_name ); OID_TO_SYM.put( OBJ_issuer_alt_name, SN_issuer_alt_name ); OID_TO_SYM.put( OBJ_basic_constraints, SN_basic_constraints ); OID_TO_SYM.put( OBJ_crl_number, SN_crl_number ); OID_TO_SYM.put( OBJ_crl_reason, SN_crl_reason ); OID_TO_SYM.put( OBJ_invalidity_date, SN_invalidity_date ); OID_TO_SYM.put( OBJ_delta_crl, SN_delta_crl ); OID_TO_SYM.put( OBJ_issuing_distribution_point, SN_issuing_distribution_point ); OID_TO_SYM.put( OBJ_certificate_issuer, SN_certificate_issuer ); OID_TO_SYM.put( OBJ_name_constraints, SN_name_constraints ); OID_TO_SYM.put( OBJ_crl_distribution_points, SN_crl_distribution_points ); OID_TO_SYM.put( OBJ_certificate_policies, SN_certificate_policies ); OID_TO_SYM.put( OBJ_any_policy, SN_any_policy ); OID_TO_SYM.put( OBJ_policy_mappings, SN_policy_mappings ); OID_TO_SYM.put( OBJ_authority_key_identifier, SN_authority_key_identifier ); OID_TO_SYM.put( OBJ_policy_constraints, SN_policy_constraints ); OID_TO_SYM.put( OBJ_ext_key_usage, SN_ext_key_usage ); OID_TO_SYM.put( OBJ_freshest_crl, SN_freshest_crl ); OID_TO_SYM.put( OBJ_inhibit_any_policy, SN_inhibit_any_policy ); OID_TO_SYM.put( OBJ_target_information, SN_target_information ); OID_TO_SYM.put( OBJ_no_rev_avail, SN_no_rev_avail ); OID_TO_SYM.put( OBJ_anyExtendedKeyUsage, SN_anyExtendedKeyUsage ); OID_TO_SYM.put( OBJ_netscape, SN_netscape ); OID_TO_SYM.put( OBJ_netscape_cert_extension, SN_netscape_cert_extension ); OID_TO_SYM.put( OBJ_netscape_data_type, SN_netscape_data_type ); OID_TO_SYM.put( OBJ_netscape_cert_type, SN_netscape_cert_type ); OID_TO_SYM.put( OBJ_netscape_base_url, SN_netscape_base_url ); OID_TO_SYM.put( OBJ_netscape_revocation_url, SN_netscape_revocation_url ); OID_TO_SYM.put( OBJ_netscape_ca_revocation_url, SN_netscape_ca_revocation_url ); OID_TO_SYM.put( OBJ_netscape_renewal_url, SN_netscape_renewal_url ); OID_TO_SYM.put( OBJ_netscape_ca_policy_url, SN_netscape_ca_policy_url ); OID_TO_SYM.put( OBJ_netscape_ssl_server_name, SN_netscape_ssl_server_name ); OID_TO_SYM.put( OBJ_netscape_comment, SN_netscape_comment ); OID_TO_SYM.put( OBJ_netscape_cert_sequence, SN_netscape_cert_sequence ); OID_TO_SYM.put( OBJ_ns_sgc, SN_ns_sgc ); OID_TO_SYM.put( OBJ_org, SN_org ); OID_TO_SYM.put( OBJ_dod, SN_dod ); OID_TO_SYM.put( OBJ_iana, SN_iana ); OID_TO_SYM.put( OBJ_Directory, SN_Directory ); OID_TO_SYM.put( OBJ_Management, SN_Management ); OID_TO_SYM.put( OBJ_Experimental, SN_Experimental ); OID_TO_SYM.put( OBJ_Private, SN_Private ); OID_TO_SYM.put( OBJ_Security, SN_Security ); OID_TO_SYM.put( OBJ_SNMPv2, SN_SNMPv2 ); OID_TO_SYM.put( OBJ_Mail, LN_Mail ); OID_TO_SYM.put( OBJ_Enterprises, SN_Enterprises ); OID_TO_SYM.put( OBJ_dcObject, SN_dcObject ); OID_TO_SYM.put( OBJ_mime_mhs, SN_mime_mhs ); OID_TO_SYM.put( OBJ_mime_mhs_headings, SN_mime_mhs_headings ); OID_TO_SYM.put( OBJ_mime_mhs_bodies, SN_mime_mhs_bodies ); OID_TO_SYM.put( OBJ_id_hex_partial_message, SN_id_hex_partial_message ); OID_TO_SYM.put( OBJ_id_hex_multipart_message, SN_id_hex_multipart_message ); OID_TO_SYM.put( OBJ_rle_compression, SN_rle_compression ); OID_TO_SYM.put( OBJ_zlib_compression, SN_zlib_compression ); OID_TO_SYM.put( OBJ_aes_128_ecb, SN_aes_128_ecb ); OID_TO_SYM.put( OBJ_aes_128_cbc, SN_aes_128_cbc ); OID_TO_SYM.put( OBJ_aes_128_ofb128, SN_aes_128_ofb128 ); OID_TO_SYM.put( OBJ_aes_128_cfb128, SN_aes_128_cfb128 ); OID_TO_SYM.put( OBJ_aes_128_gcm, SN_aes_128_gcm ); OID_TO_SYM.put( OBJ_aes_128_ccm, SN_aes_128_ccm ); OID_TO_SYM.put( OBJ_aes_192_ecb, SN_aes_192_ecb ); OID_TO_SYM.put( OBJ_aes_192_cbc, SN_aes_192_cbc ); OID_TO_SYM.put( OBJ_aes_192_ofb128, SN_aes_192_ofb128 ); OID_TO_SYM.put( OBJ_aes_192_cfb128, SN_aes_192_cfb128 ); OID_TO_SYM.put( OBJ_aes_192_gcm, SN_aes_192_gcm ); OID_TO_SYM.put( OBJ_aes_192_ccm, SN_aes_192_ccm ); OID_TO_SYM.put( OBJ_aes_256_ecb, SN_aes_256_ecb ); OID_TO_SYM.put( OBJ_aes_256_cbc, SN_aes_256_cbc ); OID_TO_SYM.put( OBJ_aes_256_ofb128, SN_aes_256_ofb128 ); OID_TO_SYM.put( OBJ_aes_256_cfb128, SN_aes_256_cfb128 ); OID_TO_SYM.put( OBJ_aes_256_gcm, SN_aes_256_gcm ); OID_TO_SYM.put( OBJ_aes_256_ccm, SN_aes_256_ccm ); OID_TO_SYM.put( OBJ_sha256, SN_sha256 ); OID_TO_SYM.put( OBJ_sha384, SN_sha384 ); OID_TO_SYM.put( OBJ_sha512, SN_sha512 ); OID_TO_SYM.put( OBJ_sha224, SN_sha224 ); OID_TO_SYM.put( OBJ_hold_instruction_code, SN_hold_instruction_code ); OID_TO_SYM.put( OBJ_hold_instruction_none, SN_hold_instruction_none ); OID_TO_SYM.put( OBJ_hold_instruction_call_issuer, SN_hold_instruction_call_issuer ); OID_TO_SYM.put( OBJ_hold_instruction_reject, SN_hold_instruction_reject ); OID_TO_SYM.put( OBJ_pilotAttributeType, LN_pilotAttributeType ); OID_TO_SYM.put( OBJ_pilotAttributeSyntax, LN_pilotAttributeSyntax ); OID_TO_SYM.put( OBJ_pilotObjectClass, LN_pilotObjectClass ); OID_TO_SYM.put( OBJ_pilotGroups, LN_pilotGroups ); OID_TO_SYM.put( OBJ_iA5StringSyntax, LN_iA5StringSyntax ); OID_TO_SYM.put( OBJ_caseIgnoreIA5StringSyntax, LN_caseIgnoreIA5StringSyntax ); OID_TO_SYM.put( OBJ_pilotObject, LN_pilotObject ); OID_TO_SYM.put( OBJ_pilotPerson, LN_pilotPerson ); OID_TO_SYM.put( OBJ_documentSeries, LN_documentSeries ); OID_TO_SYM.put( OBJ_Domain, SN_Domain ); OID_TO_SYM.put( OBJ_rFC822localPart, LN_rFC822localPart ); OID_TO_SYM.put( OBJ_dNSDomain, LN_dNSDomain ); OID_TO_SYM.put( OBJ_domainRelatedObject, LN_domainRelatedObject ); OID_TO_SYM.put( OBJ_friendlyCountry, LN_friendlyCountry ); OID_TO_SYM.put( OBJ_simpleSecurityObject, LN_simpleSecurityObject ); OID_TO_SYM.put( OBJ_pilotOrganization, LN_pilotOrganization ); OID_TO_SYM.put( OBJ_pilotDSA, LN_pilotDSA ); OID_TO_SYM.put( OBJ_qualityLabelledData, LN_qualityLabelledData ); OID_TO_SYM.put( OBJ_userId, SN_userId ); OID_TO_SYM.put( OBJ_textEncodedORAddress, LN_textEncodedORAddress ); OID_TO_SYM.put( OBJ_rfc822Mailbox, SN_rfc822Mailbox ); OID_TO_SYM.put( OBJ_favouriteDrink, LN_favouriteDrink ); OID_TO_SYM.put( OBJ_roomNumber, LN_roomNumber ); OID_TO_SYM.put( OBJ_userClass, LN_userClass ); OID_TO_SYM.put( OBJ_documentIdentifier, LN_documentIdentifier ); OID_TO_SYM.put( OBJ_documentTitle, LN_documentTitle ); OID_TO_SYM.put( OBJ_documentVersion, LN_documentVersion ); OID_TO_SYM.put( OBJ_documentAuthor, LN_documentAuthor ); OID_TO_SYM.put( OBJ_documentLocation, LN_documentLocation ); OID_TO_SYM.put( OBJ_homeTelephoneNumber, LN_homeTelephoneNumber ); OID_TO_SYM.put( OBJ_otherMailbox, LN_otherMailbox ); OID_TO_SYM.put( OBJ_lastModifiedTime, LN_lastModifiedTime ); OID_TO_SYM.put( OBJ_lastModifiedBy, LN_lastModifiedBy ); OID_TO_SYM.put( OBJ_domainComponent, SN_domainComponent ); OID_TO_SYM.put( OBJ_aRecord, LN_aRecord ); OID_TO_SYM.put( OBJ_pilotAttributeType27, LN_pilotAttributeType27 ); OID_TO_SYM.put( OBJ_mXRecord, LN_mXRecord ); OID_TO_SYM.put( OBJ_nSRecord, LN_nSRecord ); OID_TO_SYM.put( OBJ_sOARecord, LN_sOARecord ); OID_TO_SYM.put( OBJ_cNAMERecord, LN_cNAMERecord ); OID_TO_SYM.put( OBJ_associatedDomain, LN_associatedDomain ); OID_TO_SYM.put( OBJ_associatedName, LN_associatedName ); OID_TO_SYM.put( OBJ_homePostalAddress, LN_homePostalAddress ); OID_TO_SYM.put( OBJ_personalTitle, LN_personalTitle ); OID_TO_SYM.put( OBJ_mobileTelephoneNumber, LN_mobileTelephoneNumber ); OID_TO_SYM.put( OBJ_pagerTelephoneNumber, LN_pagerTelephoneNumber ); OID_TO_SYM.put( OBJ_friendlyCountryName, LN_friendlyCountryName ); OID_TO_SYM.put( OBJ_organizationalStatus, LN_organizationalStatus ); OID_TO_SYM.put( OBJ_janetMailbox, LN_janetMailbox ); OID_TO_SYM.put( OBJ_mailPreferenceOption, LN_mailPreferenceOption ); OID_TO_SYM.put( OBJ_buildingName, LN_buildingName ); OID_TO_SYM.put( OBJ_dSAQuality, LN_dSAQuality ); OID_TO_SYM.put( OBJ_singleLevelQuality, LN_singleLevelQuality ); OID_TO_SYM.put( OBJ_subtreeMinimumQuality, LN_subtreeMinimumQuality ); OID_TO_SYM.put( OBJ_subtreeMaximumQuality, LN_subtreeMaximumQuality ); OID_TO_SYM.put( OBJ_personalSignature, LN_personalSignature ); OID_TO_SYM.put( OBJ_dITRedirect, LN_dITRedirect ); OID_TO_SYM.put( OBJ_documentPublisher, LN_documentPublisher ); OID_TO_SYM.put( OBJ_id_set, SN_id_set ); OID_TO_SYM.put( OBJ_set_ctype, SN_set_ctype ); OID_TO_SYM.put( OBJ_set_msgExt, SN_set_msgExt ); OID_TO_SYM.put( OBJ_set_certExt, SN_set_certExt ); OID_TO_SYM.put( OBJ_setext_genCrypt, SN_setext_genCrypt ); OID_TO_SYM.put( OBJ_setext_miAuth, SN_setext_miAuth ); OID_TO_SYM.put( OBJ_setext_cv, SN_setext_cv ); OID_TO_SYM.put( OBJ_setAttr_PGWYcap, SN_setAttr_PGWYcap ); OID_TO_SYM.put( OBJ_setAttr_IssCap, SN_setAttr_IssCap ); OID_TO_SYM.put( OBJ_setAttr_GenCryptgrm, SN_setAttr_GenCryptgrm ); OID_TO_SYM.put( OBJ_setAttr_T2Enc, SN_setAttr_T2Enc ); OID_TO_SYM.put( OBJ_setAttr_T2cleartxt, SN_setAttr_T2cleartxt ); OID_TO_SYM.put( OBJ_setAttr_TokICCsig, SN_setAttr_TokICCsig ); OID_TO_SYM.put( OBJ_setAttr_SecDevSig, SN_setAttr_SecDevSig ); OID_TO_SYM.put( OBJ_des_cdmf, SN_des_cdmf ); OID_TO_SYM.put( OBJ_id_GostR3411_94_with_GostR3410_2001, SN_id_GostR3411_94_with_GostR3410_2001 ); OID_TO_SYM.put( OBJ_id_GostR3411_94_with_GostR3410_94, SN_id_GostR3411_94_with_GostR3410_94 ); OID_TO_SYM.put( OBJ_id_GostR3411_94, SN_id_GostR3411_94 ); OID_TO_SYM.put( OBJ_id_HMACGostR3411_94, SN_id_HMACGostR3411_94 ); OID_TO_SYM.put( OBJ_id_GostR3410_2001, SN_id_GostR3410_2001 ); OID_TO_SYM.put( OBJ_id_GostR3410_94, SN_id_GostR3410_94 ); OID_TO_SYM.put( OBJ_id_Gost28147_89, SN_id_Gost28147_89 ); OID_TO_SYM.put( OBJ_id_Gost28147_89_MAC, SN_id_Gost28147_89_MAC ); OID_TO_SYM.put( OBJ_id_GostR3411_94_prf, SN_id_GostR3411_94_prf ); OID_TO_SYM.put( OBJ_id_GostR3410_2001DH, SN_id_GostR3410_2001DH ); OID_TO_SYM.put( OBJ_id_GostR3410_94DH, SN_id_GostR3410_94DH ); OID_TO_SYM.put( OBJ_id_Gost28147_89_cc, SN_id_Gost28147_89_cc ); OID_TO_SYM.put( OBJ_id_GostR3410_94_cc, SN_id_GostR3410_94_cc ); OID_TO_SYM.put( OBJ_id_GostR3410_2001_cc, SN_id_GostR3410_2001_cc ); OID_TO_SYM.put( OBJ_id_GostR3411_94_with_GostR3410_94_cc, SN_id_GostR3411_94_with_GostR3410_94_cc ); OID_TO_SYM.put( OBJ_id_GostR3411_94_with_GostR3410_2001_cc, SN_id_GostR3411_94_with_GostR3410_2001_cc ); OID_TO_SYM.put( OBJ_id_GostR3410_2001_ParamSet_cc, SN_id_GostR3410_2001_ParamSet_cc ); OID_TO_SYM.put( OBJ_camellia_128_cbc, SN_camellia_128_cbc ); OID_TO_SYM.put( OBJ_camellia_192_cbc, SN_camellia_192_cbc ); OID_TO_SYM.put( OBJ_camellia_256_cbc, SN_camellia_256_cbc ); OID_TO_SYM.put( OBJ_camellia_128_ecb, SN_camellia_128_ecb ); OID_TO_SYM.put( OBJ_camellia_128_ofb128, SN_camellia_128_ofb128 ); OID_TO_SYM.put( OBJ_camellia_128_cfb128, SN_camellia_128_cfb128 ); OID_TO_SYM.put( OBJ_camellia_192_ecb, SN_camellia_192_ecb ); OID_TO_SYM.put( OBJ_camellia_192_ofb128, SN_camellia_192_ofb128 ); OID_TO_SYM.put( OBJ_camellia_192_cfb128, SN_camellia_192_cfb128 ); OID_TO_SYM.put( OBJ_camellia_256_ecb, SN_camellia_256_ecb ); OID_TO_SYM.put( OBJ_camellia_256_ofb128, SN_camellia_256_ofb128 ); OID_TO_SYM.put( OBJ_camellia_256_cfb128, SN_camellia_256_cfb128 ); OID_TO_SYM.put( OBJ_kisa, SN_kisa ); OID_TO_SYM.put( OBJ_seed_ecb, SN_seed_ecb ); OID_TO_SYM.put( OBJ_seed_cbc, SN_seed_cbc ); OID_TO_SYM.put( OBJ_seed_cfb128, SN_seed_cfb128 ); OID_TO_SYM.put( OBJ_seed_ofb128, SN_seed_ofb128 ); OID_TO_SYM.put( OBJ_dhpublicnumber, SN_dhpublicnumber ); OID_TO_SYM.put( OBJ_ct_precert_scts, SN_ct_precert_scts ); OID_TO_SYM.put( OBJ_ct_precert_poison, SN_ct_precert_poison ); OID_TO_SYM.put( OBJ_ct_precert_signer, SN_ct_precert_signer ); OID_TO_SYM.put( OBJ_ct_cert_scts, SN_ct_cert_scts ); OID_TO_SYM.put( OBJ_jurisdictionLocalityName, SN_jurisdictionLocalityName ); OID_TO_SYM.put( OBJ_jurisdictionStateOrProvinceName, SN_jurisdictionStateOrProvinceName ); OID_TO_SYM.put( OBJ_jurisdictionCountryName, SN_jurisdictionCountryName ); } private static final HashMap OID_TO_NID = new HashMap(1052, 1); static { OID_TO_NID.put( OBJ_undef, Integer.valueOf( NID_undef ) ); OID_TO_NID.put( OBJ_itu_t, Integer.valueOf( NID_itu_t ) ); OID_TO_NID.put( OBJ_ccitt, Integer.valueOf( NID_ccitt ) ); OID_TO_NID.put( OBJ_iso, Integer.valueOf( NID_iso ) ); OID_TO_NID.put( OBJ_joint_iso_itu_t, Integer.valueOf( NID_joint_iso_itu_t ) ); OID_TO_NID.put( OBJ_joint_iso_ccitt, Integer.valueOf( NID_joint_iso_ccitt ) ); OID_TO_NID.put( OBJ_member_body, Integer.valueOf( NID_member_body ) ); OID_TO_NID.put( OBJ_identified_organization, Integer.valueOf( NID_identified_organization ) ); OID_TO_NID.put( OBJ_hmac_md5, Integer.valueOf( NID_hmac_md5 ) ); OID_TO_NID.put( OBJ_hmac_sha1, Integer.valueOf( NID_hmac_sha1 ) ); OID_TO_NID.put( OBJ_certicom_arc, Integer.valueOf( NID_certicom_arc ) ); OID_TO_NID.put( OBJ_international_organizations, Integer.valueOf( NID_international_organizations ) ); OID_TO_NID.put( OBJ_wap, Integer.valueOf( NID_wap ) ); OID_TO_NID.put( OBJ_wap_wsg, Integer.valueOf( NID_wap_wsg ) ); OID_TO_NID.put( OBJ_selected_attribute_types, Integer.valueOf( NID_selected_attribute_types ) ); OID_TO_NID.put( OBJ_clearance, Integer.valueOf( NID_clearance ) ); OID_TO_NID.put( OBJ_ISO_US, Integer.valueOf( NID_ISO_US ) ); OID_TO_NID.put( OBJ_X9_57, Integer.valueOf( NID_X9_57 ) ); OID_TO_NID.put( OBJ_X9cm, Integer.valueOf( NID_X9cm ) ); OID_TO_NID.put( OBJ_dsa, Integer.valueOf( NID_dsa ) ); OID_TO_NID.put( OBJ_dsaWithSHA1, Integer.valueOf( NID_dsaWithSHA1 ) ); OID_TO_NID.put( OBJ_ansi_X9_62, Integer.valueOf( NID_ansi_X9_62 ) ); OID_TO_NID.put( OBJ_X9_62_prime_field, Integer.valueOf( NID_X9_62_prime_field ) ); OID_TO_NID.put( OBJ_X9_62_characteristic_two_field, Integer.valueOf( NID_X9_62_characteristic_two_field ) ); OID_TO_NID.put( OBJ_X9_62_id_characteristic_two_basis, Integer.valueOf( NID_X9_62_id_characteristic_two_basis ) ); OID_TO_NID.put( OBJ_X9_62_onBasis, Integer.valueOf( NID_X9_62_onBasis ) ); OID_TO_NID.put( OBJ_X9_62_tpBasis, Integer.valueOf( NID_X9_62_tpBasis ) ); OID_TO_NID.put( OBJ_X9_62_ppBasis, Integer.valueOf( NID_X9_62_ppBasis ) ); OID_TO_NID.put( OBJ_X9_62_id_ecPublicKey, Integer.valueOf( NID_X9_62_id_ecPublicKey ) ); OID_TO_NID.put( OBJ_X9_62_c2pnb163v1, Integer.valueOf( NID_X9_62_c2pnb163v1 ) ); OID_TO_NID.put( OBJ_X9_62_c2pnb163v2, Integer.valueOf( NID_X9_62_c2pnb163v2 ) ); OID_TO_NID.put( OBJ_X9_62_c2pnb163v3, Integer.valueOf( NID_X9_62_c2pnb163v3 ) ); OID_TO_NID.put( OBJ_X9_62_c2pnb176v1, Integer.valueOf( NID_X9_62_c2pnb176v1 ) ); OID_TO_NID.put( OBJ_X9_62_c2tnb191v1, Integer.valueOf( NID_X9_62_c2tnb191v1 ) ); OID_TO_NID.put( OBJ_X9_62_c2tnb191v2, Integer.valueOf( NID_X9_62_c2tnb191v2 ) ); OID_TO_NID.put( OBJ_X9_62_c2tnb191v3, Integer.valueOf( NID_X9_62_c2tnb191v3 ) ); OID_TO_NID.put( OBJ_X9_62_c2onb191v4, Integer.valueOf( NID_X9_62_c2onb191v4 ) ); OID_TO_NID.put( OBJ_X9_62_c2onb191v5, Integer.valueOf( NID_X9_62_c2onb191v5 ) ); OID_TO_NID.put( OBJ_X9_62_c2pnb208w1, Integer.valueOf( NID_X9_62_c2pnb208w1 ) ); OID_TO_NID.put( OBJ_X9_62_c2tnb239v1, Integer.valueOf( NID_X9_62_c2tnb239v1 ) ); OID_TO_NID.put( OBJ_X9_62_c2tnb239v2, Integer.valueOf( NID_X9_62_c2tnb239v2 ) ); OID_TO_NID.put( OBJ_X9_62_c2tnb239v3, Integer.valueOf( NID_X9_62_c2tnb239v3 ) ); OID_TO_NID.put( OBJ_X9_62_c2onb239v4, Integer.valueOf( NID_X9_62_c2onb239v4 ) ); OID_TO_NID.put( OBJ_X9_62_c2onb239v5, Integer.valueOf( NID_X9_62_c2onb239v5 ) ); OID_TO_NID.put( OBJ_X9_62_c2pnb272w1, Integer.valueOf( NID_X9_62_c2pnb272w1 ) ); OID_TO_NID.put( OBJ_X9_62_c2pnb304w1, Integer.valueOf( NID_X9_62_c2pnb304w1 ) ); OID_TO_NID.put( OBJ_X9_62_c2tnb359v1, Integer.valueOf( NID_X9_62_c2tnb359v1 ) ); OID_TO_NID.put( OBJ_X9_62_c2pnb368w1, Integer.valueOf( NID_X9_62_c2pnb368w1 ) ); OID_TO_NID.put( OBJ_X9_62_c2tnb431r1, Integer.valueOf( NID_X9_62_c2tnb431r1 ) ); OID_TO_NID.put( OBJ_X9_62_prime192v1, Integer.valueOf( NID_X9_62_prime192v1 ) ); OID_TO_NID.put( OBJ_X9_62_prime192v2, Integer.valueOf( NID_X9_62_prime192v2 ) ); OID_TO_NID.put( OBJ_X9_62_prime192v3, Integer.valueOf( NID_X9_62_prime192v3 ) ); OID_TO_NID.put( OBJ_X9_62_prime239v1, Integer.valueOf( NID_X9_62_prime239v1 ) ); OID_TO_NID.put( OBJ_X9_62_prime239v2, Integer.valueOf( NID_X9_62_prime239v2 ) ); OID_TO_NID.put( OBJ_X9_62_prime239v3, Integer.valueOf( NID_X9_62_prime239v3 ) ); OID_TO_NID.put( OBJ_X9_62_prime256v1, Integer.valueOf( NID_X9_62_prime256v1 ) ); OID_TO_NID.put( OBJ_ecdsa_with_SHA1, Integer.valueOf( NID_ecdsa_with_SHA1 ) ); OID_TO_NID.put( OBJ_ecdsa_with_Recommended, Integer.valueOf( NID_ecdsa_with_Recommended ) ); OID_TO_NID.put( OBJ_ecdsa_with_Specified, Integer.valueOf( NID_ecdsa_with_Specified ) ); OID_TO_NID.put( OBJ_ecdsa_with_SHA224, Integer.valueOf( NID_ecdsa_with_SHA224 ) ); OID_TO_NID.put( OBJ_ecdsa_with_SHA256, Integer.valueOf( NID_ecdsa_with_SHA256 ) ); OID_TO_NID.put( OBJ_ecdsa_with_SHA384, Integer.valueOf( NID_ecdsa_with_SHA384 ) ); OID_TO_NID.put( OBJ_ecdsa_with_SHA512, Integer.valueOf( NID_ecdsa_with_SHA512 ) ); OID_TO_NID.put( OBJ_secp112r1, Integer.valueOf( NID_secp112r1 ) ); OID_TO_NID.put( OBJ_secp112r2, Integer.valueOf( NID_secp112r2 ) ); OID_TO_NID.put( OBJ_secp128r1, Integer.valueOf( NID_secp128r1 ) ); OID_TO_NID.put( OBJ_secp128r2, Integer.valueOf( NID_secp128r2 ) ); OID_TO_NID.put( OBJ_secp160k1, Integer.valueOf( NID_secp160k1 ) ); OID_TO_NID.put( OBJ_secp160r1, Integer.valueOf( NID_secp160r1 ) ); OID_TO_NID.put( OBJ_secp160r2, Integer.valueOf( NID_secp160r2 ) ); OID_TO_NID.put( OBJ_secp192k1, Integer.valueOf( NID_secp192k1 ) ); OID_TO_NID.put( OBJ_secp224k1, Integer.valueOf( NID_secp224k1 ) ); OID_TO_NID.put( OBJ_secp224r1, Integer.valueOf( NID_secp224r1 ) ); OID_TO_NID.put( OBJ_secp256k1, Integer.valueOf( NID_secp256k1 ) ); OID_TO_NID.put( OBJ_secp384r1, Integer.valueOf( NID_secp384r1 ) ); OID_TO_NID.put( OBJ_secp521r1, Integer.valueOf( NID_secp521r1 ) ); OID_TO_NID.put( OBJ_sect113r1, Integer.valueOf( NID_sect113r1 ) ); OID_TO_NID.put( OBJ_sect113r2, Integer.valueOf( NID_sect113r2 ) ); OID_TO_NID.put( OBJ_sect131r1, Integer.valueOf( NID_sect131r1 ) ); OID_TO_NID.put( OBJ_sect131r2, Integer.valueOf( NID_sect131r2 ) ); OID_TO_NID.put( OBJ_sect163k1, Integer.valueOf( NID_sect163k1 ) ); OID_TO_NID.put( OBJ_sect163r1, Integer.valueOf( NID_sect163r1 ) ); OID_TO_NID.put( OBJ_sect163r2, Integer.valueOf( NID_sect163r2 ) ); OID_TO_NID.put( OBJ_sect193r1, Integer.valueOf( NID_sect193r1 ) ); OID_TO_NID.put( OBJ_sect193r2, Integer.valueOf( NID_sect193r2 ) ); OID_TO_NID.put( OBJ_sect233k1, Integer.valueOf( NID_sect233k1 ) ); OID_TO_NID.put( OBJ_sect233r1, Integer.valueOf( NID_sect233r1 ) ); OID_TO_NID.put( OBJ_sect239k1, Integer.valueOf( NID_sect239k1 ) ); OID_TO_NID.put( OBJ_sect283k1, Integer.valueOf( NID_sect283k1 ) ); OID_TO_NID.put( OBJ_sect283r1, Integer.valueOf( NID_sect283r1 ) ); OID_TO_NID.put( OBJ_sect409k1, Integer.valueOf( NID_sect409k1 ) ); OID_TO_NID.put( OBJ_sect409r1, Integer.valueOf( NID_sect409r1 ) ); OID_TO_NID.put( OBJ_sect571k1, Integer.valueOf( NID_sect571k1 ) ); OID_TO_NID.put( OBJ_sect571r1, Integer.valueOf( NID_sect571r1 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls1, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls1 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls3, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls3 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls4, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls4 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls5, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls5 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls6, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls6 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls7, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls7 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls8, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls8 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls9, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls9 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls10, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls10 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls11, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls11 ) ); OID_TO_NID.put( OBJ_wap_wsg_idm_ecid_wtls12, Integer.valueOf( NID_wap_wsg_idm_ecid_wtls12 ) ); OID_TO_NID.put( OBJ_cast5_cbc, Integer.valueOf( NID_cast5_cbc ) ); OID_TO_NID.put( OBJ_pbeWithMD5AndCast5_CBC, Integer.valueOf( NID_pbeWithMD5AndCast5_CBC ) ); OID_TO_NID.put( OBJ_id_PasswordBasedMAC, Integer.valueOf( NID_id_PasswordBasedMAC ) ); OID_TO_NID.put( OBJ_id_DHBasedMac, Integer.valueOf( NID_id_DHBasedMac ) ); OID_TO_NID.put( OBJ_rsadsi, Integer.valueOf( NID_rsadsi ) ); OID_TO_NID.put( OBJ_pkcs, Integer.valueOf( NID_pkcs ) ); OID_TO_NID.put( OBJ_pkcs1, Integer.valueOf( NID_pkcs1 ) ); OID_TO_NID.put( OBJ_rsaEncryption, Integer.valueOf( NID_rsaEncryption ) ); OID_TO_NID.put( OBJ_md2WithRSAEncryption, Integer.valueOf( NID_md2WithRSAEncryption ) ); OID_TO_NID.put( OBJ_md4WithRSAEncryption, Integer.valueOf( NID_md4WithRSAEncryption ) ); OID_TO_NID.put( OBJ_md5WithRSAEncryption, Integer.valueOf( NID_md5WithRSAEncryption ) ); OID_TO_NID.put( OBJ_sha1WithRSAEncryption, Integer.valueOf( NID_sha1WithRSAEncryption ) ); OID_TO_NID.put( OBJ_rsaesOaep, Integer.valueOf( NID_rsaesOaep ) ); OID_TO_NID.put( OBJ_mgf1, Integer.valueOf( NID_mgf1 ) ); OID_TO_NID.put( OBJ_pSpecified, Integer.valueOf( NID_pSpecified ) ); OID_TO_NID.put( OBJ_rsassaPss, Integer.valueOf( NID_rsassaPss ) ); OID_TO_NID.put( OBJ_sha256WithRSAEncryption, Integer.valueOf( NID_sha256WithRSAEncryption ) ); OID_TO_NID.put( OBJ_sha384WithRSAEncryption, Integer.valueOf( NID_sha384WithRSAEncryption ) ); OID_TO_NID.put( OBJ_sha512WithRSAEncryption, Integer.valueOf( NID_sha512WithRSAEncryption ) ); OID_TO_NID.put( OBJ_sha224WithRSAEncryption, Integer.valueOf( NID_sha224WithRSAEncryption ) ); OID_TO_NID.put( OBJ_pkcs3, Integer.valueOf( NID_pkcs3 ) ); OID_TO_NID.put( OBJ_dhKeyAgreement, Integer.valueOf( NID_dhKeyAgreement ) ); OID_TO_NID.put( OBJ_pkcs5, Integer.valueOf( NID_pkcs5 ) ); OID_TO_NID.put( OBJ_pbeWithMD2AndDES_CBC, Integer.valueOf( NID_pbeWithMD2AndDES_CBC ) ); OID_TO_NID.put( OBJ_pbeWithMD5AndDES_CBC, Integer.valueOf( NID_pbeWithMD5AndDES_CBC ) ); OID_TO_NID.put( OBJ_pbeWithMD2AndRC2_CBC, Integer.valueOf( NID_pbeWithMD2AndRC2_CBC ) ); OID_TO_NID.put( OBJ_pbeWithMD5AndRC2_CBC, Integer.valueOf( NID_pbeWithMD5AndRC2_CBC ) ); OID_TO_NID.put( OBJ_pbeWithSHA1AndDES_CBC, Integer.valueOf( NID_pbeWithSHA1AndDES_CBC ) ); OID_TO_NID.put( OBJ_pbeWithSHA1AndRC2_CBC, Integer.valueOf( NID_pbeWithSHA1AndRC2_CBC ) ); OID_TO_NID.put( OBJ_id_pbkdf2, Integer.valueOf( NID_id_pbkdf2 ) ); OID_TO_NID.put( OBJ_pbes2, Integer.valueOf( NID_pbes2 ) ); OID_TO_NID.put( OBJ_pbmac1, Integer.valueOf( NID_pbmac1 ) ); OID_TO_NID.put( OBJ_pkcs7, Integer.valueOf( NID_pkcs7 ) ); OID_TO_NID.put( OBJ_pkcs7_data, Integer.valueOf( NID_pkcs7_data ) ); OID_TO_NID.put( OBJ_pkcs7_signed, Integer.valueOf( NID_pkcs7_signed ) ); OID_TO_NID.put( OBJ_pkcs7_enveloped, Integer.valueOf( NID_pkcs7_enveloped ) ); OID_TO_NID.put( OBJ_pkcs7_signedAndEnveloped, Integer.valueOf( NID_pkcs7_signedAndEnveloped ) ); OID_TO_NID.put( OBJ_pkcs7_digest, Integer.valueOf( NID_pkcs7_digest ) ); OID_TO_NID.put( OBJ_pkcs7_encrypted, Integer.valueOf( NID_pkcs7_encrypted ) ); OID_TO_NID.put( OBJ_pkcs9, Integer.valueOf( NID_pkcs9 ) ); OID_TO_NID.put( OBJ_pkcs9_emailAddress, Integer.valueOf( NID_pkcs9_emailAddress ) ); OID_TO_NID.put( OBJ_pkcs9_unstructuredName, Integer.valueOf( NID_pkcs9_unstructuredName ) ); OID_TO_NID.put( OBJ_pkcs9_contentType, Integer.valueOf( NID_pkcs9_contentType ) ); OID_TO_NID.put( OBJ_pkcs9_messageDigest, Integer.valueOf( NID_pkcs9_messageDigest ) ); OID_TO_NID.put( OBJ_pkcs9_signingTime, Integer.valueOf( NID_pkcs9_signingTime ) ); OID_TO_NID.put( OBJ_pkcs9_countersignature, Integer.valueOf( NID_pkcs9_countersignature ) ); OID_TO_NID.put( OBJ_pkcs9_challengePassword, Integer.valueOf( NID_pkcs9_challengePassword ) ); OID_TO_NID.put( OBJ_pkcs9_unstructuredAddress, Integer.valueOf( NID_pkcs9_unstructuredAddress ) ); OID_TO_NID.put( OBJ_pkcs9_extCertAttributes, Integer.valueOf( NID_pkcs9_extCertAttributes ) ); OID_TO_NID.put( OBJ_ext_req, Integer.valueOf( NID_ext_req ) ); OID_TO_NID.put( OBJ_SMIMECapabilities, Integer.valueOf( NID_SMIMECapabilities ) ); OID_TO_NID.put( OBJ_SMIME, Integer.valueOf( NID_SMIME ) ); OID_TO_NID.put( OBJ_id_smime_mod, Integer.valueOf( NID_id_smime_mod ) ); OID_TO_NID.put( OBJ_id_smime_ct, Integer.valueOf( NID_id_smime_ct ) ); OID_TO_NID.put( OBJ_id_smime_aa, Integer.valueOf( NID_id_smime_aa ) ); OID_TO_NID.put( OBJ_id_smime_alg, Integer.valueOf( NID_id_smime_alg ) ); OID_TO_NID.put( OBJ_id_smime_cd, Integer.valueOf( NID_id_smime_cd ) ); OID_TO_NID.put( OBJ_id_smime_spq, Integer.valueOf( NID_id_smime_spq ) ); OID_TO_NID.put( OBJ_id_smime_cti, Integer.valueOf( NID_id_smime_cti ) ); OID_TO_NID.put( OBJ_id_smime_mod_cms, Integer.valueOf( NID_id_smime_mod_cms ) ); OID_TO_NID.put( OBJ_id_smime_mod_ess, Integer.valueOf( NID_id_smime_mod_ess ) ); OID_TO_NID.put( OBJ_id_smime_mod_oid, Integer.valueOf( NID_id_smime_mod_oid ) ); OID_TO_NID.put( OBJ_id_smime_mod_msg_v3, Integer.valueOf( NID_id_smime_mod_msg_v3 ) ); OID_TO_NID.put( OBJ_id_smime_mod_ets_eSignature_88, Integer.valueOf( NID_id_smime_mod_ets_eSignature_88 ) ); OID_TO_NID.put( OBJ_id_smime_mod_ets_eSignature_97, Integer.valueOf( NID_id_smime_mod_ets_eSignature_97 ) ); OID_TO_NID.put( OBJ_id_smime_mod_ets_eSigPolicy_88, Integer.valueOf( NID_id_smime_mod_ets_eSigPolicy_88 ) ); OID_TO_NID.put( OBJ_id_smime_mod_ets_eSigPolicy_97, Integer.valueOf( NID_id_smime_mod_ets_eSigPolicy_97 ) ); OID_TO_NID.put( OBJ_id_smime_ct_receipt, Integer.valueOf( NID_id_smime_ct_receipt ) ); OID_TO_NID.put( OBJ_id_smime_ct_authData, Integer.valueOf( NID_id_smime_ct_authData ) ); OID_TO_NID.put( OBJ_id_smime_ct_publishCert, Integer.valueOf( NID_id_smime_ct_publishCert ) ); OID_TO_NID.put( OBJ_id_smime_ct_TSTInfo, Integer.valueOf( NID_id_smime_ct_TSTInfo ) ); OID_TO_NID.put( OBJ_id_smime_ct_TDTInfo, Integer.valueOf( NID_id_smime_ct_TDTInfo ) ); OID_TO_NID.put( OBJ_id_smime_ct_contentInfo, Integer.valueOf( NID_id_smime_ct_contentInfo ) ); OID_TO_NID.put( OBJ_id_smime_ct_DVCSRequestData, Integer.valueOf( NID_id_smime_ct_DVCSRequestData ) ); OID_TO_NID.put( OBJ_id_smime_ct_DVCSResponseData, Integer.valueOf( NID_id_smime_ct_DVCSResponseData ) ); OID_TO_NID.put( OBJ_id_smime_ct_compressedData, Integer.valueOf( NID_id_smime_ct_compressedData ) ); OID_TO_NID.put( OBJ_id_ct_asciiTextWithCRLF, Integer.valueOf( NID_id_ct_asciiTextWithCRLF ) ); OID_TO_NID.put( OBJ_id_smime_aa_receiptRequest, Integer.valueOf( NID_id_smime_aa_receiptRequest ) ); OID_TO_NID.put( OBJ_id_smime_aa_securityLabel, Integer.valueOf( NID_id_smime_aa_securityLabel ) ); OID_TO_NID.put( OBJ_id_smime_aa_mlExpandHistory, Integer.valueOf( NID_id_smime_aa_mlExpandHistory ) ); OID_TO_NID.put( OBJ_id_smime_aa_contentHint, Integer.valueOf( NID_id_smime_aa_contentHint ) ); OID_TO_NID.put( OBJ_id_smime_aa_msgSigDigest, Integer.valueOf( NID_id_smime_aa_msgSigDigest ) ); OID_TO_NID.put( OBJ_id_smime_aa_encapContentType, Integer.valueOf( NID_id_smime_aa_encapContentType ) ); OID_TO_NID.put( OBJ_id_smime_aa_contentIdentifier, Integer.valueOf( NID_id_smime_aa_contentIdentifier ) ); OID_TO_NID.put( OBJ_id_smime_aa_macValue, Integer.valueOf( NID_id_smime_aa_macValue ) ); OID_TO_NID.put( OBJ_id_smime_aa_equivalentLabels, Integer.valueOf( NID_id_smime_aa_equivalentLabels ) ); OID_TO_NID.put( OBJ_id_smime_aa_contentReference, Integer.valueOf( NID_id_smime_aa_contentReference ) ); OID_TO_NID.put( OBJ_id_smime_aa_encrypKeyPref, Integer.valueOf( NID_id_smime_aa_encrypKeyPref ) ); OID_TO_NID.put( OBJ_id_smime_aa_signingCertificate, Integer.valueOf( NID_id_smime_aa_signingCertificate ) ); OID_TO_NID.put( OBJ_id_smime_aa_smimeEncryptCerts, Integer.valueOf( NID_id_smime_aa_smimeEncryptCerts ) ); OID_TO_NID.put( OBJ_id_smime_aa_timeStampToken, Integer.valueOf( NID_id_smime_aa_timeStampToken ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_sigPolicyId, Integer.valueOf( NID_id_smime_aa_ets_sigPolicyId ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_commitmentType, Integer.valueOf( NID_id_smime_aa_ets_commitmentType ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_signerLocation, Integer.valueOf( NID_id_smime_aa_ets_signerLocation ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_signerAttr, Integer.valueOf( NID_id_smime_aa_ets_signerAttr ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_otherSigCert, Integer.valueOf( NID_id_smime_aa_ets_otherSigCert ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_contentTimestamp, Integer.valueOf( NID_id_smime_aa_ets_contentTimestamp ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_CertificateRefs, Integer.valueOf( NID_id_smime_aa_ets_CertificateRefs ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_RevocationRefs, Integer.valueOf( NID_id_smime_aa_ets_RevocationRefs ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_certValues, Integer.valueOf( NID_id_smime_aa_ets_certValues ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_revocationValues, Integer.valueOf( NID_id_smime_aa_ets_revocationValues ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_escTimeStamp, Integer.valueOf( NID_id_smime_aa_ets_escTimeStamp ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_certCRLTimestamp, Integer.valueOf( NID_id_smime_aa_ets_certCRLTimestamp ) ); OID_TO_NID.put( OBJ_id_smime_aa_ets_archiveTimeStamp, Integer.valueOf( NID_id_smime_aa_ets_archiveTimeStamp ) ); OID_TO_NID.put( OBJ_id_smime_aa_signatureType, Integer.valueOf( NID_id_smime_aa_signatureType ) ); OID_TO_NID.put( OBJ_id_smime_aa_dvcs_dvc, Integer.valueOf( NID_id_smime_aa_dvcs_dvc ) ); OID_TO_NID.put( OBJ_id_smime_alg_ESDHwith3DES, Integer.valueOf( NID_id_smime_alg_ESDHwith3DES ) ); OID_TO_NID.put( OBJ_id_smime_alg_ESDHwithRC2, Integer.valueOf( NID_id_smime_alg_ESDHwithRC2 ) ); OID_TO_NID.put( OBJ_id_smime_alg_3DESwrap, Integer.valueOf( NID_id_smime_alg_3DESwrap ) ); OID_TO_NID.put( OBJ_id_smime_alg_RC2wrap, Integer.valueOf( NID_id_smime_alg_RC2wrap ) ); OID_TO_NID.put( OBJ_id_smime_alg_ESDH, Integer.valueOf( NID_id_smime_alg_ESDH ) ); OID_TO_NID.put( OBJ_id_smime_alg_CMS3DESwrap, Integer.valueOf( NID_id_smime_alg_CMS3DESwrap ) ); OID_TO_NID.put( OBJ_id_smime_alg_CMSRC2wrap, Integer.valueOf( NID_id_smime_alg_CMSRC2wrap ) ); OID_TO_NID.put( OBJ_id_alg_PWRI_KEK, Integer.valueOf( NID_id_alg_PWRI_KEK ) ); OID_TO_NID.put( OBJ_id_smime_cd_ldap, Integer.valueOf( NID_id_smime_cd_ldap ) ); OID_TO_NID.put( OBJ_id_smime_spq_ets_sqt_uri, Integer.valueOf( NID_id_smime_spq_ets_sqt_uri ) ); OID_TO_NID.put( OBJ_id_smime_spq_ets_sqt_unotice, Integer.valueOf( NID_id_smime_spq_ets_sqt_unotice ) ); OID_TO_NID.put( OBJ_id_smime_cti_ets_proofOfOrigin, Integer.valueOf( NID_id_smime_cti_ets_proofOfOrigin ) ); OID_TO_NID.put( OBJ_id_smime_cti_ets_proofOfReceipt, Integer.valueOf( NID_id_smime_cti_ets_proofOfReceipt ) ); OID_TO_NID.put( OBJ_id_smime_cti_ets_proofOfDelivery, Integer.valueOf( NID_id_smime_cti_ets_proofOfDelivery ) ); OID_TO_NID.put( OBJ_id_smime_cti_ets_proofOfSender, Integer.valueOf( NID_id_smime_cti_ets_proofOfSender ) ); OID_TO_NID.put( OBJ_id_smime_cti_ets_proofOfApproval, Integer.valueOf( NID_id_smime_cti_ets_proofOfApproval ) ); OID_TO_NID.put( OBJ_id_smime_cti_ets_proofOfCreation, Integer.valueOf( NID_id_smime_cti_ets_proofOfCreation ) ); OID_TO_NID.put( OBJ_friendlyName, Integer.valueOf( NID_friendlyName ) ); OID_TO_NID.put( OBJ_localKeyID, Integer.valueOf( NID_localKeyID ) ); OID_TO_NID.put( OBJ_ms_csp_name, Integer.valueOf( NID_ms_csp_name ) ); OID_TO_NID.put( OBJ_LocalKeySet, Integer.valueOf( NID_LocalKeySet ) ); OID_TO_NID.put( OBJ_x509Certificate, Integer.valueOf( NID_x509Certificate ) ); OID_TO_NID.put( OBJ_sdsiCertificate, Integer.valueOf( NID_sdsiCertificate ) ); OID_TO_NID.put( OBJ_x509Crl, Integer.valueOf( NID_x509Crl ) ); OID_TO_NID.put( OBJ_pbe_WithSHA1And128BitRC4, Integer.valueOf( NID_pbe_WithSHA1And128BitRC4 ) ); OID_TO_NID.put( OBJ_pbe_WithSHA1And40BitRC4, Integer.valueOf( NID_pbe_WithSHA1And40BitRC4 ) ); OID_TO_NID.put( OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC, Integer.valueOf( NID_pbe_WithSHA1And3_Key_TripleDES_CBC ) ); OID_TO_NID.put( OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC, Integer.valueOf( NID_pbe_WithSHA1And2_Key_TripleDES_CBC ) ); OID_TO_NID.put( OBJ_pbe_WithSHA1And128BitRC2_CBC, Integer.valueOf( NID_pbe_WithSHA1And128BitRC2_CBC ) ); OID_TO_NID.put( OBJ_pbe_WithSHA1And40BitRC2_CBC, Integer.valueOf( NID_pbe_WithSHA1And40BitRC2_CBC ) ); OID_TO_NID.put( OBJ_keyBag, Integer.valueOf( NID_keyBag ) ); OID_TO_NID.put( OBJ_pkcs8ShroudedKeyBag, Integer.valueOf( NID_pkcs8ShroudedKeyBag ) ); OID_TO_NID.put( OBJ_certBag, Integer.valueOf( NID_certBag ) ); OID_TO_NID.put( OBJ_crlBag, Integer.valueOf( NID_crlBag ) ); OID_TO_NID.put( OBJ_secretBag, Integer.valueOf( NID_secretBag ) ); OID_TO_NID.put( OBJ_safeContentsBag, Integer.valueOf( NID_safeContentsBag ) ); OID_TO_NID.put( OBJ_md2, Integer.valueOf( NID_md2 ) ); OID_TO_NID.put( OBJ_md4, Integer.valueOf( NID_md4 ) ); OID_TO_NID.put( OBJ_md5, Integer.valueOf( NID_md5 ) ); OID_TO_NID.put( OBJ_hmacWithMD5, Integer.valueOf( NID_hmacWithMD5 ) ); OID_TO_NID.put( OBJ_hmacWithSHA1, Integer.valueOf( NID_hmacWithSHA1 ) ); OID_TO_NID.put( OBJ_hmacWithSHA224, Integer.valueOf( NID_hmacWithSHA224 ) ); OID_TO_NID.put( OBJ_hmacWithSHA256, Integer.valueOf( NID_hmacWithSHA256 ) ); OID_TO_NID.put( OBJ_hmacWithSHA384, Integer.valueOf( NID_hmacWithSHA384 ) ); OID_TO_NID.put( OBJ_hmacWithSHA512, Integer.valueOf( NID_hmacWithSHA512 ) ); OID_TO_NID.put( OBJ_rc2_cbc, Integer.valueOf( NID_rc2_cbc ) ); OID_TO_NID.put( OBJ_rc4, Integer.valueOf( NID_rc4 ) ); OID_TO_NID.put( OBJ_des_ede3_cbc, Integer.valueOf( NID_des_ede3_cbc ) ); OID_TO_NID.put( OBJ_rc5_cbc, Integer.valueOf( NID_rc5_cbc ) ); OID_TO_NID.put( OBJ_ms_ext_req, Integer.valueOf( NID_ms_ext_req ) ); OID_TO_NID.put( OBJ_ms_code_ind, Integer.valueOf( NID_ms_code_ind ) ); OID_TO_NID.put( OBJ_ms_code_com, Integer.valueOf( NID_ms_code_com ) ); OID_TO_NID.put( OBJ_ms_ctl_sign, Integer.valueOf( NID_ms_ctl_sign ) ); OID_TO_NID.put( OBJ_ms_sgc, Integer.valueOf( NID_ms_sgc ) ); OID_TO_NID.put( OBJ_ms_efs, Integer.valueOf( NID_ms_efs ) ); OID_TO_NID.put( OBJ_ms_smartcard_login, Integer.valueOf( NID_ms_smartcard_login ) ); OID_TO_NID.put( OBJ_ms_upn, Integer.valueOf( NID_ms_upn ) ); OID_TO_NID.put( OBJ_idea_cbc, Integer.valueOf( NID_idea_cbc ) ); OID_TO_NID.put( OBJ_bf_cbc, Integer.valueOf( NID_bf_cbc ) ); OID_TO_NID.put( OBJ_id_pkix, Integer.valueOf( NID_id_pkix ) ); OID_TO_NID.put( OBJ_id_pkix_mod, Integer.valueOf( NID_id_pkix_mod ) ); OID_TO_NID.put( OBJ_id_pe, Integer.valueOf( NID_id_pe ) ); OID_TO_NID.put( OBJ_id_qt, Integer.valueOf( NID_id_qt ) ); OID_TO_NID.put( OBJ_id_kp, Integer.valueOf( NID_id_kp ) ); OID_TO_NID.put( OBJ_id_it, Integer.valueOf( NID_id_it ) ); OID_TO_NID.put( OBJ_id_pkip, Integer.valueOf( NID_id_pkip ) ); OID_TO_NID.put( OBJ_id_alg, Integer.valueOf( NID_id_alg ) ); OID_TO_NID.put( OBJ_id_cmc, Integer.valueOf( NID_id_cmc ) ); OID_TO_NID.put( OBJ_id_on, Integer.valueOf( NID_id_on ) ); OID_TO_NID.put( OBJ_id_pda, Integer.valueOf( NID_id_pda ) ); OID_TO_NID.put( OBJ_id_aca, Integer.valueOf( NID_id_aca ) ); OID_TO_NID.put( OBJ_id_qcs, Integer.valueOf( NID_id_qcs ) ); OID_TO_NID.put( OBJ_id_cct, Integer.valueOf( NID_id_cct ) ); OID_TO_NID.put( OBJ_id_ppl, Integer.valueOf( NID_id_ppl ) ); OID_TO_NID.put( OBJ_id_ad, Integer.valueOf( NID_id_ad ) ); OID_TO_NID.put( OBJ_id_pkix1_explicit_88, Integer.valueOf( NID_id_pkix1_explicit_88 ) ); OID_TO_NID.put( OBJ_id_pkix1_implicit_88, Integer.valueOf( NID_id_pkix1_implicit_88 ) ); OID_TO_NID.put( OBJ_id_pkix1_explicit_93, Integer.valueOf( NID_id_pkix1_explicit_93 ) ); OID_TO_NID.put( OBJ_id_pkix1_implicit_93, Integer.valueOf( NID_id_pkix1_implicit_93 ) ); OID_TO_NID.put( OBJ_id_mod_crmf, Integer.valueOf( NID_id_mod_crmf ) ); OID_TO_NID.put( OBJ_id_mod_cmc, Integer.valueOf( NID_id_mod_cmc ) ); OID_TO_NID.put( OBJ_id_mod_kea_profile_88, Integer.valueOf( NID_id_mod_kea_profile_88 ) ); OID_TO_NID.put( OBJ_id_mod_kea_profile_93, Integer.valueOf( NID_id_mod_kea_profile_93 ) ); OID_TO_NID.put( OBJ_id_mod_cmp, Integer.valueOf( NID_id_mod_cmp ) ); OID_TO_NID.put( OBJ_id_mod_qualified_cert_88, Integer.valueOf( NID_id_mod_qualified_cert_88 ) ); OID_TO_NID.put( OBJ_id_mod_qualified_cert_93, Integer.valueOf( NID_id_mod_qualified_cert_93 ) ); OID_TO_NID.put( OBJ_id_mod_attribute_cert, Integer.valueOf( NID_id_mod_attribute_cert ) ); OID_TO_NID.put( OBJ_id_mod_timestamp_protocol, Integer.valueOf( NID_id_mod_timestamp_protocol ) ); OID_TO_NID.put( OBJ_id_mod_ocsp, Integer.valueOf( NID_id_mod_ocsp ) ); OID_TO_NID.put( OBJ_id_mod_dvcs, Integer.valueOf( NID_id_mod_dvcs ) ); OID_TO_NID.put( OBJ_id_mod_cmp2000, Integer.valueOf( NID_id_mod_cmp2000 ) ); OID_TO_NID.put( OBJ_info_access, Integer.valueOf( NID_info_access ) ); OID_TO_NID.put( OBJ_biometricInfo, Integer.valueOf( NID_biometricInfo ) ); OID_TO_NID.put( OBJ_qcStatements, Integer.valueOf( NID_qcStatements ) ); OID_TO_NID.put( OBJ_ac_auditEntity, Integer.valueOf( NID_ac_auditEntity ) ); OID_TO_NID.put( OBJ_ac_targeting, Integer.valueOf( NID_ac_targeting ) ); OID_TO_NID.put( OBJ_aaControls, Integer.valueOf( NID_aaControls ) ); OID_TO_NID.put( OBJ_sbgp_ipAddrBlock, Integer.valueOf( NID_sbgp_ipAddrBlock ) ); OID_TO_NID.put( OBJ_sbgp_autonomousSysNum, Integer.valueOf( NID_sbgp_autonomousSysNum ) ); OID_TO_NID.put( OBJ_sbgp_routerIdentifier, Integer.valueOf( NID_sbgp_routerIdentifier ) ); OID_TO_NID.put( OBJ_ac_proxying, Integer.valueOf( NID_ac_proxying ) ); OID_TO_NID.put( OBJ_sinfo_access, Integer.valueOf( NID_sinfo_access ) ); OID_TO_NID.put( OBJ_proxyCertInfo, Integer.valueOf( NID_proxyCertInfo ) ); OID_TO_NID.put( OBJ_id_qt_cps, Integer.valueOf( NID_id_qt_cps ) ); OID_TO_NID.put( OBJ_id_qt_unotice, Integer.valueOf( NID_id_qt_unotice ) ); OID_TO_NID.put( OBJ_textNotice, Integer.valueOf( NID_textNotice ) ); OID_TO_NID.put( OBJ_server_auth, Integer.valueOf( NID_server_auth ) ); OID_TO_NID.put( OBJ_client_auth, Integer.valueOf( NID_client_auth ) ); OID_TO_NID.put( OBJ_code_sign, Integer.valueOf( NID_code_sign ) ); OID_TO_NID.put( OBJ_email_protect, Integer.valueOf( NID_email_protect ) ); OID_TO_NID.put( OBJ_ipsecEndSystem, Integer.valueOf( NID_ipsecEndSystem ) ); OID_TO_NID.put( OBJ_ipsecTunnel, Integer.valueOf( NID_ipsecTunnel ) ); OID_TO_NID.put( OBJ_ipsecUser, Integer.valueOf( NID_ipsecUser ) ); OID_TO_NID.put( OBJ_time_stamp, Integer.valueOf( NID_time_stamp ) ); OID_TO_NID.put( OBJ_OCSP_sign, Integer.valueOf( NID_OCSP_sign ) ); OID_TO_NID.put( OBJ_dvcs, Integer.valueOf( NID_dvcs ) ); OID_TO_NID.put( OBJ_id_it_caProtEncCert, Integer.valueOf( NID_id_it_caProtEncCert ) ); OID_TO_NID.put( OBJ_id_it_signKeyPairTypes, Integer.valueOf( NID_id_it_signKeyPairTypes ) ); OID_TO_NID.put( OBJ_id_it_encKeyPairTypes, Integer.valueOf( NID_id_it_encKeyPairTypes ) ); OID_TO_NID.put( OBJ_id_it_preferredSymmAlg, Integer.valueOf( NID_id_it_preferredSymmAlg ) ); OID_TO_NID.put( OBJ_id_it_caKeyUpdateInfo, Integer.valueOf( NID_id_it_caKeyUpdateInfo ) ); OID_TO_NID.put( OBJ_id_it_currentCRL, Integer.valueOf( NID_id_it_currentCRL ) ); OID_TO_NID.put( OBJ_id_it_unsupportedOIDs, Integer.valueOf( NID_id_it_unsupportedOIDs ) ); OID_TO_NID.put( OBJ_id_it_subscriptionRequest, Integer.valueOf( NID_id_it_subscriptionRequest ) ); OID_TO_NID.put( OBJ_id_it_subscriptionResponse, Integer.valueOf( NID_id_it_subscriptionResponse ) ); OID_TO_NID.put( OBJ_id_it_keyPairParamReq, Integer.valueOf( NID_id_it_keyPairParamReq ) ); OID_TO_NID.put( OBJ_id_it_keyPairParamRep, Integer.valueOf( NID_id_it_keyPairParamRep ) ); OID_TO_NID.put( OBJ_id_it_revPassphrase, Integer.valueOf( NID_id_it_revPassphrase ) ); OID_TO_NID.put( OBJ_id_it_implicitConfirm, Integer.valueOf( NID_id_it_implicitConfirm ) ); OID_TO_NID.put( OBJ_id_it_confirmWaitTime, Integer.valueOf( NID_id_it_confirmWaitTime ) ); OID_TO_NID.put( OBJ_id_it_origPKIMessage, Integer.valueOf( NID_id_it_origPKIMessage ) ); OID_TO_NID.put( OBJ_id_it_suppLangTags, Integer.valueOf( NID_id_it_suppLangTags ) ); OID_TO_NID.put( OBJ_id_regCtrl, Integer.valueOf( NID_id_regCtrl ) ); OID_TO_NID.put( OBJ_id_regInfo, Integer.valueOf( NID_id_regInfo ) ); OID_TO_NID.put( OBJ_id_regCtrl_regToken, Integer.valueOf( NID_id_regCtrl_regToken ) ); OID_TO_NID.put( OBJ_id_regCtrl_authenticator, Integer.valueOf( NID_id_regCtrl_authenticator ) ); OID_TO_NID.put( OBJ_id_regCtrl_pkiPublicationInfo, Integer.valueOf( NID_id_regCtrl_pkiPublicationInfo ) ); OID_TO_NID.put( OBJ_id_regCtrl_pkiArchiveOptions, Integer.valueOf( NID_id_regCtrl_pkiArchiveOptions ) ); OID_TO_NID.put( OBJ_id_regCtrl_oldCertID, Integer.valueOf( NID_id_regCtrl_oldCertID ) ); OID_TO_NID.put( OBJ_id_regCtrl_protocolEncrKey, Integer.valueOf( NID_id_regCtrl_protocolEncrKey ) ); OID_TO_NID.put( OBJ_id_regInfo_utf8Pairs, Integer.valueOf( NID_id_regInfo_utf8Pairs ) ); OID_TO_NID.put( OBJ_id_regInfo_certReq, Integer.valueOf( NID_id_regInfo_certReq ) ); OID_TO_NID.put( OBJ_id_alg_des40, Integer.valueOf( NID_id_alg_des40 ) ); OID_TO_NID.put( OBJ_id_alg_noSignature, Integer.valueOf( NID_id_alg_noSignature ) ); OID_TO_NID.put( OBJ_id_alg_dh_sig_hmac_sha1, Integer.valueOf( NID_id_alg_dh_sig_hmac_sha1 ) ); OID_TO_NID.put( OBJ_id_alg_dh_pop, Integer.valueOf( NID_id_alg_dh_pop ) ); OID_TO_NID.put( OBJ_id_cmc_statusInfo, Integer.valueOf( NID_id_cmc_statusInfo ) ); OID_TO_NID.put( OBJ_id_cmc_identification, Integer.valueOf( NID_id_cmc_identification ) ); OID_TO_NID.put( OBJ_id_cmc_identityProof, Integer.valueOf( NID_id_cmc_identityProof ) ); OID_TO_NID.put( OBJ_id_cmc_dataReturn, Integer.valueOf( NID_id_cmc_dataReturn ) ); OID_TO_NID.put( OBJ_id_cmc_transactionId, Integer.valueOf( NID_id_cmc_transactionId ) ); OID_TO_NID.put( OBJ_id_cmc_senderNonce, Integer.valueOf( NID_id_cmc_senderNonce ) ); OID_TO_NID.put( OBJ_id_cmc_recipientNonce, Integer.valueOf( NID_id_cmc_recipientNonce ) ); OID_TO_NID.put( OBJ_id_cmc_addExtensions, Integer.valueOf( NID_id_cmc_addExtensions ) ); OID_TO_NID.put( OBJ_id_cmc_encryptedPOP, Integer.valueOf( NID_id_cmc_encryptedPOP ) ); OID_TO_NID.put( OBJ_id_cmc_decryptedPOP, Integer.valueOf( NID_id_cmc_decryptedPOP ) ); OID_TO_NID.put( OBJ_id_cmc_lraPOPWitness, Integer.valueOf( NID_id_cmc_lraPOPWitness ) ); OID_TO_NID.put( OBJ_id_cmc_getCert, Integer.valueOf( NID_id_cmc_getCert ) ); OID_TO_NID.put( OBJ_id_cmc_getCRL, Integer.valueOf( NID_id_cmc_getCRL ) ); OID_TO_NID.put( OBJ_id_cmc_revokeRequest, Integer.valueOf( NID_id_cmc_revokeRequest ) ); OID_TO_NID.put( OBJ_id_cmc_regInfo, Integer.valueOf( NID_id_cmc_regInfo ) ); OID_TO_NID.put( OBJ_id_cmc_responseInfo, Integer.valueOf( NID_id_cmc_responseInfo ) ); OID_TO_NID.put( OBJ_id_cmc_queryPending, Integer.valueOf( NID_id_cmc_queryPending ) ); OID_TO_NID.put( OBJ_id_cmc_popLinkRandom, Integer.valueOf( NID_id_cmc_popLinkRandom ) ); OID_TO_NID.put( OBJ_id_cmc_popLinkWitness, Integer.valueOf( NID_id_cmc_popLinkWitness ) ); OID_TO_NID.put( OBJ_id_cmc_confirmCertAcceptance, Integer.valueOf( NID_id_cmc_confirmCertAcceptance ) ); OID_TO_NID.put( OBJ_id_on_personalData, Integer.valueOf( NID_id_on_personalData ) ); OID_TO_NID.put( OBJ_id_on_permanentIdentifier, Integer.valueOf( NID_id_on_permanentIdentifier ) ); OID_TO_NID.put( OBJ_id_pda_dateOfBirth, Integer.valueOf( NID_id_pda_dateOfBirth ) ); OID_TO_NID.put( OBJ_id_pda_placeOfBirth, Integer.valueOf( NID_id_pda_placeOfBirth ) ); OID_TO_NID.put( OBJ_id_pda_gender, Integer.valueOf( NID_id_pda_gender ) ); OID_TO_NID.put( OBJ_id_pda_countryOfCitizenship, Integer.valueOf( NID_id_pda_countryOfCitizenship ) ); OID_TO_NID.put( OBJ_id_pda_countryOfResidence, Integer.valueOf( NID_id_pda_countryOfResidence ) ); OID_TO_NID.put( OBJ_id_aca_authenticationInfo, Integer.valueOf( NID_id_aca_authenticationInfo ) ); OID_TO_NID.put( OBJ_id_aca_accessIdentity, Integer.valueOf( NID_id_aca_accessIdentity ) ); OID_TO_NID.put( OBJ_id_aca_chargingIdentity, Integer.valueOf( NID_id_aca_chargingIdentity ) ); OID_TO_NID.put( OBJ_id_aca_group, Integer.valueOf( NID_id_aca_group ) ); OID_TO_NID.put( OBJ_id_aca_role, Integer.valueOf( NID_id_aca_role ) ); OID_TO_NID.put( OBJ_id_aca_encAttrs, Integer.valueOf( NID_id_aca_encAttrs ) ); OID_TO_NID.put( OBJ_id_qcs_pkixQCSyntax_v1, Integer.valueOf( NID_id_qcs_pkixQCSyntax_v1 ) ); OID_TO_NID.put( OBJ_id_cct_crs, Integer.valueOf( NID_id_cct_crs ) ); OID_TO_NID.put( OBJ_id_cct_PKIData, Integer.valueOf( NID_id_cct_PKIData ) ); OID_TO_NID.put( OBJ_id_cct_PKIResponse, Integer.valueOf( NID_id_cct_PKIResponse ) ); OID_TO_NID.put( OBJ_id_ppl_anyLanguage, Integer.valueOf( NID_id_ppl_anyLanguage ) ); OID_TO_NID.put( OBJ_id_ppl_inheritAll, Integer.valueOf( NID_id_ppl_inheritAll ) ); OID_TO_NID.put( OBJ_Independent, Integer.valueOf( NID_Independent ) ); OID_TO_NID.put( OBJ_ad_OCSP, Integer.valueOf( NID_ad_OCSP ) ); OID_TO_NID.put( OBJ_ad_ca_issuers, Integer.valueOf( NID_ad_ca_issuers ) ); OID_TO_NID.put( OBJ_ad_timeStamping, Integer.valueOf( NID_ad_timeStamping ) ); OID_TO_NID.put( OBJ_ad_dvcs, Integer.valueOf( NID_ad_dvcs ) ); OID_TO_NID.put( OBJ_caRepository, Integer.valueOf( NID_caRepository ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_basic, Integer.valueOf( NID_id_pkix_OCSP_basic ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_Nonce, Integer.valueOf( NID_id_pkix_OCSP_Nonce ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_CrlID, Integer.valueOf( NID_id_pkix_OCSP_CrlID ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_acceptableResponses, Integer.valueOf( NID_id_pkix_OCSP_acceptableResponses ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_noCheck, Integer.valueOf( NID_id_pkix_OCSP_noCheck ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_archiveCutoff, Integer.valueOf( NID_id_pkix_OCSP_archiveCutoff ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_serviceLocator, Integer.valueOf( NID_id_pkix_OCSP_serviceLocator ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_extendedStatus, Integer.valueOf( NID_id_pkix_OCSP_extendedStatus ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_valid, Integer.valueOf( NID_id_pkix_OCSP_valid ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_path, Integer.valueOf( NID_id_pkix_OCSP_path ) ); OID_TO_NID.put( OBJ_id_pkix_OCSP_trustRoot, Integer.valueOf( NID_id_pkix_OCSP_trustRoot ) ); OID_TO_NID.put( OBJ_algorithm, Integer.valueOf( NID_algorithm ) ); OID_TO_NID.put( OBJ_md5WithRSA, Integer.valueOf( NID_md5WithRSA ) ); OID_TO_NID.put( OBJ_des_ecb, Integer.valueOf( NID_des_ecb ) ); OID_TO_NID.put( OBJ_des_cbc, Integer.valueOf( NID_des_cbc ) ); OID_TO_NID.put( OBJ_des_ofb64, Integer.valueOf( NID_des_ofb64 ) ); OID_TO_NID.put( OBJ_des_cfb64, Integer.valueOf( NID_des_cfb64 ) ); OID_TO_NID.put( OBJ_rsaSignature, Integer.valueOf( NID_rsaSignature ) ); OID_TO_NID.put( OBJ_dsa_2, Integer.valueOf( NID_dsa_2 ) ); OID_TO_NID.put( OBJ_dsaWithSHA, Integer.valueOf( NID_dsaWithSHA ) ); OID_TO_NID.put( OBJ_shaWithRSAEncryption, Integer.valueOf( NID_shaWithRSAEncryption ) ); OID_TO_NID.put( OBJ_des_ede_ecb, Integer.valueOf( NID_des_ede_ecb ) ); OID_TO_NID.put( OBJ_sha, Integer.valueOf( NID_sha ) ); OID_TO_NID.put( OBJ_sha1, Integer.valueOf( NID_sha1 ) ); OID_TO_NID.put( OBJ_dsaWithSHA1_2, Integer.valueOf( NID_dsaWithSHA1_2 ) ); OID_TO_NID.put( OBJ_sha1WithRSA, Integer.valueOf( NID_sha1WithRSA ) ); OID_TO_NID.put( OBJ_ripemd160, Integer.valueOf( NID_ripemd160 ) ); OID_TO_NID.put( OBJ_ripemd160WithRSA, Integer.valueOf( NID_ripemd160WithRSA ) ); OID_TO_NID.put( OBJ_sxnet, Integer.valueOf( NID_sxnet ) ); OID_TO_NID.put( OBJ_X500, Integer.valueOf( NID_X500 ) ); OID_TO_NID.put( OBJ_X509, Integer.valueOf( NID_X509 ) ); OID_TO_NID.put( OBJ_commonName, Integer.valueOf( NID_commonName ) ); OID_TO_NID.put( OBJ_surname, Integer.valueOf( NID_surname ) ); OID_TO_NID.put( OBJ_serialNumber, Integer.valueOf( NID_serialNumber ) ); OID_TO_NID.put( OBJ_countryName, Integer.valueOf( NID_countryName ) ); OID_TO_NID.put( OBJ_localityName, Integer.valueOf( NID_localityName ) ); OID_TO_NID.put( OBJ_stateOrProvinceName, Integer.valueOf( NID_stateOrProvinceName ) ); OID_TO_NID.put( OBJ_streetAddress, Integer.valueOf( NID_streetAddress ) ); OID_TO_NID.put( OBJ_organizationName, Integer.valueOf( NID_organizationName ) ); OID_TO_NID.put( OBJ_organizationalUnitName, Integer.valueOf( NID_organizationalUnitName ) ); OID_TO_NID.put( OBJ_title, Integer.valueOf( NID_title ) ); OID_TO_NID.put( OBJ_description, Integer.valueOf( NID_description ) ); OID_TO_NID.put( OBJ_searchGuide, Integer.valueOf( NID_searchGuide ) ); OID_TO_NID.put( OBJ_businessCategory, Integer.valueOf( NID_businessCategory ) ); OID_TO_NID.put( OBJ_postalAddress, Integer.valueOf( NID_postalAddress ) ); OID_TO_NID.put( OBJ_postalCode, Integer.valueOf( NID_postalCode ) ); OID_TO_NID.put( OBJ_postOfficeBox, Integer.valueOf( NID_postOfficeBox ) ); OID_TO_NID.put( OBJ_physicalDeliveryOfficeName, Integer.valueOf( NID_physicalDeliveryOfficeName ) ); OID_TO_NID.put( OBJ_telephoneNumber, Integer.valueOf( NID_telephoneNumber ) ); OID_TO_NID.put( OBJ_telexNumber, Integer.valueOf( NID_telexNumber ) ); OID_TO_NID.put( OBJ_teletexTerminalIdentifier, Integer.valueOf( NID_teletexTerminalIdentifier ) ); OID_TO_NID.put( OBJ_facsimileTelephoneNumber, Integer.valueOf( NID_facsimileTelephoneNumber ) ); OID_TO_NID.put( OBJ_x121Address, Integer.valueOf( NID_x121Address ) ); OID_TO_NID.put( OBJ_internationaliSDNNumber, Integer.valueOf( NID_internationaliSDNNumber ) ); OID_TO_NID.put( OBJ_registeredAddress, Integer.valueOf( NID_registeredAddress ) ); OID_TO_NID.put( OBJ_destinationIndicator, Integer.valueOf( NID_destinationIndicator ) ); OID_TO_NID.put( OBJ_preferredDeliveryMethod, Integer.valueOf( NID_preferredDeliveryMethod ) ); OID_TO_NID.put( OBJ_presentationAddress, Integer.valueOf( NID_presentationAddress ) ); OID_TO_NID.put( OBJ_supportedApplicationContext, Integer.valueOf( NID_supportedApplicationContext ) ); OID_TO_NID.put( OBJ_member, Integer.valueOf( NID_member ) ); OID_TO_NID.put( OBJ_owner, Integer.valueOf( NID_owner ) ); OID_TO_NID.put( OBJ_roleOccupant, Integer.valueOf( NID_roleOccupant ) ); OID_TO_NID.put( OBJ_seeAlso, Integer.valueOf( NID_seeAlso ) ); OID_TO_NID.put( OBJ_userPassword, Integer.valueOf( NID_userPassword ) ); OID_TO_NID.put( OBJ_userCertificate, Integer.valueOf( NID_userCertificate ) ); OID_TO_NID.put( OBJ_cACertificate, Integer.valueOf( NID_cACertificate ) ); OID_TO_NID.put( OBJ_authorityRevocationList, Integer.valueOf( NID_authorityRevocationList ) ); OID_TO_NID.put( OBJ_certificateRevocationList, Integer.valueOf( NID_certificateRevocationList ) ); OID_TO_NID.put( OBJ_crossCertificatePair, Integer.valueOf( NID_crossCertificatePair ) ); OID_TO_NID.put( OBJ_name, Integer.valueOf( NID_name ) ); OID_TO_NID.put( OBJ_givenName, Integer.valueOf( NID_givenName ) ); OID_TO_NID.put( OBJ_initials, Integer.valueOf( NID_initials ) ); OID_TO_NID.put( OBJ_generationQualifier, Integer.valueOf( NID_generationQualifier ) ); OID_TO_NID.put( OBJ_x500UniqueIdentifier, Integer.valueOf( NID_x500UniqueIdentifier ) ); OID_TO_NID.put( OBJ_dnQualifier, Integer.valueOf( NID_dnQualifier ) ); OID_TO_NID.put( OBJ_enhancedSearchGuide, Integer.valueOf( NID_enhancedSearchGuide ) ); OID_TO_NID.put( OBJ_protocolInformation, Integer.valueOf( NID_protocolInformation ) ); OID_TO_NID.put( OBJ_distinguishedName, Integer.valueOf( NID_distinguishedName ) ); OID_TO_NID.put( OBJ_uniqueMember, Integer.valueOf( NID_uniqueMember ) ); OID_TO_NID.put( OBJ_houseIdentifier, Integer.valueOf( NID_houseIdentifier ) ); OID_TO_NID.put( OBJ_supportedAlgorithms, Integer.valueOf( NID_supportedAlgorithms ) ); OID_TO_NID.put( OBJ_deltaRevocationList, Integer.valueOf( NID_deltaRevocationList ) ); OID_TO_NID.put( OBJ_dmdName, Integer.valueOf( NID_dmdName ) ); OID_TO_NID.put( OBJ_pseudonym, Integer.valueOf( NID_pseudonym ) ); OID_TO_NID.put( OBJ_role, Integer.valueOf( NID_role ) ); OID_TO_NID.put( OBJ_X500algorithms, Integer.valueOf( NID_X500algorithms ) ); OID_TO_NID.put( OBJ_rsa, Integer.valueOf( NID_rsa ) ); OID_TO_NID.put( OBJ_mdc2WithRSA, Integer.valueOf( NID_mdc2WithRSA ) ); OID_TO_NID.put( OBJ_mdc2, Integer.valueOf( NID_mdc2 ) ); OID_TO_NID.put( OBJ_id_ce, Integer.valueOf( NID_id_ce ) ); OID_TO_NID.put( OBJ_subject_directory_attributes, Integer.valueOf( NID_subject_directory_attributes ) ); OID_TO_NID.put( OBJ_subject_key_identifier, Integer.valueOf( NID_subject_key_identifier ) ); OID_TO_NID.put( OBJ_key_usage, Integer.valueOf( NID_key_usage ) ); OID_TO_NID.put( OBJ_private_key_usage_period, Integer.valueOf( NID_private_key_usage_period ) ); OID_TO_NID.put( OBJ_subject_alt_name, Integer.valueOf( NID_subject_alt_name ) ); OID_TO_NID.put( OBJ_issuer_alt_name, Integer.valueOf( NID_issuer_alt_name ) ); OID_TO_NID.put( OBJ_basic_constraints, Integer.valueOf( NID_basic_constraints ) ); OID_TO_NID.put( OBJ_crl_number, Integer.valueOf( NID_crl_number ) ); OID_TO_NID.put( OBJ_crl_reason, Integer.valueOf( NID_crl_reason ) ); OID_TO_NID.put( OBJ_invalidity_date, Integer.valueOf( NID_invalidity_date ) ); OID_TO_NID.put( OBJ_delta_crl, Integer.valueOf( NID_delta_crl ) ); OID_TO_NID.put( OBJ_issuing_distribution_point, Integer.valueOf( NID_issuing_distribution_point ) ); OID_TO_NID.put( OBJ_certificate_issuer, Integer.valueOf( NID_certificate_issuer ) ); OID_TO_NID.put( OBJ_name_constraints, Integer.valueOf( NID_name_constraints ) ); OID_TO_NID.put( OBJ_crl_distribution_points, Integer.valueOf( NID_crl_distribution_points ) ); OID_TO_NID.put( OBJ_certificate_policies, Integer.valueOf( NID_certificate_policies ) ); OID_TO_NID.put( OBJ_any_policy, Integer.valueOf( NID_any_policy ) ); OID_TO_NID.put( OBJ_policy_mappings, Integer.valueOf( NID_policy_mappings ) ); OID_TO_NID.put( OBJ_authority_key_identifier, Integer.valueOf( NID_authority_key_identifier ) ); OID_TO_NID.put( OBJ_policy_constraints, Integer.valueOf( NID_policy_constraints ) ); OID_TO_NID.put( OBJ_ext_key_usage, Integer.valueOf( NID_ext_key_usage ) ); OID_TO_NID.put( OBJ_freshest_crl, Integer.valueOf( NID_freshest_crl ) ); OID_TO_NID.put( OBJ_inhibit_any_policy, Integer.valueOf( NID_inhibit_any_policy ) ); OID_TO_NID.put( OBJ_target_information, Integer.valueOf( NID_target_information ) ); OID_TO_NID.put( OBJ_no_rev_avail, Integer.valueOf( NID_no_rev_avail ) ); OID_TO_NID.put( OBJ_anyExtendedKeyUsage, Integer.valueOf( NID_anyExtendedKeyUsage ) ); OID_TO_NID.put( OBJ_netscape, Integer.valueOf( NID_netscape ) ); OID_TO_NID.put( OBJ_netscape_cert_extension, Integer.valueOf( NID_netscape_cert_extension ) ); OID_TO_NID.put( OBJ_netscape_data_type, Integer.valueOf( NID_netscape_data_type ) ); OID_TO_NID.put( OBJ_netscape_cert_type, Integer.valueOf( NID_netscape_cert_type ) ); OID_TO_NID.put( OBJ_netscape_base_url, Integer.valueOf( NID_netscape_base_url ) ); OID_TO_NID.put( OBJ_netscape_revocation_url, Integer.valueOf( NID_netscape_revocation_url ) ); OID_TO_NID.put( OBJ_netscape_ca_revocation_url, Integer.valueOf( NID_netscape_ca_revocation_url ) ); OID_TO_NID.put( OBJ_netscape_renewal_url, Integer.valueOf( NID_netscape_renewal_url ) ); OID_TO_NID.put( OBJ_netscape_ca_policy_url, Integer.valueOf( NID_netscape_ca_policy_url ) ); OID_TO_NID.put( OBJ_netscape_ssl_server_name, Integer.valueOf( NID_netscape_ssl_server_name ) ); OID_TO_NID.put( OBJ_netscape_comment, Integer.valueOf( NID_netscape_comment ) ); OID_TO_NID.put( OBJ_netscape_cert_sequence, Integer.valueOf( NID_netscape_cert_sequence ) ); OID_TO_NID.put( OBJ_ns_sgc, Integer.valueOf( NID_ns_sgc ) ); OID_TO_NID.put( OBJ_org, Integer.valueOf( NID_org ) ); OID_TO_NID.put( OBJ_dod, Integer.valueOf( NID_dod ) ); OID_TO_NID.put( OBJ_iana, Integer.valueOf( NID_iana ) ); OID_TO_NID.put( OBJ_Directory, Integer.valueOf( NID_Directory ) ); OID_TO_NID.put( OBJ_Management, Integer.valueOf( NID_Management ) ); OID_TO_NID.put( OBJ_Experimental, Integer.valueOf( NID_Experimental ) ); OID_TO_NID.put( OBJ_Private, Integer.valueOf( NID_Private ) ); OID_TO_NID.put( OBJ_Security, Integer.valueOf( NID_Security ) ); OID_TO_NID.put( OBJ_SNMPv2, Integer.valueOf( NID_SNMPv2 ) ); OID_TO_NID.put( OBJ_Mail, Integer.valueOf( NID_Mail ) ); OID_TO_NID.put( OBJ_Enterprises, Integer.valueOf( NID_Enterprises ) ); OID_TO_NID.put( OBJ_dcObject, Integer.valueOf( NID_dcObject ) ); OID_TO_NID.put( OBJ_mime_mhs, Integer.valueOf( NID_mime_mhs ) ); OID_TO_NID.put( OBJ_mime_mhs_headings, Integer.valueOf( NID_mime_mhs_headings ) ); OID_TO_NID.put( OBJ_mime_mhs_bodies, Integer.valueOf( NID_mime_mhs_bodies ) ); OID_TO_NID.put( OBJ_id_hex_partial_message, Integer.valueOf( NID_id_hex_partial_message ) ); OID_TO_NID.put( OBJ_id_hex_multipart_message, Integer.valueOf( NID_id_hex_multipart_message ) ); OID_TO_NID.put( OBJ_rle_compression, Integer.valueOf( NID_rle_compression ) ); OID_TO_NID.put( OBJ_zlib_compression, Integer.valueOf( NID_zlib_compression ) ); OID_TO_NID.put( OBJ_aes_128_ecb, Integer.valueOf( NID_aes_128_ecb ) ); OID_TO_NID.put( OBJ_aes_128_cbc, Integer.valueOf( NID_aes_128_cbc ) ); OID_TO_NID.put( OBJ_aes_128_ofb128, Integer.valueOf( NID_aes_128_ofb128 ) ); OID_TO_NID.put( OBJ_aes_128_cfb128, Integer.valueOf( NID_aes_128_cfb128 ) ); OID_TO_NID.put( OBJ_id_aes128_wrap, Integer.valueOf( NID_id_aes128_wrap ) ); OID_TO_NID.put( OBJ_aes_128_gcm, Integer.valueOf( NID_aes_128_gcm ) ); OID_TO_NID.put( OBJ_aes_128_ccm, Integer.valueOf( NID_aes_128_ccm ) ); OID_TO_NID.put( OBJ_id_aes128_wrap_pad, Integer.valueOf( NID_id_aes128_wrap_pad ) ); OID_TO_NID.put( OBJ_aes_192_ecb, Integer.valueOf( NID_aes_192_ecb ) ); OID_TO_NID.put( OBJ_aes_192_cbc, Integer.valueOf( NID_aes_192_cbc ) ); OID_TO_NID.put( OBJ_aes_192_ofb128, Integer.valueOf( NID_aes_192_ofb128 ) ); OID_TO_NID.put( OBJ_aes_192_cfb128, Integer.valueOf( NID_aes_192_cfb128 ) ); OID_TO_NID.put( OBJ_id_aes192_wrap, Integer.valueOf( NID_id_aes192_wrap ) ); OID_TO_NID.put( OBJ_aes_192_gcm, Integer.valueOf( NID_aes_192_gcm ) ); OID_TO_NID.put( OBJ_aes_192_ccm, Integer.valueOf( NID_aes_192_ccm ) ); OID_TO_NID.put( OBJ_id_aes192_wrap_pad, Integer.valueOf( NID_id_aes192_wrap_pad ) ); OID_TO_NID.put( OBJ_aes_256_ecb, Integer.valueOf( NID_aes_256_ecb ) ); OID_TO_NID.put( OBJ_aes_256_cbc, Integer.valueOf( NID_aes_256_cbc ) ); OID_TO_NID.put( OBJ_aes_256_ofb128, Integer.valueOf( NID_aes_256_ofb128 ) ); OID_TO_NID.put( OBJ_aes_256_cfb128, Integer.valueOf( NID_aes_256_cfb128 ) ); OID_TO_NID.put( OBJ_id_aes256_wrap, Integer.valueOf( NID_id_aes256_wrap ) ); OID_TO_NID.put( OBJ_aes_256_gcm, Integer.valueOf( NID_aes_256_gcm ) ); OID_TO_NID.put( OBJ_aes_256_ccm, Integer.valueOf( NID_aes_256_ccm ) ); OID_TO_NID.put( OBJ_id_aes256_wrap_pad, Integer.valueOf( NID_id_aes256_wrap_pad ) ); OID_TO_NID.put( OBJ_sha256, Integer.valueOf( NID_sha256 ) ); OID_TO_NID.put( OBJ_sha384, Integer.valueOf( NID_sha384 ) ); OID_TO_NID.put( OBJ_sha512, Integer.valueOf( NID_sha512 ) ); OID_TO_NID.put( OBJ_sha224, Integer.valueOf( NID_sha224 ) ); OID_TO_NID.put( OBJ_dsa_with_SHA224, Integer.valueOf( NID_dsa_with_SHA224 ) ); OID_TO_NID.put( OBJ_dsa_with_SHA256, Integer.valueOf( NID_dsa_with_SHA256 ) ); OID_TO_NID.put( OBJ_hold_instruction_code, Integer.valueOf( NID_hold_instruction_code ) ); OID_TO_NID.put( OBJ_hold_instruction_none, Integer.valueOf( NID_hold_instruction_none ) ); OID_TO_NID.put( OBJ_hold_instruction_call_issuer, Integer.valueOf( NID_hold_instruction_call_issuer ) ); OID_TO_NID.put( OBJ_hold_instruction_reject, Integer.valueOf( NID_hold_instruction_reject ) ); OID_TO_NID.put( OBJ_data, Integer.valueOf( NID_data ) ); OID_TO_NID.put( OBJ_pss, Integer.valueOf( NID_pss ) ); OID_TO_NID.put( OBJ_ucl, Integer.valueOf( NID_ucl ) ); OID_TO_NID.put( OBJ_pilot, Integer.valueOf( NID_pilot ) ); OID_TO_NID.put( OBJ_pilotAttributeType, Integer.valueOf( NID_pilotAttributeType ) ); OID_TO_NID.put( OBJ_pilotAttributeSyntax, Integer.valueOf( NID_pilotAttributeSyntax ) ); OID_TO_NID.put( OBJ_pilotObjectClass, Integer.valueOf( NID_pilotObjectClass ) ); OID_TO_NID.put( OBJ_pilotGroups, Integer.valueOf( NID_pilotGroups ) ); OID_TO_NID.put( OBJ_iA5StringSyntax, Integer.valueOf( NID_iA5StringSyntax ) ); OID_TO_NID.put( OBJ_caseIgnoreIA5StringSyntax, Integer.valueOf( NID_caseIgnoreIA5StringSyntax ) ); OID_TO_NID.put( OBJ_pilotObject, Integer.valueOf( NID_pilotObject ) ); OID_TO_NID.put( OBJ_pilotPerson, Integer.valueOf( NID_pilotPerson ) ); OID_TO_NID.put( OBJ_account, Integer.valueOf( NID_account ) ); OID_TO_NID.put( OBJ_document, Integer.valueOf( NID_document ) ); OID_TO_NID.put( OBJ_room, Integer.valueOf( NID_room ) ); OID_TO_NID.put( OBJ_documentSeries, Integer.valueOf( NID_documentSeries ) ); OID_TO_NID.put( OBJ_Domain, Integer.valueOf( NID_Domain ) ); OID_TO_NID.put( OBJ_rFC822localPart, Integer.valueOf( NID_rFC822localPart ) ); OID_TO_NID.put( OBJ_dNSDomain, Integer.valueOf( NID_dNSDomain ) ); OID_TO_NID.put( OBJ_domainRelatedObject, Integer.valueOf( NID_domainRelatedObject ) ); OID_TO_NID.put( OBJ_friendlyCountry, Integer.valueOf( NID_friendlyCountry ) ); OID_TO_NID.put( OBJ_simpleSecurityObject, Integer.valueOf( NID_simpleSecurityObject ) ); OID_TO_NID.put( OBJ_pilotOrganization, Integer.valueOf( NID_pilotOrganization ) ); OID_TO_NID.put( OBJ_pilotDSA, Integer.valueOf( NID_pilotDSA ) ); OID_TO_NID.put( OBJ_qualityLabelledData, Integer.valueOf( NID_qualityLabelledData ) ); OID_TO_NID.put( OBJ_userId, Integer.valueOf( NID_userId ) ); OID_TO_NID.put( OBJ_textEncodedORAddress, Integer.valueOf( NID_textEncodedORAddress ) ); OID_TO_NID.put( OBJ_rfc822Mailbox, Integer.valueOf( NID_rfc822Mailbox ) ); OID_TO_NID.put( OBJ_info, Integer.valueOf( NID_info ) ); OID_TO_NID.put( OBJ_favouriteDrink, Integer.valueOf( NID_favouriteDrink ) ); OID_TO_NID.put( OBJ_roomNumber, Integer.valueOf( NID_roomNumber ) ); OID_TO_NID.put( OBJ_photo, Integer.valueOf( NID_photo ) ); OID_TO_NID.put( OBJ_userClass, Integer.valueOf( NID_userClass ) ); OID_TO_NID.put( OBJ_host, Integer.valueOf( NID_host ) ); OID_TO_NID.put( OBJ_manager, Integer.valueOf( NID_manager ) ); OID_TO_NID.put( OBJ_documentIdentifier, Integer.valueOf( NID_documentIdentifier ) ); OID_TO_NID.put( OBJ_documentTitle, Integer.valueOf( NID_documentTitle ) ); OID_TO_NID.put( OBJ_documentVersion, Integer.valueOf( NID_documentVersion ) ); OID_TO_NID.put( OBJ_documentAuthor, Integer.valueOf( NID_documentAuthor ) ); OID_TO_NID.put( OBJ_documentLocation, Integer.valueOf( NID_documentLocation ) ); OID_TO_NID.put( OBJ_homeTelephoneNumber, Integer.valueOf( NID_homeTelephoneNumber ) ); OID_TO_NID.put( OBJ_secretary, Integer.valueOf( NID_secretary ) ); OID_TO_NID.put( OBJ_otherMailbox, Integer.valueOf( NID_otherMailbox ) ); OID_TO_NID.put( OBJ_lastModifiedTime, Integer.valueOf( NID_lastModifiedTime ) ); OID_TO_NID.put( OBJ_lastModifiedBy, Integer.valueOf( NID_lastModifiedBy ) ); OID_TO_NID.put( OBJ_domainComponent, Integer.valueOf( NID_domainComponent ) ); OID_TO_NID.put( OBJ_aRecord, Integer.valueOf( NID_aRecord ) ); OID_TO_NID.put( OBJ_pilotAttributeType27, Integer.valueOf( NID_pilotAttributeType27 ) ); OID_TO_NID.put( OBJ_mXRecord, Integer.valueOf( NID_mXRecord ) ); OID_TO_NID.put( OBJ_nSRecord, Integer.valueOf( NID_nSRecord ) ); OID_TO_NID.put( OBJ_sOARecord, Integer.valueOf( NID_sOARecord ) ); OID_TO_NID.put( OBJ_cNAMERecord, Integer.valueOf( NID_cNAMERecord ) ); OID_TO_NID.put( OBJ_associatedDomain, Integer.valueOf( NID_associatedDomain ) ); OID_TO_NID.put( OBJ_associatedName, Integer.valueOf( NID_associatedName ) ); OID_TO_NID.put( OBJ_homePostalAddress, Integer.valueOf( NID_homePostalAddress ) ); OID_TO_NID.put( OBJ_personalTitle, Integer.valueOf( NID_personalTitle ) ); OID_TO_NID.put( OBJ_mobileTelephoneNumber, Integer.valueOf( NID_mobileTelephoneNumber ) ); OID_TO_NID.put( OBJ_pagerTelephoneNumber, Integer.valueOf( NID_pagerTelephoneNumber ) ); OID_TO_NID.put( OBJ_friendlyCountryName, Integer.valueOf( NID_friendlyCountryName ) ); OID_TO_NID.put( OBJ_organizationalStatus, Integer.valueOf( NID_organizationalStatus ) ); OID_TO_NID.put( OBJ_janetMailbox, Integer.valueOf( NID_janetMailbox ) ); OID_TO_NID.put( OBJ_mailPreferenceOption, Integer.valueOf( NID_mailPreferenceOption ) ); OID_TO_NID.put( OBJ_buildingName, Integer.valueOf( NID_buildingName ) ); OID_TO_NID.put( OBJ_dSAQuality, Integer.valueOf( NID_dSAQuality ) ); OID_TO_NID.put( OBJ_singleLevelQuality, Integer.valueOf( NID_singleLevelQuality ) ); OID_TO_NID.put( OBJ_subtreeMinimumQuality, Integer.valueOf( NID_subtreeMinimumQuality ) ); OID_TO_NID.put( OBJ_subtreeMaximumQuality, Integer.valueOf( NID_subtreeMaximumQuality ) ); OID_TO_NID.put( OBJ_personalSignature, Integer.valueOf( NID_personalSignature ) ); OID_TO_NID.put( OBJ_dITRedirect, Integer.valueOf( NID_dITRedirect ) ); OID_TO_NID.put( OBJ_audio, Integer.valueOf( NID_audio ) ); OID_TO_NID.put( OBJ_documentPublisher, Integer.valueOf( NID_documentPublisher ) ); OID_TO_NID.put( OBJ_id_set, Integer.valueOf( NID_id_set ) ); OID_TO_NID.put( OBJ_set_ctype, Integer.valueOf( NID_set_ctype ) ); OID_TO_NID.put( OBJ_set_msgExt, Integer.valueOf( NID_set_msgExt ) ); OID_TO_NID.put( OBJ_set_attr, Integer.valueOf( NID_set_attr ) ); OID_TO_NID.put( OBJ_set_policy, Integer.valueOf( NID_set_policy ) ); OID_TO_NID.put( OBJ_set_certExt, Integer.valueOf( NID_set_certExt ) ); OID_TO_NID.put( OBJ_set_brand, Integer.valueOf( NID_set_brand ) ); OID_TO_NID.put( OBJ_setct_PANData, Integer.valueOf( NID_setct_PANData ) ); OID_TO_NID.put( OBJ_setct_PANToken, Integer.valueOf( NID_setct_PANToken ) ); OID_TO_NID.put( OBJ_setct_PANOnly, Integer.valueOf( NID_setct_PANOnly ) ); OID_TO_NID.put( OBJ_setct_OIData, Integer.valueOf( NID_setct_OIData ) ); OID_TO_NID.put( OBJ_setct_PI, Integer.valueOf( NID_setct_PI ) ); OID_TO_NID.put( OBJ_setct_PIData, Integer.valueOf( NID_setct_PIData ) ); OID_TO_NID.put( OBJ_setct_PIDataUnsigned, Integer.valueOf( NID_setct_PIDataUnsigned ) ); OID_TO_NID.put( OBJ_setct_HODInput, Integer.valueOf( NID_setct_HODInput ) ); OID_TO_NID.put( OBJ_setct_AuthResBaggage, Integer.valueOf( NID_setct_AuthResBaggage ) ); OID_TO_NID.put( OBJ_setct_AuthRevReqBaggage, Integer.valueOf( NID_setct_AuthRevReqBaggage ) ); OID_TO_NID.put( OBJ_setct_AuthRevResBaggage, Integer.valueOf( NID_setct_AuthRevResBaggage ) ); OID_TO_NID.put( OBJ_setct_CapTokenSeq, Integer.valueOf( NID_setct_CapTokenSeq ) ); OID_TO_NID.put( OBJ_setct_PInitResData, Integer.valueOf( NID_setct_PInitResData ) ); OID_TO_NID.put( OBJ_setct_PI_TBS, Integer.valueOf( NID_setct_PI_TBS ) ); OID_TO_NID.put( OBJ_setct_PResData, Integer.valueOf( NID_setct_PResData ) ); OID_TO_NID.put( OBJ_setct_AuthReqTBS, Integer.valueOf( NID_setct_AuthReqTBS ) ); OID_TO_NID.put( OBJ_setct_AuthResTBS, Integer.valueOf( NID_setct_AuthResTBS ) ); OID_TO_NID.put( OBJ_setct_AuthResTBSX, Integer.valueOf( NID_setct_AuthResTBSX ) ); OID_TO_NID.put( OBJ_setct_AuthTokenTBS, Integer.valueOf( NID_setct_AuthTokenTBS ) ); OID_TO_NID.put( OBJ_setct_CapTokenData, Integer.valueOf( NID_setct_CapTokenData ) ); OID_TO_NID.put( OBJ_setct_CapTokenTBS, Integer.valueOf( NID_setct_CapTokenTBS ) ); OID_TO_NID.put( OBJ_setct_AcqCardCodeMsg, Integer.valueOf( NID_setct_AcqCardCodeMsg ) ); OID_TO_NID.put( OBJ_setct_AuthRevReqTBS, Integer.valueOf( NID_setct_AuthRevReqTBS ) ); OID_TO_NID.put( OBJ_setct_AuthRevResData, Integer.valueOf( NID_setct_AuthRevResData ) ); OID_TO_NID.put( OBJ_setct_AuthRevResTBS, Integer.valueOf( NID_setct_AuthRevResTBS ) ); OID_TO_NID.put( OBJ_setct_CapReqTBS, Integer.valueOf( NID_setct_CapReqTBS ) ); OID_TO_NID.put( OBJ_setct_CapReqTBSX, Integer.valueOf( NID_setct_CapReqTBSX ) ); OID_TO_NID.put( OBJ_setct_CapResData, Integer.valueOf( NID_setct_CapResData ) ); OID_TO_NID.put( OBJ_setct_CapRevReqTBS, Integer.valueOf( NID_setct_CapRevReqTBS ) ); OID_TO_NID.put( OBJ_setct_CapRevReqTBSX, Integer.valueOf( NID_setct_CapRevReqTBSX ) ); OID_TO_NID.put( OBJ_setct_CapRevResData, Integer.valueOf( NID_setct_CapRevResData ) ); OID_TO_NID.put( OBJ_setct_CredReqTBS, Integer.valueOf( NID_setct_CredReqTBS ) ); OID_TO_NID.put( OBJ_setct_CredReqTBSX, Integer.valueOf( NID_setct_CredReqTBSX ) ); OID_TO_NID.put( OBJ_setct_CredResData, Integer.valueOf( NID_setct_CredResData ) ); OID_TO_NID.put( OBJ_setct_CredRevReqTBS, Integer.valueOf( NID_setct_CredRevReqTBS ) ); OID_TO_NID.put( OBJ_setct_CredRevReqTBSX, Integer.valueOf( NID_setct_CredRevReqTBSX ) ); OID_TO_NID.put( OBJ_setct_CredRevResData, Integer.valueOf( NID_setct_CredRevResData ) ); OID_TO_NID.put( OBJ_setct_PCertReqData, Integer.valueOf( NID_setct_PCertReqData ) ); OID_TO_NID.put( OBJ_setct_PCertResTBS, Integer.valueOf( NID_setct_PCertResTBS ) ); OID_TO_NID.put( OBJ_setct_BatchAdminReqData, Integer.valueOf( NID_setct_BatchAdminReqData ) ); OID_TO_NID.put( OBJ_setct_BatchAdminResData, Integer.valueOf( NID_setct_BatchAdminResData ) ); OID_TO_NID.put( OBJ_setct_CardCInitResTBS, Integer.valueOf( NID_setct_CardCInitResTBS ) ); OID_TO_NID.put( OBJ_setct_MeAqCInitResTBS, Integer.valueOf( NID_setct_MeAqCInitResTBS ) ); OID_TO_NID.put( OBJ_setct_RegFormResTBS, Integer.valueOf( NID_setct_RegFormResTBS ) ); OID_TO_NID.put( OBJ_setct_CertReqData, Integer.valueOf( NID_setct_CertReqData ) ); OID_TO_NID.put( OBJ_setct_CertReqTBS, Integer.valueOf( NID_setct_CertReqTBS ) ); OID_TO_NID.put( OBJ_setct_CertResData, Integer.valueOf( NID_setct_CertResData ) ); OID_TO_NID.put( OBJ_setct_CertInqReqTBS, Integer.valueOf( NID_setct_CertInqReqTBS ) ); OID_TO_NID.put( OBJ_setct_ErrorTBS, Integer.valueOf( NID_setct_ErrorTBS ) ); OID_TO_NID.put( OBJ_setct_PIDualSignedTBE, Integer.valueOf( NID_setct_PIDualSignedTBE ) ); OID_TO_NID.put( OBJ_setct_PIUnsignedTBE, Integer.valueOf( NID_setct_PIUnsignedTBE ) ); OID_TO_NID.put( OBJ_setct_AuthReqTBE, Integer.valueOf( NID_setct_AuthReqTBE ) ); OID_TO_NID.put( OBJ_setct_AuthResTBE, Integer.valueOf( NID_setct_AuthResTBE ) ); OID_TO_NID.put( OBJ_setct_AuthResTBEX, Integer.valueOf( NID_setct_AuthResTBEX ) ); OID_TO_NID.put( OBJ_setct_AuthTokenTBE, Integer.valueOf( NID_setct_AuthTokenTBE ) ); OID_TO_NID.put( OBJ_setct_CapTokenTBE, Integer.valueOf( NID_setct_CapTokenTBE ) ); OID_TO_NID.put( OBJ_setct_CapTokenTBEX, Integer.valueOf( NID_setct_CapTokenTBEX ) ); OID_TO_NID.put( OBJ_setct_AcqCardCodeMsgTBE, Integer.valueOf( NID_setct_AcqCardCodeMsgTBE ) ); OID_TO_NID.put( OBJ_setct_AuthRevReqTBE, Integer.valueOf( NID_setct_AuthRevReqTBE ) ); OID_TO_NID.put( OBJ_setct_AuthRevResTBE, Integer.valueOf( NID_setct_AuthRevResTBE ) ); OID_TO_NID.put( OBJ_setct_AuthRevResTBEB, Integer.valueOf( NID_setct_AuthRevResTBEB ) ); OID_TO_NID.put( OBJ_setct_CapReqTBE, Integer.valueOf( NID_setct_CapReqTBE ) ); OID_TO_NID.put( OBJ_setct_CapReqTBEX, Integer.valueOf( NID_setct_CapReqTBEX ) ); OID_TO_NID.put( OBJ_setct_CapResTBE, Integer.valueOf( NID_setct_CapResTBE ) ); OID_TO_NID.put( OBJ_setct_CapRevReqTBE, Integer.valueOf( NID_setct_CapRevReqTBE ) ); OID_TO_NID.put( OBJ_setct_CapRevReqTBEX, Integer.valueOf( NID_setct_CapRevReqTBEX ) ); OID_TO_NID.put( OBJ_setct_CapRevResTBE, Integer.valueOf( NID_setct_CapRevResTBE ) ); OID_TO_NID.put( OBJ_setct_CredReqTBE, Integer.valueOf( NID_setct_CredReqTBE ) ); OID_TO_NID.put( OBJ_setct_CredReqTBEX, Integer.valueOf( NID_setct_CredReqTBEX ) ); OID_TO_NID.put( OBJ_setct_CredResTBE, Integer.valueOf( NID_setct_CredResTBE ) ); OID_TO_NID.put( OBJ_setct_CredRevReqTBE, Integer.valueOf( NID_setct_CredRevReqTBE ) ); OID_TO_NID.put( OBJ_setct_CredRevReqTBEX, Integer.valueOf( NID_setct_CredRevReqTBEX ) ); OID_TO_NID.put( OBJ_setct_CredRevResTBE, Integer.valueOf( NID_setct_CredRevResTBE ) ); OID_TO_NID.put( OBJ_setct_BatchAdminReqTBE, Integer.valueOf( NID_setct_BatchAdminReqTBE ) ); OID_TO_NID.put( OBJ_setct_BatchAdminResTBE, Integer.valueOf( NID_setct_BatchAdminResTBE ) ); OID_TO_NID.put( OBJ_setct_RegFormReqTBE, Integer.valueOf( NID_setct_RegFormReqTBE ) ); OID_TO_NID.put( OBJ_setct_CertReqTBE, Integer.valueOf( NID_setct_CertReqTBE ) ); OID_TO_NID.put( OBJ_setct_CertReqTBEX, Integer.valueOf( NID_setct_CertReqTBEX ) ); OID_TO_NID.put( OBJ_setct_CertResTBE, Integer.valueOf( NID_setct_CertResTBE ) ); OID_TO_NID.put( OBJ_setct_CRLNotificationTBS, Integer.valueOf( NID_setct_CRLNotificationTBS ) ); OID_TO_NID.put( OBJ_setct_CRLNotificationResTBS, Integer.valueOf( NID_setct_CRLNotificationResTBS ) ); OID_TO_NID.put( OBJ_setct_BCIDistributionTBS, Integer.valueOf( NID_setct_BCIDistributionTBS ) ); OID_TO_NID.put( OBJ_setext_genCrypt, Integer.valueOf( NID_setext_genCrypt ) ); OID_TO_NID.put( OBJ_setext_miAuth, Integer.valueOf( NID_setext_miAuth ) ); OID_TO_NID.put( OBJ_setext_pinSecure, Integer.valueOf( NID_setext_pinSecure ) ); OID_TO_NID.put( OBJ_setext_pinAny, Integer.valueOf( NID_setext_pinAny ) ); OID_TO_NID.put( OBJ_setext_track2, Integer.valueOf( NID_setext_track2 ) ); OID_TO_NID.put( OBJ_setext_cv, Integer.valueOf( NID_setext_cv ) ); OID_TO_NID.put( OBJ_set_policy_root, Integer.valueOf( NID_set_policy_root ) ); OID_TO_NID.put( OBJ_setCext_hashedRoot, Integer.valueOf( NID_setCext_hashedRoot ) ); OID_TO_NID.put( OBJ_setCext_certType, Integer.valueOf( NID_setCext_certType ) ); OID_TO_NID.put( OBJ_setCext_merchData, Integer.valueOf( NID_setCext_merchData ) ); OID_TO_NID.put( OBJ_setCext_cCertRequired, Integer.valueOf( NID_setCext_cCertRequired ) ); OID_TO_NID.put( OBJ_setCext_tunneling, Integer.valueOf( NID_setCext_tunneling ) ); OID_TO_NID.put( OBJ_setCext_setExt, Integer.valueOf( NID_setCext_setExt ) ); OID_TO_NID.put( OBJ_setCext_setQualf, Integer.valueOf( NID_setCext_setQualf ) ); OID_TO_NID.put( OBJ_setCext_PGWYcapabilities, Integer.valueOf( NID_setCext_PGWYcapabilities ) ); OID_TO_NID.put( OBJ_setCext_TokenIdentifier, Integer.valueOf( NID_setCext_TokenIdentifier ) ); OID_TO_NID.put( OBJ_setCext_Track2Data, Integer.valueOf( NID_setCext_Track2Data ) ); OID_TO_NID.put( OBJ_setCext_TokenType, Integer.valueOf( NID_setCext_TokenType ) ); OID_TO_NID.put( OBJ_setCext_IssuerCapabilities, Integer.valueOf( NID_setCext_IssuerCapabilities ) ); OID_TO_NID.put( OBJ_setAttr_Cert, Integer.valueOf( NID_setAttr_Cert ) ); OID_TO_NID.put( OBJ_setAttr_PGWYcap, Integer.valueOf( NID_setAttr_PGWYcap ) ); OID_TO_NID.put( OBJ_setAttr_TokenType, Integer.valueOf( NID_setAttr_TokenType ) ); OID_TO_NID.put( OBJ_setAttr_IssCap, Integer.valueOf( NID_setAttr_IssCap ) ); OID_TO_NID.put( OBJ_set_rootKeyThumb, Integer.valueOf( NID_set_rootKeyThumb ) ); OID_TO_NID.put( OBJ_set_addPolicy, Integer.valueOf( NID_set_addPolicy ) ); OID_TO_NID.put( OBJ_setAttr_Token_EMV, Integer.valueOf( NID_setAttr_Token_EMV ) ); OID_TO_NID.put( OBJ_setAttr_Token_B0Prime, Integer.valueOf( NID_setAttr_Token_B0Prime ) ); OID_TO_NID.put( OBJ_setAttr_IssCap_CVM, Integer.valueOf( NID_setAttr_IssCap_CVM ) ); OID_TO_NID.put( OBJ_setAttr_IssCap_T2, Integer.valueOf( NID_setAttr_IssCap_T2 ) ); OID_TO_NID.put( OBJ_setAttr_IssCap_Sig, Integer.valueOf( NID_setAttr_IssCap_Sig ) ); OID_TO_NID.put( OBJ_setAttr_GenCryptgrm, Integer.valueOf( NID_setAttr_GenCryptgrm ) ); OID_TO_NID.put( OBJ_setAttr_T2Enc, Integer.valueOf( NID_setAttr_T2Enc ) ); OID_TO_NID.put( OBJ_setAttr_T2cleartxt, Integer.valueOf( NID_setAttr_T2cleartxt ) ); OID_TO_NID.put( OBJ_setAttr_TokICCsig, Integer.valueOf( NID_setAttr_TokICCsig ) ); OID_TO_NID.put( OBJ_setAttr_SecDevSig, Integer.valueOf( NID_setAttr_SecDevSig ) ); OID_TO_NID.put( OBJ_set_brand_IATA_ATA, Integer.valueOf( NID_set_brand_IATA_ATA ) ); OID_TO_NID.put( OBJ_set_brand_Diners, Integer.valueOf( NID_set_brand_Diners ) ); OID_TO_NID.put( OBJ_set_brand_AmericanExpress, Integer.valueOf( NID_set_brand_AmericanExpress ) ); OID_TO_NID.put( OBJ_set_brand_JCB, Integer.valueOf( NID_set_brand_JCB ) ); OID_TO_NID.put( OBJ_set_brand_Visa, Integer.valueOf( NID_set_brand_Visa ) ); OID_TO_NID.put( OBJ_set_brand_MasterCard, Integer.valueOf( NID_set_brand_MasterCard ) ); OID_TO_NID.put( OBJ_set_brand_Novus, Integer.valueOf( NID_set_brand_Novus ) ); OID_TO_NID.put( OBJ_des_cdmf, Integer.valueOf( NID_des_cdmf ) ); OID_TO_NID.put( OBJ_rsaOAEPEncryptionSET, Integer.valueOf( NID_rsaOAEPEncryptionSET ) ); OID_TO_NID.put( OBJ_whirlpool, Integer.valueOf( NID_whirlpool ) ); OID_TO_NID.put( OBJ_cryptopro, Integer.valueOf( NID_cryptopro ) ); OID_TO_NID.put( OBJ_cryptocom, Integer.valueOf( NID_cryptocom ) ); OID_TO_NID.put( OBJ_id_GostR3411_94_with_GostR3410_2001, Integer.valueOf( NID_id_GostR3411_94_with_GostR3410_2001 ) ); OID_TO_NID.put( OBJ_id_GostR3411_94_with_GostR3410_94, Integer.valueOf( NID_id_GostR3411_94_with_GostR3410_94 ) ); OID_TO_NID.put( OBJ_id_GostR3411_94, Integer.valueOf( NID_id_GostR3411_94 ) ); OID_TO_NID.put( OBJ_id_HMACGostR3411_94, Integer.valueOf( NID_id_HMACGostR3411_94 ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001, Integer.valueOf( NID_id_GostR3410_2001 ) ); OID_TO_NID.put( OBJ_id_GostR3410_94, Integer.valueOf( NID_id_GostR3410_94 ) ); OID_TO_NID.put( OBJ_id_Gost28147_89, Integer.valueOf( NID_id_Gost28147_89 ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_MAC, Integer.valueOf( NID_id_Gost28147_89_MAC ) ); OID_TO_NID.put( OBJ_id_GostR3411_94_prf, Integer.valueOf( NID_id_GostR3411_94_prf ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001DH, Integer.valueOf( NID_id_GostR3410_2001DH ) ); OID_TO_NID.put( OBJ_id_GostR3410_94DH, Integer.valueOf( NID_id_GostR3410_94DH ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_CryptoPro_KeyMeshing, Integer.valueOf( NID_id_Gost28147_89_CryptoPro_KeyMeshing ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_None_KeyMeshing, Integer.valueOf( NID_id_Gost28147_89_None_KeyMeshing ) ); OID_TO_NID.put( OBJ_id_GostR3411_94_TestParamSet, Integer.valueOf( NID_id_GostR3411_94_TestParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3411_94_CryptoProParamSet, Integer.valueOf( NID_id_GostR3411_94_CryptoProParamSet ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_TestParamSet, Integer.valueOf( NID_id_Gost28147_89_TestParamSet ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_CryptoPro_A_ParamSet, Integer.valueOf( NID_id_Gost28147_89_CryptoPro_A_ParamSet ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_CryptoPro_B_ParamSet, Integer.valueOf( NID_id_Gost28147_89_CryptoPro_B_ParamSet ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_CryptoPro_C_ParamSet, Integer.valueOf( NID_id_Gost28147_89_CryptoPro_C_ParamSet ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_CryptoPro_D_ParamSet, Integer.valueOf( NID_id_Gost28147_89_CryptoPro_D_ParamSet ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet, Integer.valueOf( NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet, Integer.valueOf( NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet, Integer.valueOf( NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_TestParamSet, Integer.valueOf( NID_id_GostR3410_94_TestParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_CryptoPro_A_ParamSet, Integer.valueOf( NID_id_GostR3410_94_CryptoPro_A_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_CryptoPro_B_ParamSet, Integer.valueOf( NID_id_GostR3410_94_CryptoPro_B_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_CryptoPro_C_ParamSet, Integer.valueOf( NID_id_GostR3410_94_CryptoPro_C_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_CryptoPro_D_ParamSet, Integer.valueOf( NID_id_GostR3410_94_CryptoPro_D_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet, Integer.valueOf( NID_id_GostR3410_94_CryptoPro_XchA_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet, Integer.valueOf( NID_id_GostR3410_94_CryptoPro_XchB_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet, Integer.valueOf( NID_id_GostR3410_94_CryptoPro_XchC_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001_TestParamSet, Integer.valueOf( NID_id_GostR3410_2001_TestParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet, Integer.valueOf( NID_id_GostR3410_2001_CryptoPro_A_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet, Integer.valueOf( NID_id_GostR3410_2001_CryptoPro_B_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet, Integer.valueOf( NID_id_GostR3410_2001_CryptoPro_C_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet, Integer.valueOf( NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet, Integer.valueOf( NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_a, Integer.valueOf( NID_id_GostR3410_94_a ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_aBis, Integer.valueOf( NID_id_GostR3410_94_aBis ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_b, Integer.valueOf( NID_id_GostR3410_94_b ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_bBis, Integer.valueOf( NID_id_GostR3410_94_bBis ) ); OID_TO_NID.put( OBJ_id_Gost28147_89_cc, Integer.valueOf( NID_id_Gost28147_89_cc ) ); OID_TO_NID.put( OBJ_id_GostR3410_94_cc, Integer.valueOf( NID_id_GostR3410_94_cc ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001_cc, Integer.valueOf( NID_id_GostR3410_2001_cc ) ); OID_TO_NID.put( OBJ_id_GostR3411_94_with_GostR3410_94_cc, Integer.valueOf( NID_id_GostR3411_94_with_GostR3410_94_cc ) ); OID_TO_NID.put( OBJ_id_GostR3411_94_with_GostR3410_2001_cc, Integer.valueOf( NID_id_GostR3411_94_with_GostR3410_2001_cc ) ); OID_TO_NID.put( OBJ_id_GostR3410_2001_ParamSet_cc, Integer.valueOf( NID_id_GostR3410_2001_ParamSet_cc ) ); OID_TO_NID.put( OBJ_camellia_128_cbc, Integer.valueOf( NID_camellia_128_cbc ) ); OID_TO_NID.put( OBJ_camellia_192_cbc, Integer.valueOf( NID_camellia_192_cbc ) ); OID_TO_NID.put( OBJ_camellia_256_cbc, Integer.valueOf( NID_camellia_256_cbc ) ); OID_TO_NID.put( OBJ_id_camellia128_wrap, Integer.valueOf( NID_id_camellia128_wrap ) ); OID_TO_NID.put( OBJ_id_camellia192_wrap, Integer.valueOf( NID_id_camellia192_wrap ) ); OID_TO_NID.put( OBJ_id_camellia256_wrap, Integer.valueOf( NID_id_camellia256_wrap ) ); OID_TO_NID.put( OBJ_camellia_128_ecb, Integer.valueOf( NID_camellia_128_ecb ) ); OID_TO_NID.put( OBJ_camellia_128_ofb128, Integer.valueOf( NID_camellia_128_ofb128 ) ); OID_TO_NID.put( OBJ_camellia_128_cfb128, Integer.valueOf( NID_camellia_128_cfb128 ) ); OID_TO_NID.put( OBJ_camellia_192_ecb, Integer.valueOf( NID_camellia_192_ecb ) ); OID_TO_NID.put( OBJ_camellia_192_ofb128, Integer.valueOf( NID_camellia_192_ofb128 ) ); OID_TO_NID.put( OBJ_camellia_192_cfb128, Integer.valueOf( NID_camellia_192_cfb128 ) ); OID_TO_NID.put( OBJ_camellia_256_ecb, Integer.valueOf( NID_camellia_256_ecb ) ); OID_TO_NID.put( OBJ_camellia_256_ofb128, Integer.valueOf( NID_camellia_256_ofb128 ) ); OID_TO_NID.put( OBJ_camellia_256_cfb128, Integer.valueOf( NID_camellia_256_cfb128 ) ); OID_TO_NID.put( OBJ_kisa, Integer.valueOf( NID_kisa ) ); OID_TO_NID.put( OBJ_seed_ecb, Integer.valueOf( NID_seed_ecb ) ); OID_TO_NID.put( OBJ_seed_cbc, Integer.valueOf( NID_seed_cbc ) ); OID_TO_NID.put( OBJ_seed_cfb128, Integer.valueOf( NID_seed_cfb128 ) ); OID_TO_NID.put( OBJ_seed_ofb128, Integer.valueOf( NID_seed_ofb128 ) ); OID_TO_NID.put( OBJ_dhpublicnumber, Integer.valueOf( NID_dhpublicnumber ) ); OID_TO_NID.put( OBJ_brainpoolP160r1, Integer.valueOf( NID_brainpoolP160r1 ) ); OID_TO_NID.put( OBJ_brainpoolP160t1, Integer.valueOf( NID_brainpoolP160t1 ) ); OID_TO_NID.put( OBJ_brainpoolP192r1, Integer.valueOf( NID_brainpoolP192r1 ) ); OID_TO_NID.put( OBJ_brainpoolP192t1, Integer.valueOf( NID_brainpoolP192t1 ) ); OID_TO_NID.put( OBJ_brainpoolP224r1, Integer.valueOf( NID_brainpoolP224r1 ) ); OID_TO_NID.put( OBJ_brainpoolP224t1, Integer.valueOf( NID_brainpoolP224t1 ) ); OID_TO_NID.put( OBJ_brainpoolP256r1, Integer.valueOf( NID_brainpoolP256r1 ) ); OID_TO_NID.put( OBJ_brainpoolP256t1, Integer.valueOf( NID_brainpoolP256t1 ) ); OID_TO_NID.put( OBJ_brainpoolP320r1, Integer.valueOf( NID_brainpoolP320r1 ) ); OID_TO_NID.put( OBJ_brainpoolP320t1, Integer.valueOf( NID_brainpoolP320t1 ) ); OID_TO_NID.put( OBJ_brainpoolP384r1, Integer.valueOf( NID_brainpoolP384r1 ) ); OID_TO_NID.put( OBJ_brainpoolP384t1, Integer.valueOf( NID_brainpoolP384t1 ) ); OID_TO_NID.put( OBJ_brainpoolP512r1, Integer.valueOf( NID_brainpoolP512r1 ) ); OID_TO_NID.put( OBJ_brainpoolP512t1, Integer.valueOf( NID_brainpoolP512t1 ) ); OID_TO_NID.put( OBJ_dhSinglePass_stdDH_sha1kdf_scheme, Integer.valueOf( NID_dhSinglePass_stdDH_sha1kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_stdDH_sha224kdf_scheme, Integer.valueOf( NID_dhSinglePass_stdDH_sha224kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_stdDH_sha256kdf_scheme, Integer.valueOf( NID_dhSinglePass_stdDH_sha256kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_stdDH_sha384kdf_scheme, Integer.valueOf( NID_dhSinglePass_stdDH_sha384kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_stdDH_sha512kdf_scheme, Integer.valueOf( NID_dhSinglePass_stdDH_sha512kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme, Integer.valueOf( NID_dhSinglePass_cofactorDH_sha1kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme, Integer.valueOf( NID_dhSinglePass_cofactorDH_sha224kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme, Integer.valueOf( NID_dhSinglePass_cofactorDH_sha256kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme, Integer.valueOf( NID_dhSinglePass_cofactorDH_sha384kdf_scheme ) ); OID_TO_NID.put( OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme, Integer.valueOf( NID_dhSinglePass_cofactorDH_sha512kdf_scheme ) ); OID_TO_NID.put( OBJ_ct_precert_scts, Integer.valueOf( NID_ct_precert_scts ) ); OID_TO_NID.put( OBJ_ct_precert_poison, Integer.valueOf( NID_ct_precert_poison ) ); OID_TO_NID.put( OBJ_ct_precert_signer, Integer.valueOf( NID_ct_precert_signer ) ); OID_TO_NID.put( OBJ_ct_cert_scts, Integer.valueOf( NID_ct_cert_scts ) ); OID_TO_NID.put( OBJ_jurisdictionLocalityName, Integer.valueOf( NID_jurisdictionLocalityName ) ); OID_TO_NID.put( OBJ_jurisdictionStateOrProvinceName, Integer.valueOf( NID_jurisdictionStateOrProvinceName ) ); OID_TO_NID.put( OBJ_jurisdictionCountryName, Integer.valueOf( NID_jurisdictionCountryName ) ); } private static final String[] NID_TO_SN = new String[ 958 ]; static { NID_TO_SN[ NID_undef ] = SN_undef; NID_TO_SN[ NID_itu_t ] = SN_itu_t; NID_TO_SN[ NID_iso ] = SN_iso; NID_TO_SN[ NID_joint_iso_itu_t ] = SN_joint_iso_itu_t; NID_TO_SN[ NID_member_body ] = SN_member_body; NID_TO_SN[ NID_identified_organization ] = SN_identified_organization; NID_TO_SN[ NID_hmac_md5 ] = SN_hmac_md5; NID_TO_SN[ NID_hmac_sha1 ] = SN_hmac_sha1; NID_TO_SN[ NID_certicom_arc ] = SN_certicom_arc; NID_TO_SN[ NID_international_organizations ] = SN_international_organizations; NID_TO_SN[ NID_wap ] = SN_wap; NID_TO_SN[ NID_wap_wsg ] = SN_wap_wsg; NID_TO_SN[ NID_selected_attribute_types ] = SN_selected_attribute_types; NID_TO_SN[ NID_clearance ] = SN_clearance; NID_TO_SN[ NID_ISO_US ] = SN_ISO_US; NID_TO_SN[ NID_X9_57 ] = SN_X9_57; NID_TO_SN[ NID_X9cm ] = SN_X9cm; NID_TO_SN[ NID_dsa ] = SN_dsa; NID_TO_SN[ NID_dsaWithSHA1 ] = SN_dsaWithSHA1; NID_TO_SN[ NID_ansi_X9_62 ] = SN_ansi_X9_62; NID_TO_SN[ NID_X9_62_prime_field ] = SN_X9_62_prime_field; NID_TO_SN[ NID_X9_62_characteristic_two_field ] = SN_X9_62_characteristic_two_field; NID_TO_SN[ NID_X9_62_id_characteristic_two_basis ] = SN_X9_62_id_characteristic_two_basis; NID_TO_SN[ NID_X9_62_onBasis ] = SN_X9_62_onBasis; NID_TO_SN[ NID_X9_62_tpBasis ] = SN_X9_62_tpBasis; NID_TO_SN[ NID_X9_62_ppBasis ] = SN_X9_62_ppBasis; NID_TO_SN[ NID_X9_62_id_ecPublicKey ] = SN_X9_62_id_ecPublicKey; NID_TO_SN[ NID_X9_62_c2pnb163v1 ] = SN_X9_62_c2pnb163v1; NID_TO_SN[ NID_X9_62_c2pnb163v2 ] = SN_X9_62_c2pnb163v2; NID_TO_SN[ NID_X9_62_c2pnb163v3 ] = SN_X9_62_c2pnb163v3; NID_TO_SN[ NID_X9_62_c2pnb176v1 ] = SN_X9_62_c2pnb176v1; NID_TO_SN[ NID_X9_62_c2tnb191v1 ] = SN_X9_62_c2tnb191v1; NID_TO_SN[ NID_X9_62_c2tnb191v2 ] = SN_X9_62_c2tnb191v2; NID_TO_SN[ NID_X9_62_c2tnb191v3 ] = SN_X9_62_c2tnb191v3; NID_TO_SN[ NID_X9_62_c2onb191v4 ] = SN_X9_62_c2onb191v4; NID_TO_SN[ NID_X9_62_c2onb191v5 ] = SN_X9_62_c2onb191v5; NID_TO_SN[ NID_X9_62_c2pnb208w1 ] = SN_X9_62_c2pnb208w1; NID_TO_SN[ NID_X9_62_c2tnb239v1 ] = SN_X9_62_c2tnb239v1; NID_TO_SN[ NID_X9_62_c2tnb239v2 ] = SN_X9_62_c2tnb239v2; NID_TO_SN[ NID_X9_62_c2tnb239v3 ] = SN_X9_62_c2tnb239v3; NID_TO_SN[ NID_X9_62_c2onb239v4 ] = SN_X9_62_c2onb239v4; NID_TO_SN[ NID_X9_62_c2onb239v5 ] = SN_X9_62_c2onb239v5; NID_TO_SN[ NID_X9_62_c2pnb272w1 ] = SN_X9_62_c2pnb272w1; NID_TO_SN[ NID_X9_62_c2pnb304w1 ] = SN_X9_62_c2pnb304w1; NID_TO_SN[ NID_X9_62_c2tnb359v1 ] = SN_X9_62_c2tnb359v1; NID_TO_SN[ NID_X9_62_c2pnb368w1 ] = SN_X9_62_c2pnb368w1; NID_TO_SN[ NID_X9_62_c2tnb431r1 ] = SN_X9_62_c2tnb431r1; NID_TO_SN[ NID_X9_62_prime192v1 ] = SN_X9_62_prime192v1; NID_TO_SN[ NID_X9_62_prime192v2 ] = SN_X9_62_prime192v2; NID_TO_SN[ NID_X9_62_prime192v3 ] = SN_X9_62_prime192v3; NID_TO_SN[ NID_X9_62_prime239v1 ] = SN_X9_62_prime239v1; NID_TO_SN[ NID_X9_62_prime239v2 ] = SN_X9_62_prime239v2; NID_TO_SN[ NID_X9_62_prime239v3 ] = SN_X9_62_prime239v3; NID_TO_SN[ NID_X9_62_prime256v1 ] = SN_X9_62_prime256v1; NID_TO_SN[ NID_ecdsa_with_SHA1 ] = SN_ecdsa_with_SHA1; NID_TO_SN[ NID_ecdsa_with_Recommended ] = SN_ecdsa_with_Recommended; NID_TO_SN[ NID_ecdsa_with_Specified ] = SN_ecdsa_with_Specified; NID_TO_SN[ NID_ecdsa_with_SHA224 ] = SN_ecdsa_with_SHA224; NID_TO_SN[ NID_ecdsa_with_SHA256 ] = SN_ecdsa_with_SHA256; NID_TO_SN[ NID_ecdsa_with_SHA384 ] = SN_ecdsa_with_SHA384; NID_TO_SN[ NID_ecdsa_with_SHA512 ] = SN_ecdsa_with_SHA512; NID_TO_SN[ NID_secp112r1 ] = SN_secp112r1; NID_TO_SN[ NID_secp112r2 ] = SN_secp112r2; NID_TO_SN[ NID_secp128r1 ] = SN_secp128r1; NID_TO_SN[ NID_secp128r2 ] = SN_secp128r2; NID_TO_SN[ NID_secp160k1 ] = SN_secp160k1; NID_TO_SN[ NID_secp160r1 ] = SN_secp160r1; NID_TO_SN[ NID_secp160r2 ] = SN_secp160r2; NID_TO_SN[ NID_secp192k1 ] = SN_secp192k1; NID_TO_SN[ NID_secp224k1 ] = SN_secp224k1; NID_TO_SN[ NID_secp224r1 ] = SN_secp224r1; NID_TO_SN[ NID_secp256k1 ] = SN_secp256k1; NID_TO_SN[ NID_secp384r1 ] = SN_secp384r1; NID_TO_SN[ NID_secp521r1 ] = SN_secp521r1; NID_TO_SN[ NID_sect113r1 ] = SN_sect113r1; NID_TO_SN[ NID_sect113r2 ] = SN_sect113r2; NID_TO_SN[ NID_sect131r1 ] = SN_sect131r1; NID_TO_SN[ NID_sect131r2 ] = SN_sect131r2; NID_TO_SN[ NID_sect163k1 ] = SN_sect163k1; NID_TO_SN[ NID_sect163r1 ] = SN_sect163r1; NID_TO_SN[ NID_sect163r2 ] = SN_sect163r2; NID_TO_SN[ NID_sect193r1 ] = SN_sect193r1; NID_TO_SN[ NID_sect193r2 ] = SN_sect193r2; NID_TO_SN[ NID_sect233k1 ] = SN_sect233k1; NID_TO_SN[ NID_sect233r1 ] = SN_sect233r1; NID_TO_SN[ NID_sect239k1 ] = SN_sect239k1; NID_TO_SN[ NID_sect283k1 ] = SN_sect283k1; NID_TO_SN[ NID_sect283r1 ] = SN_sect283r1; NID_TO_SN[ NID_sect409k1 ] = SN_sect409k1; NID_TO_SN[ NID_sect409r1 ] = SN_sect409r1; NID_TO_SN[ NID_sect571k1 ] = SN_sect571k1; NID_TO_SN[ NID_sect571r1 ] = SN_sect571r1; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls1 ] = SN_wap_wsg_idm_ecid_wtls1; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls3 ] = SN_wap_wsg_idm_ecid_wtls3; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls4 ] = SN_wap_wsg_idm_ecid_wtls4; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls5 ] = SN_wap_wsg_idm_ecid_wtls5; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls6 ] = SN_wap_wsg_idm_ecid_wtls6; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls7 ] = SN_wap_wsg_idm_ecid_wtls7; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls8 ] = SN_wap_wsg_idm_ecid_wtls8; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls9 ] = SN_wap_wsg_idm_ecid_wtls9; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls10 ] = SN_wap_wsg_idm_ecid_wtls10; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls11 ] = SN_wap_wsg_idm_ecid_wtls11; NID_TO_SN[ NID_wap_wsg_idm_ecid_wtls12 ] = SN_wap_wsg_idm_ecid_wtls12; NID_TO_SN[ NID_cast5_cbc ] = SN_cast5_cbc; NID_TO_SN[ NID_cast5_ecb ] = SN_cast5_ecb; NID_TO_SN[ NID_cast5_cfb64 ] = SN_cast5_cfb64; NID_TO_SN[ NID_cast5_ofb64 ] = SN_cast5_ofb64; NID_TO_SN[ NID_id_PasswordBasedMAC ] = SN_id_PasswordBasedMAC; NID_TO_SN[ NID_id_DHBasedMac ] = SN_id_DHBasedMac; NID_TO_SN[ NID_rsadsi ] = SN_rsadsi; NID_TO_SN[ NID_pkcs ] = SN_pkcs; NID_TO_SN[ NID_pkcs1 ] = SN_pkcs1; NID_TO_SN[ NID_md2WithRSAEncryption ] = SN_md2WithRSAEncryption; NID_TO_SN[ NID_md4WithRSAEncryption ] = SN_md4WithRSAEncryption; NID_TO_SN[ NID_md5WithRSAEncryption ] = SN_md5WithRSAEncryption; NID_TO_SN[ NID_sha1WithRSAEncryption ] = SN_sha1WithRSAEncryption; NID_TO_SN[ NID_rsaesOaep ] = SN_rsaesOaep; NID_TO_SN[ NID_mgf1 ] = SN_mgf1; NID_TO_SN[ NID_pSpecified ] = SN_pSpecified; NID_TO_SN[ NID_rsassaPss ] = SN_rsassaPss; NID_TO_SN[ NID_sha256WithRSAEncryption ] = SN_sha256WithRSAEncryption; NID_TO_SN[ NID_sha384WithRSAEncryption ] = SN_sha384WithRSAEncryption; NID_TO_SN[ NID_sha512WithRSAEncryption ] = SN_sha512WithRSAEncryption; NID_TO_SN[ NID_sha224WithRSAEncryption ] = SN_sha224WithRSAEncryption; NID_TO_SN[ NID_pkcs3 ] = SN_pkcs3; NID_TO_SN[ NID_pkcs5 ] = SN_pkcs5; NID_TO_SN[ NID_pbeWithMD2AndDES_CBC ] = SN_pbeWithMD2AndDES_CBC; NID_TO_SN[ NID_pbeWithMD5AndDES_CBC ] = SN_pbeWithMD5AndDES_CBC; NID_TO_SN[ NID_pbeWithMD2AndRC2_CBC ] = SN_pbeWithMD2AndRC2_CBC; NID_TO_SN[ NID_pbeWithMD5AndRC2_CBC ] = SN_pbeWithMD5AndRC2_CBC; NID_TO_SN[ NID_pbeWithSHA1AndDES_CBC ] = SN_pbeWithSHA1AndDES_CBC; NID_TO_SN[ NID_pbeWithSHA1AndRC2_CBC ] = SN_pbeWithSHA1AndRC2_CBC; NID_TO_SN[ NID_pkcs7 ] = SN_pkcs7; NID_TO_SN[ NID_pkcs9 ] = SN_pkcs9; NID_TO_SN[ NID_ext_req ] = SN_ext_req; NID_TO_SN[ NID_SMIMECapabilities ] = SN_SMIMECapabilities; NID_TO_SN[ NID_SMIME ] = SN_SMIME; NID_TO_SN[ NID_id_smime_mod ] = SN_id_smime_mod; NID_TO_SN[ NID_id_smime_ct ] = SN_id_smime_ct; NID_TO_SN[ NID_id_smime_aa ] = SN_id_smime_aa; NID_TO_SN[ NID_id_smime_alg ] = SN_id_smime_alg; NID_TO_SN[ NID_id_smime_cd ] = SN_id_smime_cd; NID_TO_SN[ NID_id_smime_spq ] = SN_id_smime_spq; NID_TO_SN[ NID_id_smime_cti ] = SN_id_smime_cti; NID_TO_SN[ NID_id_smime_mod_cms ] = SN_id_smime_mod_cms; NID_TO_SN[ NID_id_smime_mod_ess ] = SN_id_smime_mod_ess; NID_TO_SN[ NID_id_smime_mod_oid ] = SN_id_smime_mod_oid; NID_TO_SN[ NID_id_smime_mod_msg_v3 ] = SN_id_smime_mod_msg_v3; NID_TO_SN[ NID_id_smime_mod_ets_eSignature_88 ] = SN_id_smime_mod_ets_eSignature_88; NID_TO_SN[ NID_id_smime_mod_ets_eSignature_97 ] = SN_id_smime_mod_ets_eSignature_97; NID_TO_SN[ NID_id_smime_mod_ets_eSigPolicy_88 ] = SN_id_smime_mod_ets_eSigPolicy_88; NID_TO_SN[ NID_id_smime_mod_ets_eSigPolicy_97 ] = SN_id_smime_mod_ets_eSigPolicy_97; NID_TO_SN[ NID_id_smime_ct_receipt ] = SN_id_smime_ct_receipt; NID_TO_SN[ NID_id_smime_ct_authData ] = SN_id_smime_ct_authData; NID_TO_SN[ NID_id_smime_ct_publishCert ] = SN_id_smime_ct_publishCert; NID_TO_SN[ NID_id_smime_ct_TSTInfo ] = SN_id_smime_ct_TSTInfo; NID_TO_SN[ NID_id_smime_ct_TDTInfo ] = SN_id_smime_ct_TDTInfo; NID_TO_SN[ NID_id_smime_ct_contentInfo ] = SN_id_smime_ct_contentInfo; NID_TO_SN[ NID_id_smime_ct_DVCSRequestData ] = SN_id_smime_ct_DVCSRequestData; NID_TO_SN[ NID_id_smime_ct_DVCSResponseData ] = SN_id_smime_ct_DVCSResponseData; NID_TO_SN[ NID_id_smime_ct_compressedData ] = SN_id_smime_ct_compressedData; NID_TO_SN[ NID_id_ct_asciiTextWithCRLF ] = SN_id_ct_asciiTextWithCRLF; NID_TO_SN[ NID_id_smime_aa_receiptRequest ] = SN_id_smime_aa_receiptRequest; NID_TO_SN[ NID_id_smime_aa_securityLabel ] = SN_id_smime_aa_securityLabel; NID_TO_SN[ NID_id_smime_aa_mlExpandHistory ] = SN_id_smime_aa_mlExpandHistory; NID_TO_SN[ NID_id_smime_aa_contentHint ] = SN_id_smime_aa_contentHint; NID_TO_SN[ NID_id_smime_aa_msgSigDigest ] = SN_id_smime_aa_msgSigDigest; NID_TO_SN[ NID_id_smime_aa_encapContentType ] = SN_id_smime_aa_encapContentType; NID_TO_SN[ NID_id_smime_aa_contentIdentifier ] = SN_id_smime_aa_contentIdentifier; NID_TO_SN[ NID_id_smime_aa_macValue ] = SN_id_smime_aa_macValue; NID_TO_SN[ NID_id_smime_aa_equivalentLabels ] = SN_id_smime_aa_equivalentLabels; NID_TO_SN[ NID_id_smime_aa_contentReference ] = SN_id_smime_aa_contentReference; NID_TO_SN[ NID_id_smime_aa_encrypKeyPref ] = SN_id_smime_aa_encrypKeyPref; NID_TO_SN[ NID_id_smime_aa_signingCertificate ] = SN_id_smime_aa_signingCertificate; NID_TO_SN[ NID_id_smime_aa_smimeEncryptCerts ] = SN_id_smime_aa_smimeEncryptCerts; NID_TO_SN[ NID_id_smime_aa_timeStampToken ] = SN_id_smime_aa_timeStampToken; NID_TO_SN[ NID_id_smime_aa_ets_sigPolicyId ] = SN_id_smime_aa_ets_sigPolicyId; NID_TO_SN[ NID_id_smime_aa_ets_commitmentType ] = SN_id_smime_aa_ets_commitmentType; NID_TO_SN[ NID_id_smime_aa_ets_signerLocation ] = SN_id_smime_aa_ets_signerLocation; NID_TO_SN[ NID_id_smime_aa_ets_signerAttr ] = SN_id_smime_aa_ets_signerAttr; NID_TO_SN[ NID_id_smime_aa_ets_otherSigCert ] = SN_id_smime_aa_ets_otherSigCert; NID_TO_SN[ NID_id_smime_aa_ets_contentTimestamp ] = SN_id_smime_aa_ets_contentTimestamp; NID_TO_SN[ NID_id_smime_aa_ets_CertificateRefs ] = SN_id_smime_aa_ets_CertificateRefs; NID_TO_SN[ NID_id_smime_aa_ets_RevocationRefs ] = SN_id_smime_aa_ets_RevocationRefs; NID_TO_SN[ NID_id_smime_aa_ets_certValues ] = SN_id_smime_aa_ets_certValues; NID_TO_SN[ NID_id_smime_aa_ets_revocationValues ] = SN_id_smime_aa_ets_revocationValues; NID_TO_SN[ NID_id_smime_aa_ets_escTimeStamp ] = SN_id_smime_aa_ets_escTimeStamp; NID_TO_SN[ NID_id_smime_aa_ets_certCRLTimestamp ] = SN_id_smime_aa_ets_certCRLTimestamp; NID_TO_SN[ NID_id_smime_aa_ets_archiveTimeStamp ] = SN_id_smime_aa_ets_archiveTimeStamp; NID_TO_SN[ NID_id_smime_aa_signatureType ] = SN_id_smime_aa_signatureType; NID_TO_SN[ NID_id_smime_aa_dvcs_dvc ] = SN_id_smime_aa_dvcs_dvc; NID_TO_SN[ NID_id_smime_alg_ESDHwith3DES ] = SN_id_smime_alg_ESDHwith3DES; NID_TO_SN[ NID_id_smime_alg_ESDHwithRC2 ] = SN_id_smime_alg_ESDHwithRC2; NID_TO_SN[ NID_id_smime_alg_3DESwrap ] = SN_id_smime_alg_3DESwrap; NID_TO_SN[ NID_id_smime_alg_RC2wrap ] = SN_id_smime_alg_RC2wrap; NID_TO_SN[ NID_id_smime_alg_ESDH ] = SN_id_smime_alg_ESDH; NID_TO_SN[ NID_id_smime_alg_CMS3DESwrap ] = SN_id_smime_alg_CMS3DESwrap; NID_TO_SN[ NID_id_smime_alg_CMSRC2wrap ] = SN_id_smime_alg_CMSRC2wrap; NID_TO_SN[ NID_id_alg_PWRI_KEK ] = SN_id_alg_PWRI_KEK; NID_TO_SN[ NID_id_smime_cd_ldap ] = SN_id_smime_cd_ldap; NID_TO_SN[ NID_id_smime_spq_ets_sqt_uri ] = SN_id_smime_spq_ets_sqt_uri; NID_TO_SN[ NID_id_smime_spq_ets_sqt_unotice ] = SN_id_smime_spq_ets_sqt_unotice; NID_TO_SN[ NID_id_smime_cti_ets_proofOfOrigin ] = SN_id_smime_cti_ets_proofOfOrigin; NID_TO_SN[ NID_id_smime_cti_ets_proofOfReceipt ] = SN_id_smime_cti_ets_proofOfReceipt; NID_TO_SN[ NID_id_smime_cti_ets_proofOfDelivery ] = SN_id_smime_cti_ets_proofOfDelivery; NID_TO_SN[ NID_id_smime_cti_ets_proofOfSender ] = SN_id_smime_cti_ets_proofOfSender; NID_TO_SN[ NID_id_smime_cti_ets_proofOfApproval ] = SN_id_smime_cti_ets_proofOfApproval; NID_TO_SN[ NID_id_smime_cti_ets_proofOfCreation ] = SN_id_smime_cti_ets_proofOfCreation; NID_TO_SN[ NID_ms_csp_name ] = SN_ms_csp_name; NID_TO_SN[ NID_LocalKeySet ] = SN_LocalKeySet; NID_TO_SN[ NID_pbe_WithSHA1And128BitRC4 ] = SN_pbe_WithSHA1And128BitRC4; NID_TO_SN[ NID_pbe_WithSHA1And40BitRC4 ] = SN_pbe_WithSHA1And40BitRC4; NID_TO_SN[ NID_pbe_WithSHA1And3_Key_TripleDES_CBC ] = SN_pbe_WithSHA1And3_Key_TripleDES_CBC; NID_TO_SN[ NID_pbe_WithSHA1And2_Key_TripleDES_CBC ] = SN_pbe_WithSHA1And2_Key_TripleDES_CBC; NID_TO_SN[ NID_pbe_WithSHA1And128BitRC2_CBC ] = SN_pbe_WithSHA1And128BitRC2_CBC; NID_TO_SN[ NID_pbe_WithSHA1And40BitRC2_CBC ] = SN_pbe_WithSHA1And40BitRC2_CBC; NID_TO_SN[ NID_md2 ] = SN_md2; NID_TO_SN[ NID_md4 ] = SN_md4; NID_TO_SN[ NID_md5 ] = SN_md5; NID_TO_SN[ NID_md5_sha1 ] = SN_md5_sha1; NID_TO_SN[ NID_rc2_cbc ] = SN_rc2_cbc; NID_TO_SN[ NID_rc2_ecb ] = SN_rc2_ecb; NID_TO_SN[ NID_rc2_cfb64 ] = SN_rc2_cfb64; NID_TO_SN[ NID_rc2_ofb64 ] = SN_rc2_ofb64; NID_TO_SN[ NID_rc2_40_cbc ] = SN_rc2_40_cbc; NID_TO_SN[ NID_rc2_64_cbc ] = SN_rc2_64_cbc; NID_TO_SN[ NID_rc4 ] = SN_rc4; NID_TO_SN[ NID_rc4_40 ] = SN_rc4_40; NID_TO_SN[ NID_des_ede3_cbc ] = SN_des_ede3_cbc; NID_TO_SN[ NID_rc5_cbc ] = SN_rc5_cbc; NID_TO_SN[ NID_rc5_ecb ] = SN_rc5_ecb; NID_TO_SN[ NID_rc5_cfb64 ] = SN_rc5_cfb64; NID_TO_SN[ NID_rc5_ofb64 ] = SN_rc5_ofb64; NID_TO_SN[ NID_ms_ext_req ] = SN_ms_ext_req; NID_TO_SN[ NID_ms_code_ind ] = SN_ms_code_ind; NID_TO_SN[ NID_ms_code_com ] = SN_ms_code_com; NID_TO_SN[ NID_ms_ctl_sign ] = SN_ms_ctl_sign; NID_TO_SN[ NID_ms_sgc ] = SN_ms_sgc; NID_TO_SN[ NID_ms_efs ] = SN_ms_efs; NID_TO_SN[ NID_ms_smartcard_login ] = SN_ms_smartcard_login; NID_TO_SN[ NID_ms_upn ] = SN_ms_upn; NID_TO_SN[ NID_idea_cbc ] = SN_idea_cbc; NID_TO_SN[ NID_idea_ecb ] = SN_idea_ecb; NID_TO_SN[ NID_idea_cfb64 ] = SN_idea_cfb64; NID_TO_SN[ NID_idea_ofb64 ] = SN_idea_ofb64; NID_TO_SN[ NID_bf_cbc ] = SN_bf_cbc; NID_TO_SN[ NID_bf_ecb ] = SN_bf_ecb; NID_TO_SN[ NID_bf_cfb64 ] = SN_bf_cfb64; NID_TO_SN[ NID_bf_ofb64 ] = SN_bf_ofb64; NID_TO_SN[ NID_id_pkix ] = SN_id_pkix; NID_TO_SN[ NID_id_pkix_mod ] = SN_id_pkix_mod; NID_TO_SN[ NID_id_pe ] = SN_id_pe; NID_TO_SN[ NID_id_qt ] = SN_id_qt; NID_TO_SN[ NID_id_kp ] = SN_id_kp; NID_TO_SN[ NID_id_it ] = SN_id_it; NID_TO_SN[ NID_id_pkip ] = SN_id_pkip; NID_TO_SN[ NID_id_alg ] = SN_id_alg; NID_TO_SN[ NID_id_cmc ] = SN_id_cmc; NID_TO_SN[ NID_id_on ] = SN_id_on; NID_TO_SN[ NID_id_pda ] = SN_id_pda; NID_TO_SN[ NID_id_aca ] = SN_id_aca; NID_TO_SN[ NID_id_qcs ] = SN_id_qcs; NID_TO_SN[ NID_id_cct ] = SN_id_cct; NID_TO_SN[ NID_id_ppl ] = SN_id_ppl; NID_TO_SN[ NID_id_ad ] = SN_id_ad; NID_TO_SN[ NID_id_pkix1_explicit_88 ] = SN_id_pkix1_explicit_88; NID_TO_SN[ NID_id_pkix1_implicit_88 ] = SN_id_pkix1_implicit_88; NID_TO_SN[ NID_id_pkix1_explicit_93 ] = SN_id_pkix1_explicit_93; NID_TO_SN[ NID_id_pkix1_implicit_93 ] = SN_id_pkix1_implicit_93; NID_TO_SN[ NID_id_mod_crmf ] = SN_id_mod_crmf; NID_TO_SN[ NID_id_mod_cmc ] = SN_id_mod_cmc; NID_TO_SN[ NID_id_mod_kea_profile_88 ] = SN_id_mod_kea_profile_88; NID_TO_SN[ NID_id_mod_kea_profile_93 ] = SN_id_mod_kea_profile_93; NID_TO_SN[ NID_id_mod_cmp ] = SN_id_mod_cmp; NID_TO_SN[ NID_id_mod_qualified_cert_88 ] = SN_id_mod_qualified_cert_88; NID_TO_SN[ NID_id_mod_qualified_cert_93 ] = SN_id_mod_qualified_cert_93; NID_TO_SN[ NID_id_mod_attribute_cert ] = SN_id_mod_attribute_cert; NID_TO_SN[ NID_id_mod_timestamp_protocol ] = SN_id_mod_timestamp_protocol; NID_TO_SN[ NID_id_mod_ocsp ] = SN_id_mod_ocsp; NID_TO_SN[ NID_id_mod_dvcs ] = SN_id_mod_dvcs; NID_TO_SN[ NID_id_mod_cmp2000 ] = SN_id_mod_cmp2000; NID_TO_SN[ NID_info_access ] = SN_info_access; NID_TO_SN[ NID_biometricInfo ] = SN_biometricInfo; NID_TO_SN[ NID_qcStatements ] = SN_qcStatements; NID_TO_SN[ NID_ac_auditEntity ] = SN_ac_auditEntity; NID_TO_SN[ NID_ac_targeting ] = SN_ac_targeting; NID_TO_SN[ NID_aaControls ] = SN_aaControls; NID_TO_SN[ NID_sbgp_ipAddrBlock ] = SN_sbgp_ipAddrBlock; NID_TO_SN[ NID_sbgp_autonomousSysNum ] = SN_sbgp_autonomousSysNum; NID_TO_SN[ NID_sbgp_routerIdentifier ] = SN_sbgp_routerIdentifier; NID_TO_SN[ NID_ac_proxying ] = SN_ac_proxying; NID_TO_SN[ NID_sinfo_access ] = SN_sinfo_access; NID_TO_SN[ NID_proxyCertInfo ] = SN_proxyCertInfo; NID_TO_SN[ NID_id_qt_cps ] = SN_id_qt_cps; NID_TO_SN[ NID_id_qt_unotice ] = SN_id_qt_unotice; NID_TO_SN[ NID_textNotice ] = SN_textNotice; NID_TO_SN[ NID_server_auth ] = SN_server_auth; NID_TO_SN[ NID_client_auth ] = SN_client_auth; NID_TO_SN[ NID_code_sign ] = SN_code_sign; NID_TO_SN[ NID_email_protect ] = SN_email_protect; NID_TO_SN[ NID_ipsecEndSystem ] = SN_ipsecEndSystem; NID_TO_SN[ NID_ipsecTunnel ] = SN_ipsecTunnel; NID_TO_SN[ NID_ipsecUser ] = SN_ipsecUser; NID_TO_SN[ NID_time_stamp ] = SN_time_stamp; NID_TO_SN[ NID_OCSP_sign ] = SN_OCSP_sign; NID_TO_SN[ NID_dvcs ] = SN_dvcs; NID_TO_SN[ NID_id_it_caProtEncCert ] = SN_id_it_caProtEncCert; NID_TO_SN[ NID_id_it_signKeyPairTypes ] = SN_id_it_signKeyPairTypes; NID_TO_SN[ NID_id_it_encKeyPairTypes ] = SN_id_it_encKeyPairTypes; NID_TO_SN[ NID_id_it_preferredSymmAlg ] = SN_id_it_preferredSymmAlg; NID_TO_SN[ NID_id_it_caKeyUpdateInfo ] = SN_id_it_caKeyUpdateInfo; NID_TO_SN[ NID_id_it_currentCRL ] = SN_id_it_currentCRL; NID_TO_SN[ NID_id_it_unsupportedOIDs ] = SN_id_it_unsupportedOIDs; NID_TO_SN[ NID_id_it_subscriptionRequest ] = SN_id_it_subscriptionRequest; NID_TO_SN[ NID_id_it_subscriptionResponse ] = SN_id_it_subscriptionResponse; NID_TO_SN[ NID_id_it_keyPairParamReq ] = SN_id_it_keyPairParamReq; NID_TO_SN[ NID_id_it_keyPairParamRep ] = SN_id_it_keyPairParamRep; NID_TO_SN[ NID_id_it_revPassphrase ] = SN_id_it_revPassphrase; NID_TO_SN[ NID_id_it_implicitConfirm ] = SN_id_it_implicitConfirm; NID_TO_SN[ NID_id_it_confirmWaitTime ] = SN_id_it_confirmWaitTime; NID_TO_SN[ NID_id_it_origPKIMessage ] = SN_id_it_origPKIMessage; NID_TO_SN[ NID_id_it_suppLangTags ] = SN_id_it_suppLangTags; NID_TO_SN[ NID_id_regCtrl ] = SN_id_regCtrl; NID_TO_SN[ NID_id_regInfo ] = SN_id_regInfo; NID_TO_SN[ NID_id_regCtrl_regToken ] = SN_id_regCtrl_regToken; NID_TO_SN[ NID_id_regCtrl_authenticator ] = SN_id_regCtrl_authenticator; NID_TO_SN[ NID_id_regCtrl_pkiPublicationInfo ] = SN_id_regCtrl_pkiPublicationInfo; NID_TO_SN[ NID_id_regCtrl_pkiArchiveOptions ] = SN_id_regCtrl_pkiArchiveOptions; NID_TO_SN[ NID_id_regCtrl_oldCertID ] = SN_id_regCtrl_oldCertID; NID_TO_SN[ NID_id_regCtrl_protocolEncrKey ] = SN_id_regCtrl_protocolEncrKey; NID_TO_SN[ NID_id_regInfo_utf8Pairs ] = SN_id_regInfo_utf8Pairs; NID_TO_SN[ NID_id_regInfo_certReq ] = SN_id_regInfo_certReq; NID_TO_SN[ NID_id_alg_des40 ] = SN_id_alg_des40; NID_TO_SN[ NID_id_alg_noSignature ] = SN_id_alg_noSignature; NID_TO_SN[ NID_id_alg_dh_sig_hmac_sha1 ] = SN_id_alg_dh_sig_hmac_sha1; NID_TO_SN[ NID_id_alg_dh_pop ] = SN_id_alg_dh_pop; NID_TO_SN[ NID_id_cmc_statusInfo ] = SN_id_cmc_statusInfo; NID_TO_SN[ NID_id_cmc_identification ] = SN_id_cmc_identification; NID_TO_SN[ NID_id_cmc_identityProof ] = SN_id_cmc_identityProof; NID_TO_SN[ NID_id_cmc_dataReturn ] = SN_id_cmc_dataReturn; NID_TO_SN[ NID_id_cmc_transactionId ] = SN_id_cmc_transactionId; NID_TO_SN[ NID_id_cmc_senderNonce ] = SN_id_cmc_senderNonce; NID_TO_SN[ NID_id_cmc_recipientNonce ] = SN_id_cmc_recipientNonce; NID_TO_SN[ NID_id_cmc_addExtensions ] = SN_id_cmc_addExtensions; NID_TO_SN[ NID_id_cmc_encryptedPOP ] = SN_id_cmc_encryptedPOP; NID_TO_SN[ NID_id_cmc_decryptedPOP ] = SN_id_cmc_decryptedPOP; NID_TO_SN[ NID_id_cmc_lraPOPWitness ] = SN_id_cmc_lraPOPWitness; NID_TO_SN[ NID_id_cmc_getCert ] = SN_id_cmc_getCert; NID_TO_SN[ NID_id_cmc_getCRL ] = SN_id_cmc_getCRL; NID_TO_SN[ NID_id_cmc_revokeRequest ] = SN_id_cmc_revokeRequest; NID_TO_SN[ NID_id_cmc_regInfo ] = SN_id_cmc_regInfo; NID_TO_SN[ NID_id_cmc_responseInfo ] = SN_id_cmc_responseInfo; NID_TO_SN[ NID_id_cmc_queryPending ] = SN_id_cmc_queryPending; NID_TO_SN[ NID_id_cmc_popLinkRandom ] = SN_id_cmc_popLinkRandom; NID_TO_SN[ NID_id_cmc_popLinkWitness ] = SN_id_cmc_popLinkWitness; NID_TO_SN[ NID_id_cmc_confirmCertAcceptance ] = SN_id_cmc_confirmCertAcceptance; NID_TO_SN[ NID_id_on_personalData ] = SN_id_on_personalData; NID_TO_SN[ NID_id_on_permanentIdentifier ] = SN_id_on_permanentIdentifier; NID_TO_SN[ NID_id_pda_dateOfBirth ] = SN_id_pda_dateOfBirth; NID_TO_SN[ NID_id_pda_placeOfBirth ] = SN_id_pda_placeOfBirth; NID_TO_SN[ NID_id_pda_gender ] = SN_id_pda_gender; NID_TO_SN[ NID_id_pda_countryOfCitizenship ] = SN_id_pda_countryOfCitizenship; NID_TO_SN[ NID_id_pda_countryOfResidence ] = SN_id_pda_countryOfResidence; NID_TO_SN[ NID_id_aca_authenticationInfo ] = SN_id_aca_authenticationInfo; NID_TO_SN[ NID_id_aca_accessIdentity ] = SN_id_aca_accessIdentity; NID_TO_SN[ NID_id_aca_chargingIdentity ] = SN_id_aca_chargingIdentity; NID_TO_SN[ NID_id_aca_group ] = SN_id_aca_group; NID_TO_SN[ NID_id_aca_role ] = SN_id_aca_role; NID_TO_SN[ NID_id_aca_encAttrs ] = SN_id_aca_encAttrs; NID_TO_SN[ NID_id_qcs_pkixQCSyntax_v1 ] = SN_id_qcs_pkixQCSyntax_v1; NID_TO_SN[ NID_id_cct_crs ] = SN_id_cct_crs; NID_TO_SN[ NID_id_cct_PKIData ] = SN_id_cct_PKIData; NID_TO_SN[ NID_id_cct_PKIResponse ] = SN_id_cct_PKIResponse; NID_TO_SN[ NID_id_ppl_anyLanguage ] = SN_id_ppl_anyLanguage; NID_TO_SN[ NID_id_ppl_inheritAll ] = SN_id_ppl_inheritAll; NID_TO_SN[ NID_Independent ] = SN_Independent; NID_TO_SN[ NID_ad_OCSP ] = SN_ad_OCSP; NID_TO_SN[ NID_ad_ca_issuers ] = SN_ad_ca_issuers; NID_TO_SN[ NID_ad_timeStamping ] = SN_ad_timeStamping; NID_TO_SN[ NID_ad_dvcs ] = SN_ad_dvcs; NID_TO_SN[ NID_caRepository ] = SN_caRepository; NID_TO_SN[ NID_id_pkix_OCSP_basic ] = SN_id_pkix_OCSP_basic; NID_TO_SN[ NID_id_pkix_OCSP_Nonce ] = SN_id_pkix_OCSP_Nonce; NID_TO_SN[ NID_id_pkix_OCSP_CrlID ] = SN_id_pkix_OCSP_CrlID; NID_TO_SN[ NID_id_pkix_OCSP_acceptableResponses ] = SN_id_pkix_OCSP_acceptableResponses; NID_TO_SN[ NID_id_pkix_OCSP_noCheck ] = SN_id_pkix_OCSP_noCheck; NID_TO_SN[ NID_id_pkix_OCSP_archiveCutoff ] = SN_id_pkix_OCSP_archiveCutoff; NID_TO_SN[ NID_id_pkix_OCSP_serviceLocator ] = SN_id_pkix_OCSP_serviceLocator; NID_TO_SN[ NID_id_pkix_OCSP_extendedStatus ] = SN_id_pkix_OCSP_extendedStatus; NID_TO_SN[ NID_id_pkix_OCSP_valid ] = SN_id_pkix_OCSP_valid; NID_TO_SN[ NID_id_pkix_OCSP_path ] = SN_id_pkix_OCSP_path; NID_TO_SN[ NID_id_pkix_OCSP_trustRoot ] = SN_id_pkix_OCSP_trustRoot; NID_TO_SN[ NID_algorithm ] = SN_algorithm; NID_TO_SN[ NID_md5WithRSA ] = SN_md5WithRSA; NID_TO_SN[ NID_des_ecb ] = SN_des_ecb; NID_TO_SN[ NID_des_cbc ] = SN_des_cbc; NID_TO_SN[ NID_des_ofb64 ] = SN_des_ofb64; NID_TO_SN[ NID_des_cfb64 ] = SN_des_cfb64; NID_TO_SN[ NID_rsaSignature ] = SN_rsaSignature; NID_TO_SN[ NID_dsa_2 ] = SN_dsa_2; NID_TO_SN[ NID_dsaWithSHA ] = SN_dsaWithSHA; NID_TO_SN[ NID_shaWithRSAEncryption ] = SN_shaWithRSAEncryption; NID_TO_SN[ NID_des_ede_ecb ] = SN_des_ede_ecb; NID_TO_SN[ NID_des_ede3_ecb ] = SN_des_ede3_ecb; NID_TO_SN[ NID_des_ede_cbc ] = SN_des_ede_cbc; NID_TO_SN[ NID_des_ede_cfb64 ] = SN_des_ede_cfb64; NID_TO_SN[ NID_des_ede3_cfb64 ] = SN_des_ede3_cfb64; NID_TO_SN[ NID_des_ede_ofb64 ] = SN_des_ede_ofb64; NID_TO_SN[ NID_des_ede3_ofb64 ] = SN_des_ede3_ofb64; NID_TO_SN[ NID_desx_cbc ] = SN_desx_cbc; NID_TO_SN[ NID_sha ] = SN_sha; NID_TO_SN[ NID_sha1 ] = SN_sha1; NID_TO_SN[ NID_dsaWithSHA1_2 ] = SN_dsaWithSHA1_2; NID_TO_SN[ NID_sha1WithRSA ] = SN_sha1WithRSA; NID_TO_SN[ NID_ripemd160 ] = SN_ripemd160; NID_TO_SN[ NID_ripemd160WithRSA ] = SN_ripemd160WithRSA; NID_TO_SN[ NID_sxnet ] = SN_sxnet; NID_TO_SN[ NID_X500 ] = SN_X500; NID_TO_SN[ NID_X509 ] = SN_X509; NID_TO_SN[ NID_commonName ] = SN_commonName; NID_TO_SN[ NID_surname ] = SN_surname; NID_TO_SN[ NID_countryName ] = SN_countryName; NID_TO_SN[ NID_localityName ] = SN_localityName; NID_TO_SN[ NID_stateOrProvinceName ] = SN_stateOrProvinceName; NID_TO_SN[ NID_streetAddress ] = SN_streetAddress; NID_TO_SN[ NID_organizationName ] = SN_organizationName; NID_TO_SN[ NID_organizationalUnitName ] = SN_organizationalUnitName; NID_TO_SN[ NID_title ] = SN_title; NID_TO_SN[ NID_member ] = SN_member; NID_TO_SN[ NID_owner ] = SN_owner; NID_TO_SN[ NID_seeAlso ] = SN_seeAlso; NID_TO_SN[ NID_name ] = SN_name; NID_TO_SN[ NID_givenName ] = SN_givenName; NID_TO_SN[ NID_initials ] = SN_initials; NID_TO_SN[ NID_dnQualifier ] = SN_dnQualifier; NID_TO_SN[ NID_dmdName ] = SN_dmdName; NID_TO_SN[ NID_role ] = SN_role; NID_TO_SN[ NID_X500algorithms ] = SN_X500algorithms; NID_TO_SN[ NID_rsa ] = SN_rsa; NID_TO_SN[ NID_mdc2WithRSA ] = SN_mdc2WithRSA; NID_TO_SN[ NID_mdc2 ] = SN_mdc2; NID_TO_SN[ NID_id_ce ] = SN_id_ce; NID_TO_SN[ NID_subject_directory_attributes ] = SN_subject_directory_attributes; NID_TO_SN[ NID_subject_key_identifier ] = SN_subject_key_identifier; NID_TO_SN[ NID_key_usage ] = SN_key_usage; NID_TO_SN[ NID_private_key_usage_period ] = SN_private_key_usage_period; NID_TO_SN[ NID_subject_alt_name ] = SN_subject_alt_name; NID_TO_SN[ NID_issuer_alt_name ] = SN_issuer_alt_name; NID_TO_SN[ NID_basic_constraints ] = SN_basic_constraints; NID_TO_SN[ NID_crl_number ] = SN_crl_number; NID_TO_SN[ NID_crl_reason ] = SN_crl_reason; NID_TO_SN[ NID_invalidity_date ] = SN_invalidity_date; NID_TO_SN[ NID_delta_crl ] = SN_delta_crl; NID_TO_SN[ NID_issuing_distribution_point ] = SN_issuing_distribution_point; NID_TO_SN[ NID_certificate_issuer ] = SN_certificate_issuer; NID_TO_SN[ NID_name_constraints ] = SN_name_constraints; NID_TO_SN[ NID_crl_distribution_points ] = SN_crl_distribution_points; NID_TO_SN[ NID_certificate_policies ] = SN_certificate_policies; NID_TO_SN[ NID_any_policy ] = SN_any_policy; NID_TO_SN[ NID_policy_mappings ] = SN_policy_mappings; NID_TO_SN[ NID_authority_key_identifier ] = SN_authority_key_identifier; NID_TO_SN[ NID_policy_constraints ] = SN_policy_constraints; NID_TO_SN[ NID_ext_key_usage ] = SN_ext_key_usage; NID_TO_SN[ NID_freshest_crl ] = SN_freshest_crl; NID_TO_SN[ NID_inhibit_any_policy ] = SN_inhibit_any_policy; NID_TO_SN[ NID_target_information ] = SN_target_information; NID_TO_SN[ NID_no_rev_avail ] = SN_no_rev_avail; NID_TO_SN[ NID_anyExtendedKeyUsage ] = SN_anyExtendedKeyUsage; NID_TO_SN[ NID_netscape ] = SN_netscape; NID_TO_SN[ NID_netscape_cert_extension ] = SN_netscape_cert_extension; NID_TO_SN[ NID_netscape_data_type ] = SN_netscape_data_type; NID_TO_SN[ NID_netscape_cert_type ] = SN_netscape_cert_type; NID_TO_SN[ NID_netscape_base_url ] = SN_netscape_base_url; NID_TO_SN[ NID_netscape_revocation_url ] = SN_netscape_revocation_url; NID_TO_SN[ NID_netscape_ca_revocation_url ] = SN_netscape_ca_revocation_url; NID_TO_SN[ NID_netscape_renewal_url ] = SN_netscape_renewal_url; NID_TO_SN[ NID_netscape_ca_policy_url ] = SN_netscape_ca_policy_url; NID_TO_SN[ NID_netscape_ssl_server_name ] = SN_netscape_ssl_server_name; NID_TO_SN[ NID_netscape_comment ] = SN_netscape_comment; NID_TO_SN[ NID_netscape_cert_sequence ] = SN_netscape_cert_sequence; NID_TO_SN[ NID_ns_sgc ] = SN_ns_sgc; NID_TO_SN[ NID_org ] = SN_org; NID_TO_SN[ NID_dod ] = SN_dod; NID_TO_SN[ NID_iana ] = SN_iana; NID_TO_SN[ NID_Directory ] = SN_Directory; NID_TO_SN[ NID_Management ] = SN_Management; NID_TO_SN[ NID_Experimental ] = SN_Experimental; NID_TO_SN[ NID_Private ] = SN_Private; NID_TO_SN[ NID_Security ] = SN_Security; NID_TO_SN[ NID_SNMPv2 ] = SN_SNMPv2; NID_TO_SN[ NID_Enterprises ] = SN_Enterprises; NID_TO_SN[ NID_dcObject ] = SN_dcObject; NID_TO_SN[ NID_mime_mhs ] = SN_mime_mhs; NID_TO_SN[ NID_mime_mhs_headings ] = SN_mime_mhs_headings; NID_TO_SN[ NID_mime_mhs_bodies ] = SN_mime_mhs_bodies; NID_TO_SN[ NID_id_hex_partial_message ] = SN_id_hex_partial_message; NID_TO_SN[ NID_id_hex_multipart_message ] = SN_id_hex_multipart_message; NID_TO_SN[ NID_rle_compression ] = SN_rle_compression; NID_TO_SN[ NID_zlib_compression ] = SN_zlib_compression; NID_TO_SN[ NID_aes_128_ecb ] = SN_aes_128_ecb; NID_TO_SN[ NID_aes_128_cbc ] = SN_aes_128_cbc; NID_TO_SN[ NID_aes_128_ofb128 ] = SN_aes_128_ofb128; NID_TO_SN[ NID_aes_128_cfb128 ] = SN_aes_128_cfb128; NID_TO_SN[ NID_id_aes128_wrap ] = SN_id_aes128_wrap; NID_TO_SN[ NID_aes_128_gcm ] = SN_aes_128_gcm; NID_TO_SN[ NID_aes_128_ccm ] = SN_aes_128_ccm; NID_TO_SN[ NID_id_aes128_wrap_pad ] = SN_id_aes128_wrap_pad; NID_TO_SN[ NID_aes_192_ecb ] = SN_aes_192_ecb; NID_TO_SN[ NID_aes_192_cbc ] = SN_aes_192_cbc; NID_TO_SN[ NID_aes_192_ofb128 ] = SN_aes_192_ofb128; NID_TO_SN[ NID_aes_192_cfb128 ] = SN_aes_192_cfb128; NID_TO_SN[ NID_id_aes192_wrap ] = SN_id_aes192_wrap; NID_TO_SN[ NID_aes_192_gcm ] = SN_aes_192_gcm; NID_TO_SN[ NID_aes_192_ccm ] = SN_aes_192_ccm; NID_TO_SN[ NID_id_aes192_wrap_pad ] = SN_id_aes192_wrap_pad; NID_TO_SN[ NID_aes_256_ecb ] = SN_aes_256_ecb; NID_TO_SN[ NID_aes_256_cbc ] = SN_aes_256_cbc; NID_TO_SN[ NID_aes_256_ofb128 ] = SN_aes_256_ofb128; NID_TO_SN[ NID_aes_256_cfb128 ] = SN_aes_256_cfb128; NID_TO_SN[ NID_id_aes256_wrap ] = SN_id_aes256_wrap; NID_TO_SN[ NID_aes_256_gcm ] = SN_aes_256_gcm; NID_TO_SN[ NID_aes_256_ccm ] = SN_aes_256_ccm; NID_TO_SN[ NID_id_aes256_wrap_pad ] = SN_id_aes256_wrap_pad; NID_TO_SN[ NID_aes_128_cfb1 ] = SN_aes_128_cfb1; NID_TO_SN[ NID_aes_192_cfb1 ] = SN_aes_192_cfb1; NID_TO_SN[ NID_aes_256_cfb1 ] = SN_aes_256_cfb1; NID_TO_SN[ NID_aes_128_cfb8 ] = SN_aes_128_cfb8; NID_TO_SN[ NID_aes_192_cfb8 ] = SN_aes_192_cfb8; NID_TO_SN[ NID_aes_256_cfb8 ] = SN_aes_256_cfb8; NID_TO_SN[ NID_aes_128_ctr ] = SN_aes_128_ctr; NID_TO_SN[ NID_aes_192_ctr ] = SN_aes_192_ctr; NID_TO_SN[ NID_aes_256_ctr ] = SN_aes_256_ctr; NID_TO_SN[ NID_aes_128_xts ] = SN_aes_128_xts; NID_TO_SN[ NID_aes_256_xts ] = SN_aes_256_xts; NID_TO_SN[ NID_des_cfb1 ] = SN_des_cfb1; NID_TO_SN[ NID_des_cfb8 ] = SN_des_cfb8; NID_TO_SN[ NID_des_ede3_cfb1 ] = SN_des_ede3_cfb1; NID_TO_SN[ NID_des_ede3_cfb8 ] = SN_des_ede3_cfb8; NID_TO_SN[ NID_sha256 ] = SN_sha256; NID_TO_SN[ NID_sha384 ] = SN_sha384; NID_TO_SN[ NID_sha512 ] = SN_sha512; NID_TO_SN[ NID_sha224 ] = SN_sha224; NID_TO_SN[ NID_dsa_with_SHA224 ] = SN_dsa_with_SHA224; NID_TO_SN[ NID_dsa_with_SHA256 ] = SN_dsa_with_SHA256; NID_TO_SN[ NID_hold_instruction_code ] = SN_hold_instruction_code; NID_TO_SN[ NID_hold_instruction_none ] = SN_hold_instruction_none; NID_TO_SN[ NID_hold_instruction_call_issuer ] = SN_hold_instruction_call_issuer; NID_TO_SN[ NID_hold_instruction_reject ] = SN_hold_instruction_reject; NID_TO_SN[ NID_data ] = SN_data; NID_TO_SN[ NID_pss ] = SN_pss; NID_TO_SN[ NID_ucl ] = SN_ucl; NID_TO_SN[ NID_pilot ] = SN_pilot; NID_TO_SN[ NID_account ] = SN_account; NID_TO_SN[ NID_document ] = SN_document; NID_TO_SN[ NID_room ] = SN_room; NID_TO_SN[ NID_Domain ] = SN_Domain; NID_TO_SN[ NID_userId ] = SN_userId; NID_TO_SN[ NID_rfc822Mailbox ] = SN_rfc822Mailbox; NID_TO_SN[ NID_info ] = SN_info; NID_TO_SN[ NID_photo ] = SN_photo; NID_TO_SN[ NID_host ] = SN_host; NID_TO_SN[ NID_manager ] = SN_manager; NID_TO_SN[ NID_secretary ] = SN_secretary; NID_TO_SN[ NID_domainComponent ] = SN_domainComponent; NID_TO_SN[ NID_audio ] = SN_audio; NID_TO_SN[ NID_id_set ] = SN_id_set; NID_TO_SN[ NID_set_ctype ] = SN_set_ctype; NID_TO_SN[ NID_set_msgExt ] = SN_set_msgExt; NID_TO_SN[ NID_set_attr ] = SN_set_attr; NID_TO_SN[ NID_set_policy ] = SN_set_policy; NID_TO_SN[ NID_set_certExt ] = SN_set_certExt; NID_TO_SN[ NID_set_brand ] = SN_set_brand; NID_TO_SN[ NID_setct_PANData ] = SN_setct_PANData; NID_TO_SN[ NID_setct_PANToken ] = SN_setct_PANToken; NID_TO_SN[ NID_setct_PANOnly ] = SN_setct_PANOnly; NID_TO_SN[ NID_setct_OIData ] = SN_setct_OIData; NID_TO_SN[ NID_setct_PI ] = SN_setct_PI; NID_TO_SN[ NID_setct_PIData ] = SN_setct_PIData; NID_TO_SN[ NID_setct_PIDataUnsigned ] = SN_setct_PIDataUnsigned; NID_TO_SN[ NID_setct_HODInput ] = SN_setct_HODInput; NID_TO_SN[ NID_setct_AuthResBaggage ] = SN_setct_AuthResBaggage; NID_TO_SN[ NID_setct_AuthRevReqBaggage ] = SN_setct_AuthRevReqBaggage; NID_TO_SN[ NID_setct_AuthRevResBaggage ] = SN_setct_AuthRevResBaggage; NID_TO_SN[ NID_setct_CapTokenSeq ] = SN_setct_CapTokenSeq; NID_TO_SN[ NID_setct_PInitResData ] = SN_setct_PInitResData; NID_TO_SN[ NID_setct_PI_TBS ] = SN_setct_PI_TBS; NID_TO_SN[ NID_setct_PResData ] = SN_setct_PResData; NID_TO_SN[ NID_setct_AuthReqTBS ] = SN_setct_AuthReqTBS; NID_TO_SN[ NID_setct_AuthResTBS ] = SN_setct_AuthResTBS; NID_TO_SN[ NID_setct_AuthResTBSX ] = SN_setct_AuthResTBSX; NID_TO_SN[ NID_setct_AuthTokenTBS ] = SN_setct_AuthTokenTBS; NID_TO_SN[ NID_setct_CapTokenData ] = SN_setct_CapTokenData; NID_TO_SN[ NID_setct_CapTokenTBS ] = SN_setct_CapTokenTBS; NID_TO_SN[ NID_setct_AcqCardCodeMsg ] = SN_setct_AcqCardCodeMsg; NID_TO_SN[ NID_setct_AuthRevReqTBS ] = SN_setct_AuthRevReqTBS; NID_TO_SN[ NID_setct_AuthRevResData ] = SN_setct_AuthRevResData; NID_TO_SN[ NID_setct_AuthRevResTBS ] = SN_setct_AuthRevResTBS; NID_TO_SN[ NID_setct_CapReqTBS ] = SN_setct_CapReqTBS; NID_TO_SN[ NID_setct_CapReqTBSX ] = SN_setct_CapReqTBSX; NID_TO_SN[ NID_setct_CapResData ] = SN_setct_CapResData; NID_TO_SN[ NID_setct_CapRevReqTBS ] = SN_setct_CapRevReqTBS; NID_TO_SN[ NID_setct_CapRevReqTBSX ] = SN_setct_CapRevReqTBSX; NID_TO_SN[ NID_setct_CapRevResData ] = SN_setct_CapRevResData; NID_TO_SN[ NID_setct_CredReqTBS ] = SN_setct_CredReqTBS; NID_TO_SN[ NID_setct_CredReqTBSX ] = SN_setct_CredReqTBSX; NID_TO_SN[ NID_setct_CredResData ] = SN_setct_CredResData; NID_TO_SN[ NID_setct_CredRevReqTBS ] = SN_setct_CredRevReqTBS; NID_TO_SN[ NID_setct_CredRevReqTBSX ] = SN_setct_CredRevReqTBSX; NID_TO_SN[ NID_setct_CredRevResData ] = SN_setct_CredRevResData; NID_TO_SN[ NID_setct_PCertReqData ] = SN_setct_PCertReqData; NID_TO_SN[ NID_setct_PCertResTBS ] = SN_setct_PCertResTBS; NID_TO_SN[ NID_setct_BatchAdminReqData ] = SN_setct_BatchAdminReqData; NID_TO_SN[ NID_setct_BatchAdminResData ] = SN_setct_BatchAdminResData; NID_TO_SN[ NID_setct_CardCInitResTBS ] = SN_setct_CardCInitResTBS; NID_TO_SN[ NID_setct_MeAqCInitResTBS ] = SN_setct_MeAqCInitResTBS; NID_TO_SN[ NID_setct_RegFormResTBS ] = SN_setct_RegFormResTBS; NID_TO_SN[ NID_setct_CertReqData ] = SN_setct_CertReqData; NID_TO_SN[ NID_setct_CertReqTBS ] = SN_setct_CertReqTBS; NID_TO_SN[ NID_setct_CertResData ] = SN_setct_CertResData; NID_TO_SN[ NID_setct_CertInqReqTBS ] = SN_setct_CertInqReqTBS; NID_TO_SN[ NID_setct_ErrorTBS ] = SN_setct_ErrorTBS; NID_TO_SN[ NID_setct_PIDualSignedTBE ] = SN_setct_PIDualSignedTBE; NID_TO_SN[ NID_setct_PIUnsignedTBE ] = SN_setct_PIUnsignedTBE; NID_TO_SN[ NID_setct_AuthReqTBE ] = SN_setct_AuthReqTBE; NID_TO_SN[ NID_setct_AuthResTBE ] = SN_setct_AuthResTBE; NID_TO_SN[ NID_setct_AuthResTBEX ] = SN_setct_AuthResTBEX; NID_TO_SN[ NID_setct_AuthTokenTBE ] = SN_setct_AuthTokenTBE; NID_TO_SN[ NID_setct_CapTokenTBE ] = SN_setct_CapTokenTBE; NID_TO_SN[ NID_setct_CapTokenTBEX ] = SN_setct_CapTokenTBEX; NID_TO_SN[ NID_setct_AcqCardCodeMsgTBE ] = SN_setct_AcqCardCodeMsgTBE; NID_TO_SN[ NID_setct_AuthRevReqTBE ] = SN_setct_AuthRevReqTBE; NID_TO_SN[ NID_setct_AuthRevResTBE ] = SN_setct_AuthRevResTBE; NID_TO_SN[ NID_setct_AuthRevResTBEB ] = SN_setct_AuthRevResTBEB; NID_TO_SN[ NID_setct_CapReqTBE ] = SN_setct_CapReqTBE; NID_TO_SN[ NID_setct_CapReqTBEX ] = SN_setct_CapReqTBEX; NID_TO_SN[ NID_setct_CapResTBE ] = SN_setct_CapResTBE; NID_TO_SN[ NID_setct_CapRevReqTBE ] = SN_setct_CapRevReqTBE; NID_TO_SN[ NID_setct_CapRevReqTBEX ] = SN_setct_CapRevReqTBEX; NID_TO_SN[ NID_setct_CapRevResTBE ] = SN_setct_CapRevResTBE; NID_TO_SN[ NID_setct_CredReqTBE ] = SN_setct_CredReqTBE; NID_TO_SN[ NID_setct_CredReqTBEX ] = SN_setct_CredReqTBEX; NID_TO_SN[ NID_setct_CredResTBE ] = SN_setct_CredResTBE; NID_TO_SN[ NID_setct_CredRevReqTBE ] = SN_setct_CredRevReqTBE; NID_TO_SN[ NID_setct_CredRevReqTBEX ] = SN_setct_CredRevReqTBEX; NID_TO_SN[ NID_setct_CredRevResTBE ] = SN_setct_CredRevResTBE; NID_TO_SN[ NID_setct_BatchAdminReqTBE ] = SN_setct_BatchAdminReqTBE; NID_TO_SN[ NID_setct_BatchAdminResTBE ] = SN_setct_BatchAdminResTBE; NID_TO_SN[ NID_setct_RegFormReqTBE ] = SN_setct_RegFormReqTBE; NID_TO_SN[ NID_setct_CertReqTBE ] = SN_setct_CertReqTBE; NID_TO_SN[ NID_setct_CertReqTBEX ] = SN_setct_CertReqTBEX; NID_TO_SN[ NID_setct_CertResTBE ] = SN_setct_CertResTBE; NID_TO_SN[ NID_setct_CRLNotificationTBS ] = SN_setct_CRLNotificationTBS; NID_TO_SN[ NID_setct_CRLNotificationResTBS ] = SN_setct_CRLNotificationResTBS; NID_TO_SN[ NID_setct_BCIDistributionTBS ] = SN_setct_BCIDistributionTBS; NID_TO_SN[ NID_setext_genCrypt ] = SN_setext_genCrypt; NID_TO_SN[ NID_setext_miAuth ] = SN_setext_miAuth; NID_TO_SN[ NID_setext_pinSecure ] = SN_setext_pinSecure; NID_TO_SN[ NID_setext_pinAny ] = SN_setext_pinAny; NID_TO_SN[ NID_setext_track2 ] = SN_setext_track2; NID_TO_SN[ NID_setext_cv ] = SN_setext_cv; NID_TO_SN[ NID_set_policy_root ] = SN_set_policy_root; NID_TO_SN[ NID_setCext_hashedRoot ] = SN_setCext_hashedRoot; NID_TO_SN[ NID_setCext_certType ] = SN_setCext_certType; NID_TO_SN[ NID_setCext_merchData ] = SN_setCext_merchData; NID_TO_SN[ NID_setCext_cCertRequired ] = SN_setCext_cCertRequired; NID_TO_SN[ NID_setCext_tunneling ] = SN_setCext_tunneling; NID_TO_SN[ NID_setCext_setExt ] = SN_setCext_setExt; NID_TO_SN[ NID_setCext_setQualf ] = SN_setCext_setQualf; NID_TO_SN[ NID_setCext_PGWYcapabilities ] = SN_setCext_PGWYcapabilities; NID_TO_SN[ NID_setCext_TokenIdentifier ] = SN_setCext_TokenIdentifier; NID_TO_SN[ NID_setCext_Track2Data ] = SN_setCext_Track2Data; NID_TO_SN[ NID_setCext_TokenType ] = SN_setCext_TokenType; NID_TO_SN[ NID_setCext_IssuerCapabilities ] = SN_setCext_IssuerCapabilities; NID_TO_SN[ NID_setAttr_Cert ] = SN_setAttr_Cert; NID_TO_SN[ NID_setAttr_PGWYcap ] = SN_setAttr_PGWYcap; NID_TO_SN[ NID_setAttr_TokenType ] = SN_setAttr_TokenType; NID_TO_SN[ NID_setAttr_IssCap ] = SN_setAttr_IssCap; NID_TO_SN[ NID_set_rootKeyThumb ] = SN_set_rootKeyThumb; NID_TO_SN[ NID_set_addPolicy ] = SN_set_addPolicy; NID_TO_SN[ NID_setAttr_Token_EMV ] = SN_setAttr_Token_EMV; NID_TO_SN[ NID_setAttr_Token_B0Prime ] = SN_setAttr_Token_B0Prime; NID_TO_SN[ NID_setAttr_IssCap_CVM ] = SN_setAttr_IssCap_CVM; NID_TO_SN[ NID_setAttr_IssCap_T2 ] = SN_setAttr_IssCap_T2; NID_TO_SN[ NID_setAttr_IssCap_Sig ] = SN_setAttr_IssCap_Sig; NID_TO_SN[ NID_setAttr_GenCryptgrm ] = SN_setAttr_GenCryptgrm; NID_TO_SN[ NID_setAttr_T2Enc ] = SN_setAttr_T2Enc; NID_TO_SN[ NID_setAttr_T2cleartxt ] = SN_setAttr_T2cleartxt; NID_TO_SN[ NID_setAttr_TokICCsig ] = SN_setAttr_TokICCsig; NID_TO_SN[ NID_setAttr_SecDevSig ] = SN_setAttr_SecDevSig; NID_TO_SN[ NID_set_brand_IATA_ATA ] = SN_set_brand_IATA_ATA; NID_TO_SN[ NID_set_brand_Diners ] = SN_set_brand_Diners; NID_TO_SN[ NID_set_brand_AmericanExpress ] = SN_set_brand_AmericanExpress; NID_TO_SN[ NID_set_brand_JCB ] = SN_set_brand_JCB; NID_TO_SN[ NID_set_brand_Visa ] = SN_set_brand_Visa; NID_TO_SN[ NID_set_brand_MasterCard ] = SN_set_brand_MasterCard; NID_TO_SN[ NID_set_brand_Novus ] = SN_set_brand_Novus; NID_TO_SN[ NID_des_cdmf ] = SN_des_cdmf; NID_TO_SN[ NID_rsaOAEPEncryptionSET ] = SN_rsaOAEPEncryptionSET; NID_TO_SN[ NID_ipsec3 ] = SN_ipsec3; NID_TO_SN[ NID_ipsec4 ] = SN_ipsec4; NID_TO_SN[ NID_whirlpool ] = SN_whirlpool; NID_TO_SN[ NID_cryptopro ] = SN_cryptopro; NID_TO_SN[ NID_cryptocom ] = SN_cryptocom; NID_TO_SN[ NID_id_GostR3411_94_with_GostR3410_2001 ] = SN_id_GostR3411_94_with_GostR3410_2001; NID_TO_SN[ NID_id_GostR3411_94_with_GostR3410_94 ] = SN_id_GostR3411_94_with_GostR3410_94; NID_TO_SN[ NID_id_GostR3411_94 ] = SN_id_GostR3411_94; NID_TO_SN[ NID_id_HMACGostR3411_94 ] = SN_id_HMACGostR3411_94; NID_TO_SN[ NID_id_GostR3410_2001 ] = SN_id_GostR3410_2001; NID_TO_SN[ NID_id_GostR3410_94 ] = SN_id_GostR3410_94; NID_TO_SN[ NID_id_Gost28147_89 ] = SN_id_Gost28147_89; NID_TO_SN[ NID_gost89_cnt ] = SN_gost89_cnt; NID_TO_SN[ NID_id_Gost28147_89_MAC ] = SN_id_Gost28147_89_MAC; NID_TO_SN[ NID_id_GostR3411_94_prf ] = SN_id_GostR3411_94_prf; NID_TO_SN[ NID_id_GostR3410_2001DH ] = SN_id_GostR3410_2001DH; NID_TO_SN[ NID_id_GostR3410_94DH ] = SN_id_GostR3410_94DH; NID_TO_SN[ NID_id_Gost28147_89_CryptoPro_KeyMeshing ] = SN_id_Gost28147_89_CryptoPro_KeyMeshing; NID_TO_SN[ NID_id_Gost28147_89_None_KeyMeshing ] = SN_id_Gost28147_89_None_KeyMeshing; NID_TO_SN[ NID_id_GostR3411_94_TestParamSet ] = SN_id_GostR3411_94_TestParamSet; NID_TO_SN[ NID_id_GostR3411_94_CryptoProParamSet ] = SN_id_GostR3411_94_CryptoProParamSet; NID_TO_SN[ NID_id_Gost28147_89_TestParamSet ] = SN_id_Gost28147_89_TestParamSet; NID_TO_SN[ NID_id_Gost28147_89_CryptoPro_A_ParamSet ] = SN_id_Gost28147_89_CryptoPro_A_ParamSet; NID_TO_SN[ NID_id_Gost28147_89_CryptoPro_B_ParamSet ] = SN_id_Gost28147_89_CryptoPro_B_ParamSet; NID_TO_SN[ NID_id_Gost28147_89_CryptoPro_C_ParamSet ] = SN_id_Gost28147_89_CryptoPro_C_ParamSet; NID_TO_SN[ NID_id_Gost28147_89_CryptoPro_D_ParamSet ] = SN_id_Gost28147_89_CryptoPro_D_ParamSet; NID_TO_SN[ NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet ] = SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet; NID_TO_SN[ NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet ] = SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet; NID_TO_SN[ NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet ] = SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet; NID_TO_SN[ NID_id_GostR3410_94_TestParamSet ] = SN_id_GostR3410_94_TestParamSet; NID_TO_SN[ NID_id_GostR3410_94_CryptoPro_A_ParamSet ] = SN_id_GostR3410_94_CryptoPro_A_ParamSet; NID_TO_SN[ NID_id_GostR3410_94_CryptoPro_B_ParamSet ] = SN_id_GostR3410_94_CryptoPro_B_ParamSet; NID_TO_SN[ NID_id_GostR3410_94_CryptoPro_C_ParamSet ] = SN_id_GostR3410_94_CryptoPro_C_ParamSet; NID_TO_SN[ NID_id_GostR3410_94_CryptoPro_D_ParamSet ] = SN_id_GostR3410_94_CryptoPro_D_ParamSet; NID_TO_SN[ NID_id_GostR3410_94_CryptoPro_XchA_ParamSet ] = SN_id_GostR3410_94_CryptoPro_XchA_ParamSet; NID_TO_SN[ NID_id_GostR3410_94_CryptoPro_XchB_ParamSet ] = SN_id_GostR3410_94_CryptoPro_XchB_ParamSet; NID_TO_SN[ NID_id_GostR3410_94_CryptoPro_XchC_ParamSet ] = SN_id_GostR3410_94_CryptoPro_XchC_ParamSet; NID_TO_SN[ NID_id_GostR3410_2001_TestParamSet ] = SN_id_GostR3410_2001_TestParamSet; NID_TO_SN[ NID_id_GostR3410_2001_CryptoPro_A_ParamSet ] = SN_id_GostR3410_2001_CryptoPro_A_ParamSet; NID_TO_SN[ NID_id_GostR3410_2001_CryptoPro_B_ParamSet ] = SN_id_GostR3410_2001_CryptoPro_B_ParamSet; NID_TO_SN[ NID_id_GostR3410_2001_CryptoPro_C_ParamSet ] = SN_id_GostR3410_2001_CryptoPro_C_ParamSet; NID_TO_SN[ NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet ] = SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet; NID_TO_SN[ NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet ] = SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet; NID_TO_SN[ NID_id_GostR3410_94_a ] = SN_id_GostR3410_94_a; NID_TO_SN[ NID_id_GostR3410_94_aBis ] = SN_id_GostR3410_94_aBis; NID_TO_SN[ NID_id_GostR3410_94_b ] = SN_id_GostR3410_94_b; NID_TO_SN[ NID_id_GostR3410_94_bBis ] = SN_id_GostR3410_94_bBis; NID_TO_SN[ NID_id_Gost28147_89_cc ] = SN_id_Gost28147_89_cc; NID_TO_SN[ NID_id_GostR3410_94_cc ] = SN_id_GostR3410_94_cc; NID_TO_SN[ NID_id_GostR3410_2001_cc ] = SN_id_GostR3410_2001_cc; NID_TO_SN[ NID_id_GostR3411_94_with_GostR3410_94_cc ] = SN_id_GostR3411_94_with_GostR3410_94_cc; NID_TO_SN[ NID_id_GostR3411_94_with_GostR3410_2001_cc ] = SN_id_GostR3411_94_with_GostR3410_2001_cc; NID_TO_SN[ NID_id_GostR3410_2001_ParamSet_cc ] = SN_id_GostR3410_2001_ParamSet_cc; NID_TO_SN[ NID_camellia_128_cbc ] = SN_camellia_128_cbc; NID_TO_SN[ NID_camellia_192_cbc ] = SN_camellia_192_cbc; NID_TO_SN[ NID_camellia_256_cbc ] = SN_camellia_256_cbc; NID_TO_SN[ NID_id_camellia128_wrap ] = SN_id_camellia128_wrap; NID_TO_SN[ NID_id_camellia192_wrap ] = SN_id_camellia192_wrap; NID_TO_SN[ NID_id_camellia256_wrap ] = SN_id_camellia256_wrap; NID_TO_SN[ NID_camellia_128_ecb ] = SN_camellia_128_ecb; NID_TO_SN[ NID_camellia_128_ofb128 ] = SN_camellia_128_ofb128; NID_TO_SN[ NID_camellia_128_cfb128 ] = SN_camellia_128_cfb128; NID_TO_SN[ NID_camellia_192_ecb ] = SN_camellia_192_ecb; NID_TO_SN[ NID_camellia_192_ofb128 ] = SN_camellia_192_ofb128; NID_TO_SN[ NID_camellia_192_cfb128 ] = SN_camellia_192_cfb128; NID_TO_SN[ NID_camellia_256_ecb ] = SN_camellia_256_ecb; NID_TO_SN[ NID_camellia_256_ofb128 ] = SN_camellia_256_ofb128; NID_TO_SN[ NID_camellia_256_cfb128 ] = SN_camellia_256_cfb128; NID_TO_SN[ NID_camellia_128_cfb1 ] = SN_camellia_128_cfb1; NID_TO_SN[ NID_camellia_192_cfb1 ] = SN_camellia_192_cfb1; NID_TO_SN[ NID_camellia_256_cfb1 ] = SN_camellia_256_cfb1; NID_TO_SN[ NID_camellia_128_cfb8 ] = SN_camellia_128_cfb8; NID_TO_SN[ NID_camellia_192_cfb8 ] = SN_camellia_192_cfb8; NID_TO_SN[ NID_camellia_256_cfb8 ] = SN_camellia_256_cfb8; NID_TO_SN[ NID_kisa ] = SN_kisa; NID_TO_SN[ NID_seed_ecb ] = SN_seed_ecb; NID_TO_SN[ NID_seed_cbc ] = SN_seed_cbc; NID_TO_SN[ NID_seed_cfb128 ] = SN_seed_cfb128; NID_TO_SN[ NID_seed_ofb128 ] = SN_seed_ofb128; NID_TO_SN[ NID_hmac ] = SN_hmac; NID_TO_SN[ NID_cmac ] = SN_cmac; NID_TO_SN[ NID_rc4_hmac_md5 ] = SN_rc4_hmac_md5; NID_TO_SN[ NID_aes_128_cbc_hmac_sha1 ] = SN_aes_128_cbc_hmac_sha1; NID_TO_SN[ NID_aes_192_cbc_hmac_sha1 ] = SN_aes_192_cbc_hmac_sha1; NID_TO_SN[ NID_aes_256_cbc_hmac_sha1 ] = SN_aes_256_cbc_hmac_sha1; NID_TO_SN[ NID_aes_128_cbc_hmac_sha256 ] = SN_aes_128_cbc_hmac_sha256; NID_TO_SN[ NID_aes_192_cbc_hmac_sha256 ] = SN_aes_192_cbc_hmac_sha256; NID_TO_SN[ NID_aes_256_cbc_hmac_sha256 ] = SN_aes_256_cbc_hmac_sha256; NID_TO_SN[ NID_dhpublicnumber ] = SN_dhpublicnumber; NID_TO_SN[ NID_brainpoolP160r1 ] = SN_brainpoolP160r1; NID_TO_SN[ NID_brainpoolP160t1 ] = SN_brainpoolP160t1; NID_TO_SN[ NID_brainpoolP192r1 ] = SN_brainpoolP192r1; NID_TO_SN[ NID_brainpoolP192t1 ] = SN_brainpoolP192t1; NID_TO_SN[ NID_brainpoolP224r1 ] = SN_brainpoolP224r1; NID_TO_SN[ NID_brainpoolP224t1 ] = SN_brainpoolP224t1; NID_TO_SN[ NID_brainpoolP256r1 ] = SN_brainpoolP256r1; NID_TO_SN[ NID_brainpoolP256t1 ] = SN_brainpoolP256t1; NID_TO_SN[ NID_brainpoolP320r1 ] = SN_brainpoolP320r1; NID_TO_SN[ NID_brainpoolP320t1 ] = SN_brainpoolP320t1; NID_TO_SN[ NID_brainpoolP384r1 ] = SN_brainpoolP384r1; NID_TO_SN[ NID_brainpoolP384t1 ] = SN_brainpoolP384t1; NID_TO_SN[ NID_brainpoolP512r1 ] = SN_brainpoolP512r1; NID_TO_SN[ NID_brainpoolP512t1 ] = SN_brainpoolP512t1; NID_TO_SN[ NID_dhSinglePass_stdDH_sha1kdf_scheme ] = SN_dhSinglePass_stdDH_sha1kdf_scheme; NID_TO_SN[ NID_dhSinglePass_stdDH_sha224kdf_scheme ] = SN_dhSinglePass_stdDH_sha224kdf_scheme; NID_TO_SN[ NID_dhSinglePass_stdDH_sha256kdf_scheme ] = SN_dhSinglePass_stdDH_sha256kdf_scheme; NID_TO_SN[ NID_dhSinglePass_stdDH_sha384kdf_scheme ] = SN_dhSinglePass_stdDH_sha384kdf_scheme; NID_TO_SN[ NID_dhSinglePass_stdDH_sha512kdf_scheme ] = SN_dhSinglePass_stdDH_sha512kdf_scheme; NID_TO_SN[ NID_dhSinglePass_cofactorDH_sha1kdf_scheme ] = SN_dhSinglePass_cofactorDH_sha1kdf_scheme; NID_TO_SN[ NID_dhSinglePass_cofactorDH_sha224kdf_scheme ] = SN_dhSinglePass_cofactorDH_sha224kdf_scheme; NID_TO_SN[ NID_dhSinglePass_cofactorDH_sha256kdf_scheme ] = SN_dhSinglePass_cofactorDH_sha256kdf_scheme; NID_TO_SN[ NID_dhSinglePass_cofactorDH_sha384kdf_scheme ] = SN_dhSinglePass_cofactorDH_sha384kdf_scheme; NID_TO_SN[ NID_dhSinglePass_cofactorDH_sha512kdf_scheme ] = SN_dhSinglePass_cofactorDH_sha512kdf_scheme; NID_TO_SN[ NID_dh_std_kdf ] = SN_dh_std_kdf; NID_TO_SN[ NID_dh_cofactor_kdf ] = SN_dh_cofactor_kdf; NID_TO_SN[ NID_ct_precert_scts ] = SN_ct_precert_scts; NID_TO_SN[ NID_ct_precert_poison ] = SN_ct_precert_poison; NID_TO_SN[ NID_ct_precert_signer ] = SN_ct_precert_signer; NID_TO_SN[ NID_ct_cert_scts ] = SN_ct_cert_scts; NID_TO_SN[ NID_jurisdictionLocalityName ] = SN_jurisdictionLocalityName; NID_TO_SN[ NID_jurisdictionStateOrProvinceName ] = SN_jurisdictionStateOrProvinceName; NID_TO_SN[ NID_jurisdictionCountryName ] = SN_jurisdictionCountryName; } private static final String[] NID_TO_LN = new String[ 958 ]; static { NID_TO_LN[ NID_undef ] = LN_undef; NID_TO_LN[ NID_itu_t ] = LN_itu_t; NID_TO_LN[ NID_iso ] = LN_iso; NID_TO_LN[ NID_joint_iso_itu_t ] = LN_joint_iso_itu_t; NID_TO_LN[ NID_member_body ] = LN_member_body; NID_TO_LN[ NID_hmac_md5 ] = LN_hmac_md5; NID_TO_LN[ NID_hmac_sha1 ] = LN_hmac_sha1; NID_TO_LN[ NID_international_organizations ] = LN_international_organizations; NID_TO_LN[ NID_selected_attribute_types ] = LN_selected_attribute_types; NID_TO_LN[ NID_ISO_US ] = LN_ISO_US; NID_TO_LN[ NID_X9_57 ] = LN_X9_57; NID_TO_LN[ NID_X9cm ] = LN_X9cm; NID_TO_LN[ NID_dsa ] = LN_dsa; NID_TO_LN[ NID_dsaWithSHA1 ] = LN_dsaWithSHA1; NID_TO_LN[ NID_ansi_X9_62 ] = LN_ansi_X9_62; NID_TO_LN[ NID_cast5_cbc ] = LN_cast5_cbc; NID_TO_LN[ NID_cast5_ecb ] = LN_cast5_ecb; NID_TO_LN[ NID_cast5_cfb64 ] = LN_cast5_cfb64; NID_TO_LN[ NID_cast5_ofb64 ] = LN_cast5_ofb64; NID_TO_LN[ NID_pbeWithMD5AndCast5_CBC ] = LN_pbeWithMD5AndCast5_CBC; NID_TO_LN[ NID_id_PasswordBasedMAC ] = LN_id_PasswordBasedMAC; NID_TO_LN[ NID_id_DHBasedMac ] = LN_id_DHBasedMac; NID_TO_LN[ NID_rsadsi ] = LN_rsadsi; NID_TO_LN[ NID_pkcs ] = LN_pkcs; NID_TO_LN[ NID_rsaEncryption ] = LN_rsaEncryption; NID_TO_LN[ NID_md2WithRSAEncryption ] = LN_md2WithRSAEncryption; NID_TO_LN[ NID_md4WithRSAEncryption ] = LN_md4WithRSAEncryption; NID_TO_LN[ NID_md5WithRSAEncryption ] = LN_md5WithRSAEncryption; NID_TO_LN[ NID_sha1WithRSAEncryption ] = LN_sha1WithRSAEncryption; NID_TO_LN[ NID_rsaesOaep ] = LN_rsaesOaep; NID_TO_LN[ NID_mgf1 ] = LN_mgf1; NID_TO_LN[ NID_pSpecified ] = LN_pSpecified; NID_TO_LN[ NID_rsassaPss ] = LN_rsassaPss; NID_TO_LN[ NID_sha256WithRSAEncryption ] = LN_sha256WithRSAEncryption; NID_TO_LN[ NID_sha384WithRSAEncryption ] = LN_sha384WithRSAEncryption; NID_TO_LN[ NID_sha512WithRSAEncryption ] = LN_sha512WithRSAEncryption; NID_TO_LN[ NID_sha224WithRSAEncryption ] = LN_sha224WithRSAEncryption; NID_TO_LN[ NID_dhKeyAgreement ] = LN_dhKeyAgreement; NID_TO_LN[ NID_pbeWithMD2AndDES_CBC ] = LN_pbeWithMD2AndDES_CBC; NID_TO_LN[ NID_pbeWithMD5AndDES_CBC ] = LN_pbeWithMD5AndDES_CBC; NID_TO_LN[ NID_pbeWithMD2AndRC2_CBC ] = LN_pbeWithMD2AndRC2_CBC; NID_TO_LN[ NID_pbeWithMD5AndRC2_CBC ] = LN_pbeWithMD5AndRC2_CBC; NID_TO_LN[ NID_pbeWithSHA1AndDES_CBC ] = LN_pbeWithSHA1AndDES_CBC; NID_TO_LN[ NID_pbeWithSHA1AndRC2_CBC ] = LN_pbeWithSHA1AndRC2_CBC; NID_TO_LN[ NID_id_pbkdf2 ] = LN_id_pbkdf2; NID_TO_LN[ NID_pbes2 ] = LN_pbes2; NID_TO_LN[ NID_pbmac1 ] = LN_pbmac1; NID_TO_LN[ NID_pkcs7_data ] = LN_pkcs7_data; NID_TO_LN[ NID_pkcs7_signed ] = LN_pkcs7_signed; NID_TO_LN[ NID_pkcs7_enveloped ] = LN_pkcs7_enveloped; NID_TO_LN[ NID_pkcs7_signedAndEnveloped ] = LN_pkcs7_signedAndEnveloped; NID_TO_LN[ NID_pkcs7_digest ] = LN_pkcs7_digest; NID_TO_LN[ NID_pkcs7_encrypted ] = LN_pkcs7_encrypted; NID_TO_LN[ NID_pkcs9_emailAddress ] = LN_pkcs9_emailAddress; NID_TO_LN[ NID_pkcs9_unstructuredName ] = LN_pkcs9_unstructuredName; NID_TO_LN[ NID_pkcs9_contentType ] = LN_pkcs9_contentType; NID_TO_LN[ NID_pkcs9_messageDigest ] = LN_pkcs9_messageDigest; NID_TO_LN[ NID_pkcs9_signingTime ] = LN_pkcs9_signingTime; NID_TO_LN[ NID_pkcs9_countersignature ] = LN_pkcs9_countersignature; NID_TO_LN[ NID_pkcs9_challengePassword ] = LN_pkcs9_challengePassword; NID_TO_LN[ NID_pkcs9_unstructuredAddress ] = LN_pkcs9_unstructuredAddress; NID_TO_LN[ NID_pkcs9_extCertAttributes ] = LN_pkcs9_extCertAttributes; NID_TO_LN[ NID_ext_req ] = LN_ext_req; NID_TO_LN[ NID_SMIMECapabilities ] = LN_SMIMECapabilities; NID_TO_LN[ NID_SMIME ] = LN_SMIME; NID_TO_LN[ NID_friendlyName ] = LN_friendlyName; NID_TO_LN[ NID_localKeyID ] = LN_localKeyID; NID_TO_LN[ NID_ms_csp_name ] = LN_ms_csp_name; NID_TO_LN[ NID_LocalKeySet ] = LN_LocalKeySet; NID_TO_LN[ NID_x509Certificate ] = LN_x509Certificate; NID_TO_LN[ NID_sdsiCertificate ] = LN_sdsiCertificate; NID_TO_LN[ NID_x509Crl ] = LN_x509Crl; NID_TO_LN[ NID_pbe_WithSHA1And128BitRC4 ] = LN_pbe_WithSHA1And128BitRC4; NID_TO_LN[ NID_pbe_WithSHA1And40BitRC4 ] = LN_pbe_WithSHA1And40BitRC4; NID_TO_LN[ NID_pbe_WithSHA1And3_Key_TripleDES_CBC ] = LN_pbe_WithSHA1And3_Key_TripleDES_CBC; NID_TO_LN[ NID_pbe_WithSHA1And2_Key_TripleDES_CBC ] = LN_pbe_WithSHA1And2_Key_TripleDES_CBC; NID_TO_LN[ NID_pbe_WithSHA1And128BitRC2_CBC ] = LN_pbe_WithSHA1And128BitRC2_CBC; NID_TO_LN[ NID_pbe_WithSHA1And40BitRC2_CBC ] = LN_pbe_WithSHA1And40BitRC2_CBC; NID_TO_LN[ NID_keyBag ] = LN_keyBag; NID_TO_LN[ NID_pkcs8ShroudedKeyBag ] = LN_pkcs8ShroudedKeyBag; NID_TO_LN[ NID_certBag ] = LN_certBag; NID_TO_LN[ NID_crlBag ] = LN_crlBag; NID_TO_LN[ NID_secretBag ] = LN_secretBag; NID_TO_LN[ NID_safeContentsBag ] = LN_safeContentsBag; NID_TO_LN[ NID_md2 ] = LN_md2; NID_TO_LN[ NID_md4 ] = LN_md4; NID_TO_LN[ NID_md5 ] = LN_md5; NID_TO_LN[ NID_md5_sha1 ] = LN_md5_sha1; NID_TO_LN[ NID_hmacWithMD5 ] = LN_hmacWithMD5; NID_TO_LN[ NID_hmacWithSHA1 ] = LN_hmacWithSHA1; NID_TO_LN[ NID_hmacWithSHA224 ] = LN_hmacWithSHA224; NID_TO_LN[ NID_hmacWithSHA256 ] = LN_hmacWithSHA256; NID_TO_LN[ NID_hmacWithSHA384 ] = LN_hmacWithSHA384; NID_TO_LN[ NID_hmacWithSHA512 ] = LN_hmacWithSHA512; NID_TO_LN[ NID_rc2_cbc ] = LN_rc2_cbc; NID_TO_LN[ NID_rc2_ecb ] = LN_rc2_ecb; NID_TO_LN[ NID_rc2_cfb64 ] = LN_rc2_cfb64; NID_TO_LN[ NID_rc2_ofb64 ] = LN_rc2_ofb64; NID_TO_LN[ NID_rc2_40_cbc ] = LN_rc2_40_cbc; NID_TO_LN[ NID_rc2_64_cbc ] = LN_rc2_64_cbc; NID_TO_LN[ NID_rc4 ] = LN_rc4; NID_TO_LN[ NID_rc4_40 ] = LN_rc4_40; NID_TO_LN[ NID_des_ede3_cbc ] = LN_des_ede3_cbc; NID_TO_LN[ NID_rc5_cbc ] = LN_rc5_cbc; NID_TO_LN[ NID_rc5_ecb ] = LN_rc5_ecb; NID_TO_LN[ NID_rc5_cfb64 ] = LN_rc5_cfb64; NID_TO_LN[ NID_rc5_ofb64 ] = LN_rc5_ofb64; NID_TO_LN[ NID_ms_ext_req ] = LN_ms_ext_req; NID_TO_LN[ NID_ms_code_ind ] = LN_ms_code_ind; NID_TO_LN[ NID_ms_code_com ] = LN_ms_code_com; NID_TO_LN[ NID_ms_ctl_sign ] = LN_ms_ctl_sign; NID_TO_LN[ NID_ms_sgc ] = LN_ms_sgc; NID_TO_LN[ NID_ms_efs ] = LN_ms_efs; NID_TO_LN[ NID_ms_smartcard_login ] = LN_ms_smartcard_login; NID_TO_LN[ NID_ms_upn ] = LN_ms_upn; NID_TO_LN[ NID_idea_cbc ] = LN_idea_cbc; NID_TO_LN[ NID_idea_ecb ] = LN_idea_ecb; NID_TO_LN[ NID_idea_cfb64 ] = LN_idea_cfb64; NID_TO_LN[ NID_idea_ofb64 ] = LN_idea_ofb64; NID_TO_LN[ NID_bf_cbc ] = LN_bf_cbc; NID_TO_LN[ NID_bf_ecb ] = LN_bf_ecb; NID_TO_LN[ NID_bf_cfb64 ] = LN_bf_cfb64; NID_TO_LN[ NID_bf_ofb64 ] = LN_bf_ofb64; NID_TO_LN[ NID_info_access ] = LN_info_access; NID_TO_LN[ NID_biometricInfo ] = LN_biometricInfo; NID_TO_LN[ NID_sinfo_access ] = LN_sinfo_access; NID_TO_LN[ NID_proxyCertInfo ] = LN_proxyCertInfo; NID_TO_LN[ NID_id_qt_cps ] = LN_id_qt_cps; NID_TO_LN[ NID_id_qt_unotice ] = LN_id_qt_unotice; NID_TO_LN[ NID_server_auth ] = LN_server_auth; NID_TO_LN[ NID_client_auth ] = LN_client_auth; NID_TO_LN[ NID_code_sign ] = LN_code_sign; NID_TO_LN[ NID_email_protect ] = LN_email_protect; NID_TO_LN[ NID_ipsecEndSystem ] = LN_ipsecEndSystem; NID_TO_LN[ NID_ipsecTunnel ] = LN_ipsecTunnel; NID_TO_LN[ NID_ipsecUser ] = LN_ipsecUser; NID_TO_LN[ NID_time_stamp ] = LN_time_stamp; NID_TO_LN[ NID_OCSP_sign ] = LN_OCSP_sign; NID_TO_LN[ NID_dvcs ] = LN_dvcs; NID_TO_LN[ NID_id_on_permanentIdentifier ] = LN_id_on_permanentIdentifier; NID_TO_LN[ NID_id_ppl_anyLanguage ] = LN_id_ppl_anyLanguage; NID_TO_LN[ NID_id_ppl_inheritAll ] = LN_id_ppl_inheritAll; NID_TO_LN[ NID_Independent ] = LN_Independent; NID_TO_LN[ NID_ad_OCSP ] = LN_ad_OCSP; NID_TO_LN[ NID_ad_ca_issuers ] = LN_ad_ca_issuers; NID_TO_LN[ NID_ad_timeStamping ] = LN_ad_timeStamping; NID_TO_LN[ NID_ad_dvcs ] = LN_ad_dvcs; NID_TO_LN[ NID_caRepository ] = LN_caRepository; NID_TO_LN[ NID_id_pkix_OCSP_basic ] = LN_id_pkix_OCSP_basic; NID_TO_LN[ NID_id_pkix_OCSP_Nonce ] = LN_id_pkix_OCSP_Nonce; NID_TO_LN[ NID_id_pkix_OCSP_CrlID ] = LN_id_pkix_OCSP_CrlID; NID_TO_LN[ NID_id_pkix_OCSP_acceptableResponses ] = LN_id_pkix_OCSP_acceptableResponses; NID_TO_LN[ NID_id_pkix_OCSP_noCheck ] = LN_id_pkix_OCSP_noCheck; NID_TO_LN[ NID_id_pkix_OCSP_archiveCutoff ] = LN_id_pkix_OCSP_archiveCutoff; NID_TO_LN[ NID_id_pkix_OCSP_serviceLocator ] = LN_id_pkix_OCSP_serviceLocator; NID_TO_LN[ NID_id_pkix_OCSP_extendedStatus ] = LN_id_pkix_OCSP_extendedStatus; NID_TO_LN[ NID_id_pkix_OCSP_trustRoot ] = LN_id_pkix_OCSP_trustRoot; NID_TO_LN[ NID_algorithm ] = LN_algorithm; NID_TO_LN[ NID_md5WithRSA ] = LN_md5WithRSA; NID_TO_LN[ NID_des_ecb ] = LN_des_ecb; NID_TO_LN[ NID_des_cbc ] = LN_des_cbc; NID_TO_LN[ NID_des_ofb64 ] = LN_des_ofb64; NID_TO_LN[ NID_des_cfb64 ] = LN_des_cfb64; NID_TO_LN[ NID_dsa_2 ] = LN_dsa_2; NID_TO_LN[ NID_dsaWithSHA ] = LN_dsaWithSHA; NID_TO_LN[ NID_shaWithRSAEncryption ] = LN_shaWithRSAEncryption; NID_TO_LN[ NID_des_ede_ecb ] = LN_des_ede_ecb; NID_TO_LN[ NID_des_ede3_ecb ] = LN_des_ede3_ecb; NID_TO_LN[ NID_des_ede_cbc ] = LN_des_ede_cbc; NID_TO_LN[ NID_des_ede_cfb64 ] = LN_des_ede_cfb64; NID_TO_LN[ NID_des_ede3_cfb64 ] = LN_des_ede3_cfb64; NID_TO_LN[ NID_des_ede_ofb64 ] = LN_des_ede_ofb64; NID_TO_LN[ NID_des_ede3_ofb64 ] = LN_des_ede3_ofb64; NID_TO_LN[ NID_desx_cbc ] = LN_desx_cbc; NID_TO_LN[ NID_sha ] = LN_sha; NID_TO_LN[ NID_sha1 ] = LN_sha1; NID_TO_LN[ NID_dsaWithSHA1_2 ] = LN_dsaWithSHA1_2; NID_TO_LN[ NID_sha1WithRSA ] = LN_sha1WithRSA; NID_TO_LN[ NID_ripemd160 ] = LN_ripemd160; NID_TO_LN[ NID_ripemd160WithRSA ] = LN_ripemd160WithRSA; NID_TO_LN[ NID_sxnet ] = LN_sxnet; NID_TO_LN[ NID_X500 ] = LN_X500; NID_TO_LN[ NID_commonName ] = LN_commonName; NID_TO_LN[ NID_surname ] = LN_surname; NID_TO_LN[ NID_serialNumber ] = LN_serialNumber; NID_TO_LN[ NID_countryName ] = LN_countryName; NID_TO_LN[ NID_localityName ] = LN_localityName; NID_TO_LN[ NID_stateOrProvinceName ] = LN_stateOrProvinceName; NID_TO_LN[ NID_streetAddress ] = LN_streetAddress; NID_TO_LN[ NID_organizationName ] = LN_organizationName; NID_TO_LN[ NID_organizationalUnitName ] = LN_organizationalUnitName; NID_TO_LN[ NID_title ] = LN_title; NID_TO_LN[ NID_description ] = LN_description; NID_TO_LN[ NID_searchGuide ] = LN_searchGuide; NID_TO_LN[ NID_businessCategory ] = LN_businessCategory; NID_TO_LN[ NID_postalAddress ] = LN_postalAddress; NID_TO_LN[ NID_postalCode ] = LN_postalCode; NID_TO_LN[ NID_postOfficeBox ] = LN_postOfficeBox; NID_TO_LN[ NID_physicalDeliveryOfficeName ] = LN_physicalDeliveryOfficeName; NID_TO_LN[ NID_telephoneNumber ] = LN_telephoneNumber; NID_TO_LN[ NID_telexNumber ] = LN_telexNumber; NID_TO_LN[ NID_teletexTerminalIdentifier ] = LN_teletexTerminalIdentifier; NID_TO_LN[ NID_facsimileTelephoneNumber ] = LN_facsimileTelephoneNumber; NID_TO_LN[ NID_x121Address ] = LN_x121Address; NID_TO_LN[ NID_internationaliSDNNumber ] = LN_internationaliSDNNumber; NID_TO_LN[ NID_registeredAddress ] = LN_registeredAddress; NID_TO_LN[ NID_destinationIndicator ] = LN_destinationIndicator; NID_TO_LN[ NID_preferredDeliveryMethod ] = LN_preferredDeliveryMethod; NID_TO_LN[ NID_presentationAddress ] = LN_presentationAddress; NID_TO_LN[ NID_supportedApplicationContext ] = LN_supportedApplicationContext; NID_TO_LN[ NID_roleOccupant ] = LN_roleOccupant; NID_TO_LN[ NID_userPassword ] = LN_userPassword; NID_TO_LN[ NID_userCertificate ] = LN_userCertificate; NID_TO_LN[ NID_cACertificate ] = LN_cACertificate; NID_TO_LN[ NID_authorityRevocationList ] = LN_authorityRevocationList; NID_TO_LN[ NID_certificateRevocationList ] = LN_certificateRevocationList; NID_TO_LN[ NID_crossCertificatePair ] = LN_crossCertificatePair; NID_TO_LN[ NID_name ] = LN_name; NID_TO_LN[ NID_givenName ] = LN_givenName; NID_TO_LN[ NID_initials ] = LN_initials; NID_TO_LN[ NID_generationQualifier ] = LN_generationQualifier; NID_TO_LN[ NID_x500UniqueIdentifier ] = LN_x500UniqueIdentifier; NID_TO_LN[ NID_dnQualifier ] = LN_dnQualifier; NID_TO_LN[ NID_enhancedSearchGuide ] = LN_enhancedSearchGuide; NID_TO_LN[ NID_protocolInformation ] = LN_protocolInformation; NID_TO_LN[ NID_distinguishedName ] = LN_distinguishedName; NID_TO_LN[ NID_uniqueMember ] = LN_uniqueMember; NID_TO_LN[ NID_houseIdentifier ] = LN_houseIdentifier; NID_TO_LN[ NID_supportedAlgorithms ] = LN_supportedAlgorithms; NID_TO_LN[ NID_deltaRevocationList ] = LN_deltaRevocationList; NID_TO_LN[ NID_pseudonym ] = LN_pseudonym; NID_TO_LN[ NID_role ] = LN_role; NID_TO_LN[ NID_X500algorithms ] = LN_X500algorithms; NID_TO_LN[ NID_rsa ] = LN_rsa; NID_TO_LN[ NID_mdc2WithRSA ] = LN_mdc2WithRSA; NID_TO_LN[ NID_mdc2 ] = LN_mdc2; NID_TO_LN[ NID_subject_directory_attributes ] = LN_subject_directory_attributes; NID_TO_LN[ NID_subject_key_identifier ] = LN_subject_key_identifier; NID_TO_LN[ NID_key_usage ] = LN_key_usage; NID_TO_LN[ NID_private_key_usage_period ] = LN_private_key_usage_period; NID_TO_LN[ NID_subject_alt_name ] = LN_subject_alt_name; NID_TO_LN[ NID_issuer_alt_name ] = LN_issuer_alt_name; NID_TO_LN[ NID_basic_constraints ] = LN_basic_constraints; NID_TO_LN[ NID_crl_number ] = LN_crl_number; NID_TO_LN[ NID_crl_reason ] = LN_crl_reason; NID_TO_LN[ NID_invalidity_date ] = LN_invalidity_date; NID_TO_LN[ NID_delta_crl ] = LN_delta_crl; NID_TO_LN[ NID_issuing_distribution_point ] = LN_issuing_distribution_point; NID_TO_LN[ NID_certificate_issuer ] = LN_certificate_issuer; NID_TO_LN[ NID_name_constraints ] = LN_name_constraints; NID_TO_LN[ NID_crl_distribution_points ] = LN_crl_distribution_points; NID_TO_LN[ NID_certificate_policies ] = LN_certificate_policies; NID_TO_LN[ NID_any_policy ] = LN_any_policy; NID_TO_LN[ NID_policy_mappings ] = LN_policy_mappings; NID_TO_LN[ NID_authority_key_identifier ] = LN_authority_key_identifier; NID_TO_LN[ NID_policy_constraints ] = LN_policy_constraints; NID_TO_LN[ NID_ext_key_usage ] = LN_ext_key_usage; NID_TO_LN[ NID_freshest_crl ] = LN_freshest_crl; NID_TO_LN[ NID_inhibit_any_policy ] = LN_inhibit_any_policy; NID_TO_LN[ NID_target_information ] = LN_target_information; NID_TO_LN[ NID_no_rev_avail ] = LN_no_rev_avail; NID_TO_LN[ NID_anyExtendedKeyUsage ] = LN_anyExtendedKeyUsage; NID_TO_LN[ NID_netscape ] = LN_netscape; NID_TO_LN[ NID_netscape_cert_extension ] = LN_netscape_cert_extension; NID_TO_LN[ NID_netscape_data_type ] = LN_netscape_data_type; NID_TO_LN[ NID_netscape_cert_type ] = LN_netscape_cert_type; NID_TO_LN[ NID_netscape_base_url ] = LN_netscape_base_url; NID_TO_LN[ NID_netscape_revocation_url ] = LN_netscape_revocation_url; NID_TO_LN[ NID_netscape_ca_revocation_url ] = LN_netscape_ca_revocation_url; NID_TO_LN[ NID_netscape_renewal_url ] = LN_netscape_renewal_url; NID_TO_LN[ NID_netscape_ca_policy_url ] = LN_netscape_ca_policy_url; NID_TO_LN[ NID_netscape_ssl_server_name ] = LN_netscape_ssl_server_name; NID_TO_LN[ NID_netscape_comment ] = LN_netscape_comment; NID_TO_LN[ NID_netscape_cert_sequence ] = LN_netscape_cert_sequence; NID_TO_LN[ NID_ns_sgc ] = LN_ns_sgc; NID_TO_LN[ NID_org ] = LN_org; NID_TO_LN[ NID_dod ] = LN_dod; NID_TO_LN[ NID_iana ] = LN_iana; NID_TO_LN[ NID_Directory ] = LN_Directory; NID_TO_LN[ NID_Management ] = LN_Management; NID_TO_LN[ NID_Experimental ] = LN_Experimental; NID_TO_LN[ NID_Private ] = LN_Private; NID_TO_LN[ NID_Security ] = LN_Security; NID_TO_LN[ NID_SNMPv2 ] = LN_SNMPv2; NID_TO_LN[ NID_Mail ] = LN_Mail; NID_TO_LN[ NID_Enterprises ] = LN_Enterprises; NID_TO_LN[ NID_dcObject ] = LN_dcObject; NID_TO_LN[ NID_mime_mhs ] = LN_mime_mhs; NID_TO_LN[ NID_mime_mhs_headings ] = LN_mime_mhs_headings; NID_TO_LN[ NID_mime_mhs_bodies ] = LN_mime_mhs_bodies; NID_TO_LN[ NID_id_hex_partial_message ] = LN_id_hex_partial_message; NID_TO_LN[ NID_id_hex_multipart_message ] = LN_id_hex_multipart_message; NID_TO_LN[ NID_rle_compression ] = LN_rle_compression; NID_TO_LN[ NID_zlib_compression ] = LN_zlib_compression; NID_TO_LN[ NID_aes_128_ecb ] = LN_aes_128_ecb; NID_TO_LN[ NID_aes_128_cbc ] = LN_aes_128_cbc; NID_TO_LN[ NID_aes_128_ofb128 ] = LN_aes_128_ofb128; NID_TO_LN[ NID_aes_128_cfb128 ] = LN_aes_128_cfb128; NID_TO_LN[ NID_aes_128_gcm ] = LN_aes_128_gcm; NID_TO_LN[ NID_aes_128_ccm ] = LN_aes_128_ccm; NID_TO_LN[ NID_aes_192_ecb ] = LN_aes_192_ecb; NID_TO_LN[ NID_aes_192_cbc ] = LN_aes_192_cbc; NID_TO_LN[ NID_aes_192_ofb128 ] = LN_aes_192_ofb128; NID_TO_LN[ NID_aes_192_cfb128 ] = LN_aes_192_cfb128; NID_TO_LN[ NID_aes_192_gcm ] = LN_aes_192_gcm; NID_TO_LN[ NID_aes_192_ccm ] = LN_aes_192_ccm; NID_TO_LN[ NID_aes_256_ecb ] = LN_aes_256_ecb; NID_TO_LN[ NID_aes_256_cbc ] = LN_aes_256_cbc; NID_TO_LN[ NID_aes_256_ofb128 ] = LN_aes_256_ofb128; NID_TO_LN[ NID_aes_256_cfb128 ] = LN_aes_256_cfb128; NID_TO_LN[ NID_aes_256_gcm ] = LN_aes_256_gcm; NID_TO_LN[ NID_aes_256_ccm ] = LN_aes_256_ccm; NID_TO_LN[ NID_aes_128_cfb1 ] = LN_aes_128_cfb1; NID_TO_LN[ NID_aes_192_cfb1 ] = LN_aes_192_cfb1; NID_TO_LN[ NID_aes_256_cfb1 ] = LN_aes_256_cfb1; NID_TO_LN[ NID_aes_128_cfb8 ] = LN_aes_128_cfb8; NID_TO_LN[ NID_aes_192_cfb8 ] = LN_aes_192_cfb8; NID_TO_LN[ NID_aes_256_cfb8 ] = LN_aes_256_cfb8; NID_TO_LN[ NID_aes_128_ctr ] = LN_aes_128_ctr; NID_TO_LN[ NID_aes_192_ctr ] = LN_aes_192_ctr; NID_TO_LN[ NID_aes_256_ctr ] = LN_aes_256_ctr; NID_TO_LN[ NID_aes_128_xts ] = LN_aes_128_xts; NID_TO_LN[ NID_aes_256_xts ] = LN_aes_256_xts; NID_TO_LN[ NID_des_cfb1 ] = LN_des_cfb1; NID_TO_LN[ NID_des_cfb8 ] = LN_des_cfb8; NID_TO_LN[ NID_des_ede3_cfb1 ] = LN_des_ede3_cfb1; NID_TO_LN[ NID_des_ede3_cfb8 ] = LN_des_ede3_cfb8; NID_TO_LN[ NID_sha256 ] = LN_sha256; NID_TO_LN[ NID_sha384 ] = LN_sha384; NID_TO_LN[ NID_sha512 ] = LN_sha512; NID_TO_LN[ NID_sha224 ] = LN_sha224; NID_TO_LN[ NID_hold_instruction_code ] = LN_hold_instruction_code; NID_TO_LN[ NID_hold_instruction_none ] = LN_hold_instruction_none; NID_TO_LN[ NID_hold_instruction_call_issuer ] = LN_hold_instruction_call_issuer; NID_TO_LN[ NID_hold_instruction_reject ] = LN_hold_instruction_reject; NID_TO_LN[ NID_pilotAttributeType ] = LN_pilotAttributeType; NID_TO_LN[ NID_pilotAttributeSyntax ] = LN_pilotAttributeSyntax; NID_TO_LN[ NID_pilotObjectClass ] = LN_pilotObjectClass; NID_TO_LN[ NID_pilotGroups ] = LN_pilotGroups; NID_TO_LN[ NID_iA5StringSyntax ] = LN_iA5StringSyntax; NID_TO_LN[ NID_caseIgnoreIA5StringSyntax ] = LN_caseIgnoreIA5StringSyntax; NID_TO_LN[ NID_pilotObject ] = LN_pilotObject; NID_TO_LN[ NID_pilotPerson ] = LN_pilotPerson; NID_TO_LN[ NID_documentSeries ] = LN_documentSeries; NID_TO_LN[ NID_Domain ] = LN_Domain; NID_TO_LN[ NID_rFC822localPart ] = LN_rFC822localPart; NID_TO_LN[ NID_dNSDomain ] = LN_dNSDomain; NID_TO_LN[ NID_domainRelatedObject ] = LN_domainRelatedObject; NID_TO_LN[ NID_friendlyCountry ] = LN_friendlyCountry; NID_TO_LN[ NID_simpleSecurityObject ] = LN_simpleSecurityObject; NID_TO_LN[ NID_pilotOrganization ] = LN_pilotOrganization; NID_TO_LN[ NID_pilotDSA ] = LN_pilotDSA; NID_TO_LN[ NID_qualityLabelledData ] = LN_qualityLabelledData; NID_TO_LN[ NID_userId ] = LN_userId; NID_TO_LN[ NID_textEncodedORAddress ] = LN_textEncodedORAddress; NID_TO_LN[ NID_rfc822Mailbox ] = LN_rfc822Mailbox; NID_TO_LN[ NID_favouriteDrink ] = LN_favouriteDrink; NID_TO_LN[ NID_roomNumber ] = LN_roomNumber; NID_TO_LN[ NID_userClass ] = LN_userClass; NID_TO_LN[ NID_documentIdentifier ] = LN_documentIdentifier; NID_TO_LN[ NID_documentTitle ] = LN_documentTitle; NID_TO_LN[ NID_documentVersion ] = LN_documentVersion; NID_TO_LN[ NID_documentAuthor ] = LN_documentAuthor; NID_TO_LN[ NID_documentLocation ] = LN_documentLocation; NID_TO_LN[ NID_homeTelephoneNumber ] = LN_homeTelephoneNumber; NID_TO_LN[ NID_otherMailbox ] = LN_otherMailbox; NID_TO_LN[ NID_lastModifiedTime ] = LN_lastModifiedTime; NID_TO_LN[ NID_lastModifiedBy ] = LN_lastModifiedBy; NID_TO_LN[ NID_domainComponent ] = LN_domainComponent; NID_TO_LN[ NID_aRecord ] = LN_aRecord; NID_TO_LN[ NID_pilotAttributeType27 ] = LN_pilotAttributeType27; NID_TO_LN[ NID_mXRecord ] = LN_mXRecord; NID_TO_LN[ NID_nSRecord ] = LN_nSRecord; NID_TO_LN[ NID_sOARecord ] = LN_sOARecord; NID_TO_LN[ NID_cNAMERecord ] = LN_cNAMERecord; NID_TO_LN[ NID_associatedDomain ] = LN_associatedDomain; NID_TO_LN[ NID_associatedName ] = LN_associatedName; NID_TO_LN[ NID_homePostalAddress ] = LN_homePostalAddress; NID_TO_LN[ NID_personalTitle ] = LN_personalTitle; NID_TO_LN[ NID_mobileTelephoneNumber ] = LN_mobileTelephoneNumber; NID_TO_LN[ NID_pagerTelephoneNumber ] = LN_pagerTelephoneNumber; NID_TO_LN[ NID_friendlyCountryName ] = LN_friendlyCountryName; NID_TO_LN[ NID_organizationalStatus ] = LN_organizationalStatus; NID_TO_LN[ NID_janetMailbox ] = LN_janetMailbox; NID_TO_LN[ NID_mailPreferenceOption ] = LN_mailPreferenceOption; NID_TO_LN[ NID_buildingName ] = LN_buildingName; NID_TO_LN[ NID_dSAQuality ] = LN_dSAQuality; NID_TO_LN[ NID_singleLevelQuality ] = LN_singleLevelQuality; NID_TO_LN[ NID_subtreeMinimumQuality ] = LN_subtreeMinimumQuality; NID_TO_LN[ NID_subtreeMaximumQuality ] = LN_subtreeMaximumQuality; NID_TO_LN[ NID_personalSignature ] = LN_personalSignature; NID_TO_LN[ NID_dITRedirect ] = LN_dITRedirect; NID_TO_LN[ NID_documentPublisher ] = LN_documentPublisher; NID_TO_LN[ NID_id_set ] = LN_id_set; NID_TO_LN[ NID_set_ctype ] = LN_set_ctype; NID_TO_LN[ NID_set_msgExt ] = LN_set_msgExt; NID_TO_LN[ NID_set_certExt ] = LN_set_certExt; NID_TO_LN[ NID_setext_genCrypt ] = LN_setext_genCrypt; NID_TO_LN[ NID_setext_miAuth ] = LN_setext_miAuth; NID_TO_LN[ NID_setext_cv ] = LN_setext_cv; NID_TO_LN[ NID_setAttr_PGWYcap ] = LN_setAttr_PGWYcap; NID_TO_LN[ NID_setAttr_IssCap ] = LN_setAttr_IssCap; NID_TO_LN[ NID_setAttr_GenCryptgrm ] = LN_setAttr_GenCryptgrm; NID_TO_LN[ NID_setAttr_T2Enc ] = LN_setAttr_T2Enc; NID_TO_LN[ NID_setAttr_T2cleartxt ] = LN_setAttr_T2cleartxt; NID_TO_LN[ NID_setAttr_TokICCsig ] = LN_setAttr_TokICCsig; NID_TO_LN[ NID_setAttr_SecDevSig ] = LN_setAttr_SecDevSig; NID_TO_LN[ NID_des_cdmf ] = LN_des_cdmf; NID_TO_LN[ NID_ipsec3 ] = LN_ipsec3; NID_TO_LN[ NID_ipsec4 ] = LN_ipsec4; NID_TO_LN[ NID_id_GostR3411_94_with_GostR3410_2001 ] = LN_id_GostR3411_94_with_GostR3410_2001; NID_TO_LN[ NID_id_GostR3411_94_with_GostR3410_94 ] = LN_id_GostR3411_94_with_GostR3410_94; NID_TO_LN[ NID_id_GostR3411_94 ] = LN_id_GostR3411_94; NID_TO_LN[ NID_id_HMACGostR3411_94 ] = LN_id_HMACGostR3411_94; NID_TO_LN[ NID_id_GostR3410_2001 ] = LN_id_GostR3410_2001; NID_TO_LN[ NID_id_GostR3410_94 ] = LN_id_GostR3410_94; NID_TO_LN[ NID_id_Gost28147_89 ] = LN_id_Gost28147_89; NID_TO_LN[ NID_id_Gost28147_89_MAC ] = LN_id_Gost28147_89_MAC; NID_TO_LN[ NID_id_GostR3411_94_prf ] = LN_id_GostR3411_94_prf; NID_TO_LN[ NID_id_GostR3410_2001DH ] = LN_id_GostR3410_2001DH; NID_TO_LN[ NID_id_GostR3410_94DH ] = LN_id_GostR3410_94DH; NID_TO_LN[ NID_id_Gost28147_89_cc ] = LN_id_Gost28147_89_cc; NID_TO_LN[ NID_id_GostR3410_94_cc ] = LN_id_GostR3410_94_cc; NID_TO_LN[ NID_id_GostR3410_2001_cc ] = LN_id_GostR3410_2001_cc; NID_TO_LN[ NID_id_GostR3411_94_with_GostR3410_94_cc ] = LN_id_GostR3411_94_with_GostR3410_94_cc; NID_TO_LN[ NID_id_GostR3411_94_with_GostR3410_2001_cc ] = LN_id_GostR3411_94_with_GostR3410_2001_cc; NID_TO_LN[ NID_id_GostR3410_2001_ParamSet_cc ] = LN_id_GostR3410_2001_ParamSet_cc; NID_TO_LN[ NID_camellia_128_cbc ] = LN_camellia_128_cbc; NID_TO_LN[ NID_camellia_192_cbc ] = LN_camellia_192_cbc; NID_TO_LN[ NID_camellia_256_cbc ] = LN_camellia_256_cbc; NID_TO_LN[ NID_camellia_128_ecb ] = LN_camellia_128_ecb; NID_TO_LN[ NID_camellia_128_ofb128 ] = LN_camellia_128_ofb128; NID_TO_LN[ NID_camellia_128_cfb128 ] = LN_camellia_128_cfb128; NID_TO_LN[ NID_camellia_192_ecb ] = LN_camellia_192_ecb; NID_TO_LN[ NID_camellia_192_ofb128 ] = LN_camellia_192_ofb128; NID_TO_LN[ NID_camellia_192_cfb128 ] = LN_camellia_192_cfb128; NID_TO_LN[ NID_camellia_256_ecb ] = LN_camellia_256_ecb; NID_TO_LN[ NID_camellia_256_ofb128 ] = LN_camellia_256_ofb128; NID_TO_LN[ NID_camellia_256_cfb128 ] = LN_camellia_256_cfb128; NID_TO_LN[ NID_camellia_128_cfb1 ] = LN_camellia_128_cfb1; NID_TO_LN[ NID_camellia_192_cfb1 ] = LN_camellia_192_cfb1; NID_TO_LN[ NID_camellia_256_cfb1 ] = LN_camellia_256_cfb1; NID_TO_LN[ NID_camellia_128_cfb8 ] = LN_camellia_128_cfb8; NID_TO_LN[ NID_camellia_192_cfb8 ] = LN_camellia_192_cfb8; NID_TO_LN[ NID_camellia_256_cfb8 ] = LN_camellia_256_cfb8; NID_TO_LN[ NID_kisa ] = LN_kisa; NID_TO_LN[ NID_seed_ecb ] = LN_seed_ecb; NID_TO_LN[ NID_seed_cbc ] = LN_seed_cbc; NID_TO_LN[ NID_seed_cfb128 ] = LN_seed_cfb128; NID_TO_LN[ NID_seed_ofb128 ] = LN_seed_ofb128; NID_TO_LN[ NID_hmac ] = LN_hmac; NID_TO_LN[ NID_cmac ] = LN_cmac; NID_TO_LN[ NID_rc4_hmac_md5 ] = LN_rc4_hmac_md5; NID_TO_LN[ NID_aes_128_cbc_hmac_sha1 ] = LN_aes_128_cbc_hmac_sha1; NID_TO_LN[ NID_aes_192_cbc_hmac_sha1 ] = LN_aes_192_cbc_hmac_sha1; NID_TO_LN[ NID_aes_256_cbc_hmac_sha1 ] = LN_aes_256_cbc_hmac_sha1; NID_TO_LN[ NID_aes_128_cbc_hmac_sha256 ] = LN_aes_128_cbc_hmac_sha256; NID_TO_LN[ NID_aes_192_cbc_hmac_sha256 ] = LN_aes_192_cbc_hmac_sha256; NID_TO_LN[ NID_aes_256_cbc_hmac_sha256 ] = LN_aes_256_cbc_hmac_sha256; NID_TO_LN[ NID_dhpublicnumber ] = LN_dhpublicnumber; NID_TO_LN[ NID_ct_precert_scts ] = LN_ct_precert_scts; NID_TO_LN[ NID_ct_precert_poison ] = LN_ct_precert_poison; NID_TO_LN[ NID_ct_precert_signer ] = LN_ct_precert_signer; NID_TO_LN[ NID_ct_cert_scts ] = LN_ct_cert_scts; NID_TO_LN[ NID_jurisdictionLocalityName ] = LN_jurisdictionLocalityName; NID_TO_LN[ NID_jurisdictionStateOrProvinceName ] = LN_jurisdictionStateOrProvinceName; NID_TO_LN[ NID_jurisdictionCountryName ] = LN_jurisdictionCountryName; } private static final String[] NID_TO_OID = new String[ 958 ]; static { NID_TO_OID[ NID_undef ] = OBJ_undef; NID_TO_OID[ NID_itu_t ] = OBJ_itu_t; NID_TO_OID[ NID_ccitt ] = OBJ_ccitt; NID_TO_OID[ NID_iso ] = OBJ_iso; NID_TO_OID[ NID_joint_iso_itu_t ] = OBJ_joint_iso_itu_t; NID_TO_OID[ NID_joint_iso_ccitt ] = OBJ_joint_iso_ccitt; NID_TO_OID[ NID_member_body ] = OBJ_member_body; NID_TO_OID[ NID_identified_organization ] = OBJ_identified_organization; NID_TO_OID[ NID_hmac_md5 ] = OBJ_hmac_md5; NID_TO_OID[ NID_hmac_sha1 ] = OBJ_hmac_sha1; NID_TO_OID[ NID_certicom_arc ] = OBJ_certicom_arc; NID_TO_OID[ NID_international_organizations ] = OBJ_international_organizations; NID_TO_OID[ NID_wap ] = OBJ_wap; NID_TO_OID[ NID_wap_wsg ] = OBJ_wap_wsg; NID_TO_OID[ NID_selected_attribute_types ] = OBJ_selected_attribute_types; NID_TO_OID[ NID_clearance ] = OBJ_clearance; NID_TO_OID[ NID_ISO_US ] = OBJ_ISO_US; NID_TO_OID[ NID_X9_57 ] = OBJ_X9_57; NID_TO_OID[ NID_X9cm ] = OBJ_X9cm; NID_TO_OID[ NID_dsa ] = OBJ_dsa; NID_TO_OID[ NID_dsaWithSHA1 ] = OBJ_dsaWithSHA1; NID_TO_OID[ NID_ansi_X9_62 ] = OBJ_ansi_X9_62; NID_TO_OID[ NID_X9_62_prime_field ] = OBJ_X9_62_prime_field; NID_TO_OID[ NID_X9_62_characteristic_two_field ] = OBJ_X9_62_characteristic_two_field; NID_TO_OID[ NID_X9_62_id_characteristic_two_basis ] = OBJ_X9_62_id_characteristic_two_basis; NID_TO_OID[ NID_X9_62_onBasis ] = OBJ_X9_62_onBasis; NID_TO_OID[ NID_X9_62_tpBasis ] = OBJ_X9_62_tpBasis; NID_TO_OID[ NID_X9_62_ppBasis ] = OBJ_X9_62_ppBasis; NID_TO_OID[ NID_X9_62_id_ecPublicKey ] = OBJ_X9_62_id_ecPublicKey; NID_TO_OID[ NID_X9_62_c2pnb163v1 ] = OBJ_X9_62_c2pnb163v1; NID_TO_OID[ NID_X9_62_c2pnb163v2 ] = OBJ_X9_62_c2pnb163v2; NID_TO_OID[ NID_X9_62_c2pnb163v3 ] = OBJ_X9_62_c2pnb163v3; NID_TO_OID[ NID_X9_62_c2pnb176v1 ] = OBJ_X9_62_c2pnb176v1; NID_TO_OID[ NID_X9_62_c2tnb191v1 ] = OBJ_X9_62_c2tnb191v1; NID_TO_OID[ NID_X9_62_c2tnb191v2 ] = OBJ_X9_62_c2tnb191v2; NID_TO_OID[ NID_X9_62_c2tnb191v3 ] = OBJ_X9_62_c2tnb191v3; NID_TO_OID[ NID_X9_62_c2onb191v4 ] = OBJ_X9_62_c2onb191v4; NID_TO_OID[ NID_X9_62_c2onb191v5 ] = OBJ_X9_62_c2onb191v5; NID_TO_OID[ NID_X9_62_c2pnb208w1 ] = OBJ_X9_62_c2pnb208w1; NID_TO_OID[ NID_X9_62_c2tnb239v1 ] = OBJ_X9_62_c2tnb239v1; NID_TO_OID[ NID_X9_62_c2tnb239v2 ] = OBJ_X9_62_c2tnb239v2; NID_TO_OID[ NID_X9_62_c2tnb239v3 ] = OBJ_X9_62_c2tnb239v3; NID_TO_OID[ NID_X9_62_c2onb239v4 ] = OBJ_X9_62_c2onb239v4; NID_TO_OID[ NID_X9_62_c2onb239v5 ] = OBJ_X9_62_c2onb239v5; NID_TO_OID[ NID_X9_62_c2pnb272w1 ] = OBJ_X9_62_c2pnb272w1; NID_TO_OID[ NID_X9_62_c2pnb304w1 ] = OBJ_X9_62_c2pnb304w1; NID_TO_OID[ NID_X9_62_c2tnb359v1 ] = OBJ_X9_62_c2tnb359v1; NID_TO_OID[ NID_X9_62_c2pnb368w1 ] = OBJ_X9_62_c2pnb368w1; NID_TO_OID[ NID_X9_62_c2tnb431r1 ] = OBJ_X9_62_c2tnb431r1; NID_TO_OID[ NID_X9_62_prime192v1 ] = OBJ_X9_62_prime192v1; NID_TO_OID[ NID_X9_62_prime192v2 ] = OBJ_X9_62_prime192v2; NID_TO_OID[ NID_X9_62_prime192v3 ] = OBJ_X9_62_prime192v3; NID_TO_OID[ NID_X9_62_prime239v1 ] = OBJ_X9_62_prime239v1; NID_TO_OID[ NID_X9_62_prime239v2 ] = OBJ_X9_62_prime239v2; NID_TO_OID[ NID_X9_62_prime239v3 ] = OBJ_X9_62_prime239v3; NID_TO_OID[ NID_X9_62_prime256v1 ] = OBJ_X9_62_prime256v1; NID_TO_OID[ NID_ecdsa_with_SHA1 ] = OBJ_ecdsa_with_SHA1; NID_TO_OID[ NID_ecdsa_with_Recommended ] = OBJ_ecdsa_with_Recommended; NID_TO_OID[ NID_ecdsa_with_Specified ] = OBJ_ecdsa_with_Specified; NID_TO_OID[ NID_ecdsa_with_SHA224 ] = OBJ_ecdsa_with_SHA224; NID_TO_OID[ NID_ecdsa_with_SHA256 ] = OBJ_ecdsa_with_SHA256; NID_TO_OID[ NID_ecdsa_with_SHA384 ] = OBJ_ecdsa_with_SHA384; NID_TO_OID[ NID_ecdsa_with_SHA512 ] = OBJ_ecdsa_with_SHA512; NID_TO_OID[ NID_secp112r1 ] = OBJ_secp112r1; NID_TO_OID[ NID_secp112r2 ] = OBJ_secp112r2; NID_TO_OID[ NID_secp128r1 ] = OBJ_secp128r1; NID_TO_OID[ NID_secp128r2 ] = OBJ_secp128r2; NID_TO_OID[ NID_secp160k1 ] = OBJ_secp160k1; NID_TO_OID[ NID_secp160r1 ] = OBJ_secp160r1; NID_TO_OID[ NID_secp160r2 ] = OBJ_secp160r2; NID_TO_OID[ NID_secp192k1 ] = OBJ_secp192k1; NID_TO_OID[ NID_secp224k1 ] = OBJ_secp224k1; NID_TO_OID[ NID_secp224r1 ] = OBJ_secp224r1; NID_TO_OID[ NID_secp256k1 ] = OBJ_secp256k1; NID_TO_OID[ NID_secp384r1 ] = OBJ_secp384r1; NID_TO_OID[ NID_secp521r1 ] = OBJ_secp521r1; NID_TO_OID[ NID_sect113r1 ] = OBJ_sect113r1; NID_TO_OID[ NID_sect113r2 ] = OBJ_sect113r2; NID_TO_OID[ NID_sect131r1 ] = OBJ_sect131r1; NID_TO_OID[ NID_sect131r2 ] = OBJ_sect131r2; NID_TO_OID[ NID_sect163k1 ] = OBJ_sect163k1; NID_TO_OID[ NID_sect163r1 ] = OBJ_sect163r1; NID_TO_OID[ NID_sect163r2 ] = OBJ_sect163r2; NID_TO_OID[ NID_sect193r1 ] = OBJ_sect193r1; NID_TO_OID[ NID_sect193r2 ] = OBJ_sect193r2; NID_TO_OID[ NID_sect233k1 ] = OBJ_sect233k1; NID_TO_OID[ NID_sect233r1 ] = OBJ_sect233r1; NID_TO_OID[ NID_sect239k1 ] = OBJ_sect239k1; NID_TO_OID[ NID_sect283k1 ] = OBJ_sect283k1; NID_TO_OID[ NID_sect283r1 ] = OBJ_sect283r1; NID_TO_OID[ NID_sect409k1 ] = OBJ_sect409k1; NID_TO_OID[ NID_sect409r1 ] = OBJ_sect409r1; NID_TO_OID[ NID_sect571k1 ] = OBJ_sect571k1; NID_TO_OID[ NID_sect571r1 ] = OBJ_sect571r1; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls1 ] = OBJ_wap_wsg_idm_ecid_wtls1; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls3 ] = OBJ_wap_wsg_idm_ecid_wtls3; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls4 ] = OBJ_wap_wsg_idm_ecid_wtls4; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls5 ] = OBJ_wap_wsg_idm_ecid_wtls5; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls6 ] = OBJ_wap_wsg_idm_ecid_wtls6; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls7 ] = OBJ_wap_wsg_idm_ecid_wtls7; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls8 ] = OBJ_wap_wsg_idm_ecid_wtls8; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls9 ] = OBJ_wap_wsg_idm_ecid_wtls9; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls10 ] = OBJ_wap_wsg_idm_ecid_wtls10; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls11 ] = OBJ_wap_wsg_idm_ecid_wtls11; NID_TO_OID[ NID_wap_wsg_idm_ecid_wtls12 ] = OBJ_wap_wsg_idm_ecid_wtls12; NID_TO_OID[ NID_cast5_cbc ] = OBJ_cast5_cbc; NID_TO_OID[ NID_pbeWithMD5AndCast5_CBC ] = OBJ_pbeWithMD5AndCast5_CBC; NID_TO_OID[ NID_id_PasswordBasedMAC ] = OBJ_id_PasswordBasedMAC; NID_TO_OID[ NID_id_DHBasedMac ] = OBJ_id_DHBasedMac; NID_TO_OID[ NID_rsadsi ] = OBJ_rsadsi; NID_TO_OID[ NID_pkcs ] = OBJ_pkcs; NID_TO_OID[ NID_pkcs1 ] = OBJ_pkcs1; NID_TO_OID[ NID_rsaEncryption ] = OBJ_rsaEncryption; NID_TO_OID[ NID_md2WithRSAEncryption ] = OBJ_md2WithRSAEncryption; NID_TO_OID[ NID_md4WithRSAEncryption ] = OBJ_md4WithRSAEncryption; NID_TO_OID[ NID_md5WithRSAEncryption ] = OBJ_md5WithRSAEncryption; NID_TO_OID[ NID_sha1WithRSAEncryption ] = OBJ_sha1WithRSAEncryption; NID_TO_OID[ NID_rsaesOaep ] = OBJ_rsaesOaep; NID_TO_OID[ NID_mgf1 ] = OBJ_mgf1; NID_TO_OID[ NID_pSpecified ] = OBJ_pSpecified; NID_TO_OID[ NID_rsassaPss ] = OBJ_rsassaPss; NID_TO_OID[ NID_sha256WithRSAEncryption ] = OBJ_sha256WithRSAEncryption; NID_TO_OID[ NID_sha384WithRSAEncryption ] = OBJ_sha384WithRSAEncryption; NID_TO_OID[ NID_sha512WithRSAEncryption ] = OBJ_sha512WithRSAEncryption; NID_TO_OID[ NID_sha224WithRSAEncryption ] = OBJ_sha224WithRSAEncryption; NID_TO_OID[ NID_pkcs3 ] = OBJ_pkcs3; NID_TO_OID[ NID_dhKeyAgreement ] = OBJ_dhKeyAgreement; NID_TO_OID[ NID_pkcs5 ] = OBJ_pkcs5; NID_TO_OID[ NID_pbeWithMD2AndDES_CBC ] = OBJ_pbeWithMD2AndDES_CBC; NID_TO_OID[ NID_pbeWithMD5AndDES_CBC ] = OBJ_pbeWithMD5AndDES_CBC; NID_TO_OID[ NID_pbeWithMD2AndRC2_CBC ] = OBJ_pbeWithMD2AndRC2_CBC; NID_TO_OID[ NID_pbeWithMD5AndRC2_CBC ] = OBJ_pbeWithMD5AndRC2_CBC; NID_TO_OID[ NID_pbeWithSHA1AndDES_CBC ] = OBJ_pbeWithSHA1AndDES_CBC; NID_TO_OID[ NID_pbeWithSHA1AndRC2_CBC ] = OBJ_pbeWithSHA1AndRC2_CBC; NID_TO_OID[ NID_id_pbkdf2 ] = OBJ_id_pbkdf2; NID_TO_OID[ NID_pbes2 ] = OBJ_pbes2; NID_TO_OID[ NID_pbmac1 ] = OBJ_pbmac1; NID_TO_OID[ NID_pkcs7 ] = OBJ_pkcs7; NID_TO_OID[ NID_pkcs7_data ] = OBJ_pkcs7_data; NID_TO_OID[ NID_pkcs7_signed ] = OBJ_pkcs7_signed; NID_TO_OID[ NID_pkcs7_enveloped ] = OBJ_pkcs7_enveloped; NID_TO_OID[ NID_pkcs7_signedAndEnveloped ] = OBJ_pkcs7_signedAndEnveloped; NID_TO_OID[ NID_pkcs7_digest ] = OBJ_pkcs7_digest; NID_TO_OID[ NID_pkcs7_encrypted ] = OBJ_pkcs7_encrypted; NID_TO_OID[ NID_pkcs9 ] = OBJ_pkcs9; NID_TO_OID[ NID_pkcs9_emailAddress ] = OBJ_pkcs9_emailAddress; NID_TO_OID[ NID_pkcs9_unstructuredName ] = OBJ_pkcs9_unstructuredName; NID_TO_OID[ NID_pkcs9_contentType ] = OBJ_pkcs9_contentType; NID_TO_OID[ NID_pkcs9_messageDigest ] = OBJ_pkcs9_messageDigest; NID_TO_OID[ NID_pkcs9_signingTime ] = OBJ_pkcs9_signingTime; NID_TO_OID[ NID_pkcs9_countersignature ] = OBJ_pkcs9_countersignature; NID_TO_OID[ NID_pkcs9_challengePassword ] = OBJ_pkcs9_challengePassword; NID_TO_OID[ NID_pkcs9_unstructuredAddress ] = OBJ_pkcs9_unstructuredAddress; NID_TO_OID[ NID_pkcs9_extCertAttributes ] = OBJ_pkcs9_extCertAttributes; NID_TO_OID[ NID_ext_req ] = OBJ_ext_req; NID_TO_OID[ NID_SMIMECapabilities ] = OBJ_SMIMECapabilities; NID_TO_OID[ NID_SMIME ] = OBJ_SMIME; NID_TO_OID[ NID_id_smime_mod ] = OBJ_id_smime_mod; NID_TO_OID[ NID_id_smime_ct ] = OBJ_id_smime_ct; NID_TO_OID[ NID_id_smime_aa ] = OBJ_id_smime_aa; NID_TO_OID[ NID_id_smime_alg ] = OBJ_id_smime_alg; NID_TO_OID[ NID_id_smime_cd ] = OBJ_id_smime_cd; NID_TO_OID[ NID_id_smime_spq ] = OBJ_id_smime_spq; NID_TO_OID[ NID_id_smime_cti ] = OBJ_id_smime_cti; NID_TO_OID[ NID_id_smime_mod_cms ] = OBJ_id_smime_mod_cms; NID_TO_OID[ NID_id_smime_mod_ess ] = OBJ_id_smime_mod_ess; NID_TO_OID[ NID_id_smime_mod_oid ] = OBJ_id_smime_mod_oid; NID_TO_OID[ NID_id_smime_mod_msg_v3 ] = OBJ_id_smime_mod_msg_v3; NID_TO_OID[ NID_id_smime_mod_ets_eSignature_88 ] = OBJ_id_smime_mod_ets_eSignature_88; NID_TO_OID[ NID_id_smime_mod_ets_eSignature_97 ] = OBJ_id_smime_mod_ets_eSignature_97; NID_TO_OID[ NID_id_smime_mod_ets_eSigPolicy_88 ] = OBJ_id_smime_mod_ets_eSigPolicy_88; NID_TO_OID[ NID_id_smime_mod_ets_eSigPolicy_97 ] = OBJ_id_smime_mod_ets_eSigPolicy_97; NID_TO_OID[ NID_id_smime_ct_receipt ] = OBJ_id_smime_ct_receipt; NID_TO_OID[ NID_id_smime_ct_authData ] = OBJ_id_smime_ct_authData; NID_TO_OID[ NID_id_smime_ct_publishCert ] = OBJ_id_smime_ct_publishCert; NID_TO_OID[ NID_id_smime_ct_TSTInfo ] = OBJ_id_smime_ct_TSTInfo; NID_TO_OID[ NID_id_smime_ct_TDTInfo ] = OBJ_id_smime_ct_TDTInfo; NID_TO_OID[ NID_id_smime_ct_contentInfo ] = OBJ_id_smime_ct_contentInfo; NID_TO_OID[ NID_id_smime_ct_DVCSRequestData ] = OBJ_id_smime_ct_DVCSRequestData; NID_TO_OID[ NID_id_smime_ct_DVCSResponseData ] = OBJ_id_smime_ct_DVCSResponseData; NID_TO_OID[ NID_id_smime_ct_compressedData ] = OBJ_id_smime_ct_compressedData; NID_TO_OID[ NID_id_ct_asciiTextWithCRLF ] = OBJ_id_ct_asciiTextWithCRLF; NID_TO_OID[ NID_id_smime_aa_receiptRequest ] = OBJ_id_smime_aa_receiptRequest; NID_TO_OID[ NID_id_smime_aa_securityLabel ] = OBJ_id_smime_aa_securityLabel; NID_TO_OID[ NID_id_smime_aa_mlExpandHistory ] = OBJ_id_smime_aa_mlExpandHistory; NID_TO_OID[ NID_id_smime_aa_contentHint ] = OBJ_id_smime_aa_contentHint; NID_TO_OID[ NID_id_smime_aa_msgSigDigest ] = OBJ_id_smime_aa_msgSigDigest; NID_TO_OID[ NID_id_smime_aa_encapContentType ] = OBJ_id_smime_aa_encapContentType; NID_TO_OID[ NID_id_smime_aa_contentIdentifier ] = OBJ_id_smime_aa_contentIdentifier; NID_TO_OID[ NID_id_smime_aa_macValue ] = OBJ_id_smime_aa_macValue; NID_TO_OID[ NID_id_smime_aa_equivalentLabels ] = OBJ_id_smime_aa_equivalentLabels; NID_TO_OID[ NID_id_smime_aa_contentReference ] = OBJ_id_smime_aa_contentReference; NID_TO_OID[ NID_id_smime_aa_encrypKeyPref ] = OBJ_id_smime_aa_encrypKeyPref; NID_TO_OID[ NID_id_smime_aa_signingCertificate ] = OBJ_id_smime_aa_signingCertificate; NID_TO_OID[ NID_id_smime_aa_smimeEncryptCerts ] = OBJ_id_smime_aa_smimeEncryptCerts; NID_TO_OID[ NID_id_smime_aa_timeStampToken ] = OBJ_id_smime_aa_timeStampToken; NID_TO_OID[ NID_id_smime_aa_ets_sigPolicyId ] = OBJ_id_smime_aa_ets_sigPolicyId; NID_TO_OID[ NID_id_smime_aa_ets_commitmentType ] = OBJ_id_smime_aa_ets_commitmentType; NID_TO_OID[ NID_id_smime_aa_ets_signerLocation ] = OBJ_id_smime_aa_ets_signerLocation; NID_TO_OID[ NID_id_smime_aa_ets_signerAttr ] = OBJ_id_smime_aa_ets_signerAttr; NID_TO_OID[ NID_id_smime_aa_ets_otherSigCert ] = OBJ_id_smime_aa_ets_otherSigCert; NID_TO_OID[ NID_id_smime_aa_ets_contentTimestamp ] = OBJ_id_smime_aa_ets_contentTimestamp; NID_TO_OID[ NID_id_smime_aa_ets_CertificateRefs ] = OBJ_id_smime_aa_ets_CertificateRefs; NID_TO_OID[ NID_id_smime_aa_ets_RevocationRefs ] = OBJ_id_smime_aa_ets_RevocationRefs; NID_TO_OID[ NID_id_smime_aa_ets_certValues ] = OBJ_id_smime_aa_ets_certValues; NID_TO_OID[ NID_id_smime_aa_ets_revocationValues ] = OBJ_id_smime_aa_ets_revocationValues; NID_TO_OID[ NID_id_smime_aa_ets_escTimeStamp ] = OBJ_id_smime_aa_ets_escTimeStamp; NID_TO_OID[ NID_id_smime_aa_ets_certCRLTimestamp ] = OBJ_id_smime_aa_ets_certCRLTimestamp; NID_TO_OID[ NID_id_smime_aa_ets_archiveTimeStamp ] = OBJ_id_smime_aa_ets_archiveTimeStamp; NID_TO_OID[ NID_id_smime_aa_signatureType ] = OBJ_id_smime_aa_signatureType; NID_TO_OID[ NID_id_smime_aa_dvcs_dvc ] = OBJ_id_smime_aa_dvcs_dvc; NID_TO_OID[ NID_id_smime_alg_ESDHwith3DES ] = OBJ_id_smime_alg_ESDHwith3DES; NID_TO_OID[ NID_id_smime_alg_ESDHwithRC2 ] = OBJ_id_smime_alg_ESDHwithRC2; NID_TO_OID[ NID_id_smime_alg_3DESwrap ] = OBJ_id_smime_alg_3DESwrap; NID_TO_OID[ NID_id_smime_alg_RC2wrap ] = OBJ_id_smime_alg_RC2wrap; NID_TO_OID[ NID_id_smime_alg_ESDH ] = OBJ_id_smime_alg_ESDH; NID_TO_OID[ NID_id_smime_alg_CMS3DESwrap ] = OBJ_id_smime_alg_CMS3DESwrap; NID_TO_OID[ NID_id_smime_alg_CMSRC2wrap ] = OBJ_id_smime_alg_CMSRC2wrap; NID_TO_OID[ NID_id_alg_PWRI_KEK ] = OBJ_id_alg_PWRI_KEK; NID_TO_OID[ NID_id_smime_cd_ldap ] = OBJ_id_smime_cd_ldap; NID_TO_OID[ NID_id_smime_spq_ets_sqt_uri ] = OBJ_id_smime_spq_ets_sqt_uri; NID_TO_OID[ NID_id_smime_spq_ets_sqt_unotice ] = OBJ_id_smime_spq_ets_sqt_unotice; NID_TO_OID[ NID_id_smime_cti_ets_proofOfOrigin ] = OBJ_id_smime_cti_ets_proofOfOrigin; NID_TO_OID[ NID_id_smime_cti_ets_proofOfReceipt ] = OBJ_id_smime_cti_ets_proofOfReceipt; NID_TO_OID[ NID_id_smime_cti_ets_proofOfDelivery ] = OBJ_id_smime_cti_ets_proofOfDelivery; NID_TO_OID[ NID_id_smime_cti_ets_proofOfSender ] = OBJ_id_smime_cti_ets_proofOfSender; NID_TO_OID[ NID_id_smime_cti_ets_proofOfApproval ] = OBJ_id_smime_cti_ets_proofOfApproval; NID_TO_OID[ NID_id_smime_cti_ets_proofOfCreation ] = OBJ_id_smime_cti_ets_proofOfCreation; NID_TO_OID[ NID_friendlyName ] = OBJ_friendlyName; NID_TO_OID[ NID_localKeyID ] = OBJ_localKeyID; NID_TO_OID[ NID_ms_csp_name ] = OBJ_ms_csp_name; NID_TO_OID[ NID_LocalKeySet ] = OBJ_LocalKeySet; NID_TO_OID[ NID_x509Certificate ] = OBJ_x509Certificate; NID_TO_OID[ NID_sdsiCertificate ] = OBJ_sdsiCertificate; NID_TO_OID[ NID_x509Crl ] = OBJ_x509Crl; NID_TO_OID[ NID_pbe_WithSHA1And128BitRC4 ] = OBJ_pbe_WithSHA1And128BitRC4; NID_TO_OID[ NID_pbe_WithSHA1And40BitRC4 ] = OBJ_pbe_WithSHA1And40BitRC4; NID_TO_OID[ NID_pbe_WithSHA1And3_Key_TripleDES_CBC ] = OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC; NID_TO_OID[ NID_pbe_WithSHA1And2_Key_TripleDES_CBC ] = OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC; NID_TO_OID[ NID_pbe_WithSHA1And128BitRC2_CBC ] = OBJ_pbe_WithSHA1And128BitRC2_CBC; NID_TO_OID[ NID_pbe_WithSHA1And40BitRC2_CBC ] = OBJ_pbe_WithSHA1And40BitRC2_CBC; NID_TO_OID[ NID_keyBag ] = OBJ_keyBag; NID_TO_OID[ NID_pkcs8ShroudedKeyBag ] = OBJ_pkcs8ShroudedKeyBag; NID_TO_OID[ NID_certBag ] = OBJ_certBag; NID_TO_OID[ NID_crlBag ] = OBJ_crlBag; NID_TO_OID[ NID_secretBag ] = OBJ_secretBag; NID_TO_OID[ NID_safeContentsBag ] = OBJ_safeContentsBag; NID_TO_OID[ NID_md2 ] = OBJ_md2; NID_TO_OID[ NID_md4 ] = OBJ_md4; NID_TO_OID[ NID_md5 ] = OBJ_md5; NID_TO_OID[ NID_hmacWithMD5 ] = OBJ_hmacWithMD5; NID_TO_OID[ NID_hmacWithSHA1 ] = OBJ_hmacWithSHA1; NID_TO_OID[ NID_hmacWithSHA224 ] = OBJ_hmacWithSHA224; NID_TO_OID[ NID_hmacWithSHA256 ] = OBJ_hmacWithSHA256; NID_TO_OID[ NID_hmacWithSHA384 ] = OBJ_hmacWithSHA384; NID_TO_OID[ NID_hmacWithSHA512 ] = OBJ_hmacWithSHA512; NID_TO_OID[ NID_rc2_cbc ] = OBJ_rc2_cbc; NID_TO_OID[ NID_rc4 ] = OBJ_rc4; NID_TO_OID[ NID_des_ede3_cbc ] = OBJ_des_ede3_cbc; NID_TO_OID[ NID_rc5_cbc ] = OBJ_rc5_cbc; NID_TO_OID[ NID_ms_ext_req ] = OBJ_ms_ext_req; NID_TO_OID[ NID_ms_code_ind ] = OBJ_ms_code_ind; NID_TO_OID[ NID_ms_code_com ] = OBJ_ms_code_com; NID_TO_OID[ NID_ms_ctl_sign ] = OBJ_ms_ctl_sign; NID_TO_OID[ NID_ms_sgc ] = OBJ_ms_sgc; NID_TO_OID[ NID_ms_efs ] = OBJ_ms_efs; NID_TO_OID[ NID_ms_smartcard_login ] = OBJ_ms_smartcard_login; NID_TO_OID[ NID_ms_upn ] = OBJ_ms_upn; NID_TO_OID[ NID_idea_cbc ] = OBJ_idea_cbc; NID_TO_OID[ NID_bf_cbc ] = OBJ_bf_cbc; NID_TO_OID[ NID_id_pkix ] = OBJ_id_pkix; NID_TO_OID[ NID_id_pkix_mod ] = OBJ_id_pkix_mod; NID_TO_OID[ NID_id_pe ] = OBJ_id_pe; NID_TO_OID[ NID_id_qt ] = OBJ_id_qt; NID_TO_OID[ NID_id_kp ] = OBJ_id_kp; NID_TO_OID[ NID_id_it ] = OBJ_id_it; NID_TO_OID[ NID_id_pkip ] = OBJ_id_pkip; NID_TO_OID[ NID_id_alg ] = OBJ_id_alg; NID_TO_OID[ NID_id_cmc ] = OBJ_id_cmc; NID_TO_OID[ NID_id_on ] = OBJ_id_on; NID_TO_OID[ NID_id_pda ] = OBJ_id_pda; NID_TO_OID[ NID_id_aca ] = OBJ_id_aca; NID_TO_OID[ NID_id_qcs ] = OBJ_id_qcs; NID_TO_OID[ NID_id_cct ] = OBJ_id_cct; NID_TO_OID[ NID_id_ppl ] = OBJ_id_ppl; NID_TO_OID[ NID_id_ad ] = OBJ_id_ad; NID_TO_OID[ NID_id_pkix1_explicit_88 ] = OBJ_id_pkix1_explicit_88; NID_TO_OID[ NID_id_pkix1_implicit_88 ] = OBJ_id_pkix1_implicit_88; NID_TO_OID[ NID_id_pkix1_explicit_93 ] = OBJ_id_pkix1_explicit_93; NID_TO_OID[ NID_id_pkix1_implicit_93 ] = OBJ_id_pkix1_implicit_93; NID_TO_OID[ NID_id_mod_crmf ] = OBJ_id_mod_crmf; NID_TO_OID[ NID_id_mod_cmc ] = OBJ_id_mod_cmc; NID_TO_OID[ NID_id_mod_kea_profile_88 ] = OBJ_id_mod_kea_profile_88; NID_TO_OID[ NID_id_mod_kea_profile_93 ] = OBJ_id_mod_kea_profile_93; NID_TO_OID[ NID_id_mod_cmp ] = OBJ_id_mod_cmp; NID_TO_OID[ NID_id_mod_qualified_cert_88 ] = OBJ_id_mod_qualified_cert_88; NID_TO_OID[ NID_id_mod_qualified_cert_93 ] = OBJ_id_mod_qualified_cert_93; NID_TO_OID[ NID_id_mod_attribute_cert ] = OBJ_id_mod_attribute_cert; NID_TO_OID[ NID_id_mod_timestamp_protocol ] = OBJ_id_mod_timestamp_protocol; NID_TO_OID[ NID_id_mod_ocsp ] = OBJ_id_mod_ocsp; NID_TO_OID[ NID_id_mod_dvcs ] = OBJ_id_mod_dvcs; NID_TO_OID[ NID_id_mod_cmp2000 ] = OBJ_id_mod_cmp2000; NID_TO_OID[ NID_info_access ] = OBJ_info_access; NID_TO_OID[ NID_biometricInfo ] = OBJ_biometricInfo; NID_TO_OID[ NID_qcStatements ] = OBJ_qcStatements; NID_TO_OID[ NID_ac_auditEntity ] = OBJ_ac_auditEntity; NID_TO_OID[ NID_ac_targeting ] = OBJ_ac_targeting; NID_TO_OID[ NID_aaControls ] = OBJ_aaControls; NID_TO_OID[ NID_sbgp_ipAddrBlock ] = OBJ_sbgp_ipAddrBlock; NID_TO_OID[ NID_sbgp_autonomousSysNum ] = OBJ_sbgp_autonomousSysNum; NID_TO_OID[ NID_sbgp_routerIdentifier ] = OBJ_sbgp_routerIdentifier; NID_TO_OID[ NID_ac_proxying ] = OBJ_ac_proxying; NID_TO_OID[ NID_sinfo_access ] = OBJ_sinfo_access; NID_TO_OID[ NID_proxyCertInfo ] = OBJ_proxyCertInfo; NID_TO_OID[ NID_id_qt_cps ] = OBJ_id_qt_cps; NID_TO_OID[ NID_id_qt_unotice ] = OBJ_id_qt_unotice; NID_TO_OID[ NID_textNotice ] = OBJ_textNotice; NID_TO_OID[ NID_server_auth ] = OBJ_server_auth; NID_TO_OID[ NID_client_auth ] = OBJ_client_auth; NID_TO_OID[ NID_code_sign ] = OBJ_code_sign; NID_TO_OID[ NID_email_protect ] = OBJ_email_protect; NID_TO_OID[ NID_ipsecEndSystem ] = OBJ_ipsecEndSystem; NID_TO_OID[ NID_ipsecTunnel ] = OBJ_ipsecTunnel; NID_TO_OID[ NID_ipsecUser ] = OBJ_ipsecUser; NID_TO_OID[ NID_time_stamp ] = OBJ_time_stamp; NID_TO_OID[ NID_OCSP_sign ] = OBJ_OCSP_sign; NID_TO_OID[ NID_dvcs ] = OBJ_dvcs; NID_TO_OID[ NID_id_it_caProtEncCert ] = OBJ_id_it_caProtEncCert; NID_TO_OID[ NID_id_it_signKeyPairTypes ] = OBJ_id_it_signKeyPairTypes; NID_TO_OID[ NID_id_it_encKeyPairTypes ] = OBJ_id_it_encKeyPairTypes; NID_TO_OID[ NID_id_it_preferredSymmAlg ] = OBJ_id_it_preferredSymmAlg; NID_TO_OID[ NID_id_it_caKeyUpdateInfo ] = OBJ_id_it_caKeyUpdateInfo; NID_TO_OID[ NID_id_it_currentCRL ] = OBJ_id_it_currentCRL; NID_TO_OID[ NID_id_it_unsupportedOIDs ] = OBJ_id_it_unsupportedOIDs; NID_TO_OID[ NID_id_it_subscriptionRequest ] = OBJ_id_it_subscriptionRequest; NID_TO_OID[ NID_id_it_subscriptionResponse ] = OBJ_id_it_subscriptionResponse; NID_TO_OID[ NID_id_it_keyPairParamReq ] = OBJ_id_it_keyPairParamReq; NID_TO_OID[ NID_id_it_keyPairParamRep ] = OBJ_id_it_keyPairParamRep; NID_TO_OID[ NID_id_it_revPassphrase ] = OBJ_id_it_revPassphrase; NID_TO_OID[ NID_id_it_implicitConfirm ] = OBJ_id_it_implicitConfirm; NID_TO_OID[ NID_id_it_confirmWaitTime ] = OBJ_id_it_confirmWaitTime; NID_TO_OID[ NID_id_it_origPKIMessage ] = OBJ_id_it_origPKIMessage; NID_TO_OID[ NID_id_it_suppLangTags ] = OBJ_id_it_suppLangTags; NID_TO_OID[ NID_id_regCtrl ] = OBJ_id_regCtrl; NID_TO_OID[ NID_id_regInfo ] = OBJ_id_regInfo; NID_TO_OID[ NID_id_regCtrl_regToken ] = OBJ_id_regCtrl_regToken; NID_TO_OID[ NID_id_regCtrl_authenticator ] = OBJ_id_regCtrl_authenticator; NID_TO_OID[ NID_id_regCtrl_pkiPublicationInfo ] = OBJ_id_regCtrl_pkiPublicationInfo; NID_TO_OID[ NID_id_regCtrl_pkiArchiveOptions ] = OBJ_id_regCtrl_pkiArchiveOptions; NID_TO_OID[ NID_id_regCtrl_oldCertID ] = OBJ_id_regCtrl_oldCertID; NID_TO_OID[ NID_id_regCtrl_protocolEncrKey ] = OBJ_id_regCtrl_protocolEncrKey; NID_TO_OID[ NID_id_regInfo_utf8Pairs ] = OBJ_id_regInfo_utf8Pairs; NID_TO_OID[ NID_id_regInfo_certReq ] = OBJ_id_regInfo_certReq; NID_TO_OID[ NID_id_alg_des40 ] = OBJ_id_alg_des40; NID_TO_OID[ NID_id_alg_noSignature ] = OBJ_id_alg_noSignature; NID_TO_OID[ NID_id_alg_dh_sig_hmac_sha1 ] = OBJ_id_alg_dh_sig_hmac_sha1; NID_TO_OID[ NID_id_alg_dh_pop ] = OBJ_id_alg_dh_pop; NID_TO_OID[ NID_id_cmc_statusInfo ] = OBJ_id_cmc_statusInfo; NID_TO_OID[ NID_id_cmc_identification ] = OBJ_id_cmc_identification; NID_TO_OID[ NID_id_cmc_identityProof ] = OBJ_id_cmc_identityProof; NID_TO_OID[ NID_id_cmc_dataReturn ] = OBJ_id_cmc_dataReturn; NID_TO_OID[ NID_id_cmc_transactionId ] = OBJ_id_cmc_transactionId; NID_TO_OID[ NID_id_cmc_senderNonce ] = OBJ_id_cmc_senderNonce; NID_TO_OID[ NID_id_cmc_recipientNonce ] = OBJ_id_cmc_recipientNonce; NID_TO_OID[ NID_id_cmc_addExtensions ] = OBJ_id_cmc_addExtensions; NID_TO_OID[ NID_id_cmc_encryptedPOP ] = OBJ_id_cmc_encryptedPOP; NID_TO_OID[ NID_id_cmc_decryptedPOP ] = OBJ_id_cmc_decryptedPOP; NID_TO_OID[ NID_id_cmc_lraPOPWitness ] = OBJ_id_cmc_lraPOPWitness; NID_TO_OID[ NID_id_cmc_getCert ] = OBJ_id_cmc_getCert; NID_TO_OID[ NID_id_cmc_getCRL ] = OBJ_id_cmc_getCRL; NID_TO_OID[ NID_id_cmc_revokeRequest ] = OBJ_id_cmc_revokeRequest; NID_TO_OID[ NID_id_cmc_regInfo ] = OBJ_id_cmc_regInfo; NID_TO_OID[ NID_id_cmc_responseInfo ] = OBJ_id_cmc_responseInfo; NID_TO_OID[ NID_id_cmc_queryPending ] = OBJ_id_cmc_queryPending; NID_TO_OID[ NID_id_cmc_popLinkRandom ] = OBJ_id_cmc_popLinkRandom; NID_TO_OID[ NID_id_cmc_popLinkWitness ] = OBJ_id_cmc_popLinkWitness; NID_TO_OID[ NID_id_cmc_confirmCertAcceptance ] = OBJ_id_cmc_confirmCertAcceptance; NID_TO_OID[ NID_id_on_personalData ] = OBJ_id_on_personalData; NID_TO_OID[ NID_id_on_permanentIdentifier ] = OBJ_id_on_permanentIdentifier; NID_TO_OID[ NID_id_pda_dateOfBirth ] = OBJ_id_pda_dateOfBirth; NID_TO_OID[ NID_id_pda_placeOfBirth ] = OBJ_id_pda_placeOfBirth; NID_TO_OID[ NID_id_pda_gender ] = OBJ_id_pda_gender; NID_TO_OID[ NID_id_pda_countryOfCitizenship ] = OBJ_id_pda_countryOfCitizenship; NID_TO_OID[ NID_id_pda_countryOfResidence ] = OBJ_id_pda_countryOfResidence; NID_TO_OID[ NID_id_aca_authenticationInfo ] = OBJ_id_aca_authenticationInfo; NID_TO_OID[ NID_id_aca_accessIdentity ] = OBJ_id_aca_accessIdentity; NID_TO_OID[ NID_id_aca_chargingIdentity ] = OBJ_id_aca_chargingIdentity; NID_TO_OID[ NID_id_aca_group ] = OBJ_id_aca_group; NID_TO_OID[ NID_id_aca_role ] = OBJ_id_aca_role; NID_TO_OID[ NID_id_aca_encAttrs ] = OBJ_id_aca_encAttrs; NID_TO_OID[ NID_id_qcs_pkixQCSyntax_v1 ] = OBJ_id_qcs_pkixQCSyntax_v1; NID_TO_OID[ NID_id_cct_crs ] = OBJ_id_cct_crs; NID_TO_OID[ NID_id_cct_PKIData ] = OBJ_id_cct_PKIData; NID_TO_OID[ NID_id_cct_PKIResponse ] = OBJ_id_cct_PKIResponse; NID_TO_OID[ NID_id_ppl_anyLanguage ] = OBJ_id_ppl_anyLanguage; NID_TO_OID[ NID_id_ppl_inheritAll ] = OBJ_id_ppl_inheritAll; NID_TO_OID[ NID_Independent ] = OBJ_Independent; NID_TO_OID[ NID_ad_OCSP ] = OBJ_ad_OCSP; NID_TO_OID[ NID_ad_ca_issuers ] = OBJ_ad_ca_issuers; NID_TO_OID[ NID_ad_timeStamping ] = OBJ_ad_timeStamping; NID_TO_OID[ NID_ad_dvcs ] = OBJ_ad_dvcs; NID_TO_OID[ NID_caRepository ] = OBJ_caRepository; NID_TO_OID[ NID_id_pkix_OCSP_basic ] = OBJ_id_pkix_OCSP_basic; NID_TO_OID[ NID_id_pkix_OCSP_Nonce ] = OBJ_id_pkix_OCSP_Nonce; NID_TO_OID[ NID_id_pkix_OCSP_CrlID ] = OBJ_id_pkix_OCSP_CrlID; NID_TO_OID[ NID_id_pkix_OCSP_acceptableResponses ] = OBJ_id_pkix_OCSP_acceptableResponses; NID_TO_OID[ NID_id_pkix_OCSP_noCheck ] = OBJ_id_pkix_OCSP_noCheck; NID_TO_OID[ NID_id_pkix_OCSP_archiveCutoff ] = OBJ_id_pkix_OCSP_archiveCutoff; NID_TO_OID[ NID_id_pkix_OCSP_serviceLocator ] = OBJ_id_pkix_OCSP_serviceLocator; NID_TO_OID[ NID_id_pkix_OCSP_extendedStatus ] = OBJ_id_pkix_OCSP_extendedStatus; NID_TO_OID[ NID_id_pkix_OCSP_valid ] = OBJ_id_pkix_OCSP_valid; NID_TO_OID[ NID_id_pkix_OCSP_path ] = OBJ_id_pkix_OCSP_path; NID_TO_OID[ NID_id_pkix_OCSP_trustRoot ] = OBJ_id_pkix_OCSP_trustRoot; NID_TO_OID[ NID_algorithm ] = OBJ_algorithm; NID_TO_OID[ NID_md5WithRSA ] = OBJ_md5WithRSA; NID_TO_OID[ NID_des_ecb ] = OBJ_des_ecb; NID_TO_OID[ NID_des_cbc ] = OBJ_des_cbc; NID_TO_OID[ NID_des_ofb64 ] = OBJ_des_ofb64; NID_TO_OID[ NID_des_cfb64 ] = OBJ_des_cfb64; NID_TO_OID[ NID_rsaSignature ] = OBJ_rsaSignature; NID_TO_OID[ NID_dsa_2 ] = OBJ_dsa_2; NID_TO_OID[ NID_dsaWithSHA ] = OBJ_dsaWithSHA; NID_TO_OID[ NID_shaWithRSAEncryption ] = OBJ_shaWithRSAEncryption; NID_TO_OID[ NID_des_ede_ecb ] = OBJ_des_ede_ecb; NID_TO_OID[ NID_sha ] = OBJ_sha; NID_TO_OID[ NID_sha1 ] = OBJ_sha1; NID_TO_OID[ NID_dsaWithSHA1_2 ] = OBJ_dsaWithSHA1_2; NID_TO_OID[ NID_sha1WithRSA ] = OBJ_sha1WithRSA; NID_TO_OID[ NID_ripemd160 ] = OBJ_ripemd160; NID_TO_OID[ NID_ripemd160WithRSA ] = OBJ_ripemd160WithRSA; NID_TO_OID[ NID_sxnet ] = OBJ_sxnet; NID_TO_OID[ NID_X500 ] = OBJ_X500; NID_TO_OID[ NID_X509 ] = OBJ_X509; NID_TO_OID[ NID_commonName ] = OBJ_commonName; NID_TO_OID[ NID_surname ] = OBJ_surname; NID_TO_OID[ NID_serialNumber ] = OBJ_serialNumber; NID_TO_OID[ NID_countryName ] = OBJ_countryName; NID_TO_OID[ NID_localityName ] = OBJ_localityName; NID_TO_OID[ NID_stateOrProvinceName ] = OBJ_stateOrProvinceName; NID_TO_OID[ NID_streetAddress ] = OBJ_streetAddress; NID_TO_OID[ NID_organizationName ] = OBJ_organizationName; NID_TO_OID[ NID_organizationalUnitName ] = OBJ_organizationalUnitName; NID_TO_OID[ NID_title ] = OBJ_title; NID_TO_OID[ NID_description ] = OBJ_description; NID_TO_OID[ NID_searchGuide ] = OBJ_searchGuide; NID_TO_OID[ NID_businessCategory ] = OBJ_businessCategory; NID_TO_OID[ NID_postalAddress ] = OBJ_postalAddress; NID_TO_OID[ NID_postalCode ] = OBJ_postalCode; NID_TO_OID[ NID_postOfficeBox ] = OBJ_postOfficeBox; NID_TO_OID[ NID_physicalDeliveryOfficeName ] = OBJ_physicalDeliveryOfficeName; NID_TO_OID[ NID_telephoneNumber ] = OBJ_telephoneNumber; NID_TO_OID[ NID_telexNumber ] = OBJ_telexNumber; NID_TO_OID[ NID_teletexTerminalIdentifier ] = OBJ_teletexTerminalIdentifier; NID_TO_OID[ NID_facsimileTelephoneNumber ] = OBJ_facsimileTelephoneNumber; NID_TO_OID[ NID_x121Address ] = OBJ_x121Address; NID_TO_OID[ NID_internationaliSDNNumber ] = OBJ_internationaliSDNNumber; NID_TO_OID[ NID_registeredAddress ] = OBJ_registeredAddress; NID_TO_OID[ NID_destinationIndicator ] = OBJ_destinationIndicator; NID_TO_OID[ NID_preferredDeliveryMethod ] = OBJ_preferredDeliveryMethod; NID_TO_OID[ NID_presentationAddress ] = OBJ_presentationAddress; NID_TO_OID[ NID_supportedApplicationContext ] = OBJ_supportedApplicationContext; NID_TO_OID[ NID_member ] = OBJ_member; NID_TO_OID[ NID_owner ] = OBJ_owner; NID_TO_OID[ NID_roleOccupant ] = OBJ_roleOccupant; NID_TO_OID[ NID_seeAlso ] = OBJ_seeAlso; NID_TO_OID[ NID_userPassword ] = OBJ_userPassword; NID_TO_OID[ NID_userCertificate ] = OBJ_userCertificate; NID_TO_OID[ NID_cACertificate ] = OBJ_cACertificate; NID_TO_OID[ NID_authorityRevocationList ] = OBJ_authorityRevocationList; NID_TO_OID[ NID_certificateRevocationList ] = OBJ_certificateRevocationList; NID_TO_OID[ NID_crossCertificatePair ] = OBJ_crossCertificatePair; NID_TO_OID[ NID_name ] = OBJ_name; NID_TO_OID[ NID_givenName ] = OBJ_givenName; NID_TO_OID[ NID_initials ] = OBJ_initials; NID_TO_OID[ NID_generationQualifier ] = OBJ_generationQualifier; NID_TO_OID[ NID_x500UniqueIdentifier ] = OBJ_x500UniqueIdentifier; NID_TO_OID[ NID_dnQualifier ] = OBJ_dnQualifier; NID_TO_OID[ NID_enhancedSearchGuide ] = OBJ_enhancedSearchGuide; NID_TO_OID[ NID_protocolInformation ] = OBJ_protocolInformation; NID_TO_OID[ NID_distinguishedName ] = OBJ_distinguishedName; NID_TO_OID[ NID_uniqueMember ] = OBJ_uniqueMember; NID_TO_OID[ NID_houseIdentifier ] = OBJ_houseIdentifier; NID_TO_OID[ NID_supportedAlgorithms ] = OBJ_supportedAlgorithms; NID_TO_OID[ NID_deltaRevocationList ] = OBJ_deltaRevocationList; NID_TO_OID[ NID_dmdName ] = OBJ_dmdName; NID_TO_OID[ NID_pseudonym ] = OBJ_pseudonym; NID_TO_OID[ NID_role ] = OBJ_role; NID_TO_OID[ NID_X500algorithms ] = OBJ_X500algorithms; NID_TO_OID[ NID_rsa ] = OBJ_rsa; NID_TO_OID[ NID_mdc2WithRSA ] = OBJ_mdc2WithRSA; NID_TO_OID[ NID_mdc2 ] = OBJ_mdc2; NID_TO_OID[ NID_id_ce ] = OBJ_id_ce; NID_TO_OID[ NID_subject_directory_attributes ] = OBJ_subject_directory_attributes; NID_TO_OID[ NID_subject_key_identifier ] = OBJ_subject_key_identifier; NID_TO_OID[ NID_key_usage ] = OBJ_key_usage; NID_TO_OID[ NID_private_key_usage_period ] = OBJ_private_key_usage_period; NID_TO_OID[ NID_subject_alt_name ] = OBJ_subject_alt_name; NID_TO_OID[ NID_issuer_alt_name ] = OBJ_issuer_alt_name; NID_TO_OID[ NID_basic_constraints ] = OBJ_basic_constraints; NID_TO_OID[ NID_crl_number ] = OBJ_crl_number; NID_TO_OID[ NID_crl_reason ] = OBJ_crl_reason; NID_TO_OID[ NID_invalidity_date ] = OBJ_invalidity_date; NID_TO_OID[ NID_delta_crl ] = OBJ_delta_crl; NID_TO_OID[ NID_issuing_distribution_point ] = OBJ_issuing_distribution_point; NID_TO_OID[ NID_certificate_issuer ] = OBJ_certificate_issuer; NID_TO_OID[ NID_name_constraints ] = OBJ_name_constraints; NID_TO_OID[ NID_crl_distribution_points ] = OBJ_crl_distribution_points; NID_TO_OID[ NID_certificate_policies ] = OBJ_certificate_policies; NID_TO_OID[ NID_any_policy ] = OBJ_any_policy; NID_TO_OID[ NID_policy_mappings ] = OBJ_policy_mappings; NID_TO_OID[ NID_authority_key_identifier ] = OBJ_authority_key_identifier; NID_TO_OID[ NID_policy_constraints ] = OBJ_policy_constraints; NID_TO_OID[ NID_ext_key_usage ] = OBJ_ext_key_usage; NID_TO_OID[ NID_freshest_crl ] = OBJ_freshest_crl; NID_TO_OID[ NID_inhibit_any_policy ] = OBJ_inhibit_any_policy; NID_TO_OID[ NID_target_information ] = OBJ_target_information; NID_TO_OID[ NID_no_rev_avail ] = OBJ_no_rev_avail; NID_TO_OID[ NID_anyExtendedKeyUsage ] = OBJ_anyExtendedKeyUsage; NID_TO_OID[ NID_netscape ] = OBJ_netscape; NID_TO_OID[ NID_netscape_cert_extension ] = OBJ_netscape_cert_extension; NID_TO_OID[ NID_netscape_data_type ] = OBJ_netscape_data_type; NID_TO_OID[ NID_netscape_cert_type ] = OBJ_netscape_cert_type; NID_TO_OID[ NID_netscape_base_url ] = OBJ_netscape_base_url; NID_TO_OID[ NID_netscape_revocation_url ] = OBJ_netscape_revocation_url; NID_TO_OID[ NID_netscape_ca_revocation_url ] = OBJ_netscape_ca_revocation_url; NID_TO_OID[ NID_netscape_renewal_url ] = OBJ_netscape_renewal_url; NID_TO_OID[ NID_netscape_ca_policy_url ] = OBJ_netscape_ca_policy_url; NID_TO_OID[ NID_netscape_ssl_server_name ] = OBJ_netscape_ssl_server_name; NID_TO_OID[ NID_netscape_comment ] = OBJ_netscape_comment; NID_TO_OID[ NID_netscape_cert_sequence ] = OBJ_netscape_cert_sequence; NID_TO_OID[ NID_ns_sgc ] = OBJ_ns_sgc; NID_TO_OID[ NID_org ] = OBJ_org; NID_TO_OID[ NID_dod ] = OBJ_dod; NID_TO_OID[ NID_iana ] = OBJ_iana; NID_TO_OID[ NID_Directory ] = OBJ_Directory; NID_TO_OID[ NID_Management ] = OBJ_Management; NID_TO_OID[ NID_Experimental ] = OBJ_Experimental; NID_TO_OID[ NID_Private ] = OBJ_Private; NID_TO_OID[ NID_Security ] = OBJ_Security; NID_TO_OID[ NID_SNMPv2 ] = OBJ_SNMPv2; NID_TO_OID[ NID_Mail ] = OBJ_Mail; NID_TO_OID[ NID_Enterprises ] = OBJ_Enterprises; NID_TO_OID[ NID_dcObject ] = OBJ_dcObject; NID_TO_OID[ NID_mime_mhs ] = OBJ_mime_mhs; NID_TO_OID[ NID_mime_mhs_headings ] = OBJ_mime_mhs_headings; NID_TO_OID[ NID_mime_mhs_bodies ] = OBJ_mime_mhs_bodies; NID_TO_OID[ NID_id_hex_partial_message ] = OBJ_id_hex_partial_message; NID_TO_OID[ NID_id_hex_multipart_message ] = OBJ_id_hex_multipart_message; NID_TO_OID[ NID_rle_compression ] = OBJ_rle_compression; NID_TO_OID[ NID_zlib_compression ] = OBJ_zlib_compression; NID_TO_OID[ NID_aes_128_ecb ] = OBJ_aes_128_ecb; NID_TO_OID[ NID_aes_128_cbc ] = OBJ_aes_128_cbc; NID_TO_OID[ NID_aes_128_ofb128 ] = OBJ_aes_128_ofb128; NID_TO_OID[ NID_aes_128_cfb128 ] = OBJ_aes_128_cfb128; NID_TO_OID[ NID_id_aes128_wrap ] = OBJ_id_aes128_wrap; NID_TO_OID[ NID_aes_128_gcm ] = OBJ_aes_128_gcm; NID_TO_OID[ NID_aes_128_ccm ] = OBJ_aes_128_ccm; NID_TO_OID[ NID_id_aes128_wrap_pad ] = OBJ_id_aes128_wrap_pad; NID_TO_OID[ NID_aes_192_ecb ] = OBJ_aes_192_ecb; NID_TO_OID[ NID_aes_192_cbc ] = OBJ_aes_192_cbc; NID_TO_OID[ NID_aes_192_ofb128 ] = OBJ_aes_192_ofb128; NID_TO_OID[ NID_aes_192_cfb128 ] = OBJ_aes_192_cfb128; NID_TO_OID[ NID_id_aes192_wrap ] = OBJ_id_aes192_wrap; NID_TO_OID[ NID_aes_192_gcm ] = OBJ_aes_192_gcm; NID_TO_OID[ NID_aes_192_ccm ] = OBJ_aes_192_ccm; NID_TO_OID[ NID_id_aes192_wrap_pad ] = OBJ_id_aes192_wrap_pad; NID_TO_OID[ NID_aes_256_ecb ] = OBJ_aes_256_ecb; NID_TO_OID[ NID_aes_256_cbc ] = OBJ_aes_256_cbc; NID_TO_OID[ NID_aes_256_ofb128 ] = OBJ_aes_256_ofb128; NID_TO_OID[ NID_aes_256_cfb128 ] = OBJ_aes_256_cfb128; NID_TO_OID[ NID_id_aes256_wrap ] = OBJ_id_aes256_wrap; NID_TO_OID[ NID_aes_256_gcm ] = OBJ_aes_256_gcm; NID_TO_OID[ NID_aes_256_ccm ] = OBJ_aes_256_ccm; NID_TO_OID[ NID_id_aes256_wrap_pad ] = OBJ_id_aes256_wrap_pad; NID_TO_OID[ NID_sha256 ] = OBJ_sha256; NID_TO_OID[ NID_sha384 ] = OBJ_sha384; NID_TO_OID[ NID_sha512 ] = OBJ_sha512; NID_TO_OID[ NID_sha224 ] = OBJ_sha224; NID_TO_OID[ NID_dsa_with_SHA224 ] = OBJ_dsa_with_SHA224; NID_TO_OID[ NID_dsa_with_SHA256 ] = OBJ_dsa_with_SHA256; NID_TO_OID[ NID_hold_instruction_code ] = OBJ_hold_instruction_code; NID_TO_OID[ NID_hold_instruction_none ] = OBJ_hold_instruction_none; NID_TO_OID[ NID_hold_instruction_call_issuer ] = OBJ_hold_instruction_call_issuer; NID_TO_OID[ NID_hold_instruction_reject ] = OBJ_hold_instruction_reject; NID_TO_OID[ NID_data ] = OBJ_data; NID_TO_OID[ NID_pss ] = OBJ_pss; NID_TO_OID[ NID_ucl ] = OBJ_ucl; NID_TO_OID[ NID_pilot ] = OBJ_pilot; NID_TO_OID[ NID_pilotAttributeType ] = OBJ_pilotAttributeType; NID_TO_OID[ NID_pilotAttributeSyntax ] = OBJ_pilotAttributeSyntax; NID_TO_OID[ NID_pilotObjectClass ] = OBJ_pilotObjectClass; NID_TO_OID[ NID_pilotGroups ] = OBJ_pilotGroups; NID_TO_OID[ NID_iA5StringSyntax ] = OBJ_iA5StringSyntax; NID_TO_OID[ NID_caseIgnoreIA5StringSyntax ] = OBJ_caseIgnoreIA5StringSyntax; NID_TO_OID[ NID_pilotObject ] = OBJ_pilotObject; NID_TO_OID[ NID_pilotPerson ] = OBJ_pilotPerson; NID_TO_OID[ NID_account ] = OBJ_account; NID_TO_OID[ NID_document ] = OBJ_document; NID_TO_OID[ NID_room ] = OBJ_room; NID_TO_OID[ NID_documentSeries ] = OBJ_documentSeries; NID_TO_OID[ NID_Domain ] = OBJ_Domain; NID_TO_OID[ NID_rFC822localPart ] = OBJ_rFC822localPart; NID_TO_OID[ NID_dNSDomain ] = OBJ_dNSDomain; NID_TO_OID[ NID_domainRelatedObject ] = OBJ_domainRelatedObject; NID_TO_OID[ NID_friendlyCountry ] = OBJ_friendlyCountry; NID_TO_OID[ NID_simpleSecurityObject ] = OBJ_simpleSecurityObject; NID_TO_OID[ NID_pilotOrganization ] = OBJ_pilotOrganization; NID_TO_OID[ NID_pilotDSA ] = OBJ_pilotDSA; NID_TO_OID[ NID_qualityLabelledData ] = OBJ_qualityLabelledData; NID_TO_OID[ NID_userId ] = OBJ_userId; NID_TO_OID[ NID_textEncodedORAddress ] = OBJ_textEncodedORAddress; NID_TO_OID[ NID_rfc822Mailbox ] = OBJ_rfc822Mailbox; NID_TO_OID[ NID_info ] = OBJ_info; NID_TO_OID[ NID_favouriteDrink ] = OBJ_favouriteDrink; NID_TO_OID[ NID_roomNumber ] = OBJ_roomNumber; NID_TO_OID[ NID_photo ] = OBJ_photo; NID_TO_OID[ NID_userClass ] = OBJ_userClass; NID_TO_OID[ NID_host ] = OBJ_host; NID_TO_OID[ NID_manager ] = OBJ_manager; NID_TO_OID[ NID_documentIdentifier ] = OBJ_documentIdentifier; NID_TO_OID[ NID_documentTitle ] = OBJ_documentTitle; NID_TO_OID[ NID_documentVersion ] = OBJ_documentVersion; NID_TO_OID[ NID_documentAuthor ] = OBJ_documentAuthor; NID_TO_OID[ NID_documentLocation ] = OBJ_documentLocation; NID_TO_OID[ NID_homeTelephoneNumber ] = OBJ_homeTelephoneNumber; NID_TO_OID[ NID_secretary ] = OBJ_secretary; NID_TO_OID[ NID_otherMailbox ] = OBJ_otherMailbox; NID_TO_OID[ NID_lastModifiedTime ] = OBJ_lastModifiedTime; NID_TO_OID[ NID_lastModifiedBy ] = OBJ_lastModifiedBy; NID_TO_OID[ NID_domainComponent ] = OBJ_domainComponent; NID_TO_OID[ NID_aRecord ] = OBJ_aRecord; NID_TO_OID[ NID_pilotAttributeType27 ] = OBJ_pilotAttributeType27; NID_TO_OID[ NID_mXRecord ] = OBJ_mXRecord; NID_TO_OID[ NID_nSRecord ] = OBJ_nSRecord; NID_TO_OID[ NID_sOARecord ] = OBJ_sOARecord; NID_TO_OID[ NID_cNAMERecord ] = OBJ_cNAMERecord; NID_TO_OID[ NID_associatedDomain ] = OBJ_associatedDomain; NID_TO_OID[ NID_associatedName ] = OBJ_associatedName; NID_TO_OID[ NID_homePostalAddress ] = OBJ_homePostalAddress; NID_TO_OID[ NID_personalTitle ] = OBJ_personalTitle; NID_TO_OID[ NID_mobileTelephoneNumber ] = OBJ_mobileTelephoneNumber; NID_TO_OID[ NID_pagerTelephoneNumber ] = OBJ_pagerTelephoneNumber; NID_TO_OID[ NID_friendlyCountryName ] = OBJ_friendlyCountryName; NID_TO_OID[ NID_organizationalStatus ] = OBJ_organizationalStatus; NID_TO_OID[ NID_janetMailbox ] = OBJ_janetMailbox; NID_TO_OID[ NID_mailPreferenceOption ] = OBJ_mailPreferenceOption; NID_TO_OID[ NID_buildingName ] = OBJ_buildingName; NID_TO_OID[ NID_dSAQuality ] = OBJ_dSAQuality; NID_TO_OID[ NID_singleLevelQuality ] = OBJ_singleLevelQuality; NID_TO_OID[ NID_subtreeMinimumQuality ] = OBJ_subtreeMinimumQuality; NID_TO_OID[ NID_subtreeMaximumQuality ] = OBJ_subtreeMaximumQuality; NID_TO_OID[ NID_personalSignature ] = OBJ_personalSignature; NID_TO_OID[ NID_dITRedirect ] = OBJ_dITRedirect; NID_TO_OID[ NID_audio ] = OBJ_audio; NID_TO_OID[ NID_documentPublisher ] = OBJ_documentPublisher; NID_TO_OID[ NID_id_set ] = OBJ_id_set; NID_TO_OID[ NID_set_ctype ] = OBJ_set_ctype; NID_TO_OID[ NID_set_msgExt ] = OBJ_set_msgExt; NID_TO_OID[ NID_set_attr ] = OBJ_set_attr; NID_TO_OID[ NID_set_policy ] = OBJ_set_policy; NID_TO_OID[ NID_set_certExt ] = OBJ_set_certExt; NID_TO_OID[ NID_set_brand ] = OBJ_set_brand; NID_TO_OID[ NID_setct_PANData ] = OBJ_setct_PANData; NID_TO_OID[ NID_setct_PANToken ] = OBJ_setct_PANToken; NID_TO_OID[ NID_setct_PANOnly ] = OBJ_setct_PANOnly; NID_TO_OID[ NID_setct_OIData ] = OBJ_setct_OIData; NID_TO_OID[ NID_setct_PI ] = OBJ_setct_PI; NID_TO_OID[ NID_setct_PIData ] = OBJ_setct_PIData; NID_TO_OID[ NID_setct_PIDataUnsigned ] = OBJ_setct_PIDataUnsigned; NID_TO_OID[ NID_setct_HODInput ] = OBJ_setct_HODInput; NID_TO_OID[ NID_setct_AuthResBaggage ] = OBJ_setct_AuthResBaggage; NID_TO_OID[ NID_setct_AuthRevReqBaggage ] = OBJ_setct_AuthRevReqBaggage; NID_TO_OID[ NID_setct_AuthRevResBaggage ] = OBJ_setct_AuthRevResBaggage; NID_TO_OID[ NID_setct_CapTokenSeq ] = OBJ_setct_CapTokenSeq; NID_TO_OID[ NID_setct_PInitResData ] = OBJ_setct_PInitResData; NID_TO_OID[ NID_setct_PI_TBS ] = OBJ_setct_PI_TBS; NID_TO_OID[ NID_setct_PResData ] = OBJ_setct_PResData; NID_TO_OID[ NID_setct_AuthReqTBS ] = OBJ_setct_AuthReqTBS; NID_TO_OID[ NID_setct_AuthResTBS ] = OBJ_setct_AuthResTBS; NID_TO_OID[ NID_setct_AuthResTBSX ] = OBJ_setct_AuthResTBSX; NID_TO_OID[ NID_setct_AuthTokenTBS ] = OBJ_setct_AuthTokenTBS; NID_TO_OID[ NID_setct_CapTokenData ] = OBJ_setct_CapTokenData; NID_TO_OID[ NID_setct_CapTokenTBS ] = OBJ_setct_CapTokenTBS; NID_TO_OID[ NID_setct_AcqCardCodeMsg ] = OBJ_setct_AcqCardCodeMsg; NID_TO_OID[ NID_setct_AuthRevReqTBS ] = OBJ_setct_AuthRevReqTBS; NID_TO_OID[ NID_setct_AuthRevResData ] = OBJ_setct_AuthRevResData; NID_TO_OID[ NID_setct_AuthRevResTBS ] = OBJ_setct_AuthRevResTBS; NID_TO_OID[ NID_setct_CapReqTBS ] = OBJ_setct_CapReqTBS; NID_TO_OID[ NID_setct_CapReqTBSX ] = OBJ_setct_CapReqTBSX; NID_TO_OID[ NID_setct_CapResData ] = OBJ_setct_CapResData; NID_TO_OID[ NID_setct_CapRevReqTBS ] = OBJ_setct_CapRevReqTBS; NID_TO_OID[ NID_setct_CapRevReqTBSX ] = OBJ_setct_CapRevReqTBSX; NID_TO_OID[ NID_setct_CapRevResData ] = OBJ_setct_CapRevResData; NID_TO_OID[ NID_setct_CredReqTBS ] = OBJ_setct_CredReqTBS; NID_TO_OID[ NID_setct_CredReqTBSX ] = OBJ_setct_CredReqTBSX; NID_TO_OID[ NID_setct_CredResData ] = OBJ_setct_CredResData; NID_TO_OID[ NID_setct_CredRevReqTBS ] = OBJ_setct_CredRevReqTBS; NID_TO_OID[ NID_setct_CredRevReqTBSX ] = OBJ_setct_CredRevReqTBSX; NID_TO_OID[ NID_setct_CredRevResData ] = OBJ_setct_CredRevResData; NID_TO_OID[ NID_setct_PCertReqData ] = OBJ_setct_PCertReqData; NID_TO_OID[ NID_setct_PCertResTBS ] = OBJ_setct_PCertResTBS; NID_TO_OID[ NID_setct_BatchAdminReqData ] = OBJ_setct_BatchAdminReqData; NID_TO_OID[ NID_setct_BatchAdminResData ] = OBJ_setct_BatchAdminResData; NID_TO_OID[ NID_setct_CardCInitResTBS ] = OBJ_setct_CardCInitResTBS; NID_TO_OID[ NID_setct_MeAqCInitResTBS ] = OBJ_setct_MeAqCInitResTBS; NID_TO_OID[ NID_setct_RegFormResTBS ] = OBJ_setct_RegFormResTBS; NID_TO_OID[ NID_setct_CertReqData ] = OBJ_setct_CertReqData; NID_TO_OID[ NID_setct_CertReqTBS ] = OBJ_setct_CertReqTBS; NID_TO_OID[ NID_setct_CertResData ] = OBJ_setct_CertResData; NID_TO_OID[ NID_setct_CertInqReqTBS ] = OBJ_setct_CertInqReqTBS; NID_TO_OID[ NID_setct_ErrorTBS ] = OBJ_setct_ErrorTBS; NID_TO_OID[ NID_setct_PIDualSignedTBE ] = OBJ_setct_PIDualSignedTBE; NID_TO_OID[ NID_setct_PIUnsignedTBE ] = OBJ_setct_PIUnsignedTBE; NID_TO_OID[ NID_setct_AuthReqTBE ] = OBJ_setct_AuthReqTBE; NID_TO_OID[ NID_setct_AuthResTBE ] = OBJ_setct_AuthResTBE; NID_TO_OID[ NID_setct_AuthResTBEX ] = OBJ_setct_AuthResTBEX; NID_TO_OID[ NID_setct_AuthTokenTBE ] = OBJ_setct_AuthTokenTBE; NID_TO_OID[ NID_setct_CapTokenTBE ] = OBJ_setct_CapTokenTBE; NID_TO_OID[ NID_setct_CapTokenTBEX ] = OBJ_setct_CapTokenTBEX; NID_TO_OID[ NID_setct_AcqCardCodeMsgTBE ] = OBJ_setct_AcqCardCodeMsgTBE; NID_TO_OID[ NID_setct_AuthRevReqTBE ] = OBJ_setct_AuthRevReqTBE; NID_TO_OID[ NID_setct_AuthRevResTBE ] = OBJ_setct_AuthRevResTBE; NID_TO_OID[ NID_setct_AuthRevResTBEB ] = OBJ_setct_AuthRevResTBEB; NID_TO_OID[ NID_setct_CapReqTBE ] = OBJ_setct_CapReqTBE; NID_TO_OID[ NID_setct_CapReqTBEX ] = OBJ_setct_CapReqTBEX; NID_TO_OID[ NID_setct_CapResTBE ] = OBJ_setct_CapResTBE; NID_TO_OID[ NID_setct_CapRevReqTBE ] = OBJ_setct_CapRevReqTBE; NID_TO_OID[ NID_setct_CapRevReqTBEX ] = OBJ_setct_CapRevReqTBEX; NID_TO_OID[ NID_setct_CapRevResTBE ] = OBJ_setct_CapRevResTBE; NID_TO_OID[ NID_setct_CredReqTBE ] = OBJ_setct_CredReqTBE; NID_TO_OID[ NID_setct_CredReqTBEX ] = OBJ_setct_CredReqTBEX; NID_TO_OID[ NID_setct_CredResTBE ] = OBJ_setct_CredResTBE; NID_TO_OID[ NID_setct_CredRevReqTBE ] = OBJ_setct_CredRevReqTBE; NID_TO_OID[ NID_setct_CredRevReqTBEX ] = OBJ_setct_CredRevReqTBEX; NID_TO_OID[ NID_setct_CredRevResTBE ] = OBJ_setct_CredRevResTBE; NID_TO_OID[ NID_setct_BatchAdminReqTBE ] = OBJ_setct_BatchAdminReqTBE; NID_TO_OID[ NID_setct_BatchAdminResTBE ] = OBJ_setct_BatchAdminResTBE; NID_TO_OID[ NID_setct_RegFormReqTBE ] = OBJ_setct_RegFormReqTBE; NID_TO_OID[ NID_setct_CertReqTBE ] = OBJ_setct_CertReqTBE; NID_TO_OID[ NID_setct_CertReqTBEX ] = OBJ_setct_CertReqTBEX; NID_TO_OID[ NID_setct_CertResTBE ] = OBJ_setct_CertResTBE; NID_TO_OID[ NID_setct_CRLNotificationTBS ] = OBJ_setct_CRLNotificationTBS; NID_TO_OID[ NID_setct_CRLNotificationResTBS ] = OBJ_setct_CRLNotificationResTBS; NID_TO_OID[ NID_setct_BCIDistributionTBS ] = OBJ_setct_BCIDistributionTBS; NID_TO_OID[ NID_setext_genCrypt ] = OBJ_setext_genCrypt; NID_TO_OID[ NID_setext_miAuth ] = OBJ_setext_miAuth; NID_TO_OID[ NID_setext_pinSecure ] = OBJ_setext_pinSecure; NID_TO_OID[ NID_setext_pinAny ] = OBJ_setext_pinAny; NID_TO_OID[ NID_setext_track2 ] = OBJ_setext_track2; NID_TO_OID[ NID_setext_cv ] = OBJ_setext_cv; NID_TO_OID[ NID_set_policy_root ] = OBJ_set_policy_root; NID_TO_OID[ NID_setCext_hashedRoot ] = OBJ_setCext_hashedRoot; NID_TO_OID[ NID_setCext_certType ] = OBJ_setCext_certType; NID_TO_OID[ NID_setCext_merchData ] = OBJ_setCext_merchData; NID_TO_OID[ NID_setCext_cCertRequired ] = OBJ_setCext_cCertRequired; NID_TO_OID[ NID_setCext_tunneling ] = OBJ_setCext_tunneling; NID_TO_OID[ NID_setCext_setExt ] = OBJ_setCext_setExt; NID_TO_OID[ NID_setCext_setQualf ] = OBJ_setCext_setQualf; NID_TO_OID[ NID_setCext_PGWYcapabilities ] = OBJ_setCext_PGWYcapabilities; NID_TO_OID[ NID_setCext_TokenIdentifier ] = OBJ_setCext_TokenIdentifier; NID_TO_OID[ NID_setCext_Track2Data ] = OBJ_setCext_Track2Data; NID_TO_OID[ NID_setCext_TokenType ] = OBJ_setCext_TokenType; NID_TO_OID[ NID_setCext_IssuerCapabilities ] = OBJ_setCext_IssuerCapabilities; NID_TO_OID[ NID_setAttr_Cert ] = OBJ_setAttr_Cert; NID_TO_OID[ NID_setAttr_PGWYcap ] = OBJ_setAttr_PGWYcap; NID_TO_OID[ NID_setAttr_TokenType ] = OBJ_setAttr_TokenType; NID_TO_OID[ NID_setAttr_IssCap ] = OBJ_setAttr_IssCap; NID_TO_OID[ NID_set_rootKeyThumb ] = OBJ_set_rootKeyThumb; NID_TO_OID[ NID_set_addPolicy ] = OBJ_set_addPolicy; NID_TO_OID[ NID_setAttr_Token_EMV ] = OBJ_setAttr_Token_EMV; NID_TO_OID[ NID_setAttr_Token_B0Prime ] = OBJ_setAttr_Token_B0Prime; NID_TO_OID[ NID_setAttr_IssCap_CVM ] = OBJ_setAttr_IssCap_CVM; NID_TO_OID[ NID_setAttr_IssCap_T2 ] = OBJ_setAttr_IssCap_T2; NID_TO_OID[ NID_setAttr_IssCap_Sig ] = OBJ_setAttr_IssCap_Sig; NID_TO_OID[ NID_setAttr_GenCryptgrm ] = OBJ_setAttr_GenCryptgrm; NID_TO_OID[ NID_setAttr_T2Enc ] = OBJ_setAttr_T2Enc; NID_TO_OID[ NID_setAttr_T2cleartxt ] = OBJ_setAttr_T2cleartxt; NID_TO_OID[ NID_setAttr_TokICCsig ] = OBJ_setAttr_TokICCsig; NID_TO_OID[ NID_setAttr_SecDevSig ] = OBJ_setAttr_SecDevSig; NID_TO_OID[ NID_set_brand_IATA_ATA ] = OBJ_set_brand_IATA_ATA; NID_TO_OID[ NID_set_brand_Diners ] = OBJ_set_brand_Diners; NID_TO_OID[ NID_set_brand_AmericanExpress ] = OBJ_set_brand_AmericanExpress; NID_TO_OID[ NID_set_brand_JCB ] = OBJ_set_brand_JCB; NID_TO_OID[ NID_set_brand_Visa ] = OBJ_set_brand_Visa; NID_TO_OID[ NID_set_brand_MasterCard ] = OBJ_set_brand_MasterCard; NID_TO_OID[ NID_set_brand_Novus ] = OBJ_set_brand_Novus; NID_TO_OID[ NID_des_cdmf ] = OBJ_des_cdmf; NID_TO_OID[ NID_rsaOAEPEncryptionSET ] = OBJ_rsaOAEPEncryptionSET; NID_TO_OID[ NID_whirlpool ] = OBJ_whirlpool; NID_TO_OID[ NID_cryptopro ] = OBJ_cryptopro; NID_TO_OID[ NID_cryptocom ] = OBJ_cryptocom; NID_TO_OID[ NID_id_GostR3411_94_with_GostR3410_2001 ] = OBJ_id_GostR3411_94_with_GostR3410_2001; NID_TO_OID[ NID_id_GostR3411_94_with_GostR3410_94 ] = OBJ_id_GostR3411_94_with_GostR3410_94; NID_TO_OID[ NID_id_GostR3411_94 ] = OBJ_id_GostR3411_94; NID_TO_OID[ NID_id_HMACGostR3411_94 ] = OBJ_id_HMACGostR3411_94; NID_TO_OID[ NID_id_GostR3410_2001 ] = OBJ_id_GostR3410_2001; NID_TO_OID[ NID_id_GostR3410_94 ] = OBJ_id_GostR3410_94; NID_TO_OID[ NID_id_Gost28147_89 ] = OBJ_id_Gost28147_89; NID_TO_OID[ NID_id_Gost28147_89_MAC ] = OBJ_id_Gost28147_89_MAC; NID_TO_OID[ NID_id_GostR3411_94_prf ] = OBJ_id_GostR3411_94_prf; NID_TO_OID[ NID_id_GostR3410_2001DH ] = OBJ_id_GostR3410_2001DH; NID_TO_OID[ NID_id_GostR3410_94DH ] = OBJ_id_GostR3410_94DH; NID_TO_OID[ NID_id_Gost28147_89_CryptoPro_KeyMeshing ] = OBJ_id_Gost28147_89_CryptoPro_KeyMeshing; NID_TO_OID[ NID_id_Gost28147_89_None_KeyMeshing ] = OBJ_id_Gost28147_89_None_KeyMeshing; NID_TO_OID[ NID_id_GostR3411_94_TestParamSet ] = OBJ_id_GostR3411_94_TestParamSet; NID_TO_OID[ NID_id_GostR3411_94_CryptoProParamSet ] = OBJ_id_GostR3411_94_CryptoProParamSet; NID_TO_OID[ NID_id_Gost28147_89_TestParamSet ] = OBJ_id_Gost28147_89_TestParamSet; NID_TO_OID[ NID_id_Gost28147_89_CryptoPro_A_ParamSet ] = OBJ_id_Gost28147_89_CryptoPro_A_ParamSet; NID_TO_OID[ NID_id_Gost28147_89_CryptoPro_B_ParamSet ] = OBJ_id_Gost28147_89_CryptoPro_B_ParamSet; NID_TO_OID[ NID_id_Gost28147_89_CryptoPro_C_ParamSet ] = OBJ_id_Gost28147_89_CryptoPro_C_ParamSet; NID_TO_OID[ NID_id_Gost28147_89_CryptoPro_D_ParamSet ] = OBJ_id_Gost28147_89_CryptoPro_D_ParamSet; NID_TO_OID[ NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet ] = OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet; NID_TO_OID[ NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet ] = OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet; NID_TO_OID[ NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet ] = OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet; NID_TO_OID[ NID_id_GostR3410_94_TestParamSet ] = OBJ_id_GostR3410_94_TestParamSet; NID_TO_OID[ NID_id_GostR3410_94_CryptoPro_A_ParamSet ] = OBJ_id_GostR3410_94_CryptoPro_A_ParamSet; NID_TO_OID[ NID_id_GostR3410_94_CryptoPro_B_ParamSet ] = OBJ_id_GostR3410_94_CryptoPro_B_ParamSet; NID_TO_OID[ NID_id_GostR3410_94_CryptoPro_C_ParamSet ] = OBJ_id_GostR3410_94_CryptoPro_C_ParamSet; NID_TO_OID[ NID_id_GostR3410_94_CryptoPro_D_ParamSet ] = OBJ_id_GostR3410_94_CryptoPro_D_ParamSet; NID_TO_OID[ NID_id_GostR3410_94_CryptoPro_XchA_ParamSet ] = OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet; NID_TO_OID[ NID_id_GostR3410_94_CryptoPro_XchB_ParamSet ] = OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet; NID_TO_OID[ NID_id_GostR3410_94_CryptoPro_XchC_ParamSet ] = OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet; NID_TO_OID[ NID_id_GostR3410_2001_TestParamSet ] = OBJ_id_GostR3410_2001_TestParamSet; NID_TO_OID[ NID_id_GostR3410_2001_CryptoPro_A_ParamSet ] = OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet; NID_TO_OID[ NID_id_GostR3410_2001_CryptoPro_B_ParamSet ] = OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet; NID_TO_OID[ NID_id_GostR3410_2001_CryptoPro_C_ParamSet ] = OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet; NID_TO_OID[ NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet ] = OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet; NID_TO_OID[ NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet ] = OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet; NID_TO_OID[ NID_id_GostR3410_94_a ] = OBJ_id_GostR3410_94_a; NID_TO_OID[ NID_id_GostR3410_94_aBis ] = OBJ_id_GostR3410_94_aBis; NID_TO_OID[ NID_id_GostR3410_94_b ] = OBJ_id_GostR3410_94_b; NID_TO_OID[ NID_id_GostR3410_94_bBis ] = OBJ_id_GostR3410_94_bBis; NID_TO_OID[ NID_id_Gost28147_89_cc ] = OBJ_id_Gost28147_89_cc; NID_TO_OID[ NID_id_GostR3410_94_cc ] = OBJ_id_GostR3410_94_cc; NID_TO_OID[ NID_id_GostR3410_2001_cc ] = OBJ_id_GostR3410_2001_cc; NID_TO_OID[ NID_id_GostR3411_94_with_GostR3410_94_cc ] = OBJ_id_GostR3411_94_with_GostR3410_94_cc; NID_TO_OID[ NID_id_GostR3411_94_with_GostR3410_2001_cc ] = OBJ_id_GostR3411_94_with_GostR3410_2001_cc; NID_TO_OID[ NID_id_GostR3410_2001_ParamSet_cc ] = OBJ_id_GostR3410_2001_ParamSet_cc; NID_TO_OID[ NID_camellia_128_cbc ] = OBJ_camellia_128_cbc; NID_TO_OID[ NID_camellia_192_cbc ] = OBJ_camellia_192_cbc; NID_TO_OID[ NID_camellia_256_cbc ] = OBJ_camellia_256_cbc; NID_TO_OID[ NID_id_camellia128_wrap ] = OBJ_id_camellia128_wrap; NID_TO_OID[ NID_id_camellia192_wrap ] = OBJ_id_camellia192_wrap; NID_TO_OID[ NID_id_camellia256_wrap ] = OBJ_id_camellia256_wrap; NID_TO_OID[ NID_camellia_128_ecb ] = OBJ_camellia_128_ecb; NID_TO_OID[ NID_camellia_128_ofb128 ] = OBJ_camellia_128_ofb128; NID_TO_OID[ NID_camellia_128_cfb128 ] = OBJ_camellia_128_cfb128; NID_TO_OID[ NID_camellia_192_ecb ] = OBJ_camellia_192_ecb; NID_TO_OID[ NID_camellia_192_ofb128 ] = OBJ_camellia_192_ofb128; NID_TO_OID[ NID_camellia_192_cfb128 ] = OBJ_camellia_192_cfb128; NID_TO_OID[ NID_camellia_256_ecb ] = OBJ_camellia_256_ecb; NID_TO_OID[ NID_camellia_256_ofb128 ] = OBJ_camellia_256_ofb128; NID_TO_OID[ NID_camellia_256_cfb128 ] = OBJ_camellia_256_cfb128; NID_TO_OID[ NID_kisa ] = OBJ_kisa; NID_TO_OID[ NID_seed_ecb ] = OBJ_seed_ecb; NID_TO_OID[ NID_seed_cbc ] = OBJ_seed_cbc; NID_TO_OID[ NID_seed_cfb128 ] = OBJ_seed_cfb128; NID_TO_OID[ NID_seed_ofb128 ] = OBJ_seed_ofb128; NID_TO_OID[ NID_dhpublicnumber ] = OBJ_dhpublicnumber; NID_TO_OID[ NID_brainpoolP160r1 ] = OBJ_brainpoolP160r1; NID_TO_OID[ NID_brainpoolP160t1 ] = OBJ_brainpoolP160t1; NID_TO_OID[ NID_brainpoolP192r1 ] = OBJ_brainpoolP192r1; NID_TO_OID[ NID_brainpoolP192t1 ] = OBJ_brainpoolP192t1; NID_TO_OID[ NID_brainpoolP224r1 ] = OBJ_brainpoolP224r1; NID_TO_OID[ NID_brainpoolP224t1 ] = OBJ_brainpoolP224t1; NID_TO_OID[ NID_brainpoolP256r1 ] = OBJ_brainpoolP256r1; NID_TO_OID[ NID_brainpoolP256t1 ] = OBJ_brainpoolP256t1; NID_TO_OID[ NID_brainpoolP320r1 ] = OBJ_brainpoolP320r1; NID_TO_OID[ NID_brainpoolP320t1 ] = OBJ_brainpoolP320t1; NID_TO_OID[ NID_brainpoolP384r1 ] = OBJ_brainpoolP384r1; NID_TO_OID[ NID_brainpoolP384t1 ] = OBJ_brainpoolP384t1; NID_TO_OID[ NID_brainpoolP512r1 ] = OBJ_brainpoolP512r1; NID_TO_OID[ NID_brainpoolP512t1 ] = OBJ_brainpoolP512t1; NID_TO_OID[ NID_dhSinglePass_stdDH_sha1kdf_scheme ] = OBJ_dhSinglePass_stdDH_sha1kdf_scheme; NID_TO_OID[ NID_dhSinglePass_stdDH_sha224kdf_scheme ] = OBJ_dhSinglePass_stdDH_sha224kdf_scheme; NID_TO_OID[ NID_dhSinglePass_stdDH_sha256kdf_scheme ] = OBJ_dhSinglePass_stdDH_sha256kdf_scheme; NID_TO_OID[ NID_dhSinglePass_stdDH_sha384kdf_scheme ] = OBJ_dhSinglePass_stdDH_sha384kdf_scheme; NID_TO_OID[ NID_dhSinglePass_stdDH_sha512kdf_scheme ] = OBJ_dhSinglePass_stdDH_sha512kdf_scheme; NID_TO_OID[ NID_dhSinglePass_cofactorDH_sha1kdf_scheme ] = OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme; NID_TO_OID[ NID_dhSinglePass_cofactorDH_sha224kdf_scheme ] = OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme; NID_TO_OID[ NID_dhSinglePass_cofactorDH_sha256kdf_scheme ] = OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme; NID_TO_OID[ NID_dhSinglePass_cofactorDH_sha384kdf_scheme ] = OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme; NID_TO_OID[ NID_dhSinglePass_cofactorDH_sha512kdf_scheme ] = OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme; NID_TO_OID[ NID_ct_precert_scts ] = OBJ_ct_precert_scts; NID_TO_OID[ NID_ct_precert_poison ] = OBJ_ct_precert_poison; NID_TO_OID[ NID_ct_precert_signer ] = OBJ_ct_precert_signer; NID_TO_OID[ NID_ct_cert_scts ] = OBJ_ct_cert_scts; NID_TO_OID[ NID_jurisdictionLocalityName ] = OBJ_jurisdictionLocalityName; NID_TO_OID[ NID_jurisdictionStateOrProvinceName ] = OBJ_jurisdictionStateOrProvinceName; NID_TO_OID[ NID_jurisdictionCountryName ] = OBJ_jurisdictionCountryName; } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/Attribute.java000066400000000000000000000055221313661621600270400ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import org.bouncycastle.asn1.ASN1Encodable; import java.util.List; import java.util.ArrayList; /** X509_ATTRIBUTE * * @author Ola Bini */ public class Attribute { private int type; private boolean single; private List set; private Attribute() {} public static Attribute create(int nid, int atrtype, ASN1Encodable value) { Attribute ret = new Attribute(); ret.type = nid; ret.single = false; ret.set = new ArrayList(); ret.set.add(value); return ret; } public int getType() { return type; } public List getSet() { return set; } public boolean isSingle() { return this.single; } @Override public boolean equals(Object obj) { boolean ret = this == obj; if(!ret && (obj instanceof Attribute)) { Attribute attr2 = (Attribute)obj; ret = this.type == attr2.type && this.set.equals(attr2.set); } return ret; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((set == null) ? 0 : set.hashCode()); result = prime * result + type; return result; } }// Attribute jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/BIO.java000066400000000000000000000236201313661621600255050ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.MessageDigest; import javax.crypto.Cipher; /** c: BIO * * @author Ola Bini */ public class BIO { public final static int TYPE_DESCRIPTOR = 0x0100; public final static int TYPE_FILTER = 0x0200; public final static int TYPE_SOURCE_SINK = 0x0400; public final static int TYPE_NONE = 0; public final static int TYPE_MEM = 1 | TYPE_SOURCE_SINK; public final static int TYPE_FILE = 2 | TYPE_SOURCE_SINK; public final static int TYPE_FD = 4 | TYPE_SOURCE_SINK | TYPE_DESCRIPTOR; public final static int TYPE_SOCKET = 5 | TYPE_SOURCE_SINK | TYPE_DESCRIPTOR; public final static int TYPE_NULL = 6 | TYPE_SOURCE_SINK; public final static int TYPE_SSL = 7 | TYPE_FILTER; public final static int TYPE_MD = 8 | TYPE_FILTER; public final static int TYPE_BUFFER = 9 | TYPE_FILTER; public final static int TYPE_CIPHER = 10 | TYPE_FILTER; public final static int TYPE_BASE64 = 11 | TYPE_FILTER; public final static int TYPE_CONNECT = 12 | TYPE_SOURCE_SINK | TYPE_DESCRIPTOR; public final static int TYPE_ACCEPT = 13 | TYPE_SOURCE_SINK | TYPE_DESCRIPTOR; public final static int TYPE_PROXY_CLIENT = 14 | TYPE_FILTER; public final static int TYPE_PROXY_SERVER = 15 | TYPE_FILTER; public final static int TYPE_NBIO_TEST = 16 | TYPE_FILTER; public final static int TYPE_NULL_FILTER = 17 | TYPE_FILTER; public final static int TYPE_BER = 18 | TYPE_FILTER; public final static int TYPE_BIO = 19 | TYPE_SOURCE_SINK; private static final class BIOInputStream extends InputStream { private BIO bio; public BIOInputStream(BIO bio) { this.bio = bio; } @Override public int read() throws IOException { byte[] buffer = new byte[1]; int read = bio.read(buffer, 0, 1); if(read == 0) { return -1; } return ((int)buffer[0])&0xFF; } @Override public int read(byte[] into) throws IOException { return this.read(into, 0, into.length); } @Override public int read(byte[] into, int off, int len) throws IOException { int read = bio.read(into, off, len); if(read == 0) { return -1; } return read; } } private static final class BIOOutputStream extends OutputStream { private BIO bio; public BIOOutputStream(BIO bio) { this.bio = bio; } @Override public void write(int b) throws IOException { } @Override public void write(byte[] out) throws IOException { this.write(out, 0, out.length); } @Override public void write(byte[] out, int off, int len) throws IOException { bio.write(out, off, len); } } public static InputStream asInputStream(BIO input) { return new BIOInputStream(input); } public static OutputStream asOutputStream(BIO output) { return new BIOOutputStream(output); } public static BIO base64Filter(BIO real) { BIO b64 = new Base64BIOFilter(); b64.push(real); return b64; } public static BIO mdFilter(MessageDigest md) { return new MessageDigestBIOFilter(md); } public static BIO cipherFilter(Cipher cipher) { return new CipherBIOFilter(cipher); } public static BIO fromString(String input) { MemBIO bio = new MemBIO(); byte[] buf = null; try { buf = input.getBytes("ISO8859-1"); bio.write(buf, 0, buf.length); } catch(Exception e) {} return bio; } /** c: BIO_new(BIO_f_buffered()) * */ public static BIO buffered() { return null; } /** c: BIO_new(BIO_s_mem()) * */ public static BIO mem() { return new MemBIO(); } /** c: BIO_new(BIO_s_null()) * */ public static BIO nullSink() { return new NullSinkBIO(); } /** c: BIO_new_mem_buf * */ public static BIO memBuf(byte[] arr) { return memBuf(arr, 0, arr.length); } /** c: BIO_new_mem_buf * */ public static BIO memBuf(byte[] arr, int offset, int length) { // TODO: create real readonly version of MemBIO. try { BIO bio = new MemBIO(); bio.write(arr, offset, length); return bio; } catch(IOException e) { return null; } } protected BIO nextBio; protected BIO prevBio; /** c: BIO_flush * */ public void flush() throws IOException, PKCS7Exception { } private final static byte[] CONTENT_TEXT; static { byte[] val = null; try { val = "Content-Type: text/plain\r\n\r\n".getBytes("ISO8859-1"); } catch(Exception e) { val = null; } CONTENT_TEXT = val; } /** c: SMIME_crlf_copy * */ public void crlfCopy(BIO out, int flags) throws IOException { BIO in = this; byte[] linebuf = new byte[SMIME.MAX_SMLEN]; int[] len = new int[]{0}; if((flags & PKCS7.BINARY) > 0 ) { while((len[0] = in.read(linebuf, 0, SMIME.MAX_SMLEN)) > 0) { out.write(linebuf, 0, len[0]); } return; } if((flags & PKCS7.TEXT) > 0) { out.write(CONTENT_TEXT, 0, CONTENT_TEXT.length); } while((len[0] = in.gets(linebuf, SMIME.MAX_SMLEN)) > 0) { boolean eol = SMIME.stripEol(linebuf, len); if(len[0] != 0) { out.write(linebuf, 0, len[0]); } if(eol) { out.write(SMIME.NEWLINE, 0, 2); } } } /** c: BIO_gets * */ public int gets(byte[] in, int len) throws IOException { throw new UnsupportedOperationException("for " + this.getClass().getName()); } /** c: BIO_write * */ public int write(byte[] out, int offset, int len) throws IOException { throw new UnsupportedOperationException("for " + this.getClass().getName()); } /** c: BIO_read * */ public int read(byte[] into, int offset, int len) throws IOException { throw new UnsupportedOperationException("for " + this.getClass().getName()); } /** c: BIO_set_mem_eof_return * */ public void setMemEofReturn(int value) { throw new UnsupportedOperationException("for " + this.getClass().getName()); } /** c: BIO_push * */ public BIO push(BIO bio) { BIO lb = this; while(lb.nextBio != null) { lb = lb.nextBio; } if(bio != null) { bio.prevBio = lb; } lb.nextBio = bio; return this; } /** c: BIO_pop * */ public BIO pop() { BIO ret = this.nextBio; if(this.prevBio != null) { this.prevBio.nextBio = this.nextBio; } if(this.nextBio != null) { this.nextBio.prevBio = this.prevBio; } this.nextBio = null; this.prevBio = null; return ret; } /** c: BIO_find_type * */ public BIO findType(int type) { int mask = type & 0xFF; BIO bio = this; do { int mt = bio.getType(); if(mask == 0) { if((mt & type) != 0) { return bio; } } else if(mt == type) { return bio; } bio = bio.nextBio; } while(bio != null); return null; } /** c: BIO_next * */ public BIO next() { return this.nextBio; } public int getType() { return TYPE_BIO; } /** c: BIO_reset * */ public void reset() { throw new UnsupportedOperationException(); } @Override public String toString() { String[] names = getClass().getName().split("\\."); return "#"; } }// BIO jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/BIOFilter.java000066400000000000000000000032661313661621600266570ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; /** * * @author Ola Bini */ public abstract class BIOFilter extends BIO { public int getType() { return TYPE_FILTER; } }// BIOFilter jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/Base64.java000066400000000000000000002463611313661621600261310ustar00rootroot00000000000000package org.jruby.ext.openssl.impl; import org.jruby.ext.openssl.util.ByteArrayOutputStream; @SuppressWarnings("rawtypes") /** *

Encodes and decodes to and from Base64 notation.

*

Homepage: http://iharder.net/base64.

* *

Example:

* * String encoded = Base64.encode( myByteArray ); *
* byte[] myByteArray = Base64.decode( encoded ); * *

The options parameter, which appears in a few places, is used to pass * several pieces of information to the encoder. In the "higher level" methods such as * encodeBytes( bytes, options ) the options parameter can be used to indicate such * things as first gzipping the bytes before encoding them, not inserting linefeeds, * and encoding using the URL-safe and Ordered dialects.

* *

Note, according to RFC3548, * Section 2.1, implementations should not add line feeds unless explicitly told * to do so. I've got Base64 set to this behavior now, although earlier versions * broke lines by default.

* *

The constants defined in Base64 can be OR-ed together to combine options, so you * might make a call like this:

* * String encoded = Base64.encodeBytes( mybytes, Base64.GZIP | Base64.DO_BREAK_LINES ); *

to compress the data before encoding it and then making the output have newline characters.

*

Also...

* String encoded = Base64.encodeBytes( crazyString.getBytes() ); * * * *

* Change Log: *

*
    *
  • v2.3.7 - Fixed subtle bug when base 64 input stream contained the * value 01111111, which is an invalid base 64 character but should not * throw an ArrayIndexOutOfBoundsException either. Led to discovery of * mishandling (or potential for better handling) of other bad input * characters. You should now get an IOException if you try decoding * something that has bad characters in it.
  • *
  • v2.3.6 - Fixed bug when breaking lines and the final byte of the encoded * string ended in the last column; the buffer was not properly shrunk and * contained an extra (null) byte that made it into the string.
  • *
  • v2.3.5 - Fixed bug in {@link #encodeFromFile} where estimated buffer size * was wrong for files of size 31, 34, and 37 bytes.
  • *
  • v2.3.4 - Fixed bug when working with gzipped streams whereby flushing * the Base64.OutputStream closed the Base64 encoding (by padding with equals * signs) too soon. Also added an option to suppress the automatic decoding * of gzipped streams. Also added experimental support for specifying a * class loader when using the * {@link #decodeToObject(java.lang.String, int, java.lang.ClassLoader)} * method.
  • *
  • v2.3.3 - Changed default char encoding to US-ASCII which reduces the internal Java * footprint with its CharEncoders and so forth. Fixed some javadocs that were * inconsistent. Removed imports and specified things like java.io.IOException * explicitly inline.
  • *
  • v2.3.2 - Reduced memory footprint! Finally refined the "guessing" of how big the * final encoded data will be so that the code doesn't have to create two output * arrays: an oversized initial one and then a final, exact-sized one. Big win * when using the {@link #encodeBytesToBytes(byte[])} family of methods (and not * using the gzip options which uses a different mechanism with streams and stuff).
  • *
  • v2.3.1 - Added {@link #encodeBytesToBytes(byte[], int, int, int)} and some * similar helper methods to be more efficient with memory by not returning a * String but just a byte array.
  • *
  • v2.3 - This is not a drop-in replacement! This is two years of comments * and bug fixes queued up and finally executed. Thanks to everyone who sent * me stuff, and I'm sorry I wasn't able to distribute your fixes to everyone else. * Much bad coding was cleaned up including throwing exceptions where necessary * instead of returning null values or something similar. Here are some changes * that may affect you: *
      *
    • Does not break lines, by default. This is to keep in compliance with * RFC3548.
    • *
    • Throws exceptions instead of returning null values. Because some operations * (especially those that may permit the GZIP option) use IO streams, there * is a possiblity of an java.io.IOException being thrown. After some discussion and * thought, I've changed the behavior of the methods to throw java.io.IOExceptions * rather than return null if ever there's an error. I think this is more * appropriate, though it will require some changes to your code. Sorry, * it should have been done this way to begin with.
    • *
    • Removed all references to System.out, System.err, and the like. * Shame on me. All I can say is sorry they were ever there.
    • *
    • Throws NullPointerExceptions and IllegalArgumentExceptions as needed * such as when passed arrays are null or offsets are invalid.
    • *
    • Cleaned up as much javadoc as I could to avoid any javadoc warnings. * This was especially annoying before for people who were thorough in their * own projects and then had gobs of javadoc warnings on this file.
    • *
    *
  • v2.2.1 - Fixed bug using URL_SAFE and ORDERED encodings. Fixed bug * when using very small files (~< 40 bytes).
  • *
  • v2.2 - Added some helper methods for encoding/decoding directly from * one file to the next. Also added a main() method to support command line * encoding/decoding from one file to the next. Also added these Base64 dialects: *
      *
    1. The default is RFC3548 format.
    2. *
    3. Calling Base64.setFormat(Base64.BASE64_FORMAT.URLSAFE_FORMAT) generates * URL and file name friendly format as described in Section 4 of RFC3548. * http://www.faqs.org/rfcs/rfc3548.html
    4. *
    5. Calling Base64.setFormat(Base64.BASE64_FORMAT.ORDERED_FORMAT) generates * URL and file name friendly format that preserves lexical ordering as described * in http://www.faqs.org/qa/rfcc-1940.html
    6. *
    * Special thanks to Jim Kellerman at http://www.powerset.com/ * for contributing the new Base64 dialects. *
  • * *
  • v2.1 - Cleaned up javadoc comments and unused variables and methods. Added * some convenience methods for reading and writing to and from files.
  • *
  • v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems * with other encodings (like EBCDIC).
  • *
  • v2.0.1 - Fixed an error when decoding a single byte, that is, when the * encoded data was a single byte.
  • *
  • v2.0 - I got rid of methods that used booleans to set options. * Now everything is more consolidated and cleaner. The code now detects * when data that's being decoded is gzip-compressed and will decompress it * automatically. Generally things are cleaner. You'll probably have to * change some method calls that you were making to support the new * options format (ints that you "OR" together).
  • *
  • v1.5.1 - Fixed bug when decompressing and decoding to a * byte[] using decode( String s, boolean gzipCompressed ). * Added the ability to "suspend" encoding in the Output Stream so * you can turn on and off the encoding if you need to embed base64 * data in an otherwise "normal" stream (like an XML file).
  • *
  • v1.5 - Output stream pases on flush() command but doesn't do anything itself. * This helps when using GZIP streams. * Added the ability to GZip-compress objects before encoding them.
  • *
  • v1.4 - Added helper methods to read/write files.
  • *
  • v1.3.6 - Fixed OutputStream.flush() so that 'position' is reset.
  • *
  • v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream * where last buffer being read, if not completely full, was not returned.
  • *
  • v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.
  • *
  • v1.3.3 - Fixed I/O streams which were totally messed up.
  • *
* *

* I am placing this code in the Public Domain. Do with it as you will. * This software comes with no guarantees or warranties but with * plenty of well-wishing instead! * Please visit http://iharder.net/base64 * periodically to check for updates or to contribute improvements. *

* * @author Robert Harder * @author rob@iharder.net * @version 2.3.7 */ public class Base64 { /* ******** P U B L I C F I E L D S ******** */ /** No options specified. Value is zero. */ public final static int NO_OPTIONS = 0; /** Specify encoding in first bit. Value is one. */ public final static int ENCODE = 1; /** Specify decoding in first bit. Value is zero. */ public final static int DECODE = 0; /** Specify that data should be gzip-compressed in second bit. Value is two. */ public final static int GZIP = 2; /** Specify that gzipped data should not be automatically gunzipped. */ public final static int DONT_GUNZIP = 4; /** Do break lines when encoding. Value is 8. */ public final static int DO_BREAK_LINES = 8; /** * Encode using Base64-like encoding that is URL- and Filename-safe as described * in Section 4 of RFC3548: * http://www.faqs.org/rfcs/rfc3548.html. * It is important to note that data encoded this way is not officially valid Base64, * or at the very least should not be called Base64 without also specifying that is * was encoded using the URL- and Filename-safe dialect. */ public final static int URL_SAFE = 16; /** * Encode using the special "ordered" dialect of Base64 described here: * http://www.faqs.org/qa/rfcc-1940.html. */ public final static int ORDERED = 32; /* ******** P R I V A T E F I E L D S ******** */ /** Maximum line length (76) of Base64 output. */ private final static int MAX_LINE_LENGTH = 76; /** The equals sign (=) as a byte. */ private final static byte EQUALS_SIGN = (byte)'='; /** The new line character (\n) as a byte. */ private final static byte NEW_LINE = (byte)'\n'; /** Preferred encoding. */ private final static String PREFERRED_ENCODING = "US-ASCII"; private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding /* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ /** The 64 valid Base64 values. */ /* Host platform me be something funny like EBCDIC, so we hardcode these values. */ private final static byte[] _STANDARD_ALPHABET = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' }; /** * Translates a Base64 value to either its 6-bit reconstruction value * or a negative number indicating some other meaning. **/ private final static byte[] _STANDARD_DECODABET = { -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 -5,-5, // Whitespace: Tab and Linefeed -9,-9, // Decimal 11 - 12 -5, // Whitespace: Carriage Return -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 -9,-9,-9,-9,-9, // Decimal 27 - 31 -5, // Whitespace: Space -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 62, // Plus sign at decimal 43 -9,-9,-9, // Decimal 44 - 46 63, // Slash at decimal 47 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine -9,-9,-9, // Decimal 58 - 60 -1, // Equals sign at decimal 61 -9,-9,-9, // Decimal 62 - 64 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' -9,-9,-9,-9,-9,-9, // Decimal 91 - 96 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' -9,-9,-9,-9,-9 // Decimal 123 - 127 ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 }; /* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ /** * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548: * http://www.faqs.org/rfcs/rfc3548.html. * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" and "slash." */ private final static byte[] _URL_SAFE_ALPHABET = { (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'-', (byte)'_' }; /** * Used in decoding URL- and Filename-safe dialects of Base64. */ private final static byte[] _URL_SAFE_DECODABET = { -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 -5,-5, // Whitespace: Tab and Linefeed -9,-9, // Decimal 11 - 12 -5, // Whitespace: Carriage Return -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 -9,-9,-9,-9,-9, // Decimal 27 - 31 -5, // Whitespace: Space -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 -9, // Plus sign at decimal 43 -9, // Decimal 44 62, // Minus sign at decimal 45 -9, // Decimal 46 -9, // Slash at decimal 47 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine -9,-9,-9, // Decimal 58 - 60 -1, // Equals sign at decimal 61 -9,-9,-9, // Decimal 62 - 64 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' -9,-9,-9,-9, // Decimal 91 - 94 63, // Underscore at decimal 95 -9, // Decimal 96 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' -9,-9,-9,-9,-9 // Decimal 123 - 127 ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 }; /* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ /** * I don't get the point of this technique, but someone requested it, * and it is described here: * http://www.faqs.org/qa/rfcc-1940.html. */ private final static byte[] _ORDERED_ALPHABET = { (byte)'-', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'_', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z' }; /** * Used in decoding the "ordered" dialect of Base64. */ private final static byte[] _ORDERED_DECODABET = { -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 -5,-5, // Whitespace: Tab and Linefeed -9,-9, // Decimal 11 - 12 -5, // Whitespace: Carriage Return -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 -9,-9,-9,-9,-9, // Decimal 27 - 31 -5, // Whitespace: Space -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 -9, // Plus sign at decimal 43 -9, // Decimal 44 0, // Minus sign at decimal 45 -9, // Decimal 46 -9, // Slash at decimal 47 1,2,3,4,5,6,7,8,9,10, // Numbers zero through nine -9,-9,-9, // Decimal 58 - 60 -1, // Equals sign at decimal 61 -9,-9,-9, // Decimal 62 - 64 11,12,13,14,15,16,17,18,19,20,21,22,23, // Letters 'A' through 'M' 24,25,26,27,28,29,30,31,32,33,34,35,36, // Letters 'N' through 'Z' -9,-9,-9,-9, // Decimal 91 - 94 37, // Underscore at decimal 95 -9, // Decimal 96 38,39,40,41,42,43,44,45,46,47,48,49,50, // Letters 'a' through 'm' 51,52,53,54,55,56,57,58,59,60,61,62,63, // Letters 'n' through 'z' -9,-9,-9,-9,-9 // Decimal 123 - 127 ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 }; /* ******** D E T E R M I N E W H I C H A L H A B E T ******** */ /** * Returns one of the _SOMETHING_ALPHABET byte arrays depending on * the options specified. * It's possible, though silly, to specify ORDERED and URLSAFE * in which case one of them will be picked, though there is * no guarantee as to which one will be picked. */ private final static byte[] getAlphabet( int options ) { if ((options & URL_SAFE) == URL_SAFE) { return _URL_SAFE_ALPHABET; } else if ((options & ORDERED) == ORDERED) { return _ORDERED_ALPHABET; } else { return _STANDARD_ALPHABET; } } // end getAlphabet /** * Returns one of the _SOMETHING_DECODABET byte arrays depending on * the options specified. * It's possible, though silly, to specify ORDERED and URL_SAFE * in which case one of them will be picked, though there is * no guarantee as to which one will be picked. */ private final static byte[] getDecodabet( int options ) { if( (options & URL_SAFE) == URL_SAFE) { return _URL_SAFE_DECODABET; } else if ((options & ORDERED) == ORDERED) { return _ORDERED_DECODABET; } else { return _STANDARD_DECODABET; } } // end getAlphabet /** Defeats instantiation. */ private Base64(){} /* ******** E N C O D I N G M E T H O D S ******** */ /** * Encodes up to the first three bytes of array threeBytes * and returns a four-byte array in Base64 notation. * The actual number of significant bytes in your array is * given by numSigBytes. * The array threeBytes needs only be as big as * numSigBytes. * Code can reuse a byte array by passing a four-byte array as b4. * * @param b4 A reusable byte array to reduce array instantiation * @param threeBytes the array to convert * @param numSigBytes the number of significant bytes in your array * @return four byte array in Base64 notation. * @since 1.5.1 */ private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes, int options ) { encode3to4( threeBytes, 0, numSigBytes, b4, 0, options ); return b4; } // end encode3to4 /** *

Encodes up to three bytes of the array source * and writes the resulting four Base64 bytes to destination. * The source and destination arrays can be manipulated * anywhere along their length by specifying * srcOffset and destOffset. * This method does not check to make sure your arrays * are large enough to accomodate srcOffset + 3 for * the source array or destOffset + 4 for * the destination array. * The actual number of significant bytes in your array is * given by numSigBytes.

*

This is the lowest level of the encoding methods with * all possible parameters.

* * @param source the array to convert * @param srcOffset the index where conversion begins * @param numSigBytes the number of significant bytes in your array * @param destination the array to hold the conversion * @param destOffset the index where output will be put * @return the destination array * @since 1.3 */ private static byte[] encode3to4( byte[] source, int srcOffset, int numSigBytes, byte[] destination, int destOffset, int options ) { byte[] ALPHABET = getAlphabet( options ); // 1 2 3 // 01234567890123456789012345678901 Bit position // --------000000001111111122222222 Array position from threeBytes // --------| || || || | Six bit groups to index ALPHABET // >>18 >>12 >> 6 >> 0 Right shift necessary // 0x3f 0x3f 0x3f Additional AND // Create buffer with zero-padding if there are only one or two // significant bytes passed in the array. // We have to shift left 24 in order to flush out the 1's that appear // when Java treats a value as negative that is cast from a byte to an int. int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); switch( numSigBytes ) { case 3: destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; return destination; case 2: destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; destination[ destOffset + 3 ] = EQUALS_SIGN; return destination; case 1: destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; destination[ destOffset + 2 ] = EQUALS_SIGN; destination[ destOffset + 3 ] = EQUALS_SIGN; return destination; default: return destination; } // end switch } // end encode3to4 /** * Performs Base64 encoding on the raw ByteBuffer, * writing it to the encoded ByteBuffer. * This is an experimental feature. Currently it does not * pass along any options (such as {@link #DO_BREAK_LINES} * or {@link #GZIP}. * * @param raw input buffer * @param encoded output buffer * @since 2.3 */ public static void encode( java.nio.ByteBuffer raw, java.nio.ByteBuffer encoded ){ byte[] raw3 = new byte[3]; byte[] enc4 = new byte[4]; while( raw.hasRemaining() ){ int rem = Math.min(3,raw.remaining()); raw.get(raw3,0,rem); Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS ); encoded.put(enc4); } // end input remaining } /** * Performs Base64 encoding on the raw ByteBuffer, * writing it to the encoded CharBuffer. * This is an experimental feature. Currently it does not * pass along any options (such as {@link #DO_BREAK_LINES} * or {@link #GZIP}. * * @param raw input buffer * @param encoded output buffer * @since 2.3 */ public static void encode( java.nio.ByteBuffer raw, java.nio.CharBuffer encoded ){ byte[] raw3 = new byte[3]; byte[] enc4 = new byte[4]; while( raw.hasRemaining() ){ int rem = Math.min(3,raw.remaining()); raw.get(raw3,0,rem); Base64.encode3to4(enc4, raw3, rem, Base64.NO_OPTIONS ); for( int i = 0; i < 4; i++ ){ encoded.put( (char)(enc4[i] & 0xFF) ); } } // end input remaining } /** * Serializes an object and returns the Base64-encoded * version of that serialized object. * *

As of v 2.3, if the object * cannot be serialized or there is another error, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned a null value, but * in retrospect that's a pretty poor way to handle it.

* * The object is not GZip-compressed before being encoded. * * @param serializableObject The object to encode * @return The Base64-encoded object * @throws java.io.IOException if there is an error * @throws NullPointerException if serializedObject is null * @since 1.4 */ public static String encodeObject( java.io.Serializable serializableObject ) throws java.io.IOException { return encodeObject( serializableObject, NO_OPTIONS ); } // end encodeObject /** * Serializes an object and returns the Base64-encoded * version of that serialized object. * *

As of v 2.3, if the object * cannot be serialized or there is another error, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned a null value, but * in retrospect that's a pretty poor way to handle it.

* * The object is not GZip-compressed before being encoded. *

* Example options:

     *   GZIP: gzip-compresses object before encoding it.
     *   DO_BREAK_LINES: break lines at 76 characters
     * 
*

* Example: encodeObject( myObj, Base64.GZIP ) or *

* Example: encodeObject( myObj, Base64.GZIP | Base64.DO_BREAK_LINES ) * * @param serializableObject The object to encode * @param options Specified options * @return The Base64-encoded object * @see Base64#GZIP * @see Base64#DO_BREAK_LINES * @throws java.io.IOException if there is an error * @since 2.0 */ public static String encodeObject( java.io.Serializable serializableObject, int options ) throws java.io.IOException { if( serializableObject == null ){ throw new NullPointerException( "Cannot serialize a null object." ); } // end if: null // Streams ByteArrayOutputStream baos = new ByteArrayOutputStream(); java.io.OutputStream b64os = null; java.util.zip.GZIPOutputStream gzos = null; java.io.ObjectOutputStream oos = null; try { // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream b64os = new Base64.OutputStream( baos, ENCODE | options ); if( (options & GZIP) != 0 ){ // Gzip gzos = new java.util.zip.GZIPOutputStream(b64os); oos = new java.io.ObjectOutputStream( gzos ); } else { // Not gzipped oos = new java.io.ObjectOutputStream( b64os ); } oos.writeObject( serializableObject ); } // end try catch( java.io.IOException e ) { // Catch it and then throw it immediately so that // the finally{} block is called for cleanup. throw e; } // end catch finally { try{ oos.close(); } catch( Exception e ){} try{ gzos.close(); } catch( Exception e ){} try{ b64os.close(); } catch( Exception e ){} //try{ baos.close(); } catch( Exception e ){} } // end finally // Return value according to relevant encoding. try { return new String( baos.buffer(), 0, baos.size(), PREFERRED_ENCODING ); } // end try catch (java.io.UnsupportedEncodingException uue){ // Fall back to some Java default return new String( baos.buffer(), 0, baos.size() ); } // end catch } // end encode /** * Encodes a byte array into Base64 notation. * Does not GZip-compress data. * * @param source The data to convert * @return The data in Base64-encoded form * @throws NullPointerException if source array is null * @since 1.4 */ public static String encodeBytes( byte[] source ) { // Since we're not going to have the GZIP encoding turned on, // we're not going to have an java.io.IOException thrown, so // we should not force the user to have to catch it. String encoded = null; try { encoded = encodeBytes(source, 0, source.length, NO_OPTIONS); } catch (java.io.IOException ex) { assert false : ex.getMessage(); } // end catch assert encoded != null; return encoded; } // end encodeBytes /** * Encodes a byte array into Base64 notation. *

* Example options:

     *   GZIP: gzip-compresses object before encoding it.
     *   DO_BREAK_LINES: break lines at 76 characters
     *     Note: Technically, this makes your encoding non-compliant.
     * 
*

* Example: encodeBytes( myData, Base64.GZIP ) or *

* Example: encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES ) * * *

As of v 2.3, if there is an error with the GZIP stream, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned a null value, but * in retrospect that's a pretty poor way to handle it.

* * * @param source The data to convert * @param options Specified options * @return The Base64-encoded data as a String * @see Base64#GZIP * @see Base64#DO_BREAK_LINES * @throws java.io.IOException if there is an error * @throws NullPointerException if source array is null * @since 2.0 */ public static String encodeBytes( byte[] source, int options ) throws java.io.IOException { return encodeBytes( source, 0, source.length, options ); } // end encodeBytes /** * Encodes a byte array into Base64 notation. * Does not GZip-compress data. * *

As of v 2.3, if there is an error, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned a null value, but * in retrospect that's a pretty poor way to handle it.

* * * @param source The data to convert * @param off Offset in array where conversion should begin * @param len Length of data to convert * @return The Base64-encoded data as a String * @throws NullPointerException if source array is null * @throws IllegalArgumentException if source array, offset, or length are invalid * @since 1.4 */ public static String encodeBytes( byte[] source, int off, int len ) { // Since we're not going to have the GZIP encoding turned on, // we're not going to have an java.io.IOException thrown, so // we should not force the user to have to catch it. String encoded = null; try { encoded = encodeBytes( source, off, len, NO_OPTIONS ); } catch (java.io.IOException ex) { assert false : ex.getMessage(); } // end catch assert encoded != null; return encoded; } // end encodeBytes /** * Encodes a byte array into Base64 notation. *

* Example options:

     *   GZIP: gzip-compresses object before encoding it.
     *   DO_BREAK_LINES: break lines at 76 characters
     *     Note: Technically, this makes your encoding non-compliant.
     * 
*

* Example: encodeBytes( myData, Base64.GZIP ) or *

* Example: encodeBytes( myData, Base64.GZIP | Base64.DO_BREAK_LINES ) * * *

As of v 2.3, if there is an error with the GZIP stream, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned a null value, but * in retrospect that's a pretty poor way to handle it.

* * * @param source The data to convert * @param off Offset in array where conversion should begin * @param len Length of data to convert * @param options Specified options * @return The Base64-encoded data as a String * @see Base64#GZIP * @see Base64#DO_BREAK_LINES * @throws java.io.IOException if there is an error * @throws NullPointerException if source array is null * @throws IllegalArgumentException if source array, offset, or length are invalid * @since 2.0 */ public static String encodeBytes( byte[] source, int off, int len, int options ) throws java.io.IOException { byte[] encoded = encodeBytesToBytes( source, off, len, options ); // Return value according to relevant encoding. try { return new String( encoded, PREFERRED_ENCODING ); } // end try catch (java.io.UnsupportedEncodingException uue) { return new String( encoded ); } // end catch } // end encodeBytes /** * Similar to {@link #encodeBytes(byte[])} but returns * a byte array instead of instantiating a String. This is more efficient * if you're working with I/O streams and have large data sets to encode. * * * @param source The data to convert * @return The Base64-encoded data as a byte[] (of ASCII characters) * @throws NullPointerException if source array is null * @since 2.3.1 */ public static byte[] encodeBytesToBytes( byte[] source ) { byte[] encoded = null; try { encoded = encodeBytesToBytes( source, 0, source.length, Base64.NO_OPTIONS ); } catch( java.io.IOException ex ) { assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage(); } return encoded; } /** * Similar to {@link #encodeBytes(byte[], int, int, int)} but returns * a byte array instead of instantiating a String. This is more efficient * if you're working with I/O streams and have large data sets to encode. * * * @param source The data to convert * @param off Offset in array where conversion should begin * @param len Length of data to convert * @param options Specified options * @return The Base64-encoded data as a String * @see Base64#GZIP * @see Base64#DO_BREAK_LINES * @throws java.io.IOException if there is an error * @throws NullPointerException if source array is null * @throws IllegalArgumentException if source array, offset, or length are invalid * @since 2.3.1 */ public static byte[] encodeBytesToBytes( byte[] source, int off, int len, int options ) throws java.io.IOException { if( source == null ){ throw new NullPointerException( "Cannot serialize a null array." ); } // end if: null if( off < 0 ){ throw new IllegalArgumentException( "Cannot have negative offset: " + off ); } // end if: off < 0 if( len < 0 ){ throw new IllegalArgumentException( "Cannot have length offset: " + len ); } // end if: len < 0 if( off + len > source.length ){ throw new IllegalArgumentException( String.format( "Cannot have offset of %d and length of %d with array of length %d", off,len,source.length)); } // end if: off < 0 // Compress? if( (options & GZIP) != 0 ) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); java.util.zip.GZIPOutputStream gzos = null; Base64.OutputStream b64os = null; try { // GZip -> Base64 -> ByteArray b64os = new Base64.OutputStream( baos, ENCODE | options ); gzos = new java.util.zip.GZIPOutputStream( b64os ); gzos.write( source, off, len ); gzos.close(); } // end try catch( java.io.IOException e ) { // Catch it and then throw it immediately so that // the finally{} block is called for cleanup. throw e; } // end catch finally { try{ gzos.close(); } catch( Exception e ){} try{ b64os.close(); } catch( Exception e ){} //try{ baos.close(); } catch( Exception e ){} } // end finally return baos.toByteArray(); } // end if: compress // Else, don't compress. Better not to use streams at all then. else { boolean breakLines = (options & DO_BREAK_LINES) != 0; //int len43 = len * 4 / 3; //byte[] outBuff = new byte[ ( len43 ) // Main 4:3 // + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding // + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines // Try to determine more precisely how big the array needs to be. // If we get it right, we don't have to do an array copy, and // we save a bunch of memory. int encLen = ( len / 3 ) * 4 + ( len % 3 > 0 ? 4 : 0 ); // Bytes needed for actual encoding if( breakLines ){ encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters } byte[] outBuff = new byte[ encLen ]; int d = 0; int e = 0; int len2 = len - 2; int lineLength = 0; for( ; d < len2; d+=3, e+=4 ) { encode3to4( source, d+off, 3, outBuff, e, options ); lineLength += 4; if( breakLines && lineLength >= MAX_LINE_LENGTH ) { outBuff[e+4] = NEW_LINE; e++; lineLength = 0; } // end if: end of line } // en dfor: each piece of array if( d < len ) { encode3to4( source, d+off, len - d, outBuff, e, options ); e += 4; } // end if: some padding needed // Only resize array if we didn't guess it right. if( e <= outBuff.length - 1 ){ // If breaking lines and the last byte falls right at // the line length (76 bytes per line), there will be // one extra byte, and the array will need to be resized. // Not too bad of an estimate on array size, I'd say. byte[] finalOut = new byte[e]; System.arraycopy(outBuff,0, finalOut,0,e); //System.err.println("Having to resize array from " + outBuff.length + " to " + e ); return finalOut; } else { //System.err.println("No need to resize array."); return outBuff; } } // end else: don't compress } // end encodeBytesToBytes /* ******** D E C O D I N G M E T H O D S ******** */ /** * Decodes four bytes from array source * and writes the resulting bytes (up to three of them) * to destination. * The source and destination arrays can be manipulated * anywhere along their length by specifying * srcOffset and destOffset. * This method does not check to make sure your arrays * are large enough to accomodate srcOffset + 4 for * the source array or destOffset + 3 for * the destination array. * This method returns the actual number of bytes that * were converted from the Base64 encoding. *

This is the lowest level of the decoding methods with * all possible parameters.

* * * @param source the array to convert * @param srcOffset the index where conversion begins * @param destination the array to hold the conversion * @param destOffset the index where output will be put * @param options alphabet type is pulled from this (standard, url-safe, ordered) * @return the number of decoded bytes converted * @throws NullPointerException if source or destination arrays are null * @throws IllegalArgumentException if srcOffset or destOffset are invalid * or there is not enough room in the array. * @since 1.3 */ private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset, int options ) { // Lots of error checking and exception throwing if( source == null ){ throw new NullPointerException( "Source array was null." ); } // end if if( destination == null ){ throw new NullPointerException( "Destination array was null." ); } // end if if( srcOffset < 0 || srcOffset + 3 >= source.length ){ throw new IllegalArgumentException( String.format( "Source array with length %d cannot have offset of %d and still process four bytes.", source.length, srcOffset ) ); } // end if if( destOffset < 0 || destOffset +2 >= destination.length ){ throw new IllegalArgumentException( String.format( "Destination array with length %d cannot have offset of %d and still store three bytes.", destination.length, destOffset ) ); } // end if byte[] DECODABET = getDecodabet( options ); // Example: Dk== if( source[ srcOffset + 2] == EQUALS_SIGN ) { // Two ways to do the same thing. Don't know which way I like best. //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); destination[ destOffset ] = (byte)( outBuff >>> 16 ); return 1; } // Example: DkL= else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) { // Two ways to do the same thing. Don't know which way I like best. //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); destination[ destOffset ] = (byte)( outBuff >>> 16 ); destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); return 2; } // Example: DkLE else { // Two ways to do the same thing. Don't know which way I like best. //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); destination[ destOffset ] = (byte)( outBuff >> 16 ); destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); destination[ destOffset + 2 ] = (byte)( outBuff ); return 3; } } // end decodeToBytes /** * Low-level access to decoding ASCII characters in * the form of a byte array. Ignores GUNZIP option, if * it's set. This is not generally a recommended method, * although it is used internally as part of the decoding process. * Special case: if len = 0, an empty array is returned. Still, * if you need more speed and reduced memory footprint (and aren't * gzipping), consider this method. * * @param source The Base64 encoded data * @return decoded data * @since 2.3.1 */ public static byte[] decode( byte[] source ) throws java.io.IOException { byte[] decoded = null; // try { decoded = decode( source, 0, source.length, Base64.NO_OPTIONS ); // } catch( java.io.IOException ex ) { // assert false : "IOExceptions only come from GZipping, which is turned off: " + ex.getMessage(); // } return decoded; } /** * Low-level access to decoding ASCII characters in * the form of a byte array. Ignores GUNZIP option, if * it's set. This is not generally a recommended method, * although it is used internally as part of the decoding process. * Special case: if len = 0, an empty array is returned. Still, * if you need more speed and reduced memory footprint (and aren't * gzipping), consider this method. * * @param source The Base64 encoded data * @param off The offset of where to begin decoding * @param len The length of characters to decode * @param options Can specify options such as alphabet type to use * @return decoded data * @throws java.io.IOException If bogus characters exist in source data * @since 1.3 */ public static byte[] decode( byte[] source, int off, int len, int options ) throws java.io.IOException { // Lots of error checking and exception throwing if( source == null ){ throw new NullPointerException( "Cannot decode null source array." ); } // end if if( off < 0 || off + len > source.length ){ throw new IllegalArgumentException( String.format( "Source array with length %d cannot have offset of %d and process %d bytes.", source.length, off, len ) ); } // end if if( len == 0 ){ return new byte[0]; }else if( len < 4 ){ throw new IllegalArgumentException( "Base64-encoded string must have at least four characters, but length specified was " + len ); } // end if byte[] DECODABET = getDecodabet( options ); int len34 = len * 3 / 4; // Estimate on array size byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output int outBuffPosn = 0; // Keep track of where we're writing byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space int b4Posn = 0; // Keep track of four byte input buffer int i = 0; // Source array counter byte sbiDecode = 0; // Special value from DECODABET for( i = off; i < off+len; i++ ) { // Loop through source sbiDecode = DECODABET[ source[i]&0xFF ]; // White space, Equals sign, or legit Base64 character // Note the values such as -5 and -9 in the // DECODABETs at the top of the file. if( sbiDecode >= WHITE_SPACE_ENC ) { if( sbiDecode >= EQUALS_SIGN_ENC ) { b4[ b4Posn++ ] = source[i]; // Save non-whitespace if( b4Posn > 3 ) { // Time to decode? outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn, options ); b4Posn = 0; // If that was the equals sign, break out of 'for' loop if( source[i] == EQUALS_SIGN ) { break; } // end if: equals sign } // end if: quartet built } // end if: equals sign or better } // end if: white space, equals sign or better else { // There's a bad input character in the Base64 stream. throw new java.io.IOException( String.format( "Bad Base64 input character decimal %d in array position %d", ((int)source[i])&0xFF, i ) ); } // end else: } // each input character byte[] out = new byte[ outBuffPosn ]; System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); return out; } // end decode /** * Decodes data from Base64 notation, automatically * detecting gzip-compressed data and decompressing it. * * @param s the string to decode * @return the decoded data * @throws java.io.IOException If there is a problem * @since 1.4 */ public static byte[] decode( String s ) throws java.io.IOException { return decode( s, NO_OPTIONS ); } /** * Decodes data from Base64 notation, automatically * detecting gzip-compressed data and decompressing it. * * @param s the string to decode * @param options encode options such as URL_SAFE * @return the decoded data * @throws java.io.IOException if there is an error * @throws NullPointerException if s is null * @since 1.4 */ public static byte[] decode( String s, int options ) throws java.io.IOException { if( s == null ){ throw new NullPointerException( "Input string was null." ); } // end if byte[] bytes; try { bytes = s.getBytes( PREFERRED_ENCODING ); } // end try catch( java.io.UnsupportedEncodingException uee ) { bytes = s.getBytes(); } // end catch // // Decode bytes = decode( bytes, 0, bytes.length, options ); // Check to see if it's gzip-compressed // GZIP Magic Two-Byte Number: 0x8b1f (35615) boolean dontGunzip = (options & DONT_GUNZIP) != 0; if( (bytes != null) && (bytes.length >= 4) && (!dontGunzip) ) { int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) { java.io.ByteArrayInputStream bais = null; java.util.zip.GZIPInputStream gzis = null; java.io.ByteArrayOutputStream baos = null; byte[] buffer = new byte[2048]; int length = 0; try { baos = new java.io.ByteArrayOutputStream(); bais = new java.io.ByteArrayInputStream( bytes ); gzis = new java.util.zip.GZIPInputStream( bais ); while( ( length = gzis.read( buffer ) ) >= 0 ) { baos.write(buffer,0,length); } // end while: reading input // No error? Get new bytes. bytes = baos.toByteArray(); } // end try catch( java.io.IOException e ) { e.printStackTrace(); // Just return originally-decoded bytes } // end catch finally { //try{ baos.close(); } catch( Exception e ){} try{ gzis.close(); } catch( Exception e ){} try{ bais.close(); } catch( Exception e ){} } // end finally } // end if: gzipped } // end if: bytes.length >= 2 return bytes; } // end decode /** * Attempts to decode Base64 data and deserialize a Java * Object within. Returns null if there was an error. * * @param encodedObject The Base64 data to decode * @return The decoded and deserialized object * @throws NullPointerException if encodedObject is null * @throws java.io.IOException if there is a general error * @throws ClassNotFoundException if the decoded object is of a * class that cannot be found by the JVM * @since 1.5 */ public static Object decodeToObject( String encodedObject ) throws java.io.IOException, java.lang.ClassNotFoundException { return decodeToObject(encodedObject,NO_OPTIONS,null); } /** * Attempts to decode Base64 data and deserialize a Java * Object within. Returns null if there was an error. * If loader is not null, it will be the class loader * used when deserializing. * * @param encodedObject The Base64 data to decode * @param options Various parameters related to decoding * @param loader Optional class loader to use in deserializing classes. * @return The decoded and deserialized object * @throws NullPointerException if encodedObject is null * @throws java.io.IOException if there is a general error * @throws ClassNotFoundException if the decoded object is of a * class that cannot be found by the JVM * @since 2.3.4 */ public static Object decodeToObject( String encodedObject, int options, final ClassLoader loader ) throws java.io.IOException, java.lang.ClassNotFoundException { // Decode and gunzip if necessary byte[] objBytes = decode( encodedObject, options ); java.io.ByteArrayInputStream bais = null; java.io.ObjectInputStream ois = null; Object obj = null; try { bais = new java.io.ByteArrayInputStream( objBytes ); // If no custom class loader is provided, use Java's builtin OIS. if( loader == null ){ ois = new java.io.ObjectInputStream( bais ); } // end if: no loader provided // Else make a customized object input stream that uses // the provided class loader. else { ois = new java.io.ObjectInputStream(bais){ @Override public Class resolveClass(java.io.ObjectStreamClass streamClass) throws java.io.IOException, ClassNotFoundException { Class c = Class.forName(streamClass.getName(), false, loader); if( c == null ){ return super.resolveClass(streamClass); } else { return c; // Class loader knows of this class. } // end else: not null } // end resolveClass }; // end ois } // end else: no custom class loader obj = ois.readObject(); } // end try catch( java.io.IOException e ) { throw e; // Catch and throw in order to execute finally{} } // end catch catch( java.lang.ClassNotFoundException e ) { throw e; // Catch and throw in order to execute finally{} } // end catch finally { try{ bais.close(); } catch( Exception e ){} try{ ois.close(); } catch( Exception e ){} } // end finally return obj; } // end decodeObject /** * Convenience method for encoding data to a file. * *

As of v 2.3, if there is a error, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned false, but * in retrospect that's a pretty poor way to handle it.

* * @param dataToEncode byte array of data to encode in base64 form * @param filename Filename for saving encoded data * @throws java.io.IOException if there is an error * @throws NullPointerException if dataToEncode is null * @since 2.1 */ public static void encodeToFile( byte[] dataToEncode, String filename ) throws java.io.IOException { if( dataToEncode == null ){ throw new NullPointerException( "Data to encode was null." ); } // end iff Base64.OutputStream bos = null; try { bos = new Base64.OutputStream( new java.io.FileOutputStream( filename ), Base64.ENCODE ); bos.write( dataToEncode ); } // end try catch( java.io.IOException e ) { throw e; // Catch and throw to execute finally{} block } // end catch: java.io.IOException finally { try{ bos.close(); } catch( Exception e ){} } // end finally } // end encodeToFile /** * Convenience method for decoding data to a file. * *

As of v 2.3, if there is a error, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned false, but * in retrospect that's a pretty poor way to handle it.

* * @param dataToDecode Base64-encoded data as a string * @param filename Filename for saving decoded data * @throws java.io.IOException if there is an error * @since 2.1 */ public static void decodeToFile( String dataToDecode, String filename ) throws java.io.IOException { Base64.OutputStream bos = null; try{ bos = new Base64.OutputStream( new java.io.FileOutputStream( filename ), Base64.DECODE ); bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) ); } // end try catch( java.io.IOException e ) { throw e; // Catch and throw to execute finally{} block } // end catch: java.io.IOException finally { try{ bos.close(); } catch( Exception e ){} } // end finally } // end decodeToFile /** * Convenience method for reading a base64-encoded * file and decoding it. * *

As of v 2.3, if there is a error, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned false, but * in retrospect that's a pretty poor way to handle it.

* * @param filename Filename for reading encoded data * @return decoded byte array * @throws java.io.IOException if there is an error * @since 2.1 */ public static byte[] decodeFromFile( String filename ) throws java.io.IOException { byte[] decodedData = null; Base64.InputStream bis = null; try { // Set up some useful variables java.io.File file = new java.io.File( filename ); byte[] buffer = null; int length = 0; int numBytes = 0; // Check for size of file if( file.length() > Integer.MAX_VALUE ) { throw new java.io.IOException( "File is too big for this convenience method (" + file.length() + " bytes)." ); } // end if: file too big for int index buffer = new byte[ (int)file.length() ]; // Open a stream bis = new Base64.InputStream( new java.io.BufferedInputStream( new java.io.FileInputStream( file ) ), Base64.DECODE ); // Read until done while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) { length += numBytes; } // end while // Save in a variable to return decodedData = new byte[ length ]; System.arraycopy( buffer, 0, decodedData, 0, length ); } // end try catch( java.io.IOException e ) { throw e; // Catch and release to execute finally{} } // end catch: java.io.IOException finally { try{ bis.close(); } catch( Exception e) {} } // end finally return decodedData; } // end decodeFromFile /** * Convenience method for reading a binary file * and base64-encoding it. * *

As of v 2.3, if there is a error, * the method will throw an java.io.IOException. This is new to v2.3! * In earlier versions, it just returned false, but * in retrospect that's a pretty poor way to handle it.

* * @param filename Filename for reading binary data * @return base64-encoded string * @throws java.io.IOException if there is an error * @since 2.1 */ public static String encodeFromFile( String filename ) throws java.io.IOException { String encodedData = null; Base64.InputStream bis = null; try { // Set up some useful variables java.io.File file = new java.io.File( filename ); byte[] buffer = new byte[ Math.max((int)(file.length() * 1.4+1),40) ]; // Need max() for math on small files (v2.2.1); Need +1 for a few corner cases (v2.3.5) int length = 0; int numBytes = 0; // Open a stream bis = new Base64.InputStream( new java.io.BufferedInputStream( new java.io.FileInputStream( file ) ), Base64.ENCODE ); // Read until done while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) { length += numBytes; } // end while // Save in a variable to return encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING ); } // end try catch( java.io.IOException e ) { throw e; // Catch and release to execute finally{} } // end catch: java.io.IOException finally { try{ bis.close(); } catch( Exception e) {} } // end finally return encodedData; } // end encodeFromFile /** * Reads infile and encodes it to outfile. * * @param infile Input file * @param outfile Output file * @throws java.io.IOException if there is an error * @since 2.2 */ public static void encodeFileToFile( String infile, String outfile ) throws java.io.IOException { String encoded = Base64.encodeFromFile( infile ); java.io.OutputStream out = null; try{ out = new java.io.BufferedOutputStream( new java.io.FileOutputStream( outfile ) ); out.write( encoded.getBytes("US-ASCII") ); // Strict, 7-bit output. } // end try catch( java.io.IOException e ) { throw e; // Catch and release to execute finally{} } // end catch finally { try { out.close(); } catch( Exception ex ){} } // end finally } // end encodeFileToFile /** * Reads infile and decodes it to outfile. * * @param infile Input file * @param outfile Output file * @throws java.io.IOException if there is an error * @since 2.2 */ public static void decodeFileToFile( String infile, String outfile ) throws java.io.IOException { byte[] decoded = Base64.decodeFromFile( infile ); java.io.OutputStream out = null; try{ out = new java.io.BufferedOutputStream( new java.io.FileOutputStream( outfile ) ); out.write( decoded ); } // end try catch( java.io.IOException e ) { throw e; // Catch and release to execute finally{} } // end catch finally { try { out.close(); } catch( Exception ex ){} } // end finally } // end decodeFileToFile /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */ /** * A {@link Base64.InputStream} will read data from another * java.io.InputStream, given in the constructor, * and encode/decode to/from Base64 notation on the fly. * * @see Base64 * @since 1.3 */ public static class InputStream extends java.io.FilterInputStream { private boolean encode; // Encoding or decoding private int position; // Current position in the buffer private byte[] buffer; // Small buffer holding converted data private int bufferLength; // Length of buffer (3 or 4) private int numSigBytes; // Number of meaningful bytes in the buffer private int lineLength; private boolean breakLines; // Break lines at less than 80 characters private int options; // Record options used to create the stream. private byte[] decodabet; // Local copies to avoid extra method calls /** * Constructs a {@link Base64.InputStream} in DECODE mode. * * @param in the java.io.InputStream from which to read data. * @since 1.3 */ public InputStream( java.io.InputStream in ) { this( in, DECODE ); } // end constructor /** * Constructs a {@link Base64.InputStream} in * either ENCODE or DECODE mode. *

* Valid options:

         *   ENCODE or DECODE: Encode or Decode as data is read.
         *   DO_BREAK_LINES: break lines at 76 characters
         *     (only meaningful when encoding)
         * 
*

* Example: new Base64.InputStream( in, Base64.DECODE ) * * * @param in the java.io.InputStream from which to read data. * @param options Specified options * @see Base64#ENCODE * @see Base64#DECODE * @see Base64#DO_BREAK_LINES * @since 2.0 */ public InputStream( java.io.InputStream in, int options ) { super( in ); this.options = options; // Record for later this.breakLines = (options & DO_BREAK_LINES) > 0; this.encode = (options & ENCODE) > 0; this.bufferLength = encode ? 4 : 3; this.buffer = new byte[ bufferLength ]; this.position = -1; this.lineLength = 0; this.decodabet = getDecodabet(options); } // end constructor /** * Reads enough of the input stream to convert * to/from Base64 and returns the next byte. * * @return next byte * @since 1.3 */ @Override public int read() throws java.io.IOException { // Do we need to get data? if( position < 0 ) { if( encode ) { byte[] b3 = new byte[3]; int numBinaryBytes = 0; for( int i = 0; i < 3; i++ ) { int b = in.read(); // If end of stream, b is -1. if( b >= 0 ) { b3[i] = (byte)b; numBinaryBytes++; } else { break; // out of for loop } // end else: end of stream } // end for: each needed input byte if( numBinaryBytes > 0 ) { encode3to4( b3, 0, numBinaryBytes, buffer, 0, options ); position = 0; numSigBytes = 4; } // end if: got data else { return -1; // Must be end of stream } // end else } // end if: encoding // Else decoding else { byte[] b4 = new byte[4]; int i = 0; for( i = 0; i < 4; i++ ) { // Read four "meaningful" bytes: int b = 0; do{ b = in.read(); } while( b >= 0 && decodabet[ b & 0x7f ] <= WHITE_SPACE_ENC ); if( b < 0 ) { break; // Reads a -1 if end of stream } // end if: end of stream b4[i] = (byte)b; } // end for: each needed input byte if( i == 4 ) { numSigBytes = decode4to3( b4, 0, buffer, 0, options ); position = 0; } // end if: got four characters else if( i == 0 ){ return -1; } // end else if: also padded correctly else { // Must have broken out from above. throw new java.io.IOException( "Improperly padded Base64 input." ); } // end } // end else: decode } // end else: get data // Got data? if( position >= 0 ) { // End of relevant data? if( /*!encode &&*/ position >= numSigBytes ){ return -1; } // end if: got data if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) { lineLength = 0; return '\n'; } // end if else { lineLength++; // This isn't important when decoding // but throwing an extra "if" seems // just as wasteful. int b = buffer[ position++ ]; if( position >= bufferLength ) { position = -1; } // end if: end return b & 0xFF; // This is how you "cast" a byte that's // intended to be unsigned. } // end else } // end if: position >= 0 // Else error else { throw new java.io.IOException( "Error in Base64 code reading stream." ); } // end else } // end read /** * Calls {@link #read()} repeatedly until the end of stream * is reached or len bytes are read. * Returns number of bytes read into array or -1 if * end of stream is encountered. * * @param dest array to hold values * @param off offset for array * @param len max number of bytes to read into array * @return bytes read into array or -1 if end of stream is encountered. * @since 1.3 */ @Override public int read( byte[] dest, int off, int len ) throws java.io.IOException { int i; int b; for( i = 0; i < len; i++ ) { b = read(); if( b >= 0 ) { dest[off + i] = (byte) b; } else if( i == 0 ) { return -1; } else { break; // Out of 'for' loop } // Out of 'for' loop } // end for: each byte read return i; } // end read } // end inner class InputStream /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */ /** * A {@link Base64.OutputStream} will write data to another * java.io.OutputStream, given in the constructor, * and encode/decode to/from Base64 notation on the fly. * * @see Base64 * @since 1.3 */ public static class OutputStream extends java.io.FilterOutputStream { private boolean encode; private int position; private byte[] buffer; private int bufferLength; private int lineLength; private boolean breakLines; private byte[] b4; // Scratch used in a few places private boolean suspendEncoding; private int options; // Record for later private byte[] decodabet; // Local copies to avoid extra method calls /** * Constructs a {@link Base64.OutputStream} in ENCODE mode. * * @param out the java.io.OutputStream to which data will be written. * @since 1.3 */ public OutputStream( java.io.OutputStream out ) { this( out, ENCODE ); } // end constructor /** * Constructs a {@link Base64.OutputStream} in * either ENCODE or DECODE mode. *

* Valid options:

         *   ENCODE or DECODE: Encode or Decode as data is read.
         *   DO_BREAK_LINES: don't break lines at 76 characters
         *     (only meaningful when encoding)
         * 
*

* Example: new Base64.OutputStream( out, Base64.ENCODE ) * * @param out the java.io.OutputStream to which data will be written. * @param options Specified options. * @see Base64#ENCODE * @see Base64#DECODE * @see Base64#DO_BREAK_LINES * @since 1.3 */ public OutputStream( java.io.OutputStream out, int options ) { super( out ); this.breakLines = (options & DO_BREAK_LINES) != 0; this.encode = (options & ENCODE) != 0; this.bufferLength = encode ? 3 : 4; this.buffer = new byte[ bufferLength ]; this.position = 0; this.lineLength = 0; this.suspendEncoding = false; this.b4 = new byte[4]; this.options = options; this.decodabet = getDecodabet(options); } // end constructor /** * Writes the byte to the output stream after * converting to/from Base64 notation. * When encoding, bytes are buffered three * at a time before the output stream actually * gets a write() call. * When decoding, bytes are buffered four * at a time. * * @param theByte the byte to write * @since 1.3 */ @Override public void write(int theByte) throws java.io.IOException { // Encoding suspended? if( suspendEncoding ) { this.out.write( theByte ); return; } // end if: supsended // Encode? if( encode ) { buffer[ position++ ] = (byte)theByte; if( position >= bufferLength ) { // Enough to encode. this.out.write( encode3to4( b4, buffer, bufferLength, options ) ); lineLength += 4; if( breakLines && lineLength >= MAX_LINE_LENGTH ) { this.out.write( NEW_LINE ); lineLength = 0; } // end if: end of line position = 0; } // end if: enough to output } // end if: encoding // Else, Decoding else { // Meaningful Base64 character? if( decodabet[ theByte & 0x7f ] > WHITE_SPACE_ENC ) { buffer[ position++ ] = (byte)theByte; if( position >= bufferLength ) { // Enough to output. int len = Base64.decode4to3( buffer, 0, b4, 0, options ); out.write( b4, 0, len ); position = 0; } // end if: enough to output } // end if: meaningful base64 character else if( decodabet[ theByte & 0x7f ] != WHITE_SPACE_ENC ) { throw new java.io.IOException( "Invalid character in Base64 data." ); } // end else: not white space either } // end else: decoding } // end write /** * Calls {@link #write(int)} repeatedly until len * bytes are written. * * @param theBytes array from which to read bytes * @param off offset for array * @param len max number of bytes to read into array * @since 1.3 */ @Override public void write( byte[] theBytes, int off, int len ) throws java.io.IOException { // Encoding suspended? if( suspendEncoding ) { this.out.write( theBytes, off, len ); return; } // end if: supsended for( int i = 0; i < len; i++ ) { write( theBytes[ off + i ] ); } // end for: each byte written } // end write /** * Method added by PHIL. [Thanks, PHIL. -Rob] * This pads the buffer without closing the stream. * @throws java.io.IOException if there's an error. */ public void flushBase64() throws java.io.IOException { if( position > 0 ) { if( encode ) { out.write( encode3to4( b4, buffer, position, options ) ); position = 0; } // end if: encoding else { throw new java.io.IOException( "Base64 input not properly padded." ); } // end else: decoding } // end if: buffer partially full } // end flush /** * Flushes and closes (I think, in the superclass) the stream. * * @since 1.3 */ @Override public void close() throws java.io.IOException { // 1. Ensure that pending characters are written flushBase64(); // 2. Actually close the stream // Base class both flushes and closes. super.close(); buffer = null; out = null; } // end close /** * Suspends encoding of the stream. * May be helpful if you need to embed a piece of * base64-encoded data in a stream. * * @throws java.io.IOException if there's an error flushing * @since 1.5.1 */ public void suspendEncoding() throws java.io.IOException { flushBase64(); this.suspendEncoding = true; } // end suspendEncoding /** * Resumes encoding of the stream. * May be helpful if you need to embed a piece of * base64-encoded data in a stream. * * @since 1.5.1 */ public void resumeEncoding() { this.suspendEncoding = false; } // end resumeEncoding } // end inner class OutputStream } // end class Base64 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/Base64BIOFilter.java000066400000000000000000000051571313661621600276250ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * * @author Ola Bini */ public class Base64BIOFilter extends BIOFilter { private OutputStream nextOutput; private InputStream nextInput; @Override public int write(byte[] out, int offset, int len) throws IOException { this.nextOutput.write(out, offset, len); return len; } @Override public int read(byte[] into, int offset, int len) throws IOException { int read = this.nextInput.read(into, offset, len); if(read == -1) { return 0; } return read; } @Override public void flush() throws IOException { this.nextOutput.flush(); } @Override public BIO push(BIO bio) { BIO ret = super.push(bio); this.nextOutput = new Base64.OutputStream(BIO.asOutputStream(this.nextBio)); this.nextInput = new Base64.InputStream(BIO.asInputStream(this.nextBio)); return ret; } @Override public int getType() { return TYPE_BASE64; } }// Base64BIOFilter jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/CipherBIOFilter.java000066400000000000000000000132461313661621600300110ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; /** * * @author Ola Bini */ public class CipherBIOFilter extends BIOFilter { private Cipher cipher; private byte[] bufRead = new byte[4096]; private int fillLen = 0; private int fillOffset = 0; private byte[] tmpBuf = new byte[1024]; private boolean finalized = false; public CipherBIOFilter(Cipher cipher) { this.cipher = cipher; } @Override public void flush() throws IOException, PKCS7Exception { try { byte[] result = cipher.doFinal(); if(result == null) { return; } next().write(result, 0, result.length); } catch(IllegalBlockSizeException e) { throw new PKCS7Exception(-1, -1, e); } catch(BadPaddingException e) { throw new PKCS7Exception(-1, -1, e); } } public int read(byte[] into, int offset, int len) throws IOException { try { int read = 0; if(fillLen > 0) { read = Math.min(fillLen, len); System.arraycopy(bufRead, fillOffset, into, offset, read); fillOffset += read; fillLen -= read; if(fillLen == 0) { fillOffset = 0; } if(read == len) { return read; } } int req = len - read; int off = offset + read; if(finalized) { return 0; } while(req > 0) { int readFromNext = next().read(tmpBuf, 0, 1024); if(readFromNext > 0) { int required = cipher.getOutputSize(readFromNext); if(required > (bufRead.length - (fillOffset + fillLen))) { byte[] newBuf = new byte[required + fillOffset + fillLen]; System.arraycopy(bufRead, fillOffset, newBuf, 0, fillLen); fillOffset = 0; bufRead = newBuf; } int outputted = cipher.update(tmpBuf, 0, readFromNext, bufRead, fillOffset + fillLen); fillLen += outputted; read = Math.min(fillLen, req); System.arraycopy(bufRead, fillOffset, into, off, read); fillOffset += read; fillLen -= read; if(fillLen == 0) { fillOffset = 0; } req -= read; off += read; } else { int required = cipher.getOutputSize(0); if(required > (bufRead.length - (fillOffset + fillLen))) { byte[] newBuf = new byte[required + fillOffset + fillLen]; System.arraycopy(bufRead, fillOffset, newBuf, 0, fillLen); fillOffset = 0; bufRead = newBuf; } int outputted = cipher.doFinal(bufRead, fillOffset + fillLen); finalized = true; fillLen += outputted; read = Math.min(fillLen, req); System.arraycopy(bufRead, fillOffset, into, off, read); fillOffset += read; fillLen -= read; if(fillLen == 0) { fillOffset = 0; } req -= read; return len-req; } } return len; } catch(Exception e) { throw new IllegalArgumentException(e); } } public int write(byte[] out, int offset, int len) throws IOException { byte[] result = cipher.update(out, offset, len); if(result == null) { return len; } next().write(result, 0, result.length); return len; } public int getType() { return TYPE_CIPHER; } }// CipherBIOFilter jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/CipherSpec.java000066400000000000000000000051451313661621600271230ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2009 Hiroshi Nakamura * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import javax.crypto.Cipher; /** * * @author Ola Bini */ public class CipherSpec extends BIOFilter { private final Cipher cipher; private final String osslName; private final int keyLenInBits; public CipherSpec(Cipher cipher, String osslName, int keyLenInBits) { this.cipher = cipher; this.osslName = osslName; this.keyLenInBits = keyLenInBits; } public Cipher getCipher() { return cipher; } public String getOsslName() { return osslName; } public int getKeyLenInBits() { return keyLenInBits; } public String getAlgorithm() { return getCipher().getAlgorithm(); } public String getWrappingAlgorithm() { return getWrappingAlgorithm(getAlgorithm()); } public static String getWrappingAlgorithm(String algorithm) { if (algorithm == null) { return null; } if (algorithm.equalsIgnoreCase("RSA")) { return "RSA/ECB/PKCS1Padding"; } else { return algorithm; } } }// CipherSpec jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/Digest.java000066400000000000000000000070001313661621600263050ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** PKCS7_DIGEST * * @author Ola Bini */ public class Digest { /** * Describe version here. */ private int version; /** * Describe md here. */ private AlgorithmIdentifier md; /** * Describe digest here. */ private ASN1OctetString digest; PKCS7 contents; /** * Get the Version value. * * @return an int value */ public final int getVersion() { return version; } /** * Set the Version value. * * @param newVersion The new Version value. */ public final void setVersion(final int newVersion) { this.version = newVersion; } /** * Get the Contents value. * * @return a PKCS7 value */ public final PKCS7 getContents() { return contents; } /** * Set the Contents value. * * @param newContents The new Contents value. */ public final void setContents(final PKCS7 newContents) { this.contents = newContents; } /** * Get the Md value. * * @return an AlgorithmIdentifier value */ public final AlgorithmIdentifier getMd() { return md; } /** * Set the Md value. * * @param newMd The new Md value. */ public final void setMd(final AlgorithmIdentifier newMd) { this.md = newMd; } /** * Get the Digest value. * * @return an ASN1OctetString value */ public final ASN1OctetString getDigest() { return digest; } /** * Set the Digest value. * * @param newDigest The new Digest value. */ public final void setDigest(final ASN1OctetString newDigest) { this.digest = newDigest; } }// Digest jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/ECPrivateKeyWithName.java000066400000000000000000000037271313661621600310320ustar00rootroot00000000000000/* * Copyright (c) 2016 Karol Bucek. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.jruby.ext.openssl.impl; import java.math.BigInteger; import java.security.interfaces.ECPrivateKey; import java.security.spec.ECParameterSpec; import org.bouncycastle.asn1.ASN1ObjectIdentifier; /** * a trick to keep the curve name around * (since {@link java.security.KeyPair} is final). * * @author kares */ public final class ECPrivateKeyWithName implements ECPrivateKey { private final ECPrivateKey realKey; // private final String curveNameId; private final ASN1ObjectIdentifier curveNameOID; public static ECPrivateKeyWithName wrap(ECPrivateKey realKey, ASN1ObjectIdentifier nameOID) { return new ECPrivateKeyWithName(realKey, nameOID); } private ECPrivateKeyWithName(ECPrivateKey realKey, ASN1ObjectIdentifier nameOID) { this.realKey = realKey; this.curveNameOID = nameOID; } //private ECPrivateKeyWithName(ECPrivateKey realKey, String curveNameId) { // this.realKey = realKey; // this.curveNameId = curveNameId; //} //public String getCurveNameId() { // return curveNameId; //} public ASN1ObjectIdentifier getCurveNameOID() { return curveNameOID; } public ECPrivateKey unwrap() { return realKey; } public BigInteger getS() { return realKey.getS(); } public String getAlgorithm() { return realKey.getAlgorithm(); } public String getFormat() { return realKey.getFormat(); } public byte[] getEncoded() { return realKey.getEncoded(); } public ECParameterSpec getParams() { return realKey.getParams(); } @Override public String toString() { return realKey.toString(); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/EVP.java000066400000000000000000000123551313661621600255310ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.security.InvalidKeyException; import java.security.Key; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.jruby.ext.openssl.SecurityHelper; import static org.jruby.ext.openssl.Cipher.Algorithm; /** * * @author Ola Bini */ public class EVP { // This is a class that will collect mappings from ASN1 stuff to // matching Cipher and other algorithms. // Typical examples: // EVP_get_cipherbyobj // EVP_get_digestbynid /* c: EVP_get_cipherbyobj * */ public static Cipher getCipher(ASN1ObjectIdentifier oid) throws NoSuchAlgorithmException, NoSuchPaddingException { String algorithm = getAlgorithmName(oid); String realName = Algorithm.getRealName(algorithm); return SecurityHelper.getCipher(realName); } /* c: EVP_get_digestbyobj * */ public static MessageDigest getDigest(ASN1ObjectIdentifier oid) throws NoSuchAlgorithmException { String algorithm = getAlgorithmName(oid); return SecurityHelper.getMessageDigest(algorithm); } /* c: EVP_sha1 * */ public static MessageDigest sha1() { try { return SecurityHelper.getMessageDigest("SHA1"); } catch (NoSuchAlgorithmException e) { return null; } } public static int type(final MessageDigest digest) { String name = digest.getAlgorithm().toLowerCase(); String oid = ASN1Registry.getOIDLookup().get(name); if ( oid == null ) { name = name.replace("sha-", "sha"); oid = ASN1Registry.getOIDLookup().get(name); } return ASN1Registry.oid2nid(oid); } public static String signatureAlgorithm(MessageDigest digest, Key key) { String sig = digest.getAlgorithm().toLowerCase().replace("sha-", "sha"); String type = key.getAlgorithm().toLowerCase(); if ( sig == null ) sig = "none"; return sig + "with" + type; } /* c: EVP_PKEY_decrypt * */ public static byte[] decrypt(byte[] input, int offset, int len, Key key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { Cipher cipher = SecurityHelper.getCipher(key.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, key); return cipher.doFinal(input, offset, len); } /* c: EVP_PKEY_decrypt * */ public static byte[] decrypt(byte[] input, Key key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { return decrypt(input, 0, input.length, key); } private static String getAlgorithmName(ASN1ObjectIdentifier oid) { String algorithm = ASN1Registry.o2a(oid); if (algorithm != null) { return algorithm.toUpperCase(); } else { return oid.getId(); } } }// EVP jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/EncContent.java000066400000000000000000000143321313661621600271340ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.jruby.util.ByteList; /** PKCS7_ENC_CONTENT * * @author Ola Bini */ public class EncContent { /** * Describe contentType here. */ private int contentType; /** * Describe cipher here. */ private CipherSpec cipher; /** * Describe algorithm here. */ private AlgorithmIdentifier algorithm; /** * Describe encData here. */ private ASN1OctetString encData; /** * Get the ContentType value. * * @return an int value */ public final int getContentType() { return contentType; } /** * Set the ContentType value. * * @param newContentType The new ContentType value. */ public final void setContentType(final int newContentType) { this.contentType = newContentType; } /** * Get the Cipher value. * * @return a Cipher value */ public final CipherSpec getCipher() { return cipher; } /** * Set the Cipher value. * * @param newCipher The new Cipher value. */ public final void setCipher(final CipherSpec newCipher) { this.cipher = newCipher; } /** * Get the Algorithm value. * * @return an AlgorithmIdentifier value */ public final AlgorithmIdentifier getAlgorithm() { return algorithm; } /** * Set the Algorithm value. * * @param newAlgorithm The new Algorithm value. */ public final void setAlgorithm(final AlgorithmIdentifier newAlgorithm) { this.algorithm = newAlgorithm; } /** * Get the EncData value. * * @return an ASN1OctetString value */ public final ASN1OctetString getEncData() { return encData; } /** * Set the EncData value. * * @param newEncData The new EncData value. */ public final void setEncData(final ASN1OctetString newEncData) { this.encData = newEncData; } @Override public String toString() { return "#"; } /** * EncryptedContentInfo ::= SEQUENCE { * contentType ContentType, * contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, * encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL } * * EncryptedContent ::= OCTET STRING */ public static EncContent fromASN1(final ASN1Encodable content) { final ASN1Sequence sequence = (ASN1Sequence) content; ASN1ObjectIdentifier contentType = (ASN1ObjectIdentifier)(sequence.getObjectAt(0)); final EncContent ec = new EncContent(); ec.setContentType( ASN1Registry.oid2nid(contentType) ); ec.setAlgorithm(AlgorithmIdentifier.getInstance(sequence.getObjectAt(1))); if(sequence.size() > 2 && sequence.getObjectAt(2) instanceof ASN1TaggedObject && ((ASN1TaggedObject)(sequence.getObjectAt(2))).getTagNo() == 0) { ASN1Encodable ee = ((ASN1TaggedObject)(sequence.getObjectAt(2))).getObject(); if ( ee instanceof ASN1Sequence && ((ASN1Sequence) ee).size() > 0 ) { ByteList combinedOctets = new ByteList(); Enumeration enm = ((ASN1Sequence)ee).getObjects(); while (enm.hasMoreElements()) { byte[] octets = ((ASN1OctetString)enm.nextElement()).getOctets(); combinedOctets.append(octets); } ec.setEncData(new DEROctetString(combinedOctets.bytes())); } else { ec.setEncData((ASN1OctetString)ee); } } return ec; } public ASN1Encodable asASN1() { ASN1EncodableVector vector = new ASN1EncodableVector(); vector.add(ASN1Registry.nid2obj(contentType).toASN1Primitive()); vector.add(algorithm.toASN1Primitive()); if ( encData != null ) { vector.add(new DERTaggedObject(false, 0, encData)); } return new DLSequence(vector); } }// EncContent jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/Encrypt.java000066400000000000000000000050151313661621600265160ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; /** PKCS7_ENCRYPT * * @author Ola Bini */ public class Encrypt { private int version; /** * Describe encContent here. */ private EncContent encData = new EncContent(); /** * Get the Version value. * * @return an int value */ public final int getVersion() { return version; } /** * Set the Version value. * * @param newVersion The new Version value. */ public final void setVersion(final int newVersion) { this.version = newVersion; } /** * Get the EncData value. * * @return an EncContent value */ public final EncContent getEncData() { return encData; } /** * Set the EncData value. * * @param newEncContent The new EncContent value. */ public final void setEncData(final EncContent newEncData) { this.encData = newEncData; } }// Encrypt jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/Envelope.java000066400000000000000000000127051313661621600266530ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DLSequence; /** PKCS7_ENVELOPE * * @author Ola Bini */ public class Envelope { private int version; /** * Describe encContent here. */ private EncContent encData = new EncContent(); /** * Describe recipientInfo here. */ private Collection recipientInfo = new ArrayList(); /** * Get the Version value. * * @return an int value */ public final int getVersion() { return version; } /** * Set the Version value. * * @param newVersion The new Version value. */ public final void setVersion(final int newVersion) { this.version = newVersion; } /** * Get the EncData value. * * @return an EncContent value */ public final EncContent getEncData() { return encData; } /** * Set the EncData value. * * @param newEncContent The new EncContent value. */ public final void setEncData(final EncContent newEncData) { this.encData = newEncData; } /** * Get the RecipientInfo value. * * @return a Collection value */ public final Collection getRecipientInfo() { return recipientInfo; } /** * Set the RecipientInfo value. * * @param newRecipientInfo The new RecipientInfo value. */ public final void setRecipientInfo(final Collection newRecipientInfo) { this.recipientInfo = newRecipientInfo; } @Override public String toString() { return "#"; } /** * EnvelopedData ::= SEQUENCE { * version Version, * recipientInfos RecipientInfos, * encryptedContentInfo EncryptedContentInfo } * * Version ::= INTEGER * * RecipientInfos ::= SET OF RecipientInfo * */ public static Envelope fromASN1(ASN1Encodable content) { ASN1Sequence sequence = (ASN1Sequence) content; ASN1Integer version = (ASN1Integer) sequence.getObjectAt(0); ASN1Set recipients = (ASN1Set) sequence.getObjectAt(1); ASN1Encodable encContent = sequence.getObjectAt(2); Envelope envelope = new Envelope(); envelope.setVersion(version.getValue().intValue()); envelope.setRecipientInfo(recipientInfosFromASN1Set(recipients)); envelope.setEncData(EncContent.fromASN1(encContent)); return envelope; } public ASN1Encodable asASN1() { ASN1EncodableVector vector = new ASN1EncodableVector(); vector.add( new ASN1Integer( BigInteger.valueOf(version) ) ); vector.add( receipientInfosToASN1Set() ); vector.add( encData.asASN1() ); return new DLSequence(vector); } private ASN1Set receipientInfosToASN1Set() { ASN1EncodableVector vector = new ASN1EncodableVector(); for (RecipInfo ri : getRecipientInfo()) { vector.add(ri.asASN1()); } return new DERSet(vector); } private static Collection recipientInfosFromASN1Set(ASN1Encodable content) { ASN1Set set = (ASN1Set)content; Collection result = new ArrayList(); for(Enumeration e = set.getObjects(); e.hasMoreElements();) { result.add(RecipInfo.fromASN1((ASN1Encodable)e.nextElement())); } return result; } }// Envelope jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/IssuerAndSerial.java000066400000000000000000000032101313661621600301220ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; /** PKCS7_ISSUER_AND_SERIAL * * @author Ola Bini */ public class IssuerAndSerial { }// IssuerAndSerial jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/MemBIO.java000066400000000000000000000070221313661621600261420ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; /** * * @author Ola Bini */ public class MemBIO extends BIO { private byte[] buffer = new byte[1024]; private int wpointer = 0; private int rpointer = 0; private int slen = 0; private void realloc() { byte[] newBuffer = new byte[buffer.length*2]; System.arraycopy(buffer, 0, newBuffer, 0, wpointer); buffer = newBuffer; } @Override public int gets(byte[] in, int len) throws IOException { if(rpointer == slen) { return 0; } int i=0; for(;i buffer.length) { realloc(); } System.arraycopy(out, offset, buffer, wpointer, len); wpointer += len; slen += len; return len; } @Override public String toString() { try { return ""; } catch(Exception e) {} return null; } @Override public void setMemEofReturn(int value) { } public int getType() { return TYPE_MEM; } public byte[] getMemCopy() { byte[] nbuf = new byte[slen]; System.arraycopy(buffer, 0, nbuf, 0, slen); return nbuf; } public void reset() { this.rpointer = 0; } }// MemBIO jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/MessageDigestBIOFilter.java000066400000000000000000000051431313661621600313200ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; import java.security.MessageDigest; /** * * @author Ola Bini */ public class MessageDigestBIOFilter extends BIOFilter { private MessageDigest md; public MessageDigestBIOFilter(MessageDigest md) { this.md = md; } public int gets(byte[] in, int len) throws IOException { int read = next().gets(in, len); if(read > 0) { md.update(in, 0, read); } return read; } public int read(byte[] into, int offset, int len) throws IOException { int read = next().read(into, offset, len); if(read > 0) { md.update(into, offset, read); } return read; } public int write(byte[] out, int offset, int len) throws IOException { int written = next().write(out, offset, len); md.update(out, offset, written); return written; } public int getType() { return TYPE_MD; } /** c: BIO_get_md_ctx * */ public MessageDigest getMessageDigest() { return md; } }// MessageDigestBIOFilter jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/Mime.java000066400000000000000000000223361313661621600257660ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * * @author Ola Bini */ public interface Mime { Mime DEFAULT = new Mime() { private final static int MIME_START = 1; private final static int MIME_TYPE = 2; private final static int MIME_NAME = 3; private final static int MIME_VALUE = 4; private final static int MIME_QUOTE = 5; private final static int MIME_COMMENT = 6; private final static int MAX_SMLEN = 1024; /* c: static strip_start */ private int stripStart(byte[] buffer, int start, int end) { byte c; for(int p = start; p= start; p--) { mimeDebug(" p = "+p+", c = "+(char)buffer[p] + "(" + buffer[p] + ")"); c = buffer[p]; if(c == '"') { if(p - 1 == start) { return -1; } return p; } if(!Character.isWhitespace((char)c)) { return p+1; } } return -1; } /* c: static strip_ends */ private String stripEnds(byte[] buffer, int start, int end) { start = stripStart(buffer, start, end); end = stripEnd(buffer, start, end); try { return new String(buffer, start, end-start, "ISO8859-1"); } catch(Exception e) { return null; } } public void mimeDebug(String str) { // System.err.println(str); } public List parseHeaders(BIO bio) throws IOException { mimeDebug("\n!!!!!!!!!!!!!!!!!\n" + bio + "\n^^^^^^^^^^^^^^^^^^^^^^^^\n"); int state = 0; byte[] linebuf = new byte[MAX_SMLEN]; int len = 0; String ntmp = null; int p, q; byte c; MimeHeader mhdr = null; int saveState = -1; List headers = new ArrayList(); while((len = bio.gets(linebuf, MAX_SMLEN)) > 0) { if(mhdr != null && Character.isWhitespace((char)linebuf[0])) { state = MIME_NAME; } else { state = MIME_START; } for(p = 0, q = 0; p headers, String key) { for(MimeHeader hdr : headers) { if(hdr.getName().equals(key)) { return hdr; } } return null; } public MimeParam findParam(MimeHeader header, String key) { for(MimeParam par : header.getParams()) { if(par.getParamName().equals(key)) { return par; } } return null; } }; /* c: mime_parse_hdr * */ List parseHeaders(BIO bio) throws IOException; /* c: mime_hdr_find * */ MimeHeader findHeader(List headers, String key); /* c: mime_param_find * */ MimeParam findParam(MimeHeader header, String key); }// Mime jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/MimeHeader.java000066400000000000000000000073041313661621600270750ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.util.ArrayList; import java.util.List; /** MIME_HEADER * * @author Ola Bini */ public class MimeHeader { private String name; private String value; /** * Describe params here. */ private List params; public MimeHeader(String name, String value) { this(name, value, new ArrayList()); } public MimeHeader(String name, String value, List params) { this.name = (name == null) ? null : name.toLowerCase(); this.value = (value == null) ? null : value.toLowerCase(); this.params = params; } public String getName() { return this.name; } public String getValue() { return this.value; } /** * Get the Params value. * * @return a List value */ public final List getParams() { return params; } /** * Set the Params value. * * @param newParams The new Params value. */ public final void setParams(final List newParams) { this.params = newParams; } @Override public boolean equals(Object other) { boolean ret = this == other; if(!ret && (other instanceof MimeHeader)) { MimeHeader mh = (MimeHeader)other; ret = ((this.name == null) ? mh.name == null : this.name.equals(mh.name)) && ((this.value == null) ? mh.value == null : this.value.equals(mh.value)) && ((this.params == null) ? mh.params == null : this.params.equals(mh.params)); } return ret; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((params == null) ? 0 : params.hashCode()); result = prime * result + ((value == null) ? 0 : value.hashCode()); return result; } @Override public String toString() { return "#"; } }// MimeHeader jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/MimeParam.java000066400000000000000000000055741313661621600267540ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; /** MIME_PARAM * * @author Ola Bini */ public class MimeParam { private String paramName; private String paramValue; public MimeParam(String name, String value) { this.paramName = (name == null) ? null : name.toLowerCase(); this.paramValue = value; } public String getParamName() { return this.paramName; } public String getParamValue() { return this.paramValue; } @Override public boolean equals(Object other) { boolean ret = this == other; if(!ret && (other instanceof MimeParam)) { MimeParam mh = (MimeParam)other; ret = ((this.paramName == null) ? mh.paramName == null : this.paramName.equals(mh.paramName)) && ((this.paramValue == null) ? mh.paramValue == null : this.paramValue.equals(mh.paramValue)); } return ret; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((paramName == null) ? 0 : paramName.hashCode()); result = prime * result + ((paramValue == null) ? 0 : paramValue.hashCode()); return result; } @Override public String toString() { return "#"; } }// MimeParam jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/NetscapeCertRequest.java000066400000000000000000000234001313661621600310210ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERIA5String; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.jruby.ext.openssl.SecurityHelper; /** * * Handles NetScape certificate request (KEYGEN), these are constructed as: *


* SignedPublicKeyAndChallenge ::= SEQUENCE {
* publicKeyAndChallenge PublicKeyAndChallenge,
* signatureAlgorithm AlgorithmIdentifier,
* signature BIT STRING
* }
* 
* * PublicKey's encoded-format has to be X.509. * *
* Copy-pasted from BC JCE's NetscapeCertRequest (http://git.io/vpGXPA). * * @note This code avoids Java Security public API calls such as * KeyFactory.getInstance(keyAlgorithm, "BC") that depend on the * provider being registered. **/ public class NetscapeCertRequest // extends ASN1Object { private AlgorithmIdentifier sigAlg; private AlgorithmIdentifier keyAlg; private byte[] signatureBits; private final String challenge; private final DERBitString content; private PublicKey publicKey; public NetscapeCertRequest(final byte[] request) throws NoSuchAlgorithmException, InvalidKeySpecException, IllegalArgumentException { ASN1InputStream input = new ASN1InputStream( new ByteArrayInputStream(request) ); ASN1Sequence spkac; try { spkac = ASN1Sequence.getInstance( input.readObject() ); } catch (IOException e) { throw new IllegalArgumentException(e); } // // SignedPublicKeyAndChallenge ::= SEQUENCE { // publicKeyAndChallenge PublicKeyAndChallenge, // signatureAlgorithm AlgorithmIdentifier, // signature BIT STRING // } // if ( spkac.size() != 3 ) { throw new IllegalArgumentException("invalid SPKAC (size):" + spkac.size()); } final ASN1Sequence signatureId = (ASN1Sequence) spkac.getObjectAt(1); this.sigAlg = AlgorithmIdentifier.getInstance(signatureId); this.signatureBits = ((DERBitString) spkac.getObjectAt(2)).getBytes(); // // PublicKeyAndChallenge ::= SEQUENCE { // spki SubjectPublicKeyInfo, // challenge IA5STRING // } // ASN1Sequence pkac = (ASN1Sequence) spkac.getObjectAt(0); if ( pkac.size() != 2 ) { throw new IllegalArgumentException("invalid PKAC (len): " + pkac.size()); } this.challenge = ((DERIA5String) pkac.getObjectAt(1)).getString(); final String keyAlgorithm; final X509EncodedKeySpec encodedKeySpec; try { //this could be dangerous, as ASN.1 decoding/encoding //could potentially alter the bytes this.content = new DERBitString(pkac); final SubjectPublicKeyInfo pubKeyInfo = new SubjectPublicKeyInfo((ASN1Sequence) pkac.getObjectAt(0)); encodedKeySpec = new X509EncodedKeySpec( new DERBitString(pubKeyInfo).getBytes() ); this.keyAlg = pubKeyInfo.getAlgorithm(); keyAlgorithm = keyAlg.getAlgorithm().getId(); } catch (Exception e) { // new DERBitString throw IOExcetpion since BC 1.49 //if ( e instanceof IOException ) { // throw new IllegalArgumentException(e); //} if ( e instanceof RuntimeException ) throw (RuntimeException) e; throw new IllegalArgumentException(e); } KeyFactory keyFactory = SecurityHelper.getKeyFactory(keyAlgorithm); this.publicKey = keyFactory.generatePublic(encodedKeySpec); } public NetscapeCertRequest(final String challenge, final AlgorithmIdentifier signingAlg, final PublicKey publicKey) throws InvalidKeySpecException { this.challenge = challenge; this.sigAlg = signingAlg; this.publicKey = publicKey; ASN1EncodableVector contentDER = new ASN1EncodableVector(); try { contentDER.add(getKeySpec()); } catch (IOException e) { throw new InvalidKeySpecException(e); } //content_der.add(new SubjectPublicKeyInfo(sigAlg, new RSAPublicKeyStructure(pubkey.getModulus(), pubkey.getPublicExponent()).getDERObject())); contentDER.add(new DERIA5String(challenge)); try { this.content = new DERBitString(new DERSequence(contentDER)); } catch (Exception e) { // new DERBitString throw IOExcetpion since BC 1.49 if ( e instanceof RuntimeException ) throw (RuntimeException) e; throw new InvalidKeySpecException("exception encoding key: " + e.toString()); } } public String getChallenge() { return challenge; } /* public void setChallenge(String value) { challenge = value; } */ public AlgorithmIdentifier getSigningAlgorithm() { return sigAlg; } /* public void setSigningAlgorithm(AlgorithmIdentifier value) { sigAlg = value; } */ public AlgorithmIdentifier getKeyAlgorithm() { return keyAlg; } public void setKeyAlgorithm(AlgorithmIdentifier value) { keyAlg = value; } public PublicKey getPublicKey() { return publicKey; } public void setPublicKey(PublicKey value) { publicKey = value; } public boolean verify(String challenge) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException { if ( ! challenge.equals(this.challenge) ) return false; // // Verify the signature .. shows the response was generated // by someone who knew the associated private key // final Signature signature = getSignature(); signature.initVerify(publicKey); signature.update(content.getBytes()); return signature.verify(signatureBits); } public void sign(final PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidKeySpecException { sign(privateKey, null); } public void sign(final PrivateKey privateKey, SecureRandom random) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidKeySpecException { final Signature signature = getSignature(); if ( random != null ) { signature.initSign(privateKey, random); } else { signature.initSign(privateKey); } ASN1EncodableVector pkac = new ASN1EncodableVector(); try { pkac.add(getKeySpec()); } catch (IOException e) { throw new InvalidKeySpecException(e); } pkac.add(new DERIA5String(challenge)); try { signature.update(new DERSequence(pkac).getEncoded(ASN1Encoding.DER)); } catch (IOException e) { throw new SignatureException(e); } signatureBits = signature.sign(); } private Signature getSignature() throws NoSuchAlgorithmException { String algorithm = sigAlg.getAlgorithm().getId(); return SecurityHelper.getSignature(algorithm); } private ASN1Primitive getKeySpec() throws IOException { ASN1InputStream input = new ASN1InputStream( new ByteArrayInputStream( publicKey.getEncoded() ) ); return input.readObject(); } public ASN1Primitive toASN1Primitive() throws IOException { ASN1EncodableVector spkac = new ASN1EncodableVector(); ASN1EncodableVector pkac = new ASN1EncodableVector(); try { pkac.add( getKeySpec() ); } catch (IOException e) { // TODO is this really fine shouldn't it be thrown ? } pkac.add(new DERIA5String(challenge)); spkac.add(new DERSequence(pkac)); spkac.add(sigAlg); spkac.add(new DERBitString(signatureBits)); return new DERSequence(spkac); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/NotVerifiedPKCS7Exception.java000066400000000000000000000034271313661621600317440ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; /** * * @author Ola Bini */ public class NotVerifiedPKCS7Exception extends PKCS7Exception { private static final long serialVersionUID = 1L; public NotVerifiedPKCS7Exception() { super(-1, -1); } }// NotVerifiedPKCS7Exception jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/NullSinkBIO.java000066400000000000000000000037541313661621600271730ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; /** * * @author Ola Bini */ public class NullSinkBIO extends BIO { public int gets(byte[] in, int len) throws IOException { return 0; } public int write(byte[] out, int offset, int len) throws IOException { return len; } public int read(byte[] into, int offset, int len) throws IOException { return 0; } public int getType() { return TYPE_NULL; } }// NullSinkBIO jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS10Request.java000066400000000000000000000357211313661621600273530ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2013 Matt Hauck * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.util.List; import java.io.OutputStream; import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.KeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.InvalidKeySpecException; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.pkcs.CertificationRequestInfo; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.pkcs.CertificationRequest; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.crypto.util.PublicKeyFactory; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DSAPublicKeyParameters; import org.bouncycastle.crypto.params.DSAParameters; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.jce.spec.ECParameterSpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.bouncycastle.operator.ContentSigner; import org.bouncycastle.operator.ContentVerifier; import org.bouncycastle.operator.ContentVerifierProvider; import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; import org.bouncycastle.pkcs.PKCSException; import org.jruby.ext.openssl.SecurityHelper; public class PKCS10Request { private X500Name subject; private SubjectPublicKeyInfo publicKeyInfo; private List attributes; private transient PKCS10CertificationRequest signedRequest; public PKCS10Request(X500Name subject, SubjectPublicKeyInfo publicKeyInfo, List attrs) { this.subject = subject; this.publicKeyInfo = publicKeyInfo; this.attributes = attrs; } public PKCS10Request(X500Name subject, PublicKey publicKey, List attrs) { this.subject = subject; this.publicKeyInfo = makePublicKeyInfo(publicKey); this.attributes = attrs; } // For reading existing requests public PKCS10Request(final CertificationRequest req) { subject = req.getCertificationRequestInfo().getSubject(); publicKeyInfo = req.getCertificationRequestInfo().getSubjectPublicKeyInfo(); setAttributes( req.getCertificationRequestInfo().getAttributes() ); signedRequest = new PKCS10CertificationRequest(req); // valid = true; } public PKCS10Request(byte[] bytes) { this(CertificationRequest.getInstance(bytes)); } public PKCS10Request(ASN1Sequence sequence) { this(CertificationRequest.getInstance(sequence)); } private void resetSignedRequest() { if ( signedRequest == null ) return; CertificationRequest req = signedRequest.toASN1Structure(); CertificationRequestInfo reqInfo = new CertificationRequestInfo(subject, publicKeyInfo, req.getCertificationRequestInfo().getAttributes()); ASN1Sequence seq = (ASN1Sequence) req.toASN1Primitive(); req = new CertificationRequest(reqInfo, (AlgorithmIdentifier) seq.getObjectAt(1), (DERBitString) seq.getObjectAt(2)); signedRequest = new PKCS10CertificationRequest(req); // valid = true; } // sign public PKCS10CertificationRequest sign(final PrivateKey privateKey, final AlgorithmIdentifier signatureAlg) throws NoSuchAlgorithmException, InvalidKeyException { final ContentSigner signer = new PKCS10Signer(privateKey, signatureAlg); signedRequest = newBuilder().build(signer); // valid = true; return signedRequest; } public PKCS10CertificationRequest sign(final PrivateKey privateKey, final String digestAlg) throws NoSuchAlgorithmException, InvalidKeyException { String sigAlg = digestAlg + "WITH" + getPublicKeyAlgorithm(); return sign( privateKey, new DefaultSignatureAlgorithmIdentifierFinder().find( sigAlg ) ); } // verify public boolean verify(final PublicKey publicKey) throws InvalidKeyException { if ( signedRequest == null ) { if ( true ) throw new IllegalStateException("no signed request"); return false; } try { ContentVerifierProvider verifier = new PKCS10VerifierProvider( publicKey ); return signedRequest.isSignatureValid( verifier ); } catch (PKCSException e) { throw new InvalidKeyException(e); } } // privates private PKCS10CertificationRequestBuilder newBuilder() { final PKCS10CertificationRequestBuilder builder = new PKCS10CertificationRequestBuilder(subject, publicKeyInfo); if ( attributes != null ) { for ( Attribute attribute : attributes ) { builder.addAttribute(attribute.getAttrType(), attribute.getAttributeValues()); } } return builder; } private static SubjectPublicKeyInfo makePublicKeyInfo(PublicKey publicKey) { if ( publicKey == null ) return null; return SubjectPublicKeyInfo.getInstance( publicKey.getEncoded() ); } // conversion public ASN1Sequence toASN1Structure() { if ( signedRequest == null ) { // return an empty Sequence return new DLSequence(); } return ASN1Sequence.getInstance( signedRequest.toASN1Structure() ); } // getters and setters public void setSubject(final X500Name subject) { this.subject = subject; resetSignedRequest(); } public X500Name getSubject() { return subject; } //private transient String publicKeyAlgorithm; public void setPublicKey(final PublicKey publicKey) { this.publicKeyInfo = makePublicKeyInfo(publicKey); //if ( publicKey == null ) publicKeyAlgorithm = null; //else publicKeyAlgorithm = publicKey.getAlgorithm(); resetSignedRequest(); } private String getPublicKeyAlgorithm() { //if ( publicKeyAlgorithm == null ) { // throw new IllegalStateException("no public key info"); //} //return publicKeyAlgorithm; if ( publicKeyInfo == null ) { throw new IllegalStateException("no public key info"); } AlgorithmIdentifier algId = publicKeyInfo.getAlgorithm(); return ASN1Registry.oid2sym( algId.getAlgorithm() ); } public PublicKey generatePublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException { AsymmetricKeyParameter keyParams = PublicKeyFactory.createKey(publicKeyInfo); final KeySpec keySpec; final KeyFactory keyFactory; if ( keyParams instanceof RSAKeyParameters ) { RSAKeyParameters rsa = (RSAKeyParameters) keyParams; keySpec = new RSAPublicKeySpec( rsa.getModulus(), rsa.getExponent() ); keyFactory = SecurityHelper.getKeyFactory("RSA"); return keyFactory.generatePublic(keySpec); } else if ( keyParams instanceof DSAPublicKeyParameters ) { DSAPublicKeyParameters dsa = (DSAPublicKeyParameters) keyParams; DSAParameters params = dsa.getParameters(); keySpec = new DSAPublicKeySpec( dsa.getY(), params.getP(), params.getQ(), params.getG() ); keyFactory = SecurityHelper.getKeyFactory("DSA"); return keyFactory.generatePublic(keySpec); } else if ( keyParams instanceof ECPublicKeyParameters ) { ECPublicKeyParameters ec = (ECPublicKeyParameters) keyParams; ECDomainParameters ecParams = ec.getParameters(); ECParameterSpec params = new ECParameterSpec( ecParams.getCurve(), ecParams.getG(), ecParams.getN(), ecParams.getH(), ecParams.getSeed() ); // NOTE: likely to fail if non BC factory picked up : keySpec = new ECPublicKeySpec(ec.getQ(), params); keyFactory = SecurityHelper.getKeyFactory("EC"); return keyFactory.generatePublic(keySpec); } else { throw new IllegalStateException("could not generate public key for request, params type: " + keyParams); } } public Attribute[] getAttributes() { return signedRequest != null ? signedRequest.getAttributes() : attributes.toArray(new Attribute[ attributes.size() ]); } public void setAttributes(final List attrs) { this.attributes = attrs; } private void setAttributes(final ASN1Set attrs) { this.attributes = new ArrayList(); final Enumeration e = attrs.getObjects(); while ( e.hasMoreElements() ) { addAttribute( Attribute.getInstance( e.nextElement() ) ); } } public void addAttribute(final Attribute attribute) { this.attributes.add( attribute ); } public BigInteger getVersion() { if ( signedRequest == null ) return null; return signedRequest.toASN1Structure(). getCertificationRequestInfo(). getVersion().getValue(); } private static class PKCS10Signer implements ContentSigner { final AlgorithmIdentifier signatureAlg; final Signature signature; private final SignatureOutputStream out; PKCS10Signer(PrivateKey privateKey, AlgorithmIdentifier signatureAlg) throws NoSuchAlgorithmException, InvalidKeyException { this.signatureAlg = signatureAlg; signature = SecurityHelper.getSignature( signatureAlg.getAlgorithm().getId() ); signature.initSign( privateKey ); out = new SignatureOutputStream(signature); } public AlgorithmIdentifier getAlgorithmIdentifier() { return signatureAlg; } public OutputStream getOutputStream() { return out; } public byte[] getSignature() { try { return signature.sign(); } catch (SignatureException e) { throw new RuntimeException("Could not read signature: " + e); } } } private static class PKCS10VerifierProvider implements ContentVerifierProvider { final PublicKey publicKey; PKCS10VerifierProvider(PublicKey key) { publicKey = key; } public ContentVerifier get(AlgorithmIdentifier sigAlg) { try { return new PKCS10Verifier(publicKey, sigAlg); } catch (Exception e) { throw new RuntimeException("Could not create content verifier: " + e); } } public boolean hasAssociatedCertificate() { return false; } public org.bouncycastle.cert.X509CertificateHolder getAssociatedCertificate() { return null; } } private static class PKCS10Verifier implements ContentVerifier { final AlgorithmIdentifier signatureAlg; final Signature signature; private final SignatureOutputStream out; public PKCS10Verifier(PublicKey publicKey, AlgorithmIdentifier signatureAlg) throws NoSuchAlgorithmException, InvalidKeyException { this.signatureAlg = signatureAlg; signature = SecurityHelper.getSignature( signatureAlg.getAlgorithm().getId() ); signature.initVerify( publicKey ); out = new SignatureOutputStream(signature); } public AlgorithmIdentifier getAlgorithmIdentifier() { return signatureAlg; } public OutputStream getOutputStream() { return out; } public boolean verify(byte[] expected) { try { return signature.verify( expected ); } catch (SignatureException e) { throw new RuntimeException("Could not verify signature: " + e); } } } private static class SignatureOutputStream extends OutputStream { private final Signature signature; SignatureOutputStream(Signature signature) { this.signature = signature; } @Override public void write(byte[] bytes, int off, int len) throws IOException { try { signature.update(bytes, off, len); } catch (SignatureException e) { throw new IOException(e); } } @Override public void write(byte[] bytes) throws IOException { try { signature.update(bytes); } catch (SignatureException e) { throw new IOException(e); } } @Override public void write(int b) throws IOException { try { signature.update((byte) b); } catch (SignatureException e) { throw new IOException(e); } } } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7.java000066400000000000000000001346371313661621600257360ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.TimeZone; import java.security.MessageDigest; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.cert.X509CRL; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.pkcs.IssuerAndSerialNumber; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.pkcs.PKCSException; import org.jruby.ext.openssl.SecurityHelper; import org.jruby.ext.openssl.x509store.Name; import org.jruby.ext.openssl.x509store.Store; import org.jruby.ext.openssl.x509store.StoreContext; import org.jruby.ext.openssl.x509store.X509AuxCertificate; import org.jruby.ext.openssl.x509store.X509Utils; /** c: PKCS7 * * Basically equivalent of the ContentInfo structures in PKCS#7. * * @author Ola Bini */ public class PKCS7 { // OpenSSL behavior: PKCS#7 ObjectId for "ITU-T" + "0" private static final String EMPTY_PKCS7_OID = "0.0"; public static final ASN1ObjectIdentifier OID_pkcs7_data = new ASN1ObjectIdentifier(ASN1Registry.OBJ_pkcs7_data); static final ASN1ObjectIdentifier OID_des_ede3_cbc = new ASN1ObjectIdentifier(ASN1Registry.OBJ_des_ede3_cbc); static final ASN1ObjectIdentifier OID_rc2_cbc = new ASN1ObjectIdentifier(ASN1Registry.OBJ_rc2_cbc); static final ASN1ObjectIdentifier OID_des_cbc = new ASN1ObjectIdentifier(ASN1Registry.OBJ_des_cbc); /* content as defined by the type */ /* all encryption/message digests are applied to the 'contents', * leaving out the 'type' field. */ private PKCS7Data data; public Object ctrl(int cmd, Object v, Object ignored) throws PKCS7Exception { return this.data.ctrl(cmd, v, ignored); } public void setDetached(int v) throws PKCS7Exception { ctrl(OP_SET_DETACHED_SIGNATURE, Integer.valueOf(v), null); } public int getDetached() throws PKCS7Exception { return ((Integer)ctrl(OP_GET_DETACHED_SIGNATURE, null, null)).intValue(); } public boolean isDetached() throws PKCS7Exception { return isSigned() && getDetached() != 0; } private void initiateWith(int nid, ASN1Encodable content) throws PKCS7Exception { this.data = PKCS7Data.fromASN1(nid, content); } public static PKCS7 newEmpty() { PKCS7 p7 = new PKCS7(); p7.data = new PKCS7DataData(); return p7; } /** * ContentInfo ::= SEQUENCE { * contentType ContentType, * content [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL } * * ContentType ::= OBJECT IDENTIFIER */ public static PKCS7 fromASN1(ASN1Encodable obj) throws PKCS7Exception { PKCS7 p7 = new PKCS7(); try { int size = ((ASN1Sequence) obj).size(); if (size == 0) { return p7; } ASN1ObjectIdentifier contentType = (ASN1ObjectIdentifier) (((ASN1Sequence) obj).getObjectAt(0)); if ( EMPTY_PKCS7_OID.equals( contentType.getId() ) ) { // OpenSSL behavior p7.setType(ASN1Registry.NID_undef); } else { final int nid = ASN1Registry.oid2nid(contentType); ASN1Encodable content = size == 1 ? (ASN1Encodable) null : ((ASN1Sequence) obj).getObjectAt(1); if (content != null && content instanceof ASN1TaggedObject && ((ASN1TaggedObject) content).getTagNo() == 0) { content = ((ASN1TaggedObject) content).getObject(); } p7.initiateWith(nid, content); } } // somewhere the object does not obey to be PKCS7 object catch (ClassCastException e) { throw new IllegalArgumentException("not a PKCS7 Object"); } return p7; } /* c: d2i_PKCS7_bio * */ public static PKCS7 fromASN1(BIO bio) throws IOException, PKCS7Exception { ASN1InputStream ais = new ASN1InputStream(BIO.asInputStream(bio)); return fromASN1(ais.readObject()); } public ASN1Encodable asASN1() { ASN1EncodableVector vector = new ASN1EncodableVector(); ASN1ObjectIdentifier contentType; if (data == null) { // OpenSSL behavior contentType = new ASN1ObjectIdentifier(EMPTY_PKCS7_OID); } else { contentType = ASN1Registry.nid2obj(getType()); } vector.add(contentType); if (data != null) { vector.add(new DERTaggedObject(0, data.asASN1())); } return new DLSequence(vector); } /* c: i2d_PKCS7 * */ public byte[] toASN1() throws IOException { return asASN1().toASN1Primitive().getEncoded(); } /* c: PKCS7_add_signature * */ public SignerInfoWithPkey addSignature(X509AuxCertificate x509, PrivateKey pkey, MessageDigest dgst) throws PKCS7Exception{ SignerInfoWithPkey si = new SignerInfoWithPkey(); si.set(x509, pkey, dgst); addSigner(si); return si; } /* c: X509_find_by_issuer_and_serial * */ public static X509AuxCertificate findByIssuerAndSerial( final Collection certs, final X500Name issuer, final BigInteger serial) { final Name name = new Name(issuer); for ( X509AuxCertificate cert : certs ) { if ( name.equalTo(cert.getIssuerX500Principal()) && serial.equals(cert.getSerialNumber()) ) { return cert; } } return null; } /* c: PKCS7_get0_signers * */ public List getSigners(Collection certs, Collection infos, int flags) throws PKCS7Exception { if ( ! isSigned() ) { throw new PKCS7Exception(F_PKCS7_GET0_SIGNERS, R_WRONG_CONTENT_TYPE); } if ( infos == null || infos.size() == 0) { throw new PKCS7Exception(F_PKCS7_GET0_SIGNERS, R_NO_SIGNERS); } final ArrayList signers = new ArrayList(infos.size()); for ( final SignerInfoWithPkey info : infos ) { final IssuerAndSerialNumber ias = info.getIssuerAndSerialNumber(); X509AuxCertificate signer = null; // System.err.println("looking for: " + ias.getName() + " and " + ias.getCertificateSerialNumber()); // System.err.println(" in: " + certs); // System.err.println(" in: " + getSign().getCert()); if(certs != null) { signer = findByIssuerAndSerial(certs, ias.getName(), ias.getCertificateSerialNumber().getValue()); } if(signer == null && (flags & NOINTERN) == 0 && getSign().getCert() != null) { signer = findByIssuerAndSerial(getSign().getCert(), ias.getName(), ias.getCertificateSerialNumber().getValue()); } if(signer == null) { throw new PKCS7Exception(F_PKCS7_GET0_SIGNERS,R_SIGNER_CERTIFICATE_NOT_FOUND); } signers.add(signer); } return signers; } /* c: PKCS7_digest_from_attributes * */ public ASN1OctetString digestFromAttributes(ASN1Set attributes) { return (ASN1OctetString)SignerInfoWithPkey.getAttribute(attributes, ASN1Registry.NID_pkcs9_messageDigest); } /* c: PKCS7_signatureVerify * */ public void signatureVerify(BIO bio, SignerInfoWithPkey si, X509AuxCertificate x509) throws PKCS7Exception { if(!isSigned() && !isSignedAndEnveloped()) { throw new PKCS7Exception(F_PKCS7_SIGNATUREVERIFY, R_WRONG_PKCS7_TYPE); } final int md_type = ASN1Registry.oid2nid( si.getDigestAlgorithm().getAlgorithm() ); BIO btmp = bio; MessageDigest mdc = null; for(;;) { if(btmp == null || (btmp = bio.findType(BIO.TYPE_MD)) == null) { throw new PKCS7Exception(F_PKCS7_SIGNATUREVERIFY, R_UNABLE_TO_FIND_MESSAGE_DIGEST); } mdc = ((MessageDigestBIOFilter)btmp).getMessageDigest(); if(null == mdc) { throw new PKCS7Exception(F_PKCS7_SIGNATUREVERIFY, -1); } if ( EVP.type(mdc) == md_type ) break; btmp = btmp.next(); } MessageDigest mdc_tmp = null; try { mdc_tmp = (MessageDigest)mdc.clone(); } catch(Exception e) {} byte[] currentData = new byte[0]; ASN1Set sk = si.getAuthenticatedAttributes(); try { if(sk != null && sk.size() > 0) { byte[] md_dat = mdc_tmp.digest(); ASN1OctetString message_digest = digestFromAttributes(sk); if(message_digest == null) { throw new PKCS7Exception(F_PKCS7_SIGNATUREVERIFY, R_UNABLE_TO_FIND_MESSAGE_DIGEST); } if(!Arrays.equals(md_dat, message_digest.getOctets())) { throw new NotVerifiedPKCS7Exception(); } currentData = sk.getEncoded(); } ASN1OctetString os = si.getEncryptedDigest(); PublicKey pkey = x509.getPublicKey(); Signature sign = SecurityHelper.getSignature(EVP.signatureAlgorithm(mdc_tmp, pkey)); sign.initVerify(pkey); if(currentData.length > 0) { sign.update(currentData); } if(!sign.verify(os.getOctets())) { throw new NotVerifiedPKCS7Exception(); } } catch(NotVerifiedPKCS7Exception e) { throw e; } catch(Exception e) { System.err.println("Other exception"); e.printStackTrace(System.err); throw new NotVerifiedPKCS7Exception(); } } /* c: PKCS7_verify * */ public void verify(Collection certs, Store store, BIO indata, BIO out, int flags) throws PKCS7Exception { if ( ! isSigned() ) { throw new PKCS7Exception(F_PKCS7_VERIFY, R_WRONG_CONTENT_TYPE); } if ( getDetached() != 0 && indata == null ) { throw new PKCS7Exception(F_PKCS7_VERIFY, R_NO_CONTENT); } Collection infos = getSignerInfo(); if ( infos == null || infos.size() == 0 ) { throw new PKCS7Exception(F_PKCS7_VERIFY, R_NO_SIGNATURES_ON_DATA); } List signers = getSigners(certs, infos, flags); if ( signers == null ) { throw new NotVerifiedPKCS7Exception(); } /* Now verify the certificates */ if ( (flags & NOVERIFY) == 0 ) { for ( final X509AuxCertificate signer : signers ) { final StoreContext certContext = new StoreContext(store); if ( (flags & NOCHAIN) == 0 ) { if ( certContext.init(signer, new ArrayList(getSign().getCert())) == 0 ) { throw new PKCS7Exception(F_PKCS7_VERIFY, -1); } certContext.setPurpose(X509Utils.X509_PURPOSE_SMIME_SIGN); } else if ( certContext.init(signer, null) == 0 ) { throw new PKCS7Exception(F_PKCS7_VERIFY, -1); } certContext.setExtraData(1, store.getExtraData(1)); if ( (flags & NOCRL) == 0 ) { certContext.setCRLs((List) getSign().getCrl()); } try { int i = certContext.verifyCertificate(); int j = 0; if (i <= 0) { j = certContext.getError(); } certContext.cleanup(); if ( i <= 0 ) { throw new PKCS7Exception(F_PKCS7_VERIFY, R_CERTIFICATE_VERIFY_ERROR, "Verify error:" + X509Utils.verifyCertificateErrorString(j)); } } catch (PKCS7Exception e) { throw e; } catch (Exception e) { throw new PKCS7Exception(F_PKCS7_VERIFY, R_CERTIFICATE_VERIFY_ERROR, e); } } } BIO tmpin = indata; BIO p7bio = dataInit(tmpin); final BIO tmpout = ( flags & TEXT ) != 0 ? BIO.mem() : out; final byte[] buf = new byte[4096]; for(;;) { try { final int i = p7bio.read(buf, 0, buf.length); if ( i <= 0 ) break; if (tmpout != null) tmpout.write(buf, 0, i); } catch (IOException e) { throw new PKCS7Exception(F_PKCS7_VERIFY, -1, e); } } if ( (flags & TEXT) != 0 ) { new SMIME(Mime.DEFAULT).text(tmpout, out); } if ( (flags & NOSIGS) == 0 ) { int i = 0; for ( SignerInfoWithPkey info : infos ) { X509AuxCertificate signer = signers.get(i++); signatureVerify(p7bio, info, signer); } } if ( tmpin == indata ) { if ( indata != null ) p7bio.pop(); } } private static final BigInteger BI_128 = BigInteger.valueOf(128); private static final BigInteger BI_64 = BigInteger.valueOf(64); private static final BigInteger BI_40 = BigInteger.valueOf(40); /* c: PKCS7_sign * */ public static PKCS7 sign(X509AuxCertificate signcert, PrivateKey pkey, Collection certs, BIO data, int flags) throws PKCS7Exception { PKCS7 p7 = new PKCS7(); p7.setType(ASN1Registry.NID_pkcs7_signed); p7.contentNew(ASN1Registry.NID_pkcs7_data); SignerInfoWithPkey si = p7.addSignature(signcert, pkey, EVP.sha1()); if ( (flags & NOCERTS) == 0 ) { p7.addCertificate(signcert); if(certs != null) { for(X509AuxCertificate c : certs) { p7.addCertificate(c); } } } if ( (flags & NOATTR) == 0 ) { si.addSignedAttribute(ASN1Registry.NID_pkcs9_contentType, OID_pkcs7_data); if ( (flags & NOSMIMECAP) == 0 ) { ASN1EncodableVector smcap = new ASN1EncodableVector(); smcap.add(new AlgorithmIdentifier(OID_des_ede3_cbc)); smcap.add(new AlgorithmIdentifier(OID_rc2_cbc, new ASN1Integer(BI_128))); smcap.add(new AlgorithmIdentifier(OID_rc2_cbc, new ASN1Integer(BI_64))); smcap.add(new AlgorithmIdentifier(OID_rc2_cbc, new ASN1Integer(BI_40))); smcap.add(new AlgorithmIdentifier(OID_des_cbc)); si.addSignedAttribute(ASN1Registry.NID_SMIMECapabilities, new DLSequence(smcap)); } } if ( (flags & STREAM) != 0 ) { return p7; } BIO p7bio = p7.dataInit(null); try { data.crlfCopy(p7bio, flags); } catch(IOException e) { throw new PKCS7Exception(F_PKCS7_SIGN, R_PKCS7_DATAFINAL_ERROR, e); } if ( (flags & DETACHED) != 0 ) { p7.setDetached(1); } p7.dataFinal(p7bio); return p7; } /* c: PKCS7_encrypt * */ public static PKCS7 encrypt(Collection certs, byte[] in, CipherSpec cipher, int flags) throws PKCS7Exception { PKCS7 p7 = new PKCS7(); p7.setType(ASN1Registry.NID_pkcs7_enveloped); try { p7.setCipher(cipher); for(X509AuxCertificate x509 : certs) { p7.addRecipient(x509); } BIO p7bio = p7.dataInit(null); BIO.memBuf(in).crlfCopy(p7bio, flags); p7bio.flush(); p7.dataFinal(p7bio); return p7; } catch(IOException e) { throw new PKCS7Exception(F_PKCS7_ENCRYPT, R_PKCS7_DATAFINAL_ERROR, e); } } /* c: PKCS7_decrypt * */ public void decrypt(PrivateKey pkey, X509AuxCertificate cert, BIO data, int flags) throws PKCS7Exception { if(!isEnveloped()) { throw new PKCS7Exception(F_PKCS7_DECRYPT, R_WRONG_CONTENT_TYPE); } try { BIO tmpmem = dataDecode(pkey, null, cert); if((flags & TEXT) == TEXT) { BIO tmpbuf = BIO.buffered(); BIO bread = tmpbuf.push(tmpmem); new SMIME(Mime.DEFAULT).text(bread, data); } else { int i; byte[] buf = new byte[4096]; while((i = tmpmem.read(buf, 0, 4096)) > 0) { data.write(buf, 0, i); } } } catch(IOException e) { throw new PKCS7Exception(F_PKCS7_DECRYPT, R_DECRYPT_ERROR, e); } } /** c: PKCS7_set_type * */ public void setType(int type) throws PKCS7Exception { switch(type) { case ASN1Registry.NID_undef: this.data = null; break; case ASN1Registry.NID_pkcs7_signed: this.data = new PKCS7DataSigned(); break; case ASN1Registry.NID_pkcs7_data: this.data = new PKCS7DataData(); break; case ASN1Registry.NID_pkcs7_signedAndEnveloped: this.data = new PKCS7DataSignedAndEnveloped(); break; case ASN1Registry.NID_pkcs7_enveloped: this.data = new PKCS7DataEnveloped(); break; case ASN1Registry.NID_pkcs7_encrypted: this.data = new PKCS7DataEncrypted(); break; case ASN1Registry.NID_pkcs7_digest: this.data = new PKCS7DataDigest(); break; default: throw new PKCS7Exception(F_PKCS7_SET_TYPE,R_UNSUPPORTED_CONTENT_TYPE); } } /** c: PKCS7_set_cipher * */ public void setCipher(CipherSpec cipher) throws PKCS7Exception { this.data.setCipher(cipher); } /** c: PKCS7_add_recipient * */ public RecipInfo addRecipient(X509AuxCertificate recip) throws PKCS7Exception { RecipInfo ri = new RecipInfo(); ri.set(recip); addRecipientInfo(ri); return ri; } /** c: PKCS7_content_new * */ public void contentNew(int nid) throws PKCS7Exception { PKCS7 ret = new PKCS7(); ret.setType(nid); this.setContent(ret); } /** c: PKCS7_add_signer * */ public void addSigner(SignerInfoWithPkey psi) throws PKCS7Exception { this.data.addSigner(psi); } /** c: PKCS7_add_certificate * */ public void addCertificate(X509AuxCertificate cert) throws PKCS7Exception { this.data.addCertificate(cert); } /** c: PKCS7_add_crl * */ public void addCRL(X509CRL crl) throws PKCS7Exception { this.data.addCRL(crl); } /** c: PKCS7_add_recipient_info * */ public void addRecipientInfo(RecipInfo ri) throws PKCS7Exception { this.data.addRecipientInfo(ri); } /** c: PKCS7_set_content * */ public void setContent(PKCS7 p7) throws PKCS7Exception { this.data.setContent(p7); } /** c: PKCS7_get_signer_info * */ public Collection getSignerInfo() { return this.data.getSignerInfo(); } private final static byte[] PEM_STRING_PKCS7_START = "-----BEGIN PKCS7-----".getBytes(); /** c: PEM_read_bio_PKCS7 * */ public static PKCS7 readPEM(BIO input) throws PKCS7Exception { try { byte[] buffer = new byte[SMIME.MAX_SMLEN]; int read; read = input.gets(buffer, SMIME.MAX_SMLEN); if(read > PEM_STRING_PKCS7_START.length) { byte[] tmp = new byte[PEM_STRING_PKCS7_START.length]; System.arraycopy(buffer, 0, tmp, 0, tmp.length); if(Arrays.equals(PEM_STRING_PKCS7_START, tmp)) { return fromASN1(BIO.base64Filter(input)); } else { return null; } } else { return null; } } catch(IOException e) { return null; } } /** c: stati PKCS7_bio_add_digest * */ public BIO bioAddDigest(BIO pbio, AlgorithmIdentifier alg) throws PKCS7Exception { try { MessageDigest md = EVP.getDigest(alg.getAlgorithm()); BIO btmp = BIO.mdFilter(md); if(pbio == null) { return btmp; } else { pbio.push(btmp); return pbio; } } catch(Exception e) { throw new PKCS7Exception(F_PKCS7_BIO_ADD_DIGEST, R_UNKNOWN_DIGEST_TYPE, e); } } /** c: PKCS7_dataDecode * */ public BIO dataDecode(PrivateKey pkey, BIO inBio, X509AuxCertificate pcert) throws PKCS7Exception { BIO out = null; BIO btmp; BIO etmp; BIO bio; byte[] dataBody = null; Collection mdSk = null; Collection rsk = null; AlgorithmIdentifier encAlg = null; Cipher evpCipher = null; RecipInfo ri = null; int i = getType(); switch(i) { case ASN1Registry.NID_pkcs7_signed: dataBody = getSign().getContents().getOctetString().getOctets(); mdSk = getSign().getMdAlgs(); break; case ASN1Registry.NID_pkcs7_signedAndEnveloped: rsk = getSignedAndEnveloped().getRecipientInfo(); mdSk = getSignedAndEnveloped().getMdAlgs(); dataBody = getSignedAndEnveloped().getEncData().getEncData().getOctets(); encAlg = getSignedAndEnveloped().getEncData().getAlgorithm(); try { evpCipher = EVP.getCipher(encAlg.getAlgorithm()); } catch(Exception e) { e.printStackTrace(System.err); throw new PKCS7Exception(F_PKCS7_DATADECODE, R_UNSUPPORTED_CIPHER_TYPE, e); } break; case ASN1Registry.NID_pkcs7_enveloped: rsk = getEnveloped().getRecipientInfo(); dataBody = getEnveloped().getEncData().getEncData().getOctets(); encAlg = getEnveloped().getEncData().getAlgorithm(); try { evpCipher = EVP.getCipher(encAlg.getAlgorithm()); } catch(Exception e) { e.printStackTrace(System.err); throw new PKCS7Exception(F_PKCS7_DATADECODE, R_UNSUPPORTED_CIPHER_TYPE, e); } break; default: throw new PKCS7Exception(F_PKCS7_DATADECODE, R_UNSUPPORTED_CONTENT_TYPE); } /* We will be checking the signature */ if(mdSk != null) { for(AlgorithmIdentifier xa : mdSk) { try { MessageDigest evpMd = EVP.getDigest(xa.getAlgorithm()); btmp = BIO.mdFilter(evpMd); if(out == null) { out = btmp; } else { out.push(btmp); } } catch(Exception e) { e.printStackTrace(System.err); throw new PKCS7Exception(F_PKCS7_DATADECODE, R_UNKNOWN_DIGEST_TYPE, e); } } } if(evpCipher != null) { /* It was encrypted, we need to decrypt the secret key * with the private key */ /* Find the recipientInfo which matches the passed certificate * (if any) */ if(pcert != null) { for(Iterator iter = rsk.iterator(); iter.hasNext();) { ri = iter.next(); if(ri.compare(pcert)) { break; } ri = null; } if(null == ri) { throw new PKCS7Exception(F_PKCS7_DATADECODE, R_NO_RECIPIENT_MATCHES_CERTIFICATE); } } byte[] tmp = null; /* If we haven't got a certificate try each ri in turn */ if(null == pcert) { for(Iterator iter = rsk.iterator(); iter.hasNext();) { ri = iter.next(); try { tmp = EVP.decrypt(ri.getEncKey().getOctets(), pkey); if(tmp != null) { break; } } catch(Exception e) { tmp = null; } ri = null; } if(ri == null) { throw new PKCS7Exception(F_PKCS7_DATADECODE, R_NO_RECIPIENT_MATCHES_KEY); } } else { try { Cipher cipher = SecurityHelper.getCipher(CipherSpec.getWrappingAlgorithm(pkey.getAlgorithm())); cipher.init(Cipher.DECRYPT_MODE, pkey); tmp = cipher.doFinal(ri.getEncKey().getOctets()); } catch (Exception e) { e.printStackTrace(System.err); throw new PKCS7Exception(F_PKCS7_DATADECODE, -1, e); } } ASN1Encodable params = encAlg.getParameters(); try { String algo = org.jruby.ext.openssl.Cipher.Algorithm.getAlgorithmBase(evpCipher); if(params != null && params instanceof ASN1OctetString) { if (algo.startsWith("RC2")) { // J9's IBMJCE needs this exceptional RC2 support. // Giving IvParameterSpec throws 'Illegal parameter' on IBMJCE. SecretKeySpec sks = new SecretKeySpec(tmp, algo); RC2ParameterSpec s = new RC2ParameterSpec(tmp.length * 8, ((ASN1OctetString) params).getOctets()); evpCipher.init(Cipher.DECRYPT_MODE, sks, s); } else { SecretKeySpec sks = new SecretKeySpec(tmp, algo); IvParameterSpec iv = new IvParameterSpec(((ASN1OctetString) params).getOctets()); evpCipher.init(Cipher.DECRYPT_MODE, sks, iv); } } else { evpCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(tmp, algo)); } } catch(Exception e) { e.printStackTrace(System.err); throw new PKCS7Exception(F_PKCS7_DATADECODE, -1, e); } etmp = BIO.cipherFilter(evpCipher); if(out == null) { out = etmp; } else { out.push(etmp); } } if(isDetached() || inBio != null) { bio = inBio; } else { if(dataBody != null && dataBody.length > 0) { bio = BIO.memBuf(dataBody); } else { bio = BIO.mem(); } } out.push(bio); return out; } /** c: PKCS7_dataInit * */ public BIO dataInit(BIO bio) throws PKCS7Exception { Collection mdSk = null; ASN1OctetString os = null; int i = this.data.getType(); Collection rsk = null; AlgorithmIdentifier xa = null; CipherSpec evpCipher = null; BIO out = null; BIO btmp = null; EncContent enc = null; switch (i) { case ASN1Registry.NID_pkcs7_signed: mdSk = getSign().getMdAlgs(); os = getSign().getContents().getOctetString(); break; case ASN1Registry.NID_pkcs7_signedAndEnveloped: rsk = getSignedAndEnveloped().getRecipientInfo(); mdSk = getSignedAndEnveloped().getMdAlgs(); enc = getSignedAndEnveloped().getEncData(); evpCipher = getSignedAndEnveloped().getEncData().getCipher(); if (null == evpCipher) { throw new PKCS7Exception(F_PKCS7_DATAINIT, R_CIPHER_NOT_INITIALIZED); } break; case ASN1Registry.NID_pkcs7_enveloped: rsk = getEnveloped().getRecipientInfo(); enc = getEnveloped().getEncData(); evpCipher = getEnveloped().getEncData().getCipher(); if (null == evpCipher) { throw new PKCS7Exception(F_PKCS7_DATAINIT, R_CIPHER_NOT_INITIALIZED); } break; case ASN1Registry.NID_pkcs7_digest: xa = getDigest().getMd(); os = getDigest().getContents().getOctetString(); break; default: throw new PKCS7Exception(F_PKCS7_DATAINIT, R_UNSUPPORTED_CONTENT_TYPE); } if (mdSk != null) { for (AlgorithmIdentifier ai : mdSk) { if ((out = bioAddDigest(out, ai)) == null) { return null; } } } if (xa != null && (out = bioAddDigest(out, xa)) == null) { return null; } if (evpCipher != null) { byte[] tmp; btmp = BIO.cipherFilter(evpCipher.getCipher()); String algoBase = evpCipher.getCipher().getAlgorithm(); if (algoBase.indexOf('/') != -1) { algoBase = algoBase.split("/")[0]; } try { KeyGenerator gen = SecurityHelper.getKeyGenerator(algoBase); gen.init(evpCipher.getKeyLenInBits(), SecurityHelper.getSecureRandom()); SecretKey key = gen.generateKey(); evpCipher.getCipher().init(Cipher.ENCRYPT_MODE, key); if (null != rsk) { for (RecipInfo ri : rsk) { PublicKey pkey = ri.getCert().getPublicKey(); Cipher cipher = SecurityHelper.getCipher(CipherSpec.getWrappingAlgorithm(pkey.getAlgorithm())); cipher.init(Cipher.ENCRYPT_MODE, pkey); tmp = cipher.doFinal(key.getEncoded()); ri.setEncKey(new DEROctetString(tmp)); } } } catch (Exception e) { e.printStackTrace(System.err); throw new PKCS7Exception(F_PKCS7_DATAINIT, R_ERROR_SETTING_CIPHER, e); } ASN1ObjectIdentifier encAlgo = ASN1Registry.sym2oid(evpCipher.getOsslName()); if (encAlgo == null) { throw new PKCS7Exception(F_PKCS7_DATAINIT, R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); } if (evpCipher.getCipher().getIV() != null) { enc.setAlgorithm(new AlgorithmIdentifier(encAlgo, new DEROctetString(evpCipher.getCipher().getIV()))); } else { enc.setAlgorithm(new AlgorithmIdentifier(encAlgo)); } if (out == null) { out = btmp; } else { out.push(btmp); } } if (bio == null) { if (isDetached()) { bio = BIO.nullSink(); } else if (os != null && os.getOctets().length > 0) { bio = BIO.memBuf(os.getOctets()); } if (bio == null) { bio = BIO.mem(); bio.setMemEofReturn(0); } } if (out != null) { out.push(bio); } else { out = bio; } return out; } /** c: static PKCS7_find_digest * */ public BIO findDigest(MessageDigest[] pmd, BIO bio, int nid) throws PKCS7Exception { while(true) { bio = bio.findType(BIO.TYPE_MD); if(bio == null) { throw new PKCS7Exception(F_PKCS7_FIND_DIGEST, R_UNABLE_TO_FIND_MESSAGE_DIGEST); } pmd[0] = ((MessageDigestBIOFilter)bio).getMessageDigest(); if(pmd[0] == null) { throw new PKCS7Exception(F_PKCS7_FIND_DIGEST, -1); } if(nid == EVP.type(pmd[0])) { return bio; } bio = bio.next(); } } /** c: PKCS7_dataFinal * */ public int dataFinal(BIO bio) throws PKCS7Exception { Collection siSk = null; BIO btmp; byte[] buf; MessageDigest mdc = null; MessageDigest ctx_tmp = null; ASN1Set sk; int i = this.data.getType(); switch(i) { case ASN1Registry.NID_pkcs7_signedAndEnveloped: siSk = getSignedAndEnveloped().getSignerInfo(); break; case ASN1Registry.NID_pkcs7_signed: siSk = getSign().getSignerInfo(); break; case ASN1Registry.NID_pkcs7_digest: break; default: break; } if(siSk != null) { for(SignerInfoWithPkey si : siSk) { if(si.getPkey() == null) { continue; } int j = ASN1Registry.oid2nid( si.getDigestAlgorithm().getAlgorithm() ); btmp = bio; MessageDigest[] _mdc = new MessageDigest[] {mdc}; btmp = findDigest(_mdc, btmp, j); mdc = _mdc[0]; if(btmp == null) { return 0; } try { ctx_tmp = (MessageDigest)mdc.clone(); } catch(CloneNotSupportedException e) { throw new RuntimeException(e); } sk = si.getAuthenticatedAttributes(); Signature sign = null; try { if(sk != null && sk.size() > 0) { /* Add signing time if not already present */ if(null == si.getSignedAttribute(ASN1Registry.NID_pkcs9_signingTime)) { DERUTCTime signTime = new DERUTCTime(Calendar.getInstance(TimeZone.getTimeZone("UTC")).getTime()); si.addSignedAttribute(ASN1Registry.NID_pkcs9_signingTime, signTime); } byte[] md_data = ctx_tmp.digest(); ASN1OctetString digest = new DEROctetString(md_data); si.addSignedAttribute(ASN1Registry.NID_pkcs9_messageDigest, digest); sk = si.getAuthenticatedAttributes(); sign = SecurityHelper.getSignature(EVP.signatureAlgorithm(ctx_tmp, si.getPkey())); sign.initSign(si.getPkey()); byte[] abuf = sk.getEncoded(); sign.update(abuf); } if(sign != null) { byte[] out = sign.sign(); si.setEncryptedDigest(new DEROctetString(out)); } } catch(Exception e) { throw new PKCS7Exception(F_PKCS7_DATAFINAL, -1, e); } } } else if(i == ASN1Registry.NID_pkcs7_digest) { int nid = ASN1Registry.oid2nid( getDigest().getMd().getAlgorithm() ); MessageDigest[] _mdc = new MessageDigest[] {mdc}; bio = findDigest(_mdc, bio, nid); mdc = _mdc[0]; byte[] md_data = mdc.digest(); ASN1OctetString digest = new DEROctetString(md_data); getDigest().setDigest(digest); } if(!isDetached()) { btmp = bio.findType(BIO.TYPE_MEM); if(null == btmp) { throw new PKCS7Exception(F_PKCS7_DATAFINAL, R_UNABLE_TO_FIND_MEM_BIO); } buf = ((MemBIO)btmp).getMemCopy(); switch(i) { case ASN1Registry.NID_pkcs7_signedAndEnveloped: getSignedAndEnveloped().getEncData().setEncData(new DEROctetString(buf)); break; case ASN1Registry.NID_pkcs7_enveloped: getEnveloped().getEncData().setEncData(new DEROctetString(buf)); break; case ASN1Registry.NID_pkcs7_signed: if(getSign().getContents().isData() && getDetached() != 0) { getSign().getContents().setData(null); } else { getSign().getContents().setData(new DEROctetString(buf)); } break; case ASN1Registry.NID_pkcs7_digest: if(getDigest().getContents().isData() && getDetached() != 0) { getDigest().getContents().setData(null); } else { getDigest().getContents().setData(new DEROctetString(buf)); } break; } } return 1; } @Override public String toString() { return "#"; } public static final int S_HEADER = 0; public static final int S_BODY = 1; public static final int S_TAIL = 2; public static final int OP_SET_DETACHED_SIGNATURE = 1; public static final int OP_GET_DETACHED_SIGNATURE = 2; /* S/MIME related flags */ public static final int TEXT = 0x1; public static final int NOCERTS = 0x2; public static final int NOSIGS = 0x4; public static final int NOCHAIN = 0x8; public static final int NOINTERN = 0x10; public static final int NOVERIFY = 0x20; public static final int DETACHED = 0x40; public static final int BINARY = 0x80; public static final int NOATTR = 0x100; public static final int NOSMIMECAP = 0x200; public static final int NOOLDMIMETYPE = 0x400; public static final int CRLFEOL = 0x800; public static final int STREAM = 0x1000; public static final int NOCRL = 0x2000; public static final int PARTIAL = 0x4000; public static final int REUSE_DIGEST = 0x8000; /* Flags: for compatibility with older code */ public static final int SMIME_TEXT = TEXT; public static final int SMIME_NOCERTS = NOCERTS; public static final int SMIME_NOSIGS = NOSIGS; public static final int SMIME_NOCHAIN = NOCHAIN; public static final int SMIME_NOINTERN = NOINTERN; public static final int SMIME_NOVERIFY = NOVERIFY; public static final int SMIME_DETACHED = DETACHED; public static final int SMIME_BINARY = BINARY; public static final int SMIME_NOATTR = NOATTR; public static final int SMIME_OLDMIME = NOOLDMIMETYPE; public static final int SMIME_CRLFEOL = CRLFEOL; /* Function codes. */ public static final int F_B64_READ_PKCS7 = 120; public static final int F_B64_WRITE_PKCS7 = 121; public static final int F_PKCS7_ADD_ATTRIB_SMIMECAP = 118; public static final int F_PKCS7_ADD_CERTIFICATE = 100; public static final int F_PKCS7_ADD_CRL = 101; public static final int F_PKCS7_ADD_RECIPIENT_INFO = 102; public static final int F_PKCS7_ADD_SIGNER = 103; public static final int F_PKCS7_BIO_ADD_DIGEST = 125; public static final int F_PKCS7_CTRL = 104; public static final int F_PKCS7_DATADECODE = 112; public static final int F_PKCS7_DATAFINAL = 128; public static final int F_PKCS7_DATAINIT = 105; public static final int F_PKCS7_DATASIGN = 106; public static final int F_PKCS7_DATAVERIFY = 107; public static final int F_PKCS7_DECRYPT = 114; public static final int F_PKCS7_ENCRYPT = 115; public static final int F_PKCS7_FIND_DIGEST = 127; public static final int F_PKCS7_GET0_SIGNERS = 124; public static final int F_PKCS7_SET_CIPHER = 108; public static final int F_PKCS7_SET_CONTENT = 109; public static final int F_PKCS7_SET_DIGEST = 126; public static final int F_PKCS7_SET_TYPE = 110; public static final int F_PKCS7_SIGN = 116; public static final int F_PKCS7_SIGNATUREVERIFY = 113; public static final int F_PKCS7_SIMPLE_SMIMECAP = 119; public static final int F_PKCS7_VERIFY = 117; public static final int F_SMIME_READ_PKCS7 = 122; public static final int F_SMIME_TEXT = 123; /* Reason codes. */ public static final int R_CERTIFICATE_VERIFY_ERROR = 117; public static final int R_CIPHER_HAS_NO_OBJECT_IDENTIFIER = 144; public static final int R_CIPHER_NOT_INITIALIZED = 116; public static final int R_CONTENT_AND_DATA_PRESENT = 118; public static final int R_DECODE_ERROR = 130; public static final int R_DECRYPTED_KEY_IS_WRONG_LENGTH = 100; public static final int R_DECRYPT_ERROR = 119; public static final int R_DIGEST_FAILURE = 101; public static final int R_ERROR_ADDING_RECIPIENT = 120; public static final int R_ERROR_SETTING_CIPHER = 121; public static final int R_INVALID_MIME_TYPE = 131; public static final int R_INVALID_NULL_POINTER = 143; public static final int R_MIME_NO_CONTENT_TYPE = 132; public static final int R_MIME_PARSE_ERROR = 133; public static final int R_MIME_SIG_PARSE_ERROR = 134; public static final int R_MISSING_CERIPEND_INFO = 103; public static final int R_NO_CONTENT = 122; public static final int R_NO_CONTENT_TYPE = 135; public static final int R_NO_MULTIPART_BODY_FAILURE = 136; public static final int R_NO_MULTIPART_BOUNDARY = 137; public static final int R_NO_RECIPIENT_MATCHES_CERTIFICATE = 115; public static final int R_NO_RECIPIENT_MATCHES_KEY = 146; public static final int R_NO_SIGNATURES_ON_DATA = 123; public static final int R_NO_SIGNERS = 142; public static final int R_NO_SIG_CONTENT_TYPE = 138; public static final int R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE = 104; public static final int R_PKCS7_ADD_SIGNATURE_ERROR = 124; public static final int R_PKCS7_DATAFINAL = 126; public static final int R_PKCS7_DATAFINAL_ERROR = 125; public static final int R_PKCS7_DATASIGN = 145; public static final int R_PKCS7_PARSE_ERROR = 139; public static final int R_PKCS7_SIG_PARSE_ERROR = 140; public static final int R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE = 127; public static final int R_SIGNATURE_FAILURE = 105; public static final int R_SIGNER_CERTIFICATE_NOT_FOUND = 128; public static final int R_SIG_INVALID_MIME_TYPE = 141; public static final int R_SMIME_TEXT_ERROR = 129; public static final int R_UNABLE_TO_FIND_CERTIFICATE = 106; public static final int R_UNABLE_TO_FIND_MEM_BIO = 107; public static final int R_UNABLE_TO_FIND_MESSAGE_DIGEST = 108; public static final int R_UNKNOWN_DIGEST_TYPE = 109; public static final int R_UNKNOWN_OPERATION = 110; public static final int R_UNSUPPORTED_CIPHER_TYPE = 111; public static final int R_UNSUPPORTED_CONTENT_TYPE = 112; public static final int R_WRONG_CONTENT_TYPE = 113; public static final int R_WRONG_PKCS7_TYPE = 114; public Envelope getEnveloped() { return this.data.getEnveloped(); } public SignEnvelope getSignedAndEnveloped() { return this.data.getSignedAndEnveloped(); } public Digest getDigest() { return this.data.getDigest(); } public Encrypt getEncrypted() { return this.data.getEncrypted(); } public ASN1Encodable getOther() { return this.data.getOther(); } public void setSign(Signed sign) { this.data.setSign(sign); } public Signed getSign() { return this.data.getSign(); } public void setData(ASN1OctetString data) { this.data.setData(data); } public ASN1OctetString getData() { return this.data.getData(); } public boolean isSigned() { return this.data.isSigned(); } public boolean isEncrypted() { return this.data.isEncrypted(); } public boolean isEnveloped() { return this.data.isEnveloped(); } public boolean isSignedAndEnveloped() { return this.data.isSignedAndEnveloped(); } public boolean isData() { return this.data.isData(); } public boolean isDigest() { return this.data.isDigest(); } public boolean isOther() { return this.data.isOther(); } public int getType() { return this.data.getType(); } /* c: static PKCS7_get_octet_string * */ public ASN1OctetString getOctetString() { if(isData()) { return getData(); } else if(isOther() && getOther() != null && getOther() instanceof ASN1OctetString) { return (ASN1OctetString)getOther(); } return null; } }// PKCS7 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7Data.java000066400000000000000000000126601313661621600265170ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.security.cert.X509CRL; import java.util.Collection; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1OctetString; import org.jruby.ext.openssl.x509store.X509AuxCertificate; /** * @author Ola Bini */ public abstract class PKCS7Data { public abstract int getType(); public Object ctrl(int cmd, Object v, Object ignored) throws PKCS7Exception { switch(cmd) { case PKCS7.OP_SET_DETACHED_SIGNATURE: throw new PKCS7Exception(PKCS7.F_PKCS7_CTRL,PKCS7.R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); case PKCS7.OP_GET_DETACHED_SIGNATURE: throw new PKCS7Exception(PKCS7.F_PKCS7_CTRL,PKCS7.R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); default: throw new PKCS7Exception(PKCS7.F_PKCS7_CTRL,PKCS7.R_UNKNOWN_OPERATION); } } public Envelope getEnveloped() { return null; } public SignEnvelope getSignedAndEnveloped() { return null; } public Digest getDigest() { return null; } public Encrypt getEncrypted() { return null; } public ASN1Encodable getOther() { return null; } public void setSign(Signed sign) { } public Signed getSign() { return null; } public void setData(ASN1OctetString data) { } public ASN1OctetString getData() { return null; } public boolean isSigned() { return false; } public boolean isEncrypted() { return false; } public boolean isEnveloped() { return false; } public boolean isSignedAndEnveloped() { return false; } public boolean isData() { return false; } public boolean isDigest() { return false; } public boolean isOther() { return false; } public void setCipher(CipherSpec cipher) throws PKCS7Exception { throw new PKCS7Exception(PKCS7.F_PKCS7_SET_CIPHER,PKCS7.R_WRONG_CONTENT_TYPE); } public void addRecipientInfo(RecipInfo ri) throws PKCS7Exception { throw new PKCS7Exception(PKCS7.F_PKCS7_ADD_RECIPIENT_INFO,PKCS7.R_WRONG_CONTENT_TYPE); } public void addSigner(SignerInfoWithPkey psi) throws PKCS7Exception { throw new PKCS7Exception(PKCS7.F_PKCS7_ADD_SIGNER,PKCS7.R_WRONG_CONTENT_TYPE); } public void setContent(PKCS7 p7) throws PKCS7Exception { throw new PKCS7Exception(PKCS7.F_PKCS7_SET_CONTENT,PKCS7.R_WRONG_CONTENT_TYPE); } public Collection getSignerInfo() { return null; } public void addCertificate(X509AuxCertificate cert) throws PKCS7Exception { throw new PKCS7Exception(PKCS7.F_PKCS7_ADD_CERTIFICATE,PKCS7.R_WRONG_CONTENT_TYPE); } public void addCRL(X509CRL crl) throws PKCS7Exception { throw new PKCS7Exception(PKCS7.F_PKCS7_ADD_CRL,PKCS7.R_WRONG_CONTENT_TYPE); } public static PKCS7Data fromASN1(final int nid, ASN1Encodable content) throws PKCS7Exception { switch (nid) { case ASN1Registry.NID_pkcs7_data: return PKCS7DataData.fromASN1(content); case ASN1Registry.NID_pkcs7_signed: return PKCS7DataSigned.fromASN1(content); case ASN1Registry.NID_pkcs7_enveloped: return PKCS7DataEnveloped.fromASN1(content); case ASN1Registry.NID_pkcs7_signedAndEnveloped: return PKCS7DataSignedAndEnveloped.fromASN1(content); case ASN1Registry.NID_pkcs7_digest: return PKCS7DataDigest.fromASN1(content); case ASN1Registry.NID_pkcs7_encrypted: return PKCS7DataEncrypted.fromASN1(content); default: throw new UnsupportedOperationException("can't handle PKCS#7 with content type " + ASN1Registry.nid2ln(nid)); } } public ASN1Encodable asASN1() { throw new UnsupportedOperationException("can't ASN1 PKCS#7 with content type " + ASN1Registry.nid2ln(getType())); } }// PKCS7Data jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7DataData.java000066400000000000000000000056151313661621600273130ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.util.Arrays; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.DEROctetString; /** * * @author Ola Bini */ public class PKCS7DataData extends PKCS7Data { /* NID_pkcs7_data */ private ASN1OctetString data; public PKCS7DataData() { this(new DEROctetString(new byte[0])); } public PKCS7DataData(ASN1OctetString data) { this.data = data; } @Override public int getType() { return ASN1Registry.NID_pkcs7_data; } @Override public void setData(ASN1OctetString data) { this.data = data; } @Override public ASN1OctetString getData() { return this.data; } @Override public boolean isData() { return true; } @Override public String toString() { return "#"; } /** * Data ::= OCTET STRING */ public static PKCS7DataData fromASN1(ASN1Encodable content) { if ( content == null ) return new PKCS7DataData(); return new PKCS7DataData((ASN1OctetString) content); } @Override public ASN1Encodable asASN1() { if ( data == null ) { return new DEROctetString(new byte[0]).toASN1Primitive(); } return data.toASN1Primitive(); } }// PKCS7DataData jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7DataDigest.java000066400000000000000000000044401313661621600276540ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import org.bouncycastle.asn1.ASN1Encodable; /** * * @author Ola Bini */ public class PKCS7DataDigest extends PKCS7Data { /* NID_pkcs7_digest */ private Digest digest; public PKCS7DataDigest() { this.digest = new Digest(); this.digest.setVersion(0); } public int getType() { return ASN1Registry.NID_pkcs7_digest; } public Digest getDigest() { return this.digest; } public boolean isDigest() { return true; } public void setContent(PKCS7 p7) { this.digest.setContents(p7); } public static PKCS7DataDigest fromASN1(ASN1Encodable content) { throw new UnsupportedOperationException("TODO: can't create DataDigest from ASN1 yet"); } }// PKCS7DataDigest jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7DataEncrypted.java000066400000000000000000000045131313661621600303730ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import org.bouncycastle.asn1.ASN1Encodable; /** * * @author Ola Bini */ public class PKCS7DataEncrypted extends PKCS7Data { /* NID_pkcs7_encrypted */ private Encrypt encrypted; public PKCS7DataEncrypted() { this.encrypted = new Encrypt(); this.encrypted.setVersion(0); this.encrypted.getEncData().setContentType(ASN1Registry.NID_pkcs7_data); } public int getType() { return ASN1Registry.NID_pkcs7_encrypted; } public Encrypt getEncrypted() { return this.encrypted; } public boolean isEncrypted() { return true; } public static PKCS7DataEncrypted fromASN1(ASN1Encodable content) { throw new UnsupportedOperationException("TODO: can't create DataEncrypted from ASN1 yet"); } }// PKCS7DataEncrypted jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7DataEnveloped.java000066400000000000000000000055251313661621600303630ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import org.bouncycastle.asn1.ASN1Encodable; /** * * @author Ola Bini */ public class PKCS7DataEnveloped extends PKCS7Data { /* NID_pkcs7_enveloped */ private Envelope enveloped; public PKCS7DataEnveloped() { this.enveloped = new Envelope(); this.enveloped.setVersion(0); this.enveloped.getEncData().setContentType(ASN1Registry.NID_pkcs7_data); } public PKCS7DataEnveloped(Envelope enveloped) { this.enveloped = enveloped; } public int getType() { return ASN1Registry.NID_pkcs7_enveloped; } @Override public Envelope getEnveloped() { return this.enveloped; } @Override public boolean isEnveloped() { return true; } @Override public void setCipher(CipherSpec cipher) { this.enveloped.getEncData().setCipher(cipher); } @Override public void addRecipientInfo(RecipInfo ri) { this.enveloped.getRecipientInfo().add(ri); } @Override public String toString() { return this.enveloped.toString(); } public static PKCS7DataEnveloped fromASN1(ASN1Encodable content) { return new PKCS7DataEnveloped(Envelope.fromASN1(content)); } @Override public ASN1Encodable asASN1() { return enveloped.asASN1(); } }// PKCS7DataEnveloped jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7DataSigned.java000066400000000000000000000076721313661621600276600ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.security.cert.X509CRL; import java.util.Collection; import org.bouncycastle.asn1.ASN1Encodable; import org.jruby.ext.openssl.x509store.X509AuxCertificate; /** * * @author Ola Bini */ public class PKCS7DataSigned extends PKCS7Data { /* NID_pkcs7_signed */ private Signed sign; public PKCS7DataSigned() { this.sign = new Signed(); this.sign.setVersion(1); } public PKCS7DataSigned(Signed sign) { this.sign = sign; } public int getType() { return ASN1Registry.NID_pkcs7_signed; } @Override public Object ctrl(int cmd, Object v, Object ignored) { int ret = 0; switch(cmd) { case PKCS7.OP_SET_DETACHED_SIGNATURE: ret = ((Integer)v).intValue(); if(ret != 0 && sign.contents.isData()) { sign.contents.setData(null); } break; case PKCS7.OP_GET_DETACHED_SIGNATURE: if(sign == null || sign.contents.getData() == null) { ret = 1; } else { ret = 0; } break; default: throw new RuntimeException("TODO: implement error handling"); } return Integer.valueOf(ret); } @Override public void setSign(Signed sign) { this.sign = sign; } @Override public Signed getSign() { return this.sign; } @Override public boolean isSigned() { return true; } @Override public void addSigner(SignerInfoWithPkey psi) { this.sign.getMdAlgs().add(psi.getDigestAlgorithm()); this.sign.getSignerInfo().add(psi); } @Override public void setContent(PKCS7 p7) { this.sign.setContents(p7); } @Override public Collection getSignerInfo() { return this.sign.getSignerInfo(); } @Override public void addCertificate(X509AuxCertificate cert) { this.sign.getCert().add(cert); } @Override public void addCRL(X509CRL crl) { this.sign.getCrl().add(crl); } @Override public String toString() { return this.sign.toString(); } public static PKCS7DataSigned fromASN1(ASN1Encodable content) throws PKCS7Exception { return new PKCS7DataSigned(Signed.fromASN1(content)); } @Override public ASN1Encodable asASN1() { return sign.asASN1(); } }// PKCS7DataSigned jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7DataSignedAndEnveloped.java000066400000000000000000000066661313661621600321470ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.security.cert.X509CRL; import java.util.Collection; import org.bouncycastle.asn1.ASN1Encodable; import org.jruby.ext.openssl.x509store.X509AuxCertificate; /** * * @author Ola Bini */ public class PKCS7DataSignedAndEnveloped extends PKCS7Data { /* NID_pkcs7_signedAndEnveloped */ private SignEnvelope signedAndEnveloped; public PKCS7DataSignedAndEnveloped() { this.signedAndEnveloped = new SignEnvelope(); this.signedAndEnveloped.setVersion(1); this.signedAndEnveloped.getEncData().setContentType(ASN1Registry.NID_pkcs7_data); } public int getType() { return ASN1Registry.NID_pkcs7_signedAndEnveloped; } @Override public boolean isSignedAndEnveloped() { return true; } @Override public SignEnvelope getSignedAndEnveloped() { return signedAndEnveloped; } @Override public void setCipher(CipherSpec cipher) { this.signedAndEnveloped.getEncData().setCipher(cipher); } @Override public void addRecipientInfo(RecipInfo ri) { this.signedAndEnveloped.getRecipientInfo().add(ri); } @Override public void addSigner(SignerInfoWithPkey psi) { this.signedAndEnveloped.getMdAlgs().add(psi.getDigestAlgorithm()); this.signedAndEnveloped.getSignerInfo().add(psi); } @Override public Collection getSignerInfo() { return this.signedAndEnveloped.getSignerInfo(); } @Override public void addCertificate(X509AuxCertificate cert) { this.signedAndEnveloped.getCert().add(cert); } @Override public void addCRL(X509CRL crl) { this.signedAndEnveloped.getCrl().add(crl); } public static PKCS7DataSignedAndEnveloped fromASN1(ASN1Encodable content) { throw new UnsupportedOperationException("TODO: can't create DataSignedAndEnveloped from ASN1 yet"); } }// PKCS7DataSignedAndEnveloped jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKCS7Exception.java000066400000000000000000000051011313661621600275740ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; /** * * @author Ola Bini */ public class PKCS7Exception extends Exception { private static final long serialVersionUID = 1L; private int method; private int reason; private String errorData; public PKCS7Exception(int method, int reason) { this(method, reason, ""+null); } public PKCS7Exception(int method, int reason, String errorData) { super("PKCS7[Method: " + method + ", Reason: " + reason + ", Data: " + errorData + "]"); this.method = method; this.reason = reason; this.errorData = errorData; } public PKCS7Exception(int method, int reason, Throwable cause) { super("PKCS7[Method: " + method + ", Reason: " + reason + "]", cause); this.method = method; this.reason = reason; this.errorData = cause.getMessage(); } public int getMethod() { return this.method; } public int getReason() { return this.reason; } public String getErrorData() { return this.errorData; } }// PKCS7Exception jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/PKey.java000066400000000000000000000367071313661621600257560ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2010 Hiroshi Nakamura * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.DSAPrivateKeySpec; import java.security.spec.DSAPublicKeySpec; import java.security.spec.ECParameterSpec; import java.security.spec.ECPrivateKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.sec.ECPrivateKeyStructure; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.ECNamedCurveTable; import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; import org.bouncycastle.jce.spec.ECPublicKeySpec; import org.jruby.ext.openssl.SecurityHelper; /** * * Handles PKey related ASN.1 handling. * * @author Hiroshi Nakamura */ public class PKey { public static KeyPair readPrivateKey(final byte[] input, final String type) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { KeySpec pubSpec; KeySpec privSpec; ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(input).readObject(); if ( type.equals("RSA") ) { ASN1Integer mod = (ASN1Integer) seq.getObjectAt(1); ASN1Integer pubExp = (ASN1Integer) seq.getObjectAt(2); ASN1Integer privExp = (ASN1Integer) seq.getObjectAt(3); ASN1Integer p1 = (ASN1Integer) seq.getObjectAt(4); ASN1Integer p2 = (ASN1Integer) seq.getObjectAt(5); ASN1Integer exp1 = (ASN1Integer) seq.getObjectAt(6); ASN1Integer exp2 = (ASN1Integer) seq.getObjectAt(7); ASN1Integer crtCoef = (ASN1Integer) seq.getObjectAt(8); pubSpec = new RSAPublicKeySpec(mod.getValue(), pubExp.getValue()); privSpec = new RSAPrivateCrtKeySpec(mod.getValue(), pubExp.getValue(), privExp.getValue(), p1.getValue(), p2.getValue(), exp1.getValue(), exp2.getValue(), crtCoef.getValue()); } else if ( type.equals("DSA") ) { ASN1Integer p = (ASN1Integer) seq.getObjectAt(1); ASN1Integer q = (ASN1Integer) seq.getObjectAt(2); ASN1Integer g = (ASN1Integer) seq.getObjectAt(3); ASN1Integer y = (ASN1Integer) seq.getObjectAt(4); ASN1Integer x = (ASN1Integer) seq.getObjectAt(5); privSpec = new DSAPrivateKeySpec(x.getValue(), p.getValue(), q.getValue(), g.getValue()); pubSpec = new DSAPublicKeySpec(y.getValue(), p.getValue(), q.getValue(), g.getValue()); } else if ( type.equals("ECDSA") ) { return readECPrivateKey(input); } else { throw new IllegalStateException("unsupported type: " + type); } KeyFactory fact = SecurityHelper.getKeyFactory(type); return new KeyPair(fact.generatePublic(pubSpec), fact.generatePrivate(privSpec)); } // d2i_PrivateKey_bio public static KeyPair readPrivateKey(byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { KeyPair key = null; try { key = readRSAPrivateKey(input); } catch (NoSuchAlgorithmException e) { throw e; /* should not happen */ } catch (InvalidKeySpecException e) { // ignore } if (key == null) { try { key = readDSAPrivateKey(input); } catch (NoSuchAlgorithmException e) { throw e; /* should not happen */ } catch (InvalidKeySpecException e) { // ignore } } return key; } // d2i_PUBKEY_bio public static PublicKey readPublicKey(byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { PublicKey key = null; try { key = readRSAPublicKey(input); } catch (NoSuchAlgorithmException e) { throw e; /* should not happen */ } catch (InvalidKeySpecException e) { // ignore } if (key == null) { try { key = readDSAPublicKey(input); } catch (NoSuchAlgorithmException e) { throw e; /* should not happen */ } catch (InvalidKeySpecException e) { // ignore } } return key; } // d2i_RSAPrivateKey_bio public static KeyPair readRSAPrivateKey(final byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { return readRSAPrivateKey(SecurityHelper.getKeyFactory("RSA"), input); } public static KeyPair readRSAPrivateKey(final KeyFactory rsaFactory, final byte[] input) throws IOException, InvalidKeySpecException { ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(input).readObject(); if ( seq.size() == 9 ) { BigInteger mod = ((ASN1Integer) seq.getObjectAt(1)).getValue(); BigInteger pubexp = ((ASN1Integer) seq.getObjectAt(2)).getValue(); BigInteger privexp = ((ASN1Integer) seq.getObjectAt(3)).getValue(); BigInteger primep = ((ASN1Integer) seq.getObjectAt(4)).getValue(); BigInteger primeq = ((ASN1Integer) seq.getObjectAt(5)).getValue(); BigInteger primeep = ((ASN1Integer) seq.getObjectAt(6)).getValue(); BigInteger primeeq = ((ASN1Integer) seq.getObjectAt(7)).getValue(); BigInteger crtcoeff = ((ASN1Integer) seq.getObjectAt(8)).getValue(); PrivateKey priv = rsaFactory.generatePrivate(new RSAPrivateCrtKeySpec(mod, pubexp, privexp, primep, primeq, primeep, primeeq, crtcoeff)); PublicKey pub = rsaFactory.generatePublic(new RSAPublicKeySpec(mod, pubexp)); return new KeyPair(pub, priv); } return null; } // d2i_RSAPublicKey_bio public static PublicKey readRSAPublicKey(final byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { return readRSAPublicKey(SecurityHelper.getKeyFactory("RSA"), input); } public static PublicKey readRSAPublicKey(final KeyFactory rsaFactory, final byte[] input) throws IOException, InvalidKeySpecException { ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(input).readObject(); if ( seq.size() == 2 ) { BigInteger mod = ((ASN1Integer) seq.getObjectAt(0)).getValue(); BigInteger pubexp = ((ASN1Integer) seq.getObjectAt(1)).getValue(); return rsaFactory.generatePublic(new RSAPublicKeySpec(mod, pubexp)); } return null; } // d2i_DSAPrivateKey_bio public static KeyPair readDSAPrivateKey(final byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { return readDSAPrivateKey(SecurityHelper.getKeyFactory("DSA"), input); } public static KeyPair readDSAPrivateKey(final KeyFactory dsaFactory, final byte[] input) throws IOException, InvalidKeySpecException { ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(input).readObject(); if ( seq.size() == 6 ) { BigInteger p = ((ASN1Integer) seq.getObjectAt(1)).getValue(); BigInteger q = ((ASN1Integer) seq.getObjectAt(2)).getValue(); BigInteger g = ((ASN1Integer) seq.getObjectAt(3)).getValue(); BigInteger y = ((ASN1Integer) seq.getObjectAt(4)).getValue(); BigInteger x = ((ASN1Integer) seq.getObjectAt(5)).getValue(); PrivateKey priv = dsaFactory.generatePrivate(new DSAPrivateKeySpec(x, p, q, g)); PublicKey pub = dsaFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); return new KeyPair(pub, priv); } return null; } // d2i_DSA_PUBKEY_bio public static PublicKey readDSAPublicKey(final byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { return readDSAPublicKey(SecurityHelper.getKeyFactory("DSA"), input); } public static PublicKey readDSAPublicKey(final KeyFactory dsaFactory, final byte[] input) throws IOException, InvalidKeySpecException { ASN1Sequence seq = (ASN1Sequence) new ASN1InputStream(input).readObject(); if ( seq.size() == 4 ) { BigInteger y = ((ASN1Integer) seq.getObjectAt(0)).getValue(); BigInteger p = ((ASN1Integer) seq.getObjectAt(1)).getValue(); BigInteger q = ((ASN1Integer) seq.getObjectAt(2)).getValue(); BigInteger g = ((ASN1Integer) seq.getObjectAt(3)).getValue(); return dsaFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); } return null; } // d2i_DHparams_bio public static DHParameterSpec readDHParameter(final byte[] input) throws IOException { ASN1InputStream aIn = new ASN1InputStream(input); ASN1Sequence seq = (ASN1Sequence) aIn.readObject(); BigInteger p = ((ASN1Integer) seq.getObjectAt(0)).getValue(); BigInteger g = ((ASN1Integer) seq.getObjectAt(1)).getValue(); return new DHParameterSpec(p, g); } public static KeyPair readECPrivateKey(final byte[] input) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { return readECPrivateKey(SecurityHelper.getKeyFactory("ECDSA"), input); } public static KeyPair readECPrivateKey(final KeyFactory ecFactory, final byte[] input) throws IOException, InvalidKeySpecException { try { ECPrivateKeyStructure pKey = new ECPrivateKeyStructure((ASN1Sequence) ASN1Primitive.fromByteArray(input)); AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParameters()); PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.toASN1Primitive()); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pKey.getPublicKey().getBytes()); PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privInfo.getEncoded()); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubInfo.getEncoded()); //KeyFactory fact = KeyFactory.getInstance("ECDSA", provider); ECPrivateKey privateKey = (ECPrivateKey) ecFactory.generatePrivate(privSpec); if ( algId.getParameters() instanceof ASN1ObjectIdentifier ) { privateKey = ECPrivateKeyWithName.wrap(privateKey, (ASN1ObjectIdentifier) algId.getParameters()); } return new KeyPair(ecFactory.generatePublic(pubSpec), privateKey); } catch (ClassCastException ex) { throw new IOException("wrong ASN.1 object found in stream", ex); } //catch (Exception ex) { // throw new IOException("problem parsing EC private key: " + ex); //} } public static byte[] toDerRSAKey(RSAPublicKey pubKey, RSAPrivateCrtKey privKey) throws IOException { ASN1EncodableVector vec = new ASN1EncodableVector(); if ( pubKey != null && privKey == null ) { vec.add(new ASN1Integer(pubKey.getModulus())); vec.add(new ASN1Integer(pubKey.getPublicExponent())); } else { vec.add(new ASN1Integer(BigInteger.ZERO)); vec.add(new ASN1Integer(privKey.getModulus())); vec.add(new ASN1Integer(privKey.getPublicExponent())); vec.add(new ASN1Integer(privKey.getPrivateExponent())); vec.add(new ASN1Integer(privKey.getPrimeP())); vec.add(new ASN1Integer(privKey.getPrimeQ())); vec.add(new ASN1Integer(privKey.getPrimeExponentP())); vec.add(new ASN1Integer(privKey.getPrimeExponentQ())); vec.add(new ASN1Integer(privKey.getCrtCoefficient())); } return new DLSequence(vec).getEncoded(); } public static byte[] toDerDSAKey(DSAPublicKey pubKey, DSAPrivateKey privKey) throws IOException { if ( pubKey != null && privKey == null ) { return pubKey.getEncoded(); } if ( privKey != null && pubKey != null ) { ASN1EncodableVector vec = new ASN1EncodableVector(); final DSAParams params = privKey.getParams(); vec.add(new ASN1Integer(BigInteger.ZERO)); vec.add(new ASN1Integer(params.getP())); vec.add(new ASN1Integer(params.getQ())); vec.add(new ASN1Integer(params.getG())); vec.add(new ASN1Integer(pubKey.getY())); vec.add(new ASN1Integer(privKey.getX())); return new DLSequence(vec).getEncoded(); } if ( privKey == null ) { throw new IllegalArgumentException("private key as well as public key are null"); } return privKey.getEncoded(); } public static byte[] toDerDHKey(BigInteger p, BigInteger g) throws IOException { ASN1EncodableVector vec = new ASN1EncodableVector(); if ( p != null ) vec.add( new ASN1Integer(p) ); if ( g != null ) vec.add( new ASN1Integer(g) ); return new DLSequence(vec).getEncoded(); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/RecipInfo.java000066400000000000000000000201641313661621600267520ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.math.BigInteger; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.pkcs.IssuerAndSerialNumber; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x500.X500Name; import org.jruby.ext.openssl.x509store.Name; import org.jruby.ext.openssl.x509store.X509AuxCertificate; /** PKCS7_RECIP_INFO * * @author Ola Bini */ public class RecipInfo { private int version; private IssuerAndSerialNumber issuerAndSerial; private AlgorithmIdentifier keyEncAlgor; private ASN1OctetString encKey; /** * Describe cert here. */ private X509AuxCertificate cert; /** c: PKCS7_RECIP_INFO_set * */ public void set(X509AuxCertificate cert) throws PKCS7Exception { version = 0; X500Name issuer = X500Name.getInstance(cert.getIssuerX500Principal().getEncoded()); BigInteger serial = cert.getSerialNumber(); issuerAndSerial = new IssuerAndSerialNumber(issuer, serial); String algo = addEncryptionIfNeeded(cert.getPublicKey().getAlgorithm()); keyEncAlgor = new AlgorithmIdentifier(ASN1Registry.sym2oid(algo)); this.cert = cert; } private String addEncryptionIfNeeded(String input) { input = input.toLowerCase(); if(input.equals("rsa")) { return input + "Encryption"; } else if(input.equals("dsa")) { return input + "Encryption"; } return input; } @Override public boolean equals(Object other) { boolean ret = this == other; if(!ret && (other instanceof RecipInfo)) { RecipInfo o = (RecipInfo)other; ret = this.version == o.version && (this.issuerAndSerial == null ? o.issuerAndSerial == null : (this.issuerAndSerial.equals(o.issuerAndSerial))) && (this.keyEncAlgor == null ? o.keyEncAlgor == null : (this.keyEncAlgor.equals(o.keyEncAlgor))) && (this.encKey == null ? o.encKey == null : (this.encKey.equals(o.encKey))); } return ret; } @Override public int hashCode() { int result = 31; result = result + 13 * version; result = result + ((issuerAndSerial == null) ? 0 : 13 * issuerAndSerial.hashCode()); result = result + ((keyEncAlgor == null) ? 0 : 13 * keyEncAlgor.hashCode()); result = result + ((encKey == null) ? 0 : 13 * encKey.hashCode()); return result; } @Override public String toString() { return "#"; } /** * Get the Version value. * * @return an int value */ public final int getVersion() { return version; } /** * Set the Version value. * * @param newVersion The new Version value. */ public final void setVersion(final int newVersion) { this.version = newVersion; } /** * Get the IssuerAndSerial value. * * @return an IssuerAndSerialNumber value */ public final IssuerAndSerialNumber getIssuerAndSerial() { return issuerAndSerial; } /** * Set the IssuerAndSerial value. * * @param newIssuerAndSerial The new IssuerAndSerial value. */ public final void setIssuerAndSerial(final IssuerAndSerialNumber newIssuerAndSerial) { this.issuerAndSerial = newIssuerAndSerial; } /** * Get the KeyEncAlgor value. * * @return an AlgorithmIdentifier value */ public final AlgorithmIdentifier getKeyEncAlgor() { return keyEncAlgor; } /** * Set the KeyEncAlgor value. * * @param newKeyEncAlgor The new KeyEncAlgor value. */ public final void setKeyEncAlgor(final AlgorithmIdentifier newKeyEncAlgor) { this.keyEncAlgor = newKeyEncAlgor; } /** * Get the EncKey value. * * @return an ASN1OctetString value */ public final ASN1OctetString getEncKey() { return encKey; } /** * Set the EncKey value. * * @param newEncKey The new EncKey value. */ public final void setEncKey(final ASN1OctetString newEncKey) { this.encKey = newEncKey; } /** * Get the Cert value. * * @return a X509AuxCertificate value */ public final X509AuxCertificate getCert() { return cert; } /** * Set the Cert value. * * @param newCert The new Cert value. */ public final void setCert(final X509AuxCertificate newCert) { this.cert = newCert; } /* c: static pkcs7_cmp_ri * */ public boolean compare(final X509AuxCertificate other) { if ( ! new Name( issuerAndSerial.getName() ).equalTo( other.getIssuerX500Principal() ) ) { return false; } return other.getSerialNumber().compareTo( issuerAndSerial.getCertificateSerialNumber().getValue() ) == 0; } /** * RecipientInfo ::= SEQUENCE { * version Version, * issuerAndSerialNumber IssuerAndSerialNumber, * keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, * encryptedKey EncryptedKey } * * EncryptedKey ::= OCTET STRING */ public static RecipInfo fromASN1(ASN1Encodable content) { ASN1Sequence sequence = (ASN1Sequence)content; RecipInfo ri = new RecipInfo(); ri.setVersion( ( (ASN1Integer) sequence.getObjectAt(0) ).getValue().intValue() ); ri.setIssuerAndSerial( IssuerAndSerialNumber.getInstance( sequence.getObjectAt(1) ) ); ri.setKeyEncAlgor( AlgorithmIdentifier.getInstance( sequence.getObjectAt(2) ) ); ri.setEncKey( (ASN1OctetString) sequence.getObjectAt(3) ); return ri; } public ASN1Encodable asASN1() { ASN1EncodableVector vector = new ASN1EncodableVector(); vector.add( new ASN1Integer( BigInteger.valueOf(getVersion()) ) ); vector.add( issuerAndSerial.toASN1Primitive() ); vector.add( keyEncAlgor.toASN1Primitive() ); vector.add( encKey.toASN1Primitive() ); return new DLSequence(vector); } }// RecipInfo jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/SMIME.java000066400000000000000000000347501313661621600257540ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; import java.util.Set; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; /** SMIME methods for PKCS7 * * @author Ola Bini */ public class SMIME { public final static int MAX_SMLEN = 1024; public final static byte[] NEWLINE = new byte[]{'\r','\n'}; private Mime mime; public SMIME() { this(Mime.DEFAULT); } public SMIME(Mime mime) { this.mime = mime; } private static boolean equals(byte[] first, int firstIndex, byte[] second, int secondIndex, int length) { int len = length; for(int i=firstIndex, j=secondIndex, flen=first.length, slen=second.length; i0; i++, j++, len--) { if(first[i] != second[j]) { return false; } } return len == 0; } /* c: static strip_eol * */ public static boolean stripEol(byte[] linebuf, int[] plen) { int len = plen[0]; boolean isEol = false; for(int p = len - 1; len > 0; len--, p--) { byte c = linebuf[p]; if(c == '\n') { isEol = true; } else if(c != '\r') { break; } } plen[0] = len; return isEol; } /* c: SMIME_text * */ public void text(BIO input, BIO output) { // char iobuf[4096]; // int len; // STACK_OF(MIME_HEADER) *headers; // MIME_HEADER *hdr; // if (!(headers = mime_parse_hdr(in))) { // PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_PARSE_ERROR); // return 0; // } // if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { // PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_NO_CONTENT_TYPE); // sk_MIME_HEADER_pop_free(headers, mime_hdr_free); // return 0; // } // if (strcmp (hdr->value, "text/plain")) { // PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_INVALID_MIME_TYPE); // ERR_add_error_data(2, "type: ", hdr->value); // sk_MIME_HEADER_pop_free(headers, mime_hdr_free); // return 0; // } // sk_MIME_HEADER_pop_free(headers, mime_hdr_free); // while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) // BIO_write(out, iobuf, len); // return 1; } /* c: static mime_bound_check * */ private int boundCheck(byte[] line, int linelen, byte[] bound, int blen) { if(linelen == -1) { linelen = line.length; } if(blen == -1) { blen = bound.length; } // Quickly eliminate if line length too short if(blen + 2 > linelen) { return 0; } if(line[0] == '-' && line[1] == '-' && equals(line, 2, bound, 0, blen)) { if(line.length>=(blen+4) && line[2 + blen] == '-' && line[2 + blen + 1] == '-') { return 2; } else { return 1; } } return 0; } /* c: B64_read_PKCS7 * */ public PKCS7 readPKCS7Base64(BIO bio) throws IOException, PKCS7Exception { BIO bio64 = BIO.base64Filter(bio); return PKCS7.fromASN1(bio64); } /* c: static multi_split * */ private List multiSplit(BIO bio, byte[] bound) throws IOException { List parts = new ArrayList(); byte[] linebuf = new byte[MAX_SMLEN]; int blen = bound.length; boolean eol = false; int len; int state; int part = 0; boolean first = true; BIO bpart = null; while((len = bio.gets(linebuf, MAX_SMLEN)) > 0) { state = boundCheck(linebuf, len, bound, blen); if(state == 1) { first = true; part++; } else if(state == 2) { parts.add(bpart); return parts; } else if(part != 0) { // strip CR+LF from linebuf int[] tmp = new int[] {len}; boolean nextEol = stripEol(linebuf, tmp); len = tmp[0]; if(first) { first = false; if(bpart != null) { parts.add(bpart); } bpart = BIO.mem(); bpart.setMemEofReturn(0); } else if(eol) { bpart.write(NEWLINE, 0, 2); } eol = nextEol; if(len != 0) { bpart.write(linebuf, 0, len); } } } return parts; } /* c: SMIME_read_PKCS7 * */ public PKCS7 readPKCS7(BIO bio, BIO[] bcont) throws IOException, PKCS7Exception { if(bcont != null && bcont.length > 0) { bcont[0] = null; } List headers = mime.parseHeaders(bio); if(headers == null) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_MIME_PARSE_ERROR); } MimeHeader hdr = mime.findHeader(headers, "content-type"); if(hdr == null || hdr.getValue() == null) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_NO_CONTENT_TYPE); } if("multipart/signed".equals(hdr.getValue())) { MimeParam prm = mime.findParam(hdr, "boundary"); if(prm == null || prm.getParamValue() == null) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_NO_MULTIPART_BOUNDARY); } byte[] boundary = null; try { boundary = prm.getParamValue().getBytes("ISO8859-1"); } catch(Exception e) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_NO_MULTIPART_BOUNDARY, e); } List parts = multiSplit(bio, boundary); if(parts == null || parts.size() != 2) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_NO_MULTIPART_BODY_FAILURE); } BIO p7in = parts.get(1); headers = mime.parseHeaders(p7in); if(headers == null) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_MIME_SIG_PARSE_ERROR); } hdr = mime.findHeader(headers, "content-type"); if(hdr == null || hdr.getValue() == null) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_NO_SIG_CONTENT_TYPE); } if(!"application/x-pkcs7-signature".equals(hdr.getValue()) && !"application/pkcs7-signature".equals(hdr.getValue()) && !"application/x-pkcs7-mime".equals(hdr.getValue()) && !"application/pkcs7-mime".equals(hdr.getValue())) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_SIG_INVALID_MIME_TYPE, "type: " + hdr.getValue()); } PKCS7 p7 = readPKCS7Base64(p7in); if(bcont != null && bcont.length>0) { bcont[0] = parts.get(0); } return p7; } if(!"application/x-pkcs7-mime".equals(hdr.getValue()) && !"application/pkcs7-mime".equals(hdr.getValue())) { throw new PKCS7Exception(PKCS7.F_SMIME_READ_PKCS7, PKCS7.R_INVALID_MIME_TYPE, "type: " + hdr.getValue()); } return readPKCS7Base64(bio); } /* c: SMIME_write_PKCS7 * */ public String writePKCS7(PKCS7 p7, String data, int flags) throws PKCS7Exception, IOException { int ctype = p7.getType(); Set mdAlgs = null; if (ctype == ASN1Registry.NID_pkcs7_signed) { mdAlgs = p7.getSign().getMdAlgs(); } if (data != null && p7.isDetached()) { flags |= PKCS7.SMIME_DETACHED; // to be compliant with cruby implementation. } String mimePrefix = "application/pkcs7-"; String mimeEOL; String cName = "smime.p7s"; if ((flags & PKCS7.SMIME_CRLFEOL) > 0) { mimeEOL = "\r\n"; } else { mimeEOL = "\n"; } StringBuilder output = new StringBuilder(512); output.append("MIME-Version: 1.0").append(mimeEOL); // Detached sign. if ((flags & PKCS7.SMIME_DETACHED) > 0 && data != null) { String mimeBoundary = generateMIMEBoundary(32); // write headers output.append("Content-Type: multipart/signed;"); output.append(" protocol=\"").append(mimePrefix).append("signature\";"); output.append(" micalg=\""); appendMICalg(output, mdAlgs); output.append("\";"); output.append(" boundary=\"----").append(mimeBoundary).append("\""); output.append(mimeEOL).append(mimeEOL); // write S/MIME preamble message output.append("This is an S/MIME signed message."); output.append(mimeEOL).append(mimeEOL); // write data part output.append("------").append(mimeBoundary).append(mimeEOL); if ((flags & PKCS7.TEXT) > 0) { output.append("Content-Type: text/plain;").append(mimeEOL).append(mimeEOL); } output.append(data); output.append(mimeEOL); output.append("------").append(mimeBoundary).append(mimeEOL); // write signature part output.append("Content-Type: application/x-pkcs7-signature; name=").append(cName) .append(mimeEOL); output.append("Content-Transfer-Encoding: base64").append(mimeEOL); output.append("Content-Description: S/MIME Signature").append(mimeEOL); output.append("Content-Disposition: attachment; filename=").append(cName); output.append(mimeEOL).append(mimeEOL); String p7Base64 = Base64.encodeBytes(p7.toASN1(), Base64.DO_BREAK_LINES); output.append(p7Base64).append(mimeEOL); // write final boundary output.append("------").append(mimeBoundary).append("--").append(mimeEOL); return output.toString(); } String msgType = null; // This is not a detached sign. if (ctype == ASN1Registry.NID_pkcs7_enveloped) { msgType = "enveloped-data"; } else if (ctype == ASN1Registry.NID_pkcs7_signed) { if (mdAlgs != null && mdAlgs.size() > 0) { msgType = "signed-data"; } else { msgType = "certs-only"; } } else if (ctype == ASN1Registry.NID_id_smime_ct_compressedData) { msgType = "compressed-data"; cName = "smime.p7z"; } // MIME Headers output.append("Content-Disposition: attachment;"); output.append(" filename=\"").append(cName).append("\"").append(mimeEOL); output.append("Content-Type: ").append(mimePrefix).append("mime;"); if (msgType != null) { output.append(" smime-type=").append(msgType).append(";"); } output.append(" name=").append(cName).append(mimeEOL); output.append("Content-Transfer-Encoding: base64").append(mimeEOL).append(mimeEOL); // Write content byte[] p7Bytes = p7.toASN1(); String p7Base64 = Base64.encodeBytes(p7Bytes, Base64.DO_BREAK_LINES); output.append(p7Base64).append(mimeEOL); return output.toString(); } /** * Generates MIME compatible MIC algorithm names for content-type header. * * c : asn1_write_micalg */ private static void appendMICalg(final StringBuilder output, Set mdAlgs) { final Iterator it = mdAlgs.iterator(); boolean writeComma = false; while ( it.hasNext() ) { if ( writeComma ) output.append(','); ASN1ObjectIdentifier algId = it.next().getAlgorithm(); String ln = ASN1Registry.nid2ln( ASN1Registry.oid2nid(algId) ); if ( ln == null ) ln = "unknown"; output.append(ln); writeComma = true; } // return output.toString(); } /** * Generates a random boundary for MIME multipart messages. * The alphabet can include other characters, but digits and letters should suffice. * * @param length the length of the string. (MIME spec allows a max of 70 chars) * @return the generated boundary. */ private static String generateMIMEBoundary(int length) { final char alphabet[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; Random random = new Random(); StringBuilder output = new StringBuilder(length); for ( int i = 0; i < length; i++ ) { output.append( alphabet[ random.nextInt(length) ] ); } return output.toString(); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/SignEnvelope.java000066400000000000000000000132071313661621600274720ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.security.cert.X509CRL; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.jruby.ext.openssl.x509store.X509AuxCertificate; /** PKCS7_SIGN_ENVELOPE * * @author Ola Bini */ public class SignEnvelope { private int version; /** * Describe encContent here. */ private EncContent encData = new EncContent(); /** * Describe crl here. */ private Collection crl = new ArrayList(); /** * Describe cert here. */ private Collection cert = new ArrayList(); /** * Describe mdAlgs here. */ private Set mdAlgs = new HashSet(); /** * Describe signerInfo here. */ private Collection signerInfo = new ArrayList(); /** * Describe recipientInfo here. */ private Collection recipientInfo = new ArrayList(); /** * Get the Version value. * * @return an int value */ public final int getVersion() { return version; } /** * Set the Version value. * * @param newVersion The new Version value. */ public final void setVersion(final int newVersion) { this.version = newVersion; } /** * Get the EncData value. * * @return an EncContent value */ public final EncContent getEncData() { return encData; } /** * Set the EncData value. * * @param newEncContent The new EncContent value. */ public final void setEncData(final EncContent newEncData) { this.encData = newEncData; } /** * Get the RecipientInfo value. * * @return a Collection value */ public final Collection getRecipientInfo() { return recipientInfo; } /** * Set the RecipientInfo value. * * @param newRecipientInfo The new RecipientInfo value. */ public final void setRecipientInfo(final Collection newRecipientInfo) { this.recipientInfo = newRecipientInfo; } /** * Get the SignerInfoWithPkey value. * * @return a Collection value */ public final Collection getSignerInfo() { return signerInfo; } /** * Set the SignerInfoWithPkey value. * * @param newSignerInfo The new SignerInfo value. */ public final void setSignerInfo(final Collection newSignerInfo) { this.signerInfo = newSignerInfo; } /** * Get the MdAlgs value. * * @return a Set value */ public final Set getMdAlgs() { return mdAlgs; } /** * Set the MdAlgs value. * * @param newMdAlgs The new MdAlgs value. */ public final void setMdAlgs(final Set newMdAlgs) { this.mdAlgs = newMdAlgs; } /** * Get the Cert value. * * @return a Collection value */ public final Collection getCert() { return cert; } /** * Set the Cert value. * * @param newCert The new Cert value. */ public final void setCert(final Collection newCert) { this.cert = newCert; } /** * Get the Crl value. * * @return a Collection value */ public final Collection getCrl() { return crl; } /** * Set the Crl value. * * @param newCrl The new Crl value. */ public final void setCrl(final Collection newCrl) { this.crl = newCrl; } }// SignEnvelope jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/Signed.java000066400000000000000000000312211313661621600263010ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.security.cert.CertificateException; import java.security.cert.X509CRL; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Certificate; import org.jruby.ext.openssl.x509store.X509AuxCertificate; /** PKCS7_SIGNED * * @author Ola Bini */ public class Signed { /** * Describe version here. */ private int version; /** * Describe crl here. */ private Collection crl = new ArrayList(); /** * Describe cert here. */ private Collection cert = new ArrayList(); /** * Describe mdAlgs here. */ private Set mdAlgs = new HashSet(); /** * Describe signerInfo here. */ private Collection signerInfo = new ArrayList(); PKCS7 contents; /** * Get the Version value. * * @return an int value */ public final int getVersion() { return version; } /** * Set the Version value. * * @param newVersion The new Version value. */ public final void setVersion(final int newVersion) { this.version = newVersion; } /** * Get the SignerInfo value. * * @return a Collection value */ public final Collection getSignerInfo() { return signerInfo; } /** * Set the SignerInfo value. * * @param newSignerInfo The new SignerInfo value. */ public final void setSignerInfo(final Collection newSignerInfo) { this.signerInfo = newSignerInfo; } /** * Get the MdAlgs value. * * @return a Set value */ public final Set getMdAlgs() { return mdAlgs; } /** * Set the MdAlgs value. * * @param newMdAlgs The new MdAlgs value. */ public final void setMdAlgs(final Set newMdAlgs) { this.mdAlgs = newMdAlgs; } /** * Get the Contents value. * * @return a PKCS7 value */ public final PKCS7 getContents() { return contents; } /** * Set the Contents value. * * @param newContents The new Contents value. */ public final void setContents(final PKCS7 newContents) { this.contents = newContents; } /** * Get the Cert value. * * @return a Collection value */ public final Collection getCert() { return cert; } /** * Set the Cert value. * * @param newCert The new Cert value. */ public final void setCert(final Collection newCert) { this.cert = newCert; } /** * Get the Crl value. * * @return a Set value */ public final Collection getCrl() { return crl; } /** * Set the Crl value. * * @param newCrl The new Crl value. */ public final void setCrl(final Collection newCrl) { this.crl = newCrl; } @Override public String toString() { return "#"; } public ASN1Encodable asASN1() { ASN1EncodableVector vector = new ASN1EncodableVector(); vector.add( new ASN1Integer( BigInteger.valueOf(version) ) ); vector.add( digestAlgorithmsToASN1Set() ); if (contents == null) { contents = PKCS7.newEmpty(); } vector.add( contents.asASN1() ); if (cert != null && cert.size() > 0) { if (cert.size() > 1) { vector.add( new DERTaggedObject(false, 0, certificatesToASN1Set()) ); } else { // Encode the signer certificate directly for OpenSSL compatibility. // OpenSSL does not support multiple signer signature. // And OpenSSL requires EXPLICIT tagging. vector.add( new DERTaggedObject(true, 0, firstCertificatesToASN1()) ); } } if (crl != null && crl.size() > 0) { vector.add( new DERTaggedObject(false, 1, crlsToASN1Set()) ); } vector.add( signerInfosToASN1Set() ); return new DLSequence(vector); } private ASN1Set digestAlgorithmsToASN1Set() { ASN1EncodableVector vector = new ASN1EncodableVector(); for (AlgorithmIdentifier ai : mdAlgs) { vector.add( ai.toASN1Primitive() ); } return new DERSet(vector); } // This imlementation is stupid and wasteful. Ouch. private ASN1Set certificatesToASN1Set() { try { ASN1EncodableVector vector = new ASN1EncodableVector(); for(X509AuxCertificate c : cert) { vector.add(new ASN1InputStream(new ByteArrayInputStream(c.getEncoded())).readObject()); } return new DERSet(vector); } catch(Exception e) { return null; } } private ASN1Sequence firstCertificatesToASN1() { try { X509AuxCertificate c = cert.iterator().next(); return (ASN1Sequence) (new ASN1InputStream(new ByteArrayInputStream(c.getEncoded())).readObject()); } catch (Exception e) {} return null; } private ASN1Set crlsToASN1Set() { throw new RuntimeException("TODO: implement CRL part"); } private ASN1Set signerInfosToASN1Set() { ASN1EncodableVector vector = new ASN1EncodableVector(); for(SignerInfoWithPkey si : signerInfo) { vector.add(si.toASN1Object()); } return new DERSet(vector); } /** * SignedData ::= SEQUENCE { * version Version, * digestAlgorithms DigestAlgorithmIdentifiers, * contentInfo ContentInfo, * certificates [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL, * crls [1] IMPLICIT CertificateRevocationLists OPTIONAL, * signerInfos SignerInfos } * * Version ::= INTEGER * * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier * * SignerInfos ::= SET OF SignerInfo */ public static Signed fromASN1(ASN1Encodable content) throws PKCS7Exception{ ASN1Sequence sequence = (ASN1Sequence)content; ASN1Integer version = (ASN1Integer)sequence.getObjectAt(0); ASN1Set digestAlgos = (ASN1Set)sequence.getObjectAt(1); ASN1Encodable contentInfo = sequence.getObjectAt(2); ASN1Encodable certificates = null; ASN1Encodable crls = null; int index = 3; ASN1Encodable tmp = sequence.getObjectAt(index); if((tmp instanceof ASN1TaggedObject) && ((ASN1TaggedObject)tmp).getTagNo() == 0) { certificates = ((ASN1TaggedObject)tmp).getObject(); index++; } tmp = sequence.getObjectAt(index); if((tmp instanceof ASN1TaggedObject) && ((ASN1TaggedObject)tmp).getTagNo() == 1) { crls = ((ASN1TaggedObject)tmp).getObject(); index++; } ASN1Set signerInfos = (ASN1Set)sequence.getObjectAt(index); Signed signed = new Signed(); signed.setVersion(version.getValue().intValue()); signed.setMdAlgs(algorithmIdentifiersFromASN1Set(digestAlgos)); signed.setContents(PKCS7.fromASN1(contentInfo)); if(certificates != null) { signed.setCert(certificatesFromASN1Set(certificates)); } if(crls != null) { throw new RuntimeException("TODO: implement CRL part"); } signed.setSignerInfo(signerInfosFromASN1Set(signerInfos)); return signed; } private static Collection certificatesFromASN1Set(ASN1Encodable content) throws PKCS7Exception { Collection result = new ArrayList(); if (content instanceof ASN1Sequence) { try { for (Enumeration enm = ((ASN1Sequence) content).getObjects(); enm.hasMoreElements();) { ASN1Encodable current = (ASN1Encodable) enm.nextElement(); result.add(certificateFromASN1(current)); } } catch (IllegalArgumentException iae) { result.add(certificateFromASN1(content)); } } else if (content instanceof ASN1Set) { // EXPLICIT Set shouldn't apper here but keep this for backward compatibility. for (Enumeration enm = ((ASN1Set) content).getObjects(); enm.hasMoreElements();) { ASN1Encodable current = (ASN1Encodable) enm.nextElement(); result.add(certificateFromASN1(current)); } } else { throw new PKCS7Exception(PKCS7.F_B64_READ_PKCS7, PKCS7.R_CERTIFICATE_VERIFY_ERROR, "unknown certificates format"); } return result; } private static X509AuxCertificate certificateFromASN1(ASN1Encodable current) throws PKCS7Exception { Certificate struct = Certificate.getInstance(current); try { return new X509AuxCertificate(struct); } catch (IOException e) { throw new PKCS7Exception(PKCS7.F_B64_READ_PKCS7, PKCS7.R_CERTIFICATE_VERIFY_ERROR, e); } catch (CertificateException e) { throw new PKCS7Exception(PKCS7.F_B64_READ_PKCS7, PKCS7.R_CERTIFICATE_VERIFY_ERROR, e); } } private static Set algorithmIdentifiersFromASN1Set(ASN1Encodable content) { ASN1Set set = (ASN1Set)content; Set result = new HashSet(); for(Enumeration e = set.getObjects(); e.hasMoreElements();) { result.add(AlgorithmIdentifier.getInstance(e.nextElement())); } return result; } private static Collection signerInfosFromASN1Set(ASN1Encodable content) { ASN1Set set = (ASN1Set)content; Collection result = new ArrayList(); for(Enumeration e = set.getObjects(); e.hasMoreElements();) { result.add(SignerInfoWithPkey.getInstance(e.nextElement())); } return result; } }// Signed jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/SignerInfoWithPkey.java000066400000000000000000000306161313661621600306270ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; import java.math.BigInteger; import java.security.MessageDigest; import java.security.PrivateKey; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.RSAPrivateKey; import java.util.Enumeration; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.IssuerAndSerialNumber; import org.bouncycastle.asn1.pkcs.SignerInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x500.X500Name; import org.jruby.ext.openssl.x509store.X509AuxCertificate; /** * * @author Ola Bini */ public class SignerInfoWithPkey implements ASN1Encodable { static final ASN1ObjectIdentifier OID_dsa = new ASN1ObjectIdentifier(ASN1Registry.OBJ_dsa); static final ASN1ObjectIdentifier OID_sha1 = new ASN1ObjectIdentifier(ASN1Registry.OBJ_sha1); static final ASN1ObjectIdentifier OID_ecdsa_with_SHA1 = new ASN1ObjectIdentifier(ASN1Registry.OBJ_ecdsa_with_SHA1); static final ASN1ObjectIdentifier OID_rsaEncryption = new ASN1ObjectIdentifier(ASN1Registry.OBJ_rsaEncryption); private ASN1Integer version; private IssuerAndSerialNumber issuerAndSerialNumber; private AlgorithmIdentifier digAlgorithm; private ASN1Set authenticatedAttributes; private AlgorithmIdentifier digEncryptionAlgorithm; private ASN1OctetString encryptedDigest; private ASN1Set unauthenticatedAttributes; public static SignerInfoWithPkey getInstance(Object o) { if(o instanceof SignerInfo) { return (SignerInfoWithPkey)o; } else if (o instanceof ASN1Sequence) { return new SignerInfoWithPkey((ASN1Sequence)o); } throw new IllegalArgumentException("unknown object in factory: " + o.getClass().getName()); } public SignerInfoWithPkey dup() { SignerInfoWithPkey copy = new SignerInfoWithPkey(version, issuerAndSerialNumber, digAlgorithm, authenticatedAttributes, digEncryptionAlgorithm, encryptedDigest, unauthenticatedAttributes); copy.pkey = pkey; return copy; } SignerInfoWithPkey() { } public SignerInfoWithPkey(ASN1Integer version, IssuerAndSerialNumber issuerAndSerialNumber, AlgorithmIdentifier digAlgorithm, ASN1Set authenticatedAttributes, AlgorithmIdentifier digEncryptionAlgorithm, ASN1OctetString encryptedDigest, ASN1Set unauthenticatedAttributes) { this.version = version; this.issuerAndSerialNumber = issuerAndSerialNumber; this.digAlgorithm = digAlgorithm; this.authenticatedAttributes = authenticatedAttributes; this.digEncryptionAlgorithm = digEncryptionAlgorithm; this.encryptedDigest = encryptedDigest; this.unauthenticatedAttributes = unauthenticatedAttributes; } public SignerInfoWithPkey(ASN1Sequence seq) { Enumeration e = seq.getObjects(); version = (ASN1Integer)e.nextElement(); issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(e.nextElement()); digAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); Object obj = e.nextElement(); if(obj instanceof ASN1TaggedObject) { authenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)obj, false); digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(e.nextElement()); } else { authenticatedAttributes = null; digEncryptionAlgorithm = AlgorithmIdentifier.getInstance(obj); } encryptedDigest = ASN1OctetString.getInstance(e.nextElement()); if(e.hasMoreElements()) { unauthenticatedAttributes = ASN1Set.getInstance((ASN1TaggedObject)e.nextElement(), false); } else { unauthenticatedAttributes = null; } } public ASN1Integer getVersion() { return version; } public IssuerAndSerialNumber getIssuerAndSerialNumber() { return issuerAndSerialNumber; } public ASN1Set getAuthenticatedAttributes() { return authenticatedAttributes; } public AlgorithmIdentifier getDigestAlgorithm() { return digAlgorithm; } public ASN1OctetString getEncryptedDigest() { return encryptedDigest; } public AlgorithmIdentifier getDigestEncryptionAlgorithm() { return digEncryptionAlgorithm; } public ASN1Set getUnauthenticatedAttributes() { return unauthenticatedAttributes; } /* c: PKCS7_SIGNER_INFO_set * */ public void set(X509AuxCertificate x509, PrivateKey pkey, MessageDigest dgst) throws PKCS7Exception { boolean dsa = (pkey instanceof DSAPrivateKey) || (pkey instanceof ECPrivateKey); version = new ASN1Integer(BigInteger.ONE); X500Name issuer = X500Name.getInstance(x509.getIssuerX500Principal().getEncoded()); BigInteger serial = x509.getSerialNumber(); issuerAndSerialNumber = new IssuerAndSerialNumber(issuer, serial); this.pkey = pkey; if ( dsa ) { digAlgorithm = new AlgorithmIdentifier(OID_sha1); } else { digAlgorithm = new AlgorithmIdentifier(ASN1Registry.nid2obj(EVP.type(dgst))); } if ( pkey instanceof RSAPrivateKey ) { digEncryptionAlgorithm = new AlgorithmIdentifier(OID_rsaEncryption); } else if( pkey instanceof DSAPrivateKey ) { digEncryptionAlgorithm = new AlgorithmIdentifier(OID_dsa); } else if( pkey instanceof ECPrivateKey ) { digEncryptionAlgorithm = new AlgorithmIdentifier(OID_ecdsa_with_SHA1); } } /** * Produce an object suitable for an ASN1OutputStream. *
     *  SignerInfo ::= SEQUENCE {
     *      version Version,
     *      issuerAndSerialNumber IssuerAndSerialNumber,
     *      digestAlgorithm DigestAlgorithmIdentifier,
     *      authenticatedAttributes [0] IMPLICIT Attributes OPTIONAL,
     *      digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
     *      encryptedDigest EncryptedDigest,
     *      unauthenticatedAttributes [1] IMPLICIT Attributes OPTIONAL
     *  }
     *
     *  EncryptedDigest ::= OCTET STRING
     *
     *  DigestAlgorithmIdentifier ::= AlgorithmIdentifier
     *
     *  DigestEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
     * 
*/ public ASN1Encodable toASN1Object() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(version); v.add(issuerAndSerialNumber); v.add(digAlgorithm); if (authenticatedAttributes != null) { v.add(new DERTaggedObject(false, 0, authenticatedAttributes)); } v.add(digEncryptionAlgorithm); v.add(encryptedDigest); if (unauthenticatedAttributes != null) { v.add(new DERTaggedObject(false, 1, unauthenticatedAttributes)); } return new DLSequence(v); } /** * Describe pkey here. */ private PrivateKey pkey; /** * Get the Pkey value. * * @return a PrivateKey value */ public final PrivateKey getPkey() { return pkey; } /** * Set the Pkey value. * * @param newPkey The new Pkey value. */ public final void setPkey(final PrivateKey newPkey) { this.pkey = newPkey; } public void setAuthenticatedAttributes(ASN1Set authAttr) { this.authenticatedAttributes = authAttr; } public void setUnauthenticatedAttributes(ASN1Set unauthAttr) { this.unauthenticatedAttributes = unauthAttr; } public void setEncryptedDigest(ASN1OctetString encryptedDigest) { this.encryptedDigest = encryptedDigest; } /** c: PKCS7_get_signed_attribute * */ public ASN1Encodable getSignedAttribute(int nid) { return getAttribute(this.authenticatedAttributes, nid); } /** c: PKCS7_get_attribute * */ public ASN1Encodable getAttribute(int nid) { return getAttribute(this.unauthenticatedAttributes, nid); } /** c: static get_attribute * */ static ASN1Encodable getAttribute(ASN1Set sk, int nid) { final ASN1ObjectIdentifier oid = ASN1Registry.nid2obj(nid); if ( oid == null || sk == null ) return null; for ( Enumeration e = sk.getObjects(); e.hasMoreElements(); ) { Attribute xa = Attribute.getInstance( e.nextElement() ); if ( oid.equals(xa.getAttrType()) ) { if ( xa.getAttrValues().size() > 0 ) { return xa.getAttrValues().getObjectAt(0); } return null; } } return null; } /** c: PKCS7_add_signed_attribute * */ public void addSignedAttribute(int atrType, ASN1Encodable value) { this.authenticatedAttributes = addAttribute(this.authenticatedAttributes, atrType, value); } /** c: PKCS7_add_attribute * */ public void addAttribute(int atrType, ASN1Encodable value) { this.unauthenticatedAttributes = addAttribute(this.unauthenticatedAttributes, atrType, value); } /** c: static add_attribute * */ private ASN1Set addAttribute(ASN1Set base, int atrType, ASN1Encodable value) { ASN1EncodableVector vector = new ASN1EncodableVector(); if ( base == null ) base = new DERSet(); Attribute attr; for ( Enumeration e = base.getObjects(); e.hasMoreElements(); ) { attr = Attribute.getInstance( e.nextElement() ); if ( ASN1Registry.oid2nid(attr.getAttrType()) != atrType ) { vector.add(attr); } } ASN1ObjectIdentifier ident = ASN1Registry.nid2obj(atrType); attr = new Attribute(ident, new DERSet(value)); vector.add(attr); return new DERSet(vector); } @Override public ASN1Primitive toASN1Primitive() { throw new UnsupportedOperationException("Not supported yet."); } }// SignerInfoWithPkey jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/TypeDiscriminating.java000066400000000000000000000031741313661621600307040ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2008 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.impl; /** * @author Ola Bini */ public abstract class TypeDiscriminating { }// TypeDiscriminating jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/000077500000000000000000000000001313661621600250075ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/MiscPEMGenerator.java000066400000000000000000000304021313661621600307550ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; import java.io.IOException; import java.math.BigInteger; import java.security.SecureRandom; import java.security.cert.CRLException; import java.security.cert.CertificateEncodingException; import java.util.ArrayList; import java.util.List; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.util.Strings; import org.bouncycastle.util.io.pem.PemGenerationException; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObjectGenerator; import org.bouncycastle.x509.X509AttributeCertificate; /** * PEM generator for the original set of PEM objects used in Open SSL. * * @note Based on org.bouncycastle.openssl.MiscPEMGenerator * (from BC 1.50) but "re-invented" for 1.47 compatibility * * @author kares */ public class MiscPEMGenerator implements PemObjectGenerator { private static final ASN1ObjectIdentifier[] dsaOids = { X9ObjectIdentifiers.id_dsa, OIWObjectIdentifiers.dsaWithSHA1 }; private static final byte[] hexEncodingTable = { (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F' }; private final Object obj; private final PEMEncryptor encryptor; public MiscPEMGenerator(Object o) { this.obj = o; // use of this confuses some earlier JDKs. this.encryptor = null; } private MiscPEMGenerator(Object o, PEMEncryptor encryptor) { this.obj = o; this.encryptor = encryptor; } public static MiscPEMGenerator newInstance(final Object o, final String algorithm, final char[] password, final SecureRandom random) { return new MiscPEMGenerator(o, buildPEMEncryptor(algorithm, password, random)); } private PemObject createPemObject(Object o) throws IOException { String type; byte[] encoding; if (o instanceof PemObject) { return (PemObject)o; } if (o instanceof PemObjectGenerator) { return ((PemObjectGenerator)o).generate(); } if (o instanceof X509CertificateHolder) { type = "CERTIFICATE"; encoding = ((X509CertificateHolder)o).getEncoded(); } else if (o instanceof X509CRLHolder) { type = "X509 CRL"; encoding = ((X509CRLHolder)o).getEncoded(); } else if (o instanceof PrivateKeyInfo) { PrivateKeyInfo info = (PrivateKeyInfo)o; ASN1ObjectIdentifier algOID = info.getPrivateKeyAlgorithm().getAlgorithm(); if (algOID.equals(PKCSObjectIdentifiers.rsaEncryption)) { type = "RSA PRIVATE KEY"; encoding = info.parsePrivateKey().toASN1Primitive().getEncoded(); } else if (algOID.equals(dsaOids[0]) || algOID.equals(dsaOids[1])) { type = "DSA PRIVATE KEY"; DSAParameter p = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(BigInteger.ZERO)); v.add(new ASN1Integer(p.getP())); v.add(new ASN1Integer(p.getQ())); v.add(new ASN1Integer(p.getG())); BigInteger x = ASN1Integer.getInstance(info.parsePrivateKey()).getValue(); BigInteger y = p.getG().modPow(x, p.getP()); v.add(new ASN1Integer(y)); v.add(new ASN1Integer(x)); encoding = new DERSequence(v).getEncoded(); } else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey)) { type = "EC PRIVATE KEY"; encoding = info.parsePrivateKey().toASN1Primitive().getEncoded(); } else { throw new IOException("Cannot identify private key"); } } else if (o instanceof SubjectPublicKeyInfo) { type = "PUBLIC KEY"; encoding = ((SubjectPublicKeyInfo)o).getEncoded(); } else if (o instanceof X509AttributeCertificateHolder) { type = "ATTRIBUTE CERTIFICATE"; encoding = ((X509AttributeCertificateHolder)o).getEncoded(); } else if (o instanceof PKCS10CertificationRequest) { type = "CERTIFICATE REQUEST"; encoding = ((PKCS10CertificationRequest)o).getEncoded(); } else if (o instanceof ContentInfo) { type = "PKCS7"; encoding = ((ContentInfo)o).getEncoded(); } // // NOTE: added behaviour to provide backwards compatibility with 1.47 : // else if (o instanceof java.security.cert.X509Certificate) // 1.47 compatibility { type = "CERTIFICATE"; try { encoding = ((java.security.cert.X509Certificate)o).getEncoded(); } catch (CertificateEncodingException e) { throw new PemGenerationException("Cannot encode object: " + e.toString()); } } else if (o instanceof java.security.cert.X509CRL) // 1.47 compatibility { type = "X509 CRL"; try { encoding = ((java.security.cert.X509CRL)o).getEncoded(); } catch (CRLException e) { throw new PemGenerationException("Cannot encode object: " + e.toString()); } } else if (o instanceof java.security.KeyPair) // 1.47 compatibility { return createPemObject(((java.security.KeyPair)o).getPrivate()); } else if (o instanceof java.security.PrivateKey) // 1.47 compatibility { PrivateKeyInfo info = new PrivateKeyInfo( (ASN1Sequence) ASN1Primitive.fromByteArray(((java.security.Key)o).getEncoded())); if (o instanceof java.security.interfaces.RSAPrivateKey) { type = "RSA PRIVATE KEY"; encoding = info.parsePrivateKey().toASN1Primitive().getEncoded(); } else if (o instanceof java.security.interfaces.DSAPrivateKey) { type = "DSA PRIVATE KEY"; DSAParameter p = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERInteger(0)); v.add(new DERInteger(p.getP())); v.add(new DERInteger(p.getQ())); v.add(new DERInteger(p.getG())); BigInteger x = ((java.security.interfaces.DSAPrivateKey)o).getX(); BigInteger y = p.getG().modPow(x, p.getP()); v.add(new DERInteger(y)); v.add(new DERInteger(x)); encoding = new DERSequence(v).getEncoded(); } else if (((java.security.PrivateKey)o).getAlgorithm().equals("ECDSA")) { type = "EC PRIVATE KEY"; encoding = info.parsePrivateKey().toASN1Primitive().getEncoded(); } else { throw new IOException("Cannot identify private key"); } } else if (o instanceof java.security.PublicKey) // 1.47 compatibility { type = "PUBLIC KEY"; encoding = ((java.security.PublicKey)o).getEncoded(); } else if (o instanceof X509AttributeCertificate) // 1.47 compatibility { type = "ATTRIBUTE CERTIFICATE"; encoding = ((X509AttributeCertificate)o).getEncoded(); } // // // else { throw new PemGenerationException("unknown object passed - can't encode."); } if (encryptor != null) // NEW STUFF (NOT IN OLD) { String dekAlgName = Strings.toUpperCase(encryptor.getAlgorithm()); // Note: For backward compatibility if (dekAlgName.equals("DESEDE")) { dekAlgName = "DES-EDE3-CBC"; } byte[] iv = encryptor.getIV(); byte[] encData = encryptor.encrypt(encoding); List headers = new ArrayList(2); headers.add(new PemHeader("Proc-Type", "4,ENCRYPTED")); headers.add(new PemHeader("DEK-Info", dekAlgName + "," + getHexEncoded(iv))); return new PemObject(type, headers, encData); } return new PemObject(type, encoding); } private static String getHexEncoded(byte[] bytes) throws IOException { char[] chars = new char[bytes.length * 2]; for (int i = 0; i != bytes.length; i++) { int v = bytes[i] & 0xff; chars[2 * i] = (char)(hexEncodingTable[(v >>> 4)]); chars[2 * i + 1] = (char)(hexEncodingTable[v & 0xf]); } return new String(chars); } public PemObject generate() throws PemGenerationException { try { return createPemObject(obj); } catch (IOException e) { throw new PemGenerationException("encoding exception: " + e.getMessage(), e); } } // // NOTE: re-invented piece to provide compatibility for 1.47 - 1.48 : // private static PEMEncryptor buildPEMEncryptor(final String algorithm, final char[] password, final SecureRandom random) { int ivLength = algorithm.toUpperCase().startsWith("AES-") ? 16 : 8; final byte[] iv = new byte[ivLength]; ( random == null ? new SecureRandom() : random ).nextBytes(iv); return new PEMEncryptor() { public String getAlgorithm() { return algorithm; } public byte[] getIV() { return iv; } public byte[] encrypt(byte[] encoding) throws PEMException { return PEMUtilities.crypt(true, encoding, password, algorithm, iv); } }; } private static interface PEMEncryptor { public String getAlgorithm(); public byte[] getIV(); public byte[] encrypt(byte[] bytes) throws PEMException; } }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/PEMDecryptor.java000066400000000000000000000027171313661621600301760ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; // NOTE: simply delete this whole thing once using a BC release that has PEMParser /** * Part of PEMReader (replacement) support. * * @note org.bouncycastle.openssl.PEMParser (not available in BC 1.47) */ public interface PEMDecryptor { byte[] decrypt(byte[] keyBytes, byte[] iv) throws PEMException; }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/PEMDecryptorProvider.java000066400000000000000000000030321313661621600317000ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; import org.bouncycastle.operator.OperatorCreationException; // NOTE: simply delete this whole thing once using a BC release that has PEMParser /** * Part of PEMReader (replacement) support. * * @note org.bouncycastle.openssl.PEMParser (not available in BC 1.47) */ public interface PEMDecryptorProvider { PEMDecryptor get(String dekAlgName) throws OperatorCreationException; }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/PEMEncryptedKeyPair.java000066400000000000000000000047771313661621600314550ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; // NOTE: simply delete this whole thing once using a BC release that has PEMParser import java.io.IOException; import org.bouncycastle.operator.OperatorCreationException; /** * Part of PEMReader (replacement) support. * * @note org.bouncycastle.openssl.PEMParser (not available in BC 1.47) */ public class PEMEncryptedKeyPair { private final String dekAlgName; private final byte[] iv; private final byte[] keyBytes; private final PEMKeyPairParser parser; PEMEncryptedKeyPair(String dekAlgName, byte[] iv, byte[] keyBytes, PEMKeyPairParser parser) { this.dekAlgName = dekAlgName; this.iv = iv; this.keyBytes = keyBytes; this.parser = parser; } public PEMKeyPair decryptKeyPair(PEMDecryptorProvider keyDecryptorProvider) throws IOException { try { PEMDecryptor keyDecryptor = keyDecryptorProvider.get(dekAlgName); return parser.parse(keyDecryptor.decrypt(keyBytes, iv)); } catch (IOException e) { throw e; } catch (OperatorCreationException e) { throw new PEMException("cannot create extraction operator: " + e.getMessage(), e); } catch (Exception e) { throw new PEMException("exception processing key pair: " + e.getMessage(), e); } } }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/PEMException.java000066400000000000000000000035611313661621600301570ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; // NOTE: simply delete this whole thing once using a BC release that has PEMParser import java.io.IOException; /** * Part of PEMReader (replacement) support. * * @note org.bouncycastle.openssl.PEMParser (not available in BC 1.47) */ public class PEMException extends IOException { Exception underlying; public PEMException( String message) { super(message); } public PEMException( String message, Exception underlying) { super(message); this.underlying = underlying; } public Exception getUnderlyingException() { return underlying; } public Throwable getCause() { return underlying; } }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/PEMKeyPair.java000066400000000000000000000037171313661621600275700ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; // NOTE: simply delete this whole thing once using a BC release that has PEMParser import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; /** * Part of PEMReader (replacement) support. * * @note org.bouncycastle.openssl.PEMParser (not available in BC 1.47) */ public class PEMKeyPair { private final SubjectPublicKeyInfo publicKeyInfo; private final PrivateKeyInfo privateKeyInfo; public PEMKeyPair(SubjectPublicKeyInfo publicKeyInfo, PrivateKeyInfo privateKeyInfo) { this.publicKeyInfo = publicKeyInfo; this.privateKeyInfo = privateKeyInfo; } public PrivateKeyInfo getPrivateKeyInfo() { return privateKeyInfo; } public SubjectPublicKeyInfo getPublicKeyInfo() { return publicKeyInfo; } }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/PEMKeyPairParser.java000066400000000000000000000027411313661621600307410ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; // NOTE: simply delete this whole thing once using a BC release that has PEMParser import java.io.IOException; /** * Part of PEMReader (replacement) support. * * @note org.bouncycastle.openssl.PEMParser (not available in BC 1.47) */ interface PEMKeyPairParser { PEMKeyPair parse(byte[] encoding) throws IOException; }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/PEMParser.java000066400000000000000000000413301313661621600274510ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RSAPublicKey; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.io.pem.PemHeader; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemObjectParser; import org.bouncycastle.util.io.pem.PemReader; // NOTE: simply delete this whole thing once using a BC release that has PEMParser /** * This is a PEMReader replacement. * * @note org.bouncycastle.openssl.PEMParser (not available in BC 1.47) */ public class PEMParser extends PemReader { private final Map parsers = new HashMap(); /** * Create a new PEMReader * * @param reader the Reader */ public PEMParser( Reader reader) { super(reader); parsers.put("CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); parsers.put("NEW CERTIFICATE REQUEST", new PKCS10CertificationRequestParser()); parsers.put("CERTIFICATE", new X509CertificateParser()); parsers.put("X509 CERTIFICATE", new X509CertificateParser()); parsers.put("X509 CRL", new X509CRLParser()); parsers.put("PKCS7", new PKCS7Parser()); parsers.put("ATTRIBUTE CERTIFICATE", new X509AttributeCertificateParser()); parsers.put("EC PARAMETERS", new ECCurveParamsParser()); parsers.put("PUBLIC KEY", new PublicKeyParser()); parsers.put("RSA PUBLIC KEY", new RSAPublicKeyParser()); parsers.put("RSA PRIVATE KEY", new KeyPairParser(new RSAKeyPairParser())); parsers.put("DSA PRIVATE KEY", new KeyPairParser(new DSAKeyPairParser())); parsers.put("EC PRIVATE KEY", new KeyPairParser(new ECDSAKeyPairParser())); parsers.put("ENCRYPTED PRIVATE KEY", new EncryptedPrivateKeyParser()); parsers.put("PRIVATE KEY", new PrivateKeyParser()); } public Object readObject() throws IOException { PemObject obj = readPemObject(); if (obj != null) { String type = obj.getType(); if (parsers.containsKey(type)) { return ((PemObjectParser)parsers.get(type)).parseObject(obj); } else { throw new IOException("unrecognised object: " + type); } } return null; } private class KeyPairParser implements PemObjectParser { private final PEMKeyPairParser pemKeyPairParser; public KeyPairParser(PEMKeyPairParser pemKeyPairParser) { this.pemKeyPairParser = pemKeyPairParser; } /** * Read a Key Pair */ public Object parseObject( PemObject obj) throws IOException { boolean isEncrypted = false; String dekInfo = null; List headers = obj.getHeaders(); for (Iterator it = headers.iterator(); it.hasNext();) { PemHeader hdr = (PemHeader)it.next(); if (hdr.getName().equals("Proc-Type") && hdr.getValue().equals("4,ENCRYPTED")) { isEncrypted = true; } else if (hdr.getName().equals("DEK-Info")) { dekInfo = hdr.getValue(); } } // // extract the key // byte[] keyBytes = obj.getContent(); try { if (isEncrypted) { StringTokenizer tknz = new StringTokenizer(dekInfo, ","); String dekAlgName = tknz.nextToken(); byte[] iv = Hex.decode(tknz.nextToken()); return new PEMEncryptedKeyPair(dekAlgName, iv, keyBytes, pemKeyPairParser); } return pemKeyPairParser.parse(keyBytes); } catch (IOException e) { if (isEncrypted) { throw new PEMException("exception decoding - please check password and data.", e); } else { throw new PEMException(e.getMessage(), e); } } catch (IllegalArgumentException e) { if (isEncrypted) { throw new PEMException("exception decoding - please check password and data.", e); } else { throw new PEMException(e.getMessage(), e); } } } } private class DSAKeyPairParser implements PEMKeyPairParser { public PEMKeyPair parse(byte[] encoding) throws IOException { try { ASN1Sequence seq = ASN1Sequence.getInstance(encoding); if (seq.size() != 6) { throw new PEMException("malformed sequence in DSA private key"); } // ASN1Integer v = (ASN1Integer)seq.getObjectAt(0); ASN1Integer p = ASN1Integer.getInstance(seq.getObjectAt(1)); ASN1Integer q = ASN1Integer.getInstance(seq.getObjectAt(2)); ASN1Integer g = ASN1Integer.getInstance(seq.getObjectAt(3)); ASN1Integer y = ASN1Integer.getInstance(seq.getObjectAt(4)); ASN1Integer x = ASN1Integer.getInstance(seq.getObjectAt(5)); return new PEMKeyPair( new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(p.getValue(), q.getValue(), g.getValue())), y), new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, new DSAParameter(p.getValue(), q.getValue(), g.getValue())), x)); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating DSA private key: " + e.toString(), e); } } } private class ECDSAKeyPairParser implements PEMKeyPairParser { public PEMKeyPair parse(byte[] encoding) throws IOException { try { ASN1Sequence seq = ASN1Sequence.getInstance(encoding); org.bouncycastle.asn1.sec.ECPrivateKey pKey = org.bouncycastle.asn1.sec.ECPrivateKey.getInstance(seq); AlgorithmIdentifier algId = new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, pKey.getParameters()); PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey); SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pKey.getPublicKey().getBytes()); return new PEMKeyPair(pubInfo, privInfo); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating EC private key: " + e.toString(), e); } } } private class RSAKeyPairParser implements PEMKeyPairParser { public PEMKeyPair parse(byte[] encoding) throws IOException { try { ASN1Sequence seq = ASN1Sequence.getInstance(encoding); if (seq.size() != 9) { throw new PEMException("malformed sequence in RSA private key"); } org.bouncycastle.asn1.pkcs.RSAPrivateKey keyStruct = org.bouncycastle.asn1.pkcs.RSAPrivateKey.getInstance(seq); RSAPublicKey pubSpec = new RSAPublicKey( keyStruct.getModulus(), keyStruct.getPublicExponent()); AlgorithmIdentifier algId = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); return new PEMKeyPair(new SubjectPublicKeyInfo(algId, pubSpec), new PrivateKeyInfo(algId, keyStruct)); } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException( "problem creating RSA private key: " + e.toString(), e); } } } private class PublicKeyParser implements PemObjectParser { public PublicKeyParser() { } public Object parseObject(PemObject obj) throws IOException { return SubjectPublicKeyInfo.getInstance(obj.getContent()); } } private class RSAPublicKeyParser implements PemObjectParser { public RSAPublicKeyParser() { } public Object parseObject(PemObject obj) throws IOException { try { RSAPublicKey rsaPubStructure = RSAPublicKey.getInstance(obj.getContent()); return new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), rsaPubStructure); } catch (Exception e) { if ( e instanceof IOException ) throw (IOException) e; throw new PEMException("problem extracting key: " + e.toString(), e); } } } private class X509CertificateParser implements PemObjectParser { /** * Reads in a X509Certificate. * * @return the X509Certificate * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new X509CertificateHolder(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing cert: " + e.toString(), e); } } } private class X509CRLParser implements PemObjectParser { /** * Reads in a X509CRL. * * @return the X509Certificate * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new X509CRLHolder(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing cert: " + e.toString(), e); } } } private class PKCS10CertificationRequestParser implements PemObjectParser { /** * Reads in a PKCS10 certification request. * * @return the certificate request. * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new PKCS10CertificationRequest(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing certrequest: " + e.toString(), e); } } } private class PKCS7Parser implements PemObjectParser { /** * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS * API. * * @return the X509Certificate * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { ASN1InputStream aIn = new ASN1InputStream(obj.getContent()); return ContentInfo.getInstance(aIn.readObject()); } catch (Exception e) { throw new PEMException("problem parsing PKCS7 object: " + e.toString(), e); } } } private class X509AttributeCertificateParser implements PemObjectParser { public Object parseObject(PemObject obj) throws IOException { return new X509AttributeCertificateHolder(obj.getContent()); } } private class ECCurveParamsParser implements PemObjectParser { public Object parseObject(PemObject obj) throws IOException { try { Object param = ASN1Primitive.fromByteArray(obj.getContent()); if (param instanceof ASN1ObjectIdentifier) { return ASN1Primitive.fromByteArray(obj.getContent()); } else if (param instanceof ASN1Sequence) { return X9ECParameters.getInstance(param); } else { return null; // implicitly CA } } catch (IOException e) { throw e; } catch (Exception e) { throw new PEMException("exception extracting EC named curve: " + e.toString()); } } } private class EncryptedPrivateKeyParser implements PemObjectParser { public EncryptedPrivateKeyParser() { } /** * Reads in an EncryptedPrivateKeyInfo * * @return the X509Certificate * @throws java.io.IOException if an I/O error occured */ public Object parseObject(PemObject obj) throws IOException { try { return new PKCS8EncryptedPrivateKeyInfo(EncryptedPrivateKeyInfo.getInstance(obj.getContent())); } catch (Exception e) { throw new PEMException("problem parsing ENCRYPTED PRIVATE KEY: " + e.toString(), e); } } } private class PrivateKeyParser implements PemObjectParser { public PrivateKeyParser() { } public Object parseObject(PemObject obj) throws IOException { try { return PrivateKeyInfo.getInstance(obj.getContent()); } catch (Exception e) { throw new PEMException("problem parsing PRIVATE KEY: " + e.toString(), e); } } } }jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/impl/pem/PEMUtilities.java000066400000000000000000000157131313661621600301760ustar00rootroot00000000000000/* Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package org.jruby.ext.openssl.impl.pem; import java.security.Key; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.params.KeyParameter; import org.jruby.ext.openssl.SecurityHelper; /** * org.bouncycastle.openssl.jcajce.PEMUtilities * re-implemented as 1.47 compatible * * @see MiscPEMGenerator * @author kares */ abstract class PEMUtilities { static byte[] crypt( boolean encrypt, //JcaJceHelper helper, byte[] bytes, char[] password, String dekAlgName, byte[] iv) throws PEMException { AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv); String alg; String blockMode = "CBC"; String padding = "PKCS5Padding"; Key sKey; // Figure out block mode and padding. if (dekAlgName.endsWith("-CFB")) { blockMode = "CFB"; padding = "NoPadding"; } if (dekAlgName.endsWith("-ECB") || "DES-EDE".equals(dekAlgName) || "DES-EDE3".equals(dekAlgName)) { // ECB is actually the default (though seldom used) when OpenSSL // uses DES-EDE (des2) or DES-EDE3 (des3). blockMode = "ECB"; paramSpec = null; } if (dekAlgName.endsWith("-OFB")) { blockMode = "OFB"; padding = "NoPadding"; } // Figure out algorithm and key size. if (dekAlgName.startsWith("DES-EDE")) { alg = "DESede"; // "DES-EDE" is actually des2 in OpenSSL-speak! // "DES-EDE3" is des3. boolean des2 = !dekAlgName.startsWith("DES-EDE3"); sKey = getKey(password, alg, 24, iv, des2); } else if (dekAlgName.startsWith("DES-")) { alg = "DES"; sKey = getKey(password, alg, 8, iv); } else if (dekAlgName.startsWith("BF-")) { alg = "Blowfish"; sKey = getKey(password, alg, 16, iv); } else if (dekAlgName.startsWith("RC2-")) { alg = "RC2"; int keyBits = 128; if (dekAlgName.startsWith("RC2-40-")) { keyBits = 40; } else if (dekAlgName.startsWith("RC2-64-")) { keyBits = 64; } sKey = getKey(password, alg, keyBits / 8, iv); if (paramSpec == null) // ECB block mode { paramSpec = new RC2ParameterSpec(keyBits); } else { paramSpec = new RC2ParameterSpec(keyBits, iv); } } else if (dekAlgName.startsWith("AES-")) { alg = "AES"; byte[] salt = iv; if (salt.length > 8) { salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); } int keyBits; if (dekAlgName.startsWith("AES-128-")) { keyBits = 128; } else if (dekAlgName.startsWith("AES-192-")) { keyBits = 192; } else if (dekAlgName.startsWith("AES-256-")) { keyBits = 256; } else { //throw new EncryptionException("unknown AES encryption with private key"); throw new PEMException("unknown AES encryption with private key"); } sKey = getKey(password, "AES", keyBits / 8, salt); } else { //throw new EncryptionException("unknown encryption with private key"); throw new PEMException("unknown encryption with private key"); } String transformation = alg + "/" + blockMode + "/" + padding; try { //Cipher c = helper.createCipher(transformation); Cipher c = SecurityHelper.getCipher(transformation); int mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; if (paramSpec == null) // ECB block mode { c.init(mode, sKey); } else { c.init(mode, sKey, paramSpec); } return c.doFinal(bytes); } catch (Exception e) { //throw new EncryptionException("exception using cipher - please check password and data.", e); throw new PEMException("exception using cipher - please check password and data.", e); } } private static SecretKey getKey( char[] password, String algorithm, int keyLength, byte[] salt) { return getKey(password, algorithm, keyLength, salt, false); } private static SecretKey getKey( char[] password, String algorithm, int keyLength, byte[] salt, boolean des2) { OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt); KeyParameter keyParam; keyParam = (KeyParameter) pGen.generateDerivedParameters(keyLength * 8); byte[] key = keyParam.getKey(); if (des2 && key.length >= 24) { // For DES2, we must copy first 8 bytes into the last 8 bytes. System.arraycopy(key, 0, key, 16, 8); } return new SecretKeySpec(key, algorithm); } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/util/000077500000000000000000000000001313661621600242425ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/util/ByteArrayOutputStream.java000066400000000000000000000017301313661621600314050ustar00rootroot00000000000000/* * Copyright (c) 2016 kares. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.jruby.ext.openssl.util; /** * Allows direct buffer access for less copy-ing. * * @author kares */ public final class ByteArrayOutputStream extends java.io.ByteArrayOutputStream { public ByteArrayOutputStream() { super(); } public ByteArrayOutputStream(int size) { super(size); } public byte[] buffer() { return buf; } public int size() { return count; } @Override public byte[] toByteArray() { final int len = buf.length; if (count == len) return buf; // no-copying final byte[] copy = new byte[count]; System.arraycopy(buf, 0, copy, 0, count); return copy; } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/util/Cache.java000066400000000000000000000150671313661621600261210ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2015 Karol Bucek * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.util; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; /** * a cache of a kind * * @author kares */ public class Cache { private static Cache NULL; private Cache() { /* empty-cache */ } @SuppressWarnings("unchecked") public static Cache getNullCache() { if ( NULL != null ) return NULL; return NULL = new Cache(); } /** * a soft-reference cache * @param * @param * @return new cache instance */ public static Cache newSoftCache() { return new SoftCache(); } /** * a soft-reference cache which holds strong references up to the specified * size, these are arranged in LRU order * @param * @param * @param size * @return new cache instance */ public static Cache newStrongSoftCache(final int size) { return new SoftCache(size); } public T get(K key) { return null; } public T put(K key, T value) { return null; } public T remove(K key) { return null; } public void clear() { return; } public int size() { return 0; } static final class SoftCache extends Cache { private final Map> cache; // SoftHashMap private final ReferenceQueue refQueue = new ReferenceQueue(); private final int strongLimit; private final SortedMap, T> strongRefs; // final Deque strong; private SoftCache() { this.strongLimit = 0; this.cache = new ConcurrentHashMap>(); this.strongRefs = null; } private SoftCache(final int limit) { this.strongLimit = limit; final int capacity = Math.min(limit, 32); this.cache = new ConcurrentHashMap>(capacity); this.strongRefs = new TreeMap, T>(); } public T get(K key) { T result = null; final Ref ref = cache.get(key); if ( ref != null ) { result = ref.get(); if ( result == null ) cache.remove(key); else { if ( strongRefs != null ) { synchronized (strongRefs) { strongRefs.remove(ref); strongRefs.put(ref.recordAccess(), result); if ( strongLimit > 0 && strongRefs.size() > strongLimit ) { strongRefs.remove( strongRefs.firstKey() ); } } } } } return result; } public T put(K key, T value) { purgeRefQueue(); final SoftReference prev = cache.put(key, new Ref(value, key, refQueue)); return prev == null ? null : prev.get(); } public T remove(K key) { purgeRefQueue(); final SoftReference removed = cache.remove(key); return removed == null ? null : removed.get(); } public void clear() { if ( strongRefs != null ) { synchronized (strongRefs) { strongRefs.clear(); } } purgeRefQueue(); cache.clear(); purgeRefQueue(); } public int size() { purgeRefQueue(); return cache.size(); } @SuppressWarnings("unchecked") private void purgeRefQueue() { Ref ref; while ( ( ref = (Ref) refQueue.poll() ) != null ) { synchronized (refQueue) { cache.remove( ref.key ); } } } private static class Ref extends SoftReference implements Comparable { private final K key; volatile long access; private Ref(T value, K key, ReferenceQueue queue) { super(value, queue); this.key = key; recordAccess(); } final Ref recordAccess() { access = System.currentTimeMillis(); return this; } @Override public boolean equals(Object obj) { if ( obj instanceof Ref ) { return this.key.equals( ((Ref) obj).key ); } return false; } @Override public int hashCode() { return key.hashCode(); } @Override // order by access time - more recent first (less than) others public int compareTo(final Ref that) { final long diff = this.access - that.access; if ( diff == 0 ) return 0; // diff > 0 ... this.access > that.access ... this > that return diff > 0 ? +1 : -1; // this accessed after that } } } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/util/CryptoSecurity.java000066400000000000000000000133421313661621600301200ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2017 Karol Bucek * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.util; import org.jruby.ext.openssl.OpenSSL; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.Permission; import java.security.PermissionCollection; import java.security.Security; /** * JCE security helper for disabling (default) imposed cryptographic restrictions. * * Using this class might be in **contrast with the license agreement** that came with your JRE. * * It's preferable to install: * * "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" * * specific to your Java version! * * @see http://www.oracle.com/technetwork/java/javase/downloads/index.html */ public final class CryptoSecurity { private CryptoSecurity() { /* no instances */ } public static void disableJceRestrictions() { unrestrictSecurity(); setAllPermissionPolicy(); } public static Boolean setAllPermissionPolicy() { if ( ! OpenSSL.javaHotSpot() ) return false; try { final Class JceSecurity = Class.forName("javax.crypto.JceSecurity"); final Class CryptoPermissions = Class.forName("javax.crypto.CryptoPermissions"); final Class CryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission"); Field defaultPolicy = JceSecurity.getDeclaredField("defaultPolicy"); defaultPolicy.setAccessible(true); Field perms = CryptoPermissions.getDeclaredField("perms"); perms.setAccessible(true); Field INSTANCE = CryptoAllPermission.getDeclaredField("INSTANCE"); INSTANCE.setAccessible(true); synchronized (Security.class) { final PermissionCollection defPolicy = (PermissionCollection) defaultPolicy.get(null); final java.util.Map permsMap = (java.util.Map) perms.get(defPolicy); if ( ! permsMap.isEmpty() ) { permsMap.clear(); defPolicy.add((Permission) INSTANCE.get(null)); return true; } return false; } } catch (ClassNotFoundException e) { OpenSSL.debug("unable un-restrict jce security: ", e); return null; } catch (Exception e) { OpenSSL.debug("unable un-restrict jce security: "); OpenSSL.debugStackTrace(e); return null; } } public static Boolean unrestrictSecurity() { if ( ! OpenSSL.javaHotSpot() ) return false; if ( javaVersion9() ) { return unrestrictJceSecurity9(); } return unrestrictJceSecurity8(); } static Boolean unrestrictJceSecurity9() { try { if (Security.getProperty("crypto.policy") == null) { Security.setProperty("crypto.policy", "unlimited"); return true; } return false; } catch (Exception e) { OpenSSL.debug("unable un-restrict jce security: ", e); return null; } } static Boolean unrestrictJceSecurity8() { try { final Class JceSecurity = Class.forName("javax.crypto.JceSecurity"); Field isRestricted = JceSecurity.getDeclaredField("isRestricted"); if ( Modifier.isFinal(isRestricted.getModifiers()) ) { Field modifiers = Field.class.getDeclaredField("modifiers"); modifiers.setAccessible(true); modifiers.setInt(isRestricted, isRestricted.getModifiers() & ~Modifier.FINAL); } isRestricted.setAccessible(true); if (isRestricted.getBoolean(null) == false) { isRestricted.setBoolean(null, false); // isRestricted = false; return true; } return false; } catch (ClassNotFoundException e) { OpenSSL.debug("unable un-restrict jce security: ", e); return null; } catch (Exception e) { OpenSSL.debug("unable un-restrict jce security: "); OpenSSL.debugStackTrace(e); return null; } } private static boolean javaVersion9() { final int gt = "1.8".compareTo( OpenSSL.javaVersion("0.0").substring(0, 3) ); return gt <= 0; } } jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/000077500000000000000000000000001313661621600250475ustar00rootroot00000000000000jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/CRL.java000066400000000000000000000051371313661621600263400ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.security.cert.X509CRL; /** * c: X509_OBJECT * * @author Ola Bini */ public class CRL extends X509Object { public /* final */ java.security.cert.CRL crl; @Deprecated // not-used public CRL() { /* */ } public CRL(X509CRL crl) { this.crl = crl; } @Override public int type() { return X509Utils.X509_LU_CRL; } @Override public boolean isName(final Name name) { return name.equalTo( ((X509CRL) crl).getIssuerX500Principal() ); } @Override public boolean matches(final X509Object other) { if (other instanceof CRL) { final X509CRL thisCRL = (X509CRL) crl; final X509CRL thatCRL = (X509CRL)((CRL) other).crl; return thisCRL.getIssuerX500Principal().equals( thatCRL.getIssuerX500Principal() ); } return false; } @Override public int compareTo(final X509Object other) { int cmp = super.compareTo(other); if (cmp != 0) return cmp; return crl.equals( ((CRL) other).crl ) ? 0 : -1; } }// X509_OBJECT_CRL jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Certificate.java000066400000000000000000000047221313661621600301410ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * c: X509_OBJECT * * @author Ola Bini */ public class Certificate extends X509Object { public final X509AuxCertificate x509; public Certificate(final X509AuxCertificate cert) { this.x509 = cert; } @Override public int type() { return X509Utils.X509_LU_X509; } @Override public boolean isName(final Name name) { return name.equalToCertificateSubject(x509); } @Override public boolean matches(final X509Object other) { if (other instanceof Certificate) { final Certificate that = (Certificate) other; return X509AuxCertificate.equalSubjects(this.x509, that.x509); } return false; } @Override public int compareTo(final X509Object other) { int cmp = super.compareTo(other); if (cmp != 0) return cmp; return x509.equals( ( (Certificate) other ).x509 ) ? 0 : -1; } }// X509_OBJECT_CERT jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/CertificateFile.java000066400000000000000000000037731313661621600307460ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * Contains information like x509_file_st and X509_CERT_FILER_CTX in * x509_vfy.h * * @author Ola Bini */ public class CertificateFile { public static class Path { public Path(String name, int type) { this.name = name; this.type = type; } public String name; public int type; } public int numberOfPaths; // This details how many of the paths-var that is actually used public Path[] paths; }// X509_CERT_FILE_CTX jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/CertificateHashDir.java000066400000000000000000000037721313661621600314100ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * Contains information like x509_hash_dir_st and X509_HASH_DIR_CTX in * x509_vfy.h * * @author Ola Bini */ public class CertificateHashDir { public static class Dir { public Dir(String name, int type) { this.name = name; this.type = type; } public String name; public int type; } public int numberOfDirs; // This details how many of the dirs-var that is actually used public Dir[] dirs; }// X509_HASH_DIR_CTX jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Function0.java000066400000000000000000000035111313661621600275570ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * Zero arity function call. * * @author Ola Bini */ interface Function0 { static class Empty implements Function0 { public int call() { return -1; } } public static final Function0.Empty EMPTY = new Empty(); int call() throws Exception; }// Function0 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Function1.java000066400000000000000000000035341313661621600275650ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * One arity function call. * * @author Ola Bini */ interface Function1 { static class Empty implements Function1 { public int call(Object arg0) { return -1; } } public static final Function1.Empty EMPTY = new Empty(); int call(T arg0) throws Exception; }// Function1 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Function2.java000066400000000000000000000035641313661621600275710ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * Two arity function call. * * @author Ola Bini */ interface Function2 { static class Empty implements Function2 { public int call(Object arg0, Object arg1) { return -1; } } public static final Function2.Empty EMPTY = new Empty(); int call(T arg0, U arg1) throws Exception; }// Function2 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Function3.java000066400000000000000000000036141313661621600275660ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * Three arity function call. * * @author Ola Bini */ interface Function3 { static class Empty implements Function3 { public int call(Object arg0,Object arg1,Object arg2) { return -1; } } public static final Function3.Empty EMPTY = new Empty(); int call(T arg0, U arg1, V arg2) throws Exception; }// Function3 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Function4.java000066400000000000000000000036421313661621600275700ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * Four arity function call. * * @author Ola Bini */ interface Function4 { static class Empty implements Function4 { public int call(Object arg0,Object arg1,Object arg2,Object arg3) { return -1; } } public static final Function4.Empty EMPTY = new Empty(); int call(T arg0, U arg1, V arg2, X arg3) throws Exception; }// Function4 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Function5.java000066400000000000000000000036711313661621600275730ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * Five arity function call. * * @author Ola Bini */ interface Function5 { static class Empty implements Function5 { public int call(Object arg0,Object arg1,Object arg2,Object arg3,Object arg4) { return -1; } } public static final Function5.Empty EMPTY = new Empty(); int call(T arg0, U arg1, V arg2, X arg3, Y arg4) throws Exception; }// Function5 jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Lookup.java000066400000000000000000000633741313661621600272000ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import org.jruby.ext.openssl.OpenSSL; import org.jruby.ext.openssl.util.Cache; import static org.jruby.ext.openssl.x509store.X509Utils.X509_CERT_DIR; import static org.jruby.ext.openssl.x509store.X509Utils.X509_FILETYPE_ASN1; import static org.jruby.ext.openssl.x509store.X509Utils.X509_FILETYPE_DEFAULT; import static org.jruby.ext.openssl.x509store.X509Utils.X509_FILETYPE_PEM; import static org.jruby.ext.openssl.x509store.X509Utils.X509_LU_CRL; import static org.jruby.ext.openssl.x509store.X509Utils.X509_LU_FAIL; import static org.jruby.ext.openssl.x509store.X509Utils.X509_LU_X509; import static org.jruby.ext.openssl.x509store.X509Utils.X509_L_ADD_DIR; import static org.jruby.ext.openssl.x509store.X509Utils.X509_L_FILE_LOAD; import static org.jruby.ext.openssl.x509store.X509Utils.X509_R_BAD_X509_FILETYPE; import static org.jruby.ext.openssl.x509store.X509Utils.X509_R_INVALID_DIRECTORY; import static org.jruby.ext.openssl.x509store.X509Utils.X509_R_LOADING_CERT_DIR; import static org.jruby.ext.openssl.x509store.X509Utils.X509_R_LOADING_DEFAULTS; import static org.jruby.ext.openssl.x509store.X509Utils.X509_R_WRONG_LOOKUP_TYPE; import static org.jruby.ext.openssl.x509store.X509Utils.getDefaultCertificateDirectoryEnvironment; import static org.jruby.ext.openssl.x509store.X509Utils.getDefaultCertificateFileEnvironment; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.cert.CRL; import java.security.cert.CertificateException; import java.security.cert.PKIXParameters; import java.security.cert.TrustAnchor; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import org.jruby.Ruby; import org.jruby.RubyHash; import org.jruby.ext.openssl.SecurityHelper; import org.jruby.util.JRubyFile; import org.jruby.util.SafePropertyAccessor; import org.jruby.util.io.ChannelDescriptor; import org.jruby.util.io.ChannelStream; import org.jruby.util.io.FileExistsException; import org.jruby.util.io.InvalidValueException; import org.jruby.util.io.ModeFlags; /** * X509_LOOKUP * * @author Ola Bini */ public class Lookup { boolean init = false; boolean skip = false; final LookupMethod method; private final Ruby runtime; Object methodData; Store store; /** * c: X509_LOOKUP_new */ public Lookup(Ruby runtime, LookupMethod method) { if ( method == null ) { throw new IllegalArgumentException("null method"); } this.method = method; this.runtime = runtime; final LookupMethod.NewItemFunction newItem = method.newItem; if ( newItem != null && newItem != Function1.EMPTY ) { final int result; try { result = newItem.call(this); } catch (Exception e) { if ( e instanceof RuntimeException ) throw (RuntimeException) e; throw new IllegalArgumentException("invalid lookup method", e); } if ( result == 0) throw new IllegalArgumentException("invalid lookup method"); } } /** * c: X509_LOOKUP_load_file */ public int loadFile(CertificateFile.Path file) throws Exception { return control(X509_L_FILE_LOAD, file.name, file.type, null); } /** * c: X509_LOOKUP_add_dir */ public int addDir(CertificateHashDir.Dir dir) throws Exception { return control(X509_L_ADD_DIR, dir.name, dir.type, null); } /** * c: X509_LOOKUP_hash_dir */ public static LookupMethod hashDirLookup() { return x509DirectoryLookup; } /** * c: X509_LOOKUP_file */ public static LookupMethod fileLookup() { return x509FileLookup; } /** * c: X509_LOOKUP_ctrl */ public int control(final int cmd, final String argc, final long argl, final String[] ret) throws Exception { if ( method == null ) return -1; if ( method.control != null && method.control != Function5.EMPTY ) { return method.control.call(this, Integer.valueOf(cmd), argc, Long.valueOf(argl), ret); } return 1; } private static final Cache certCache; static { // jruby.openssl.x509.cert.cache = true / false / 8 final String cache = SafePropertyAccessor.getProperty("jruby.openssl.x509.lookup.cache"); Cache certCacheInstance = null; if ( cache != null ) { try { certCacheInstance = Cache.newStrongSoftCache( Integer.parseInt(cache) ); } catch (NumberFormatException ex) { if ( Boolean.parseBoolean(cache) ) { certCacheInstance = Cache.newSoftCache(); } } } if ( certCacheInstance == null ) certCacheInstance = Cache.getNullCache(); certCache = certCacheInstance; } /** * c: X509_LOOKUP_load_cert_file */ public int loadCertificateFile(final String file, final int type) throws IOException, CertificateException { if ( file == null ) return 1; final Object[] cached = certCache.get(file); BufferedReader reader = null; try { X509AuxCertificate auxCert; if ( type == X509_FILETYPE_PEM ) { int count = 0; if ( cached != null ) { boolean storeError = false; for ( int c = 0; c < cached.length; c++ ) { auxCert = buildAuxFromCached((X509Certificate) cached[c]); if ( ! storeError ) { if ( store.addCertificate(auxCert) != 0 ) count++; else { storeError = true; count = 0; } // return 0 } } } else { reader = new BufferedReader(new InputStreamReader(wrapJRubyNormalizedInputStream(file))); final ArrayList cacheEntry = new ArrayList(8); boolean storeError = false; for (;;) { auxCert = PEMInputOutput.readX509Aux(reader, null); if ( auxCert == null ) break; cacheEntry.add( auxCert.cloneForCache() ); // make sure we cache aux if ( ! storeError ) { if ( store.addCertificate(auxCert) != 0 ) count++; else { storeError = true; count = 0; } // return 0 } } certCache.put(file, cacheEntry.toArray( new Object[ cacheEntry.size() ] )); } return count; } else if ( type == X509_FILETYPE_ASN1 ) { final X509Certificate cert; if ( cached != null ) { cert = (X509Certificate) cached[0]; auxCert = buildAuxFromCached(cert); } else { InputStream in = wrapJRubyNormalizedInputStream(file); cert = (X509Certificate) SecurityHelper.getCertificateFactory("X.509").generateCertificate(in); auxCert = new X509AuxCertificate(cert); certCache.put(file, new Object[] { auxCert.cloneForCache() }); } //if ( auxCert == null ) { // X509Error.addError(13); return 0; //} return store.addCertificate(auxCert); } else { X509Error.addError(X509_R_BAD_X509_FILETYPE); return 0; // NOTE: really? } } finally { if ( reader != null ) { try { reader.close(); } catch (Exception ignored) {} } } } private static X509AuxCertificate buildAuxFromCached(final X509Certificate cached) { X509AuxCertificate auxCert = StoreContext.ensureAux(cached); if ( cached == auxCert ) auxCert = auxCert.clone(); return auxCert; } /** * c: X509_LOOKUP_load_crl_file */ public int loadCRLFile(final String file, final int type) throws Exception { if ( file == null ) return 1; BufferedReader reader = null; try { InputStream in = wrapJRubyNormalizedInputStream(file); CRL crl; if ( type == X509_FILETYPE_PEM ) { reader = new BufferedReader(new InputStreamReader(in)); int count = 0; for (;;) { crl = PEMInputOutput.readX509CRL(reader, null); if ( crl == null ) break; if ( store.addCRL(crl) == 0 ) return 0; count++; } return count; } else if ( type == X509_FILETYPE_ASN1 ) { crl = SecurityHelper.getCertificateFactory("X.509").generateCRL(in); //if ( crl == null ) { // X509Error.addError(13); return 0; //} return store.addCRL(crl); } else { X509Error.addError(X509_R_BAD_X509_FILETYPE); return 0; // NOTE: really? } } finally { if ( reader != null ) { try { reader.close(); } catch (Exception ignored) {} } } } /** * c: X509_LOOKUP_load_cert_crl_file */ public int loadCertificateOrCRLFile(final String file, final int type) throws IOException, CertificateException { if ( type != X509_FILETYPE_PEM ) return loadCertificateFile(file, type); final Object[] cached = certCache.get(file); BufferedReader reader = null; try { int count = 0; if ( cached != null ) { for ( int c = 0; c < cached.length; c++ ) { Object cert = cached[c]; if ( cert instanceof X509Certificate ) { store.addCertificate(buildAuxFromCached((X509Certificate) cert)); count++; } else if ( cert instanceof CRL ) { store.addCRL((CRL) cert); count++; } } } else { reader = new BufferedReader(new InputStreamReader(wrapJRubyNormalizedInputStream(file))); final ArrayList cacheEntry = new ArrayList(8); for (;;) { Object cert = PEMInputOutput.readPEM(reader, null); if ( cert == null ) break; if ( cert instanceof X509Certificate ) { X509AuxCertificate auxCert = StoreContext.ensureAux((X509Certificate) cert); store.addCertificate(auxCert); count++; cert = auxCert.cloneForCache(); // make sure we cache aux } else if ( cert instanceof CRL ) { store.addCRL((CRL) cert); count++; } cacheEntry.add(cert); } certCache.put(file, cacheEntry.toArray( new Object[ cacheEntry.size() ] )); } return count; } finally { if ( reader != null ) { try { reader.close(); } catch (Exception ignored) {} } } } public int loadDefaultJavaCACertsFile(String certsFile) throws IOException, GeneralSecurityException { final FileInputStream fin = new FileInputStream(certsFile); int count = 0; try { // hardcode the keystore type, as we expect cacerts to be a java // keystore - especially needed for jdk9 KeyStore keystore = SecurityHelper.getKeyStore("jks"); // null password - as the cacerts file isn't password protected keystore.load(fin, null); PKIXParameters params = new PKIXParameters(keystore); for ( TrustAnchor trustAnchor : params.getTrustAnchors() ) { X509Certificate certificate = trustAnchor.getTrustedCert(); store.addCertificate(certificate); count++; } } finally { try { fin.close(); } catch (Exception ignored) {} } return count; } private InputStream wrapJRubyNormalizedInputStream(String file) throws IOException { try { return JRubyFile.createResource(runtime, file).inputStream(); } catch (NoSuchMethodError e) { // JRubyFile.createResource.inputStream (JRuby < 1.7.17) try { ChannelDescriptor descriptor = ChannelDescriptor.open(runtime.getCurrentDirectory(), file, new ModeFlags(ModeFlags.RDONLY)); return ChannelStream.open(runtime, descriptor).newInputStream(); } catch (NoSuchMethodError ex) { File f = new File(file); if ( ! f.isAbsolute() ) { f = new File(runtime.getCurrentDirectory(), file); } return new BufferedInputStream(new FileInputStream(f)); } catch (FileExistsException ex) { // should not happen because ModeFlag does not contain CREAT. OpenSSL.debugStackTrace(ex); throw new IllegalStateException(ex); } catch (InvalidValueException ex) { // should not happen because ModeFlasg does not contain APPEND. OpenSSL.debugStackTrace(ex); throw new IllegalStateException(ex); } } } private String envEntry(final String key) { RubyHash env = (RubyHash) runtime.getObject().getConstant("ENV"); return (String) env.get( runtime.newString(key) ); } /** * c: X509_LOOKUP_free */ public void free() throws Exception { if ( method != null && method.free != null && method.free != Function1.EMPTY ) { method.free.call(this); } } /** * c: X509_LOOKUP_init */ public int init() throws Exception { if ( method == null ) return 0; if ( method.init != null && method.init != Function1.EMPTY ) { return method.init.call(this); } return 1; } /** * c: X509_LOOKUP_by_subject */ public int bySubject(final int type, final Name name, final X509Object[] ret) throws Exception { if ( method == null || method.getBySubject == null || method.getBySubject == Function4.EMPTY ) { return X509_LU_FAIL; } if ( skip ) return 0; return method.getBySubject.call(this, Integer.valueOf(type), name, ret); } /** * c: X509_LOOKUP_by_issuer_serial */ public int byIssuerSerialNumber(final int type, final Name name, final BigInteger serial, final X509Object[] ret) throws Exception { if ( method == null || method.getByIssuerSerialNumber == null || method.getByIssuerSerialNumber == Function5.EMPTY ) { return X509_LU_FAIL; } return method.getByIssuerSerialNumber.call(this, Integer.valueOf(type), name, serial, ret); } /** * c: X509_LOOKUP_by_fingerprint */ public int byFingerprint(final int type, final String bytes, final X509Object[] ret) throws Exception { if ( method == null || method.getByFingerprint == null || method.getByFingerprint == Function4.EMPTY ) { return X509_LU_FAIL; } return method.getByFingerprint.call(this, Integer.valueOf(type), bytes, ret); } /** * c: X509_LOOKUP_by_alias */ public int byAlias(final int type, final String alias, final X509Object[] ret) throws Exception { if ( method == null || method.getByAlias == null || method.getByAlias == Function4.EMPTY ) { return X509_LU_FAIL; } return method.getByAlias.call(this, Integer.valueOf(type), alias, ret); } /** * c: X509_LOOKUP_shutdown */ public int shutdown() throws Exception { if ( method == null ) return 0; if ( method.shutdown != null && method.shutdown != Function1.EMPTY ) { return method.shutdown.call(this); } return 1; } /** * c: x509_file_lookup */ private final static LookupMethod x509FileLookup = new LookupMethod(); static { x509FileLookup.name = "Load file into cache"; x509FileLookup.control = new ByFile(); } /** * c: x509_dir_lookup */ private final static LookupMethod x509DirectoryLookup = new LookupMethod(); static { x509DirectoryLookup.name = "Load certs from files in a directory"; x509DirectoryLookup.newItem = new NewLookupDir(); x509DirectoryLookup.free = new FreeLookupDir(); x509DirectoryLookup.control = new LookupDirControl(); x509DirectoryLookup.getBySubject = new GetCertificateBySubject(); } /** * c: by_file_ctrl */ private static class ByFile implements LookupMethod.ControlFunction { public int call(final Lookup ctx, final Integer cmd, final String argp, final Number argl, String[] ret) throws Exception { int ok = 0; String file = null; final int arglInt = argl.intValue(); switch(cmd) { case X509_L_FILE_LOAD: if (arglInt == X509_FILETYPE_DEFAULT) { try { file = ctx.envEntry( getDefaultCertificateFileEnvironment() ); // ENV['SSL_CERT_FILE'] } catch (RuntimeException e) { OpenSSL.debug(ctx.runtime, "failed to read SSL_CERT_FILE", e); } if (file == null) { file = X509Utils.X509_CERT_FILE.replace('/', File.separatorChar); } if (file.matches(".*\\.(crt|cer|pem)$")) { ok = ctx.loadCertificateOrCRLFile(file, X509_FILETYPE_PEM) != 0 ? 1 : 0; } else { ok = (ctx.loadDefaultJavaCACertsFile(file) != 0) ? 1: 0; } // we ignore errors on loading default paths the same way MRI does it } else { if (arglInt == X509_FILETYPE_PEM) { ok = (ctx.loadCertificateOrCRLFile(argp, X509_FILETYPE_PEM) != 0) ? 1 : 0; } else { ok = (ctx.loadCertificateFile(argp, arglInt) != 0) ? 1 : 0; } } break; } return ok; } } /** * c: BY_DIR, lookup_dir_st */ private static class LookupDir { Collection dirs; Collection dirsType; } /** * c: new_dir */ private static class NewLookupDir implements LookupMethod.NewItemFunction { public int call(final Lookup lookup) { final LookupDir lookupDir = new LookupDir(); lookupDir.dirs = new ArrayList(); lookupDir.dirsType = new ArrayList(); lookup.methodData = lookupDir; return 1; } } /** * c: free_dir */ private static class FreeLookupDir implements LookupMethod.FreeFunction { public int call(final Lookup lookup) { final LookupDir lookupDir = (LookupDir) lookup.methodData; lookupDir.dirs = null; lookupDir.dirsType = null; lookup.methodData = null; return -1; } } /** * c: dir_ctrl */ private static class LookupDirControl implements LookupMethod.ControlFunction { public int call(final Lookup ctx, final Integer cmd, String argp, Number argl, String[] retp) { int ret = 0; final LookupDir lookupData = (LookupDir) ctx.methodData; switch ( cmd ) { case X509_L_ADD_DIR : if ( argl.intValue() == X509_FILETYPE_DEFAULT ) { String certDir = null; try { certDir = getDefaultCertificateDirectory(ctx); } catch (RuntimeException e) { } if ( certDir != null ) { ret = addCertificateDirectory(lookupData, certDir, X509_FILETYPE_PEM); } else { ret = addCertificateDirectory(lookupData, X509_CERT_DIR, X509_FILETYPE_PEM); } if ( ret == 0 ) { X509Error.addError(X509_R_LOADING_CERT_DIR); } } else { ret = addCertificateDirectory(lookupData, argp, argl.intValue()); } break; } return ret; } private static String getDefaultCertificateDirectory(final Lookup ctx) { return ctx.envEntry( getDefaultCertificateDirectoryEnvironment() ); } /** * c: add_cert_dir */ private int addCertificateDirectory(final LookupDir ctx, final String dir, final int type) { if ( dir == null || dir.isEmpty() ) { X509Error.addError(X509_R_INVALID_DIRECTORY); return 0; } String[] dirs = dir.split(File.pathSeparator); for ( int i=0; i iter = context.dirsType.iterator(); for ( final String dir : context.dirs ) { final int dirType = iter.next(); for ( int k = 0; ; k++ ) { buffer.setLength(0); // reset - clear buffer buffer.append(dir).append(File.separatorChar); buffer.append(hash); buffer.append('.').append(postfix).append(k); final String path = buffer.toString(); if ( ! new File(path).exists() ) break; if ( type == X509_LU_X509 ) { if ( lookup.loadCertificateFile(path, dirType) == 0 ) { break; } } else if ( type == X509_LU_CRL ) { if ( lookup.loadCRLFile(path, dirType) == 0 ) { break; } } } X509Object tmp = null; for ( X509Object obj : lookup.store.getObjects() ) { if ( obj.type() == type && obj.isName(name) ) { tmp = obj; break; } } if ( tmp != null ) { ok = 1; ret[0] = tmp; break; } } return ok; } } }// X509_LOOKUP jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/LookupMethod.java000066400000000000000000000060551313661621600303320ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.math.BigInteger; /** * x509_lookup_method_st and X509_LOOKUP_METHOD in x509_vfy.h * * @author Ola Bini */ public class LookupMethod { public String name; interface NewItemFunction extends Function1 {} interface FreeFunction extends Function1 {} interface InitFunction extends Function1 {} interface ShutdownFunction extends Function1 {} interface ControlFunction extends Function5 {} interface BySubjectFunction extends Function4 {} interface ByIssuerSerialNumberFunction extends Function5 {} interface ByFingerprintFunction extends Function4 {} interface ByAliasFunction extends Function4 {} /** * c: new_item */ NewItemFunction newItem; /** * c: free */ FreeFunction free; /** * c: init */ InitFunction init; /** * c: shutdown */ ShutdownFunction shutdown; /** * c: ctrl */ ControlFunction control; /** * c: get_by_subject */ BySubjectFunction getBySubject; /** * c: get_by_issuer_serial */ ByIssuerSerialNumberFunction getByIssuerSerialNumber; /** * c: get_by_fingerprint */ ByFingerprintFunction getByFingerprint; /** * c: get_by_alias */ ByAliasFunction getByAlias; }// X509_LOOKUP_METHOD jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Name.java000066400000000000000000000114321313661621600265730ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; import java.security.cert.X509Certificate; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.jce.provider.X509CertificateObject; import org.jruby.ext.openssl.SecurityHelper; /** * c: X509_NAME * * @author Ola Bini */ public class Name { final X500Name name; public Name(final X500Principal principal) { this.name = X500Name.getInstance( principal.getEncoded() ); } public Name(final X500Name name) { this.name = name; } public static int hash(final X500Name name) throws IOException { try { final byte[] bytes = name.getEncoded(); MessageDigest md5 = SecurityHelper.getMessageDigest("MD5"); final byte[] digest = md5.digest(bytes); int result = 0; result |= digest[3] & 0xff; result <<= 8; result |= digest[2] & 0xff; result <<= 8; result |= digest[1] & 0xff; result <<= 8; result |= digest[0] & 0xff; return result & 0xffffffff; } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } private transient int hash = 0; public final int hash() { try { return hash == 0 ? hash = hash(name) : hash; } catch (IOException e) { return 0; } catch (RuntimeException e) { return 0; } } /** * c: X509_NAME_hash */ @Override public int hashCode() { return hash(); } @Override public boolean equals(final Object that) { //if ( that instanceof X500Principal ) { // return equals( (X500Principal) that ); //} if ( that instanceof Name ) { return this.name.equals( ((Name) that).name ); } return false; } public boolean equalTo(final X500Name name) { return this.name.equals(name); } @SuppressWarnings("deprecation") final boolean equalTo(final Principal principal) { // assuming "legacy" non X500Principal impl (from BC) return new X509Principal(this.name).equals(principal); } public boolean equalTo(final X500Principal principal) { try { return new X500Principal(this.name.getEncoded(ASN1Encoding.DER)).equals(principal); } catch (IOException e) { return false; } } public final boolean equalToCertificateSubject(final X509AuxCertificate wrapper) { // on Oracle/OpenJDK internal certificates: sun.security.x509.X509CertImpl // BC: class org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject final X509Certificate cert = wrapper.cert; if ( cert == null ) return equalTo( wrapper.getSubjectX500Principal() ); if ( cert instanceof X509CertificateObject ) { return equalTo( cert.getSubjectDN() ); } // otherwise need to take the 'expensive' path : return equalTo( cert.getSubjectX500Principal() ); } }// X509_NAME jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java000066400000000000000000001764421313661621600306120ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * Copyright (C) 2007 William N Dortch * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.io.IOException; import java.io.Writer; import java.io.BufferedWriter; import java.io.BufferedReader; import java.io.Reader; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.CRLException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.cert.X509CRL; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.ECPrivateKey; import java.security.interfaces.ECPublicKey; import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.spec.ECParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.PBEParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.pkcs.PKCS12PBEParams; import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Object; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERUTF8String; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.pkcs.EncryptionScheme; import org.bouncycastle.asn1.pkcs.PBES2Parameters; import org.bouncycastle.asn1.pkcs.PBKDF2Params; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.pkcs.RC2CBCParameter; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.DSAParameter; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cms.CMSException; import org.bouncycastle.crypto.BufferedBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.PBEParametersGenerator; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.RC2Engine; import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.cms.CMSSignedData; import org.jruby.ext.openssl.Cipher.Algorithm; import org.jruby.ext.openssl.impl.ASN1Registry; import org.jruby.ext.openssl.impl.CipherSpec; import org.jruby.ext.openssl.impl.PKCS10Request; import org.jruby.ext.openssl.SecurityHelper; import org.jruby.ext.openssl.util.ByteArrayOutputStream; /** * Helper class to read and write PEM files correctly. * * @author Ola Bini */ public class PEMInputOutput { public static final String BEF = "-----"; public static final String AFT = "-----"; public static final String BEF_G = BEF + "BEGIN "; public static final String BEF_E = BEF + "END "; public static final String PEM_STRING_X509_OLD="X509 CERTIFICATE"; public static final String PEM_STRING_X509="CERTIFICATE"; public static final String PEM_STRING_X509_PAIR="CERTIFICATE PAIR"; public static final String PEM_STRING_X509_TRUSTED="TRUSTED CERTIFICATE"; public static final String PEM_STRING_X509_REQ_OLD="NEW CERTIFICATE REQUEST"; public static final String PEM_STRING_X509_REQ="CERTIFICATE REQUEST"; public static final String PEM_STRING_X509_CRL="X509 CRL"; public static final String PEM_STRING_EVP_PKEY="ANY PRIVATE KEY"; public static final String PEM_STRING_PUBLIC="PUBLIC KEY"; public static final String PEM_STRING_RSA="RSA PRIVATE KEY"; public static final String PEM_STRING_RSA_PUBLIC="RSA PUBLIC KEY"; public static final String PEM_STRING_DSA="DSA PRIVATE KEY"; public static final String PEM_STRING_DSA_PUBLIC="DSA PUBLIC KEY"; public static final String PEM_STRING_PKCS7="PKCS7"; public static final String PEM_STRING_PKCS8="ENCRYPTED PRIVATE KEY"; public static final String PEM_STRING_PKCS8INF="PRIVATE KEY"; public static final String PEM_STRING_DHPARAMS="DH PARAMETERS"; public static final String PEM_STRING_SSL_SESSION="SSL SESSION PARAMETERS"; public static final String PEM_STRING_DSAPARAMS="DSA PARAMETERS"; public static final String PEM_STRING_ECDSA_PUBLIC="ECDSA PUBLIC KEY"; public static final String PEM_STRING_ECPARAMETERS="EC PARAMETERS"; public static final String PEM_STRING_ECPRIVATEKEY="EC PRIVATE KEY"; private static final String BEG_STRING_PUBLIC = BEF_G + PEM_STRING_PUBLIC; private static final String BEG_STRING_DSA = BEF_G + PEM_STRING_DSA; private static final String BEG_STRING_RSA = BEF_G + PEM_STRING_RSA; private static final String BEG_STRING_RSA_PUBLIC = BEF_G + PEM_STRING_RSA_PUBLIC; private static final String BEG_STRING_X509_OLD = BEF_G + PEM_STRING_X509_OLD; private static final String BEG_STRING_X509 = BEF_G + PEM_STRING_X509; private static final String BEG_STRING_X509_TRUSTED = BEF_G + PEM_STRING_X509_TRUSTED; private static final String BEG_STRING_X509_CRL = BEF_G + PEM_STRING_X509_CRL; private static final String BEG_STRING_X509_REQ = BEF_G + PEM_STRING_X509_REQ; private static BufferedReader makeBuffered(Reader in) { if (in instanceof BufferedReader) { return (BufferedReader) in; } return new BufferedReader(in); } private static BufferedWriter makeBuffered(Writer out) { if (out instanceof BufferedWriter) { return (BufferedWriter) out; } return new BufferedWriter(out); } /** * @deprecated Prefer passing in a buffered-reader esp. in loops as the * method might return a X.509 object before reading the full PEM file ! */ public static Object readPEM(final Reader in, final char[] passwd) throws IOException { return readPEM(makeBuffered(in), passwd); } /** * c: PEM_X509_INFO_read_bio */ public static Object readPEM(final BufferedReader reader, final char[] passwd) throws IOException { String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_PUBLIC) != -1 ) { try { return readPublicKey(reader,BEF_E+PEM_STRING_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating public key: ", e); } } else if ( line.indexOf(BEG_STRING_DSA) != -1 ) { try { return readKeyPair(reader,passwd, "DSA", BEF_E+PEM_STRING_DSA); } catch (Exception e) { throw mapReadException("problem creating DSA private key: ", e); } } else if ( line.indexOf(BEG_STRING_RSA_PUBLIC) != -1 ) { try { return readPublicKey(reader,BEF_E+PEM_STRING_RSA_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating RSA public key: ", e); } } else if ( line.indexOf(BEG_STRING_X509_OLD) != -1 ) { try { return readAuxCertificate(reader,BEF_E+PEM_STRING_X509_OLD); } catch (Exception e) { throw new IOException("problem creating X509 Aux certificate: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509) != -1 ) { try { return readAuxCertificate(reader,BEF_E+PEM_STRING_X509); } catch (Exception e) { throw new IOException("problem creating X509 Aux certificate: " + e.toString(), e); } } else if( line.indexOf(BEG_STRING_X509_TRUSTED) != -1 ) { try { return readAuxCertificate(reader,BEF_E+PEM_STRING_X509_TRUSTED); } catch (Exception e) { throw new IOException("problem creating X509 Aux certificate: " + e.toString(), e); } } else if( line.indexOf(BEG_STRING_X509_CRL) != -1 ) { try { return readCRL(reader,BEF_E+PEM_STRING_X509_CRL); } catch (Exception e) { throw new IOException("problem creating X509 CRL: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509_REQ) != -1 ) { try { return readCertificateRequest(reader,BEF_E+PEM_STRING_X509_REQ); } catch (Exception e) { throw new IOException("problem creating X509 REQ: " + e.toString(), e); } } } return null; } public static byte[] readX509PEM(final Reader in) throws IOException { final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_X509_OLD) != -1 ) { try { return readBase64Bytes(reader, BEF_E + PEM_STRING_X509_OLD); } catch (Exception e) { throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509) != -1 ) { try { return readBase64Bytes(reader, BEF_E + PEM_STRING_X509); } catch (Exception e) { throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509_TRUSTED) != -1 ) { try { return readBase64Bytes(reader, BEF_E + PEM_STRING_X509_TRUSTED); } catch (Exception e) { throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509_CRL) != -1 ) { try { return readBase64Bytes(reader, BEF_E + PEM_STRING_X509_CRL); } catch (Exception e) { throw new IOException("problem reading PEM X509 CRL: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509_REQ) != -1 ) { try { return readBase64Bytes(reader, BEF_E + PEM_STRING_X509_REQ); } catch (Exception e) { throw new IOException("problem reading PEM X509 REQ: " + e.toString(), e); } } } return null; } /** * c: PEM_read_PrivateKey + PEM_read_bio_PrivateKey * CAUTION: KeyPair#getPublic() may be null. */ public static KeyPair readPrivateKey(final Reader in, char[] passwd) throws PasswordRequiredException, IOException { final String BEG_STRING_ECPRIVATEKEY = BEF_G + PEM_STRING_ECPRIVATEKEY; final String BEG_STRING_PKCS8INF = BEF_G + PEM_STRING_PKCS8INF; final String BEG_STRING_PKCS8 = BEF_G + PEM_STRING_PKCS8; final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_RSA) != -1 ) { try { return readKeyPair(reader, passwd, "RSA", BEF_E + PEM_STRING_RSA); } catch (Exception e) { throw mapReadException("problem creating RSA private key: ", e); } } else if ( line.indexOf(BEG_STRING_DSA) != -1 ) { try { return readKeyPair(reader, passwd, "DSA", BEF_E + PEM_STRING_DSA); } catch (Exception e) { throw mapReadException("problem creating DSA private key: ", e); } } else if ( line.indexOf(BEG_STRING_ECPRIVATEKEY) != -1) { try { return readKeyPair(reader, passwd, "ECDSA", BEF_E + PEM_STRING_ECPRIVATEKEY); } catch (Exception e) { throw mapReadException("problem creating DSA private key: ", e); } } else if ( line.indexOf(BEG_STRING_PKCS8INF) != -1) { try { byte[] bytes = readBase64Bytes(reader, BEF_E + PEM_STRING_PKCS8INF); PrivateKeyInfo info = PrivateKeyInfo.getInstance(bytes); String type = getPrivateKeyTypeFromObjectId(info.getPrivateKeyAlgorithm().getAlgorithm()); return org.jruby.ext.openssl.impl.PKey.readPrivateKey(((ASN1Object) info.parsePrivateKey()).getEncoded(ASN1Encoding.DER), type); } catch (Exception e) { throw mapReadException("problem creating private key: ", e); } } else if ( line.indexOf(BEG_STRING_PKCS8) != -1 ) { try { byte[] bytes = readBase64Bytes(reader, BEF_E + PEM_STRING_PKCS8); EncryptedPrivateKeyInfo eIn = EncryptedPrivateKeyInfo.getInstance(bytes); AlgorithmIdentifier algId = eIn.getEncryptionAlgorithm(); PrivateKey privKey; if (algId.getAlgorithm().toString().equals("1.2.840.113549.1.5.13")) { // PBES2 privKey = derivePrivateKeyPBES2(eIn, algId, passwd); } else { privKey = derivePrivateKeyPBES1(eIn, algId, passwd); } return new KeyPair(null, privKey); } catch (Exception e) { throw mapReadException("problem creating private key: ", e); } } } return null; } private static IOException mapReadException(final String message, final Exception ex) { if ( ex instanceof PasswordRequiredException ) { return (PasswordRequiredException) ex; } return new IOException(message + ex, ex); } private static PrivateKey derivePrivateKeyPBES1(EncryptedPrivateKeyInfo eIn, AlgorithmIdentifier algId, char[] password) throws GeneralSecurityException, IOException { // From BC's PEMReader PKCS12PBEParams pkcs12Params = PKCS12PBEParams.getInstance(algId.getParameters()); PBEKeySpec pbeSpec = new PBEKeySpec(password); PBEParameterSpec pbeParams = new PBEParameterSpec( pkcs12Params.getIV(), pkcs12Params.getIterations().intValue() ); String algorithm = ASN1Registry.o2a(algId.getAlgorithm()); algorithm = (algorithm.split("-"))[0]; SecretKeyFactory secKeyFactory = SecurityHelper.getSecretKeyFactory(algorithm); Cipher cipher = SecurityHelper.getCipher(algorithm); cipher.init(Cipher.DECRYPT_MODE, secKeyFactory.generateSecret(pbeSpec), pbeParams); PrivateKeyInfo pInfo = PrivateKeyInfo.getInstance( ASN1Primitive.fromByteArray(cipher.doFinal(eIn.getEncryptedData())) ); KeyFactory keyFactory = getKeyFactory( pInfo.getPrivateKeyAlgorithm() ); return keyFactory.generatePrivate( new PKCS8EncodedKeySpec( pInfo.getEncoded() ) ); } private static PrivateKey derivePrivateKeyPBES2(EncryptedPrivateKeyInfo eIn, AlgorithmIdentifier algId, char[] password) throws GeneralSecurityException, InvalidCipherTextException { PBES2Parameters pbeParams = PBES2Parameters.getInstance((ASN1Sequence) algId.getParameters()); CipherParameters cipherParams = extractPBES2CipherParams(password, pbeParams); EncryptionScheme scheme = pbeParams.getEncryptionScheme(); BufferedBlockCipher cipher; if ( scheme.getAlgorithm().equals( PKCSObjectIdentifiers.RC2_CBC ) ) { RC2CBCParameter rc2Params = RC2CBCParameter.getInstance(scheme); byte[] iv = rc2Params.getIV(); CipherParameters param = new ParametersWithIV(cipherParams, iv); cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RC2Engine())); cipher.init(false, param); } else { byte[] iv = ASN1OctetString.getInstance( scheme.getParameters() ).getOctets(); CipherParameters param = new ParametersWithIV(cipherParams, iv); cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine())); cipher.init(false, param); } byte[] data = eIn.getEncryptedData(); byte[] out = new byte[cipher.getOutputSize(data.length)]; int len = cipher.processBytes(data, 0, data.length, out, 0); len += cipher.doFinal(out, len); byte[] pkcs8 = new byte[len]; System.arraycopy(out, 0, pkcs8, 0, len); KeyFactory fact = SecurityHelper.getKeyFactory("RSA"); // It seems to work for both RSA and DSA. return fact.generatePrivate( new PKCS8EncodedKeySpec(pkcs8) ); } private static CipherParameters extractPBES2CipherParams(char[] password, PBES2Parameters pbeParams) { PBKDF2Params pbkdfParams = PBKDF2Params.getInstance(pbeParams.getKeyDerivationFunc().getParameters()); int keySize = 192; if (pbkdfParams.getKeyLength() != null) { keySize = pbkdfParams.getKeyLength().intValue() * 8; } int iterationCount = pbkdfParams.getIterationCount().intValue(); byte[] salt = pbkdfParams.getSalt(); PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount); return generator.generateDerivedParameters(keySize); } // PEM_read_bio_PUBKEY public static PublicKey readPubKey(Reader in) throws IOException { PublicKey pubKey = readRSAPubKey(in); if (pubKey == null) pubKey = readDSAPubKey(in); if (pubKey == null) pubKey = readECPubKey(in); return pubKey; } /* * c: PEM_read_bio_DSA_PUBKEY */ public static DSAPublicKey readDSAPubKey(Reader in) throws IOException { final String BEG_STRING_DSA_PUBLIC = BEF_G + PEM_STRING_DSA_PUBLIC; final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_DSA_PUBLIC) != -1 ) { try { return (DSAPublicKey) readPublicKey(reader, "DSA", BEF_E + PEM_STRING_DSA_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating DSA public key: ", e); } } } return null; } /* * c: PEM_read_bio_DSAPublicKey */ public static DSAPublicKey readDSAPublicKey(final Reader in, final char[] passwd) throws IOException { final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_PUBLIC) != -1 ) { try { return (DSAPublicKey) readPublicKey(reader, "DSA", BEF_E + PEM_STRING_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating DSA public key: ", e); } } } return null; } /* * c: PEM_read_bio_DSAPrivateKey */ public static KeyPair readDSAPrivateKey(final Reader in, final char[] passwd) throws PasswordRequiredException, IOException { final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_DSA) != -1 ) { try { return readKeyPair(reader, passwd, "DSA", BEF_E + PEM_STRING_DSA); } catch (Exception e) { throw mapReadException("problem creating DSA private key: ", e); } } } return null; } /** * reads an RSA public key encoded in an SubjectPublicKeyInfo RSA structure. * c: PEM_read_bio_RSA_PUBKEY */ public static RSAPublicKey readRSAPubKey(Reader in) throws IOException { final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_PUBLIC) != -1 ) { try { return readRSAPublicKey(reader, BEF_E + PEM_STRING_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating RSA public key: ", e); } } else if ( line.indexOf(BEG_STRING_RSA_PUBLIC) != -1 ) { try { return readRSAPublicKey(reader, BEF_E + PEM_STRING_RSA_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating RSA public key: ", e); } } } return null; } /** * reads an RSA public key encoded in an PKCS#1 RSA structure. * c: PEM_read_bio_RSAPublicKey */ public static RSAPublicKey readRSAPublicKey(Reader in, char[] f) throws PasswordRequiredException, IOException { final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_PUBLIC) != -1 ) { try { return (RSAPublicKey) readPublicKey(reader, "RSA", BEF_E + PEM_STRING_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating RSA public key: ", e); } } else if ( line.indexOf(BEF_G+PEM_STRING_RSA_PUBLIC) != -1 ) { try { return (RSAPublicKey) readPublicKey(reader, "RSA", BEF_E + PEM_STRING_RSA_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating RSA public key: ", e); } } } return null; } /** * c: PEM_read_bio_RSAPrivateKey */ public static KeyPair readRSAPrivateKey(Reader in, char[] f) throws PasswordRequiredException, IOException { final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_RSA) != -1 ) { try { return readKeyPair(reader,f, "RSA", BEF_E + PEM_STRING_RSA); } catch (Exception e) { throw mapReadException("problem creating RSA private key: ", e); } } } return null; } public static ECPublicKey readECPubKey(Reader in) throws IOException { final String BEG_STRING_EC_PUBLIC = BEF_G + "EC PUBLIC KEY"; final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_EC_PUBLIC) != -1 ) { try { return (ECPublicKey) readPublicKey(reader, "ECDSA", BEF_E + "EC PUBLIC KEY"); } catch (Exception e) { throw mapReadException("problem creating ECDSA public key: ", e); } } } return null; } public static ECPublicKey readECPublicKey(final Reader in, final char[] passwd) throws IOException { // final String BEG_STRING_EC = BEF_G + "EC PUBLIC KEY"; final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_PUBLIC) != -1 ) { try { return (ECPublicKey) readPublicKey(reader, "ECDSA", BEF_E + PEM_STRING_PUBLIC); } catch (Exception e) { throw mapReadException("problem creating ECDSA public key: ", e); } } } return null; } public static KeyPair readECPrivateKey(final Reader in, final char[] passwd) throws PasswordRequiredException, IOException { final String BEG_STRING_EC = BEF_G + "EC PRIVATE KEY"; final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_EC) != -1 ) { try { return readKeyPair(reader, passwd, "ECDSA", BEF_E + "EC PRIVATE KEY"); } catch (Exception e) { throw mapReadException("problem creating ECDSA private key: ", e); } } } return null; } public static CMSSignedData readPKCS7(Reader in, char[] f) throws IOException { final String BEG_STRING_PKCS7 = BEF_G + PEM_STRING_PKCS7; final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_PKCS7) != -1 ) { try { return readPKCS7(reader,f, BEF_E + PEM_STRING_PKCS7); } catch (Exception e) { throw new IOException("problem creating PKCS7: " + e.toString(), e); } } } return null; } /** * @deprecated Prefer passing in a buffered-reader esp. in loops as the * method might return a X.509 object before reading the full PEM file ! */ public static X509AuxCertificate readX509Certificate(final Reader in, final char[] passwd) throws IOException { return readX509Certificate(makeBuffered(in), passwd); } public static X509AuxCertificate readX509Certificate(final BufferedReader reader, final char[] passwd) throws IOException { String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_X509_OLD) != -1 ) { try { return new X509AuxCertificate(readCertificate(reader,BEF_E+PEM_STRING_X509_OLD)); } catch (Exception e) { throw new IOException("problem creating X509 certificate: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509) != -1 ) { try { return new X509AuxCertificate(readCertificate(reader,BEF_E+PEM_STRING_X509)); } catch (Exception e) { throw new IOException("problem creating X509 certificate: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509_TRUSTED) != -1 ) { try { return new X509AuxCertificate(readCertificate(reader,BEF_E+PEM_STRING_X509_TRUSTED)); } catch (Exception e) { throw new IOException("problem creating X509 certificate: " + e.toString(), e); } } } return null; } /** * @deprecated Prefer passing in a buffered-reader esp. in loops as the * method might return a X.509 object before reading the full PEM file ! */ public static X509AuxCertificate readX509Aux(final Reader in, final char[] passwd) throws IOException { return readX509Aux(makeBuffered(in), passwd); } public static X509AuxCertificate readX509Aux(final BufferedReader reader, final char[] passwd) throws IOException { String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_X509_OLD) != -1 ) { try { return readAuxCertificate(reader, BEF_E + PEM_STRING_X509_OLD); } catch (Exception e) { throw new IOException("problem creating X509 Aux certificate: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509) != -1 ) { try { return readAuxCertificate(reader, BEF_E + PEM_STRING_X509); } catch (Exception e) { throw new IOException("problem creating X509 Aux certificate: " + e.toString(), e); } } else if ( line.indexOf(BEG_STRING_X509_TRUSTED) != -1 ) { try { return readAuxCertificate(reader, BEF_E + PEM_STRING_X509_TRUSTED); } catch (Exception e) { throw new IOException("problem creating X509 Aux certificate: " + e.toString(), e); } } } return null; } /** * @deprecated Prefer passing in a buffered-reader esp. in loops as the * method might return a X.509 object before reading the full PEM file ! */ public static X509CRL readX509CRL(final Reader reader, final char[] passwd) throws IOException { return readX509CRL(makeBuffered(reader), passwd); } public static X509CRL readX509CRL(final BufferedReader reader, final char[] passwd) throws IOException { String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_X509_CRL) != -1 ) { try { return readCRL(reader, BEF_E + PEM_STRING_X509_CRL); } catch (Exception e) { throw new IOException("problem creating X509 CRL: " + e.toString(), e); } } } return null; } public static PKCS10Request readX509Request(final Reader in, final char[] passwd) throws IOException { final BufferedReader reader = makeBuffered(in); String line; while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_X509_REQ) != -1 ) { try { return readCertificateRequest(reader, BEF_E + PEM_STRING_X509_REQ); } catch (Exception e) { throw new IOException("problem creating X509 REQ: " + e.toString(), e); } } } return null; } public static DHParameterSpec readDHParameters(final Reader in) throws IOException { final String BEG_STRING_DHPARAMS = BEF_G + PEM_STRING_DHPARAMS; final BufferedReader reader = makeBuffered(in); String line; final StringBuilder lines = new StringBuilder(); while ( ( line = reader.readLine() ) != null ) { if ( line.indexOf(BEG_STRING_DHPARAMS) >= 0 ) { final String endParams = BEF_E + PEM_STRING_DHPARAMS; do { lines.append(line.trim()); } while ( line.indexOf(endParams) < 0 && ( line = reader.readLine() ) != null ); break; } } final Pattern DH_PARAMS_PATTERN = Pattern.compile( "(-----BEGIN DH PARAMETERS-----)(.*)(-----END DH PARAMETERS-----)", Pattern.MULTILINE); final int DH_PARAMS_GROUP = 2; // the group above containing encoded params final Matcher matcher = DH_PARAMS_PATTERN.matcher( lines.toString() ); if ( matcher.find() ) { try { byte[] decoded = Base64.decode(matcher.group(DH_PARAMS_GROUP)); return org.jruby.ext.openssl.impl.PKey.readDHParameter(decoded); } catch (IOException e) { // TODO } } return null; } private static byte[] getEncoded(java.security.Key key) { if ( key == null ) return new byte[] { '0', 0 }; return key.getEncoded(); } private static byte[] getEncoded(ASN1Encodable obj) throws IOException { if ( obj == null ) return new byte[] { '0', 0 }; return obj.toASN1Primitive().getEncoded(); } private static byte[] getEncoded(CMSSignedData obj) throws IOException { if ( obj == null ) return new byte[] { '0', 0 }; return obj.getEncoded(); } private static byte[] getEncoded(X509Certificate cert) throws IOException { if ( cert == null ) return new byte[] { '0', 0 }; try { return cert.getEncoded(); } catch (GeneralSecurityException e) { throw new IOException("problem with encoding object in write_X509", e); } } private static byte[] getEncoded(X509CRL crl) throws IOException { if ( crl == null ) return new byte[] { '0', 0 }; try { return crl.getEncoded(); } catch (GeneralSecurityException e) { throw new IOException("problem with encoding object in write_X509_CRL", e); } } public static void writeDSAPublicKey(Writer _out, DSAPublicKey obj) throws IOException { BufferedWriter out = makeBuffered(_out); final byte[] enc = getEncoded(obj); out.write(BEF_G + PEM_STRING_PUBLIC + AFT); out.newLine(); writeEncoded(out, enc, enc.length); out.write(BEF_E + PEM_STRING_PUBLIC + AFT); out.newLine(); out.flush(); } /** writes an RSA public key encoded in an PKCS#1 RSA structure. */ public static void writeRSAPublicKey(Writer _out, RSAPublicKey obj) throws IOException { BufferedWriter out = makeBuffered(_out); final byte[] enc = getEncoded(obj); out.write(BEF_G + PEM_STRING_PUBLIC + AFT); out.newLine(); writeEncoded(out, enc, enc.length); out.write(BEF_E + PEM_STRING_PUBLIC + AFT); out.newLine(); out.flush(); } public static void writeECPublicKey(Writer _out, ECPublicKey obj) throws IOException { BufferedWriter out = makeBuffered(_out); final byte[] enc = getEncoded(obj); out.write(BEF_G); out.write(PEM_STRING_PUBLIC); out.write(AFT); out.newLine(); writeEncoded(out, enc, enc.length); out.write(BEF_E); out.write(PEM_STRING_PUBLIC); out.write(AFT); out.newLine(); out.flush(); } public static void writePKCS7(Writer _out, ContentInfo obj) throws IOException { BufferedWriter out = makeBuffered(_out); final byte[] enc = getEncoded(obj); out.write(BEF_G + PEM_STRING_PKCS7 + AFT); out.newLine(); writeEncoded(out, enc, enc.length); out.write(BEF_E + PEM_STRING_PKCS7 + AFT); out.newLine(); out.flush(); } public static void writePKCS7(Writer _out, CMSSignedData obj) throws IOException { BufferedWriter out = makeBuffered(_out); final byte[] enc = getEncoded(obj); out.write(BEF_G + PEM_STRING_PKCS7 + AFT); out.newLine(); writeEncoded(out, enc, enc.length); out.write(BEF_E + PEM_STRING_PKCS7 + AFT); out.newLine(); out.flush(); } public static void writePKCS7(final Writer _out, final byte[] enc) throws IOException { BufferedWriter out = makeBuffered(_out); out.write(BEF_G + PEM_STRING_PKCS7 + AFT); out.newLine(); writeEncoded(out, enc, enc.length); out.write(BEF_E + PEM_STRING_PKCS7 + AFT); out.newLine(); out.flush(); } public static void writeX509Certificate(final Writer _out, final X509Certificate cert) throws IOException { BufferedWriter out = makeBuffered(_out); final byte[] enc = getEncoded(cert); out.write(BEF_G + PEM_STRING_X509 + AFT); out.newLine(); writeEncoded(out, enc, enc.length); out.write(BEF_E + PEM_STRING_X509 + AFT); out.newLine(); out.flush(); } public static void writeX509Aux(final Writer _out, final X509AuxCertificate cert) throws IOException { BufferedWriter out = makeBuffered(_out); final byte[] encoding; final int encLen; try { if ( cert.aux == null ) { encoding = cert.getEncoded(); encLen = encoding.length; } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] enc = cert.getEncoded(); baos.write(enc, 0, enc.length); final X509Aux aux = cert.aux; ASN1EncodableVector a1 = new ASN1EncodableVector(); if ( aux.trust.size() > 0 ) { ASN1EncodableVector a2 = new ASN1EncodableVector(); for ( String trust : aux.trust ) { a2.add(new ASN1ObjectIdentifier(trust)); } a1.add(new DLSequence(a2)); } if ( aux.reject.size() > 0 ) { ASN1EncodableVector a2 = new ASN1EncodableVector(); for ( String reject : aux.reject ) { a2.add(new ASN1ObjectIdentifier(reject)); } a1.add(new DERTaggedObject(0,new DLSequence(a2))); } if ( aux.alias != null ) { a1.add(new DERUTF8String(aux.alias)); } if ( aux.keyid != null ) { a1.add(new DEROctetString(aux.keyid)); } if ( aux.other.size() > 0 ) { ASN1EncodableVector a2 = new ASN1EncodableVector(); for ( ASN1Primitive other : aux.other ) a2.add(other); a1.add( new DERTaggedObject( 1, new DLSequence(a2) ) ); } enc = new DLSequence(a1).getEncoded(); baos.write(enc, 0, enc.length); encoding = baos.buffer(); encLen = baos.size(); } } catch (CertificateEncodingException e) { throw new IOException("problem with encoding object in write_X509_AUX", e); } out.write(BEF_G + PEM_STRING_X509_TRUSTED + AFT); out.newLine(); writeEncoded(out, encoding, encLen); out.write(BEF_E + PEM_STRING_X509_TRUSTED + AFT); out.newLine(); out.flush(); } public static void writeX509CRL(Writer _out, X509CRL obj) throws IOException { BufferedWriter out = makeBuffered(_out); byte[] encoding = getEncoded(obj); out.write(BEF_G + PEM_STRING_X509_CRL + AFT); out.newLine(); writeEncoded(out, encoding, encoding.length); out.write(BEF_E + PEM_STRING_X509_CRL + AFT); out.newLine(); out.flush(); } public static void writeX509Request(Writer _out, PKCS10Request obj) throws IOException { BufferedWriter out = makeBuffered(_out); byte[] encoding = getEncoded(obj.toASN1Structure()); out.write(BEF_G + PEM_STRING_X509_REQ + AFT); out.newLine(); writeEncoded(out, encoding, encoding.length); out.write(BEF_E + PEM_STRING_X509_REQ + AFT); out.newLine(); out.flush(); } public static void writeDSAPrivateKey(Writer _out, DSAPrivateKey obj, CipherSpec cipher, char[] passwd) throws IOException { BufferedWriter out = makeBuffered(_out); PrivateKeyInfo info = new PrivateKeyInfo((ASN1Sequence) new ASN1InputStream(getEncoded(obj)).readObject()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); DSAParameter p = DSAParameter.getInstance(info.getPrivateKeyAlgorithm().getParameters()); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(BigInteger.ZERO)); v.add(new ASN1Integer(p.getP())); v.add(new ASN1Integer(p.getQ())); v.add(new ASN1Integer(p.getG())); BigInteger x = obj.getX(); BigInteger y = p.getG().modPow(x, p.getP()); v.add(new ASN1Integer(y)); v.add(new ASN1Integer(x)); aOut.writeObject(new DLSequence(v)); if (cipher != null && passwd != null) { writePemEncrypted(out, PEM_STRING_DSA, bOut.buffer(), bOut.size(), cipher, passwd); } else { writePemPlain(out, PEM_STRING_DSA, bOut.buffer(), bOut.size()); } } public static void writeRSAPrivateKey(Writer _out, RSAPrivateCrtKey obj, CipherSpec cipher, char[] passwd) throws IOException { assert (obj != null); BufferedWriter out = makeBuffered(_out); org.bouncycastle.asn1.pkcs.RSAPrivateKey keyStruct = new org.bouncycastle.asn1.pkcs.RSAPrivateKey(obj.getModulus(), obj.getPublicExponent(), obj.getPrivateExponent(), obj.getPrimeP(), obj.getPrimeQ(), obj.getPrimeExponentP(), obj.getPrimeExponentQ(), obj.getCrtCoefficient()); if (cipher != null && passwd != null) { writePemEncrypted(out, PEM_STRING_RSA, keyStruct.getEncoded(), cipher, passwd); } else { writePemPlain(out, PEM_STRING_RSA, keyStruct.getEncoded()); } } public static void writeECPrivateKey(Writer _out, ECPrivateKey obj, CipherSpec cipher, char[] passwd) throws IOException { assert (obj != null); final String PEM_STRING_EC = "EC PRIVATE KEY"; BufferedWriter out = makeBuffered(_out); final int bitLength = obj.getParams().getOrder().bitLength(); org.bouncycastle.asn1.sec.ECPrivateKey keyStruct = new org.bouncycastle.asn1.sec.ECPrivateKey(bitLength, obj.getS()); if (cipher != null && passwd != null) { writePemEncrypted(out, PEM_STRING_EC, keyStruct.getEncoded(), cipher, passwd); } else { writePemPlain(out, PEM_STRING_EC, keyStruct.getEncoded()); } } public static void writeECParameters(Writer _out, ASN1ObjectIdentifier obj, CipherSpec cipher, char[] passwd) throws IOException { assert (obj != null); final String PEM_STRING_EC = "EC PARAMETERS"; BufferedWriter out = makeBuffered(_out); if (cipher != null && passwd != null) { writePemEncrypted(out, PEM_STRING_EC, obj.getEncoded(), cipher, passwd); } else { writePemPlain(out, PEM_STRING_EC, obj.getEncoded()); } } private static void writePemPlain(final BufferedWriter out, final String PEM_ID, final byte[] encoding) throws IOException { writePemPlain(out, PEM_ID, encoding, encoding.length); } private static void writePemPlain(final BufferedWriter out, final String PEM_ID, final byte[] encoding, final int encLen) throws IOException { out.write(BEF_G); out.write(PEM_ID); out.write(AFT); out.newLine(); writeEncoded(out, encoding, encLen); out.write(BEF_E); out.write(PEM_ID); out.write(AFT); out.newLine(); out.flush(); } private static void writePemEncrypted(final BufferedWriter out, final String PEM_ID, final byte[] encoding, final CipherSpec cipherSpec, final char[] passwd) throws IOException { writePemEncrypted(out, PEM_ID, encoding, encoding.length, cipherSpec, passwd); } private static void writePemEncrypted(final BufferedWriter out, final String PEM_ID, final byte[] encoding, final int encCount, final CipherSpec cipherSpec, final char[] passwd) throws IOException { final Cipher cipher = cipherSpec.getCipher(); final byte[] iv = new byte[cipher.getBlockSize()]; secureRandom().nextBytes(iv); final byte[] salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt); KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(cipherSpec.getKeyLenInBits()); SecretKey secretKey = new SecretKeySpec(param.getKey(), Algorithm.getAlgorithmBase(cipher)); final byte[] encData; try { cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv)); encData = cipher.doFinal(encoding, 0, encCount); } catch (InvalidKeyException e) { final String msg = e.getMessage(); if ( msg != null && msg.startsWith("Invalid key length") ) { throw new IOException("Invalid key length. See http://wiki.jruby.org/UnlimitedStrengthCrypto", e); } throw new IOException("exception using cipher: "+ cipherSpec.getOsslName() + " (" + e + ")", e); } catch (GeneralSecurityException e) { throw new IOException("exception using cipher: "+ cipherSpec.getOsslName() + " (" + e + ")", e); } out.write(BEF_G); out.write(PEM_ID); out.write(AFT); out.newLine(); out.write("Proc-Type: 4,ENCRYPTED"); out.newLine(); out.write("DEK-Info: " + cipherSpec.getOsslName() + ','); writeHexEncoded(out, iv); out.newLine(); out.newLine(); writeEncoded(out, encData, encData.length); out.write(BEF_E); out.write(PEM_ID); out.write(AFT); out.flush(); } private static SecureRandom random; private static SecureRandom secureRandom() { if ( random == null ) { try { random = SecureRandom.getInstance("SHA1PRNG"); } catch (NoSuchAlgorithmException e) { random = new SecureRandom(); } } return random; } public static void writeDHParameters(Writer _out, DHParameterSpec params) throws IOException { final BufferedWriter out = makeBuffered(_out); ASN1EncodableVector v = new ASN1EncodableVector(); BigInteger value; if ( ( value = params.getP() ) != null ) { v.add( new ASN1Integer(value) ); } if ( ( value = params.getG() ) != null ) { v.add( new ASN1Integer(value) ); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ASN1OutputStream aOut = new ASN1OutputStream(bOut); aOut.writeObject(new DLSequence(v)); out.write(BEF_G); out.write(PEM_STRING_DHPARAMS); out.write(AFT); out.newLine(); writeEncoded(out, bOut.buffer(), bOut.size()); out.write(BEF_E); out.write(PEM_STRING_DHPARAMS); out.write(AFT); out.newLine(); out.flush(); } private static String getPrivateKeyTypeFromObjectId(ASN1ObjectIdentifier oid) { if ( ASN1Registry.oid2nid(oid) == ASN1Registry.NID_rsaEncryption ) { return "RSA"; } else { return "DSA"; } } private static RSAPublicKey readRSAPublicKey(BufferedReader in, String endMarker) throws IOException { Object asnObject = new ASN1InputStream(readBase64Bytes(in, endMarker)).readObject(); ASN1Sequence sequence = (ASN1Sequence) asnObject; org.bouncycastle.asn1.pkcs.RSAPublicKey rsaPubStructure = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(sequence); RSAPublicKeySpec keySpec = new RSAPublicKeySpec( rsaPubStructure.getModulus(), rsaPubStructure.getPublicExponent()); try { return (RSAPublicKey) SecurityHelper.getKeyFactory("RSA").generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { /* ignore */ } catch (InvalidKeySpecException e) { /* ignore */ } return null; } private static PublicKey readPublicKey(byte[] input, String alg, String endMarker) throws IOException { KeySpec keySpec = new X509EncodedKeySpec(input); try { return SecurityHelper.getKeyFactory(alg).generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { /* ignore */ } catch (InvalidKeySpecException e) { /* ignore */ } return null; } private static PublicKey readPublicKey(BufferedReader in, String alg, String endMarker) throws IOException { return readPublicKey(readBase64Bytes(in, endMarker), alg, endMarker); } private static PublicKey readPublicKey(BufferedReader in, String endMarker) throws IOException { byte[] input = readBase64Bytes(in, endMarker); String[] algs = { "RSA", "DSA", "ECDSA" }; for (int i = 0; i < algs.length; i++) { PublicKey key = readPublicKey(input, algs[i], endMarker); if (key != null) { return key; } } return null; } /** * Read a Key Pair */ private static KeyPair readKeyPair(BufferedReader in, char[] passwd, String type, String endMarker) throws PasswordRequiredException, IOException, GeneralSecurityException { boolean isEncrypted = false; String dekInfo = null; String line; StringBuilder buffer = new StringBuilder(512); while ( ( line = in.readLine() ) != null ) { if ( line.startsWith("Proc-Type: 4,ENCRYPTED") ) { isEncrypted = true; } else if ( line.startsWith("DEK-Info:") ) { dekInfo = line.substring(10); } else if ( line.contains(endMarker) ) { break; } else { buffer.append( line.trim() ); } } byte[] decoded = Base64.decode( buffer.toString() ); final byte[] keyBytes; if ( isEncrypted ) { keyBytes = decrypt(decoded, dekInfo, passwd); } else { keyBytes = decoded; } return org.jruby.ext.openssl.impl.PKey.readPrivateKey(keyBytes, type); } private static byte[] decrypt(byte[] decoded, String dekInfo, char[] passwd) throws PasswordRequiredException, IOException, GeneralSecurityException { if ( passwd == null ) throw new PasswordRequiredException(); StringTokenizer tknz = new StringTokenizer(dekInfo, ","); String algorithm = tknz.nextToken(); byte[] iv = Hex.decode(tknz.nextToken()); // NOTE: shall be fine and bubble up on-demand (if really not supported) //if ( ! org.jruby.ext.openssl.Cipher.isSupportedCipher(algorithm) ) { // throw new IOException("Unknown algorithm: " + algorithm); //} String realName = Algorithm.getRealName(algorithm); int[] lengths = Algorithm.osslKeyIvLength(algorithm); int keyLen = lengths[0]; int ivLen = lengths[1]; if (iv.length != ivLen) { throw new IOException("Illegal IV length"); } byte[] salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt); KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(keyLen * 8); SecretKey secretKey = new SecretKeySpec(param.getKey(), realName); Cipher cipher = SecurityHelper.getCipher(realName); cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); return cipher.doFinal(decoded); } public static class PasswordRequiredException extends IOException { PasswordRequiredException() { super(); } } /** * Reads in a X509Certificate. * * @return the X509Certificate * @throws IOException if an I/O error occured */ private static X509Certificate readCertificate(final BufferedReader in, final String endMarker) throws IOException { final byte[] bytes = readBase64Bytes(in, endMarker); try { return (X509Certificate) getX509CertificateFactory().generateCertificate( new ByteArrayInputStream( bytes ) ); } catch (CertificateException e) { throw new IOException("failed to read certificate: " + e, e); } //catch (RuntimeException e) { // throw new IOException("problem generating cert: " + e.toString(), e); //} } private static X509AuxCertificate readAuxCertificate(final BufferedReader in, final String endMarker) throws IOException { final byte[] bytes = readBase64Bytes(in, endMarker); final ASN1InputStream asn1 = new ASN1InputStream(bytes); ByteArrayInputStream certBytes = new ByteArrayInputStream( ( asn1.readObject() ).getEncoded() ); try { final X509Certificate cert = (X509Certificate) getX509CertificateFactory().generateCertificate(certBytes); final ASN1Sequence auxSeq = (ASN1Sequence) asn1.readObject(); final X509Aux aux; if ( auxSeq != null ) { // X509Aux fields : final List trust; final List reject; final String alias; final byte[] keyid; final List other; int ix = 0; ASN1Encodable obj = null; if ( auxSeq.size() > ix ) obj = auxSeq.getObjectAt(ix); if ( obj instanceof ASN1Sequence ) { trust = new ArrayList(); final ASN1Sequence trustSeq = (ASN1Sequence) obj; for ( int i = 0; i < trustSeq.size(); i++ ) { trust.add( ((ASN1ObjectIdentifier) trustSeq.getObjectAt(i)).getId() ); } obj = ( auxSeq.size() > ++ix ) ? auxSeq.getObjectAt(ix) : null; // next obj } else trust = Collections.emptyList(); if ( obj instanceof ASN1TaggedObject && ((ASN1TaggedObject) obj).getTagNo() == 0 ) { reject = new ArrayList(); final ASN1Sequence rejectSeq = (ASN1Sequence) ((ASN1TaggedObject) obj).getObject(); for( int i = 0; i < rejectSeq.size(); i++ ) { reject.add( ((ASN1ObjectIdentifier) rejectSeq.getObjectAt(i)).getId() ); } obj = ( auxSeq.size() > ++ix ) ? auxSeq.getObjectAt(ix) : null; // next obj } else reject = Collections.emptyList(); if ( obj instanceof DERUTF8String ) { alias = ((DERUTF8String) obj).getString(); obj = ( auxSeq.size() > ++ix ) ? auxSeq.getObjectAt(ix) : null; // next obj } else alias = null; if ( obj instanceof DEROctetString ) { keyid = ((DEROctetString) obj).getOctets(); obj = ( auxSeq.size() > ++ix ) ? auxSeq.getObjectAt(ix) : null; // next obj } else keyid = null; if ( obj instanceof ASN1TaggedObject && ((ASN1TaggedObject) obj).getTagNo() == 1 ) { other = new ArrayList(); final ASN1Sequence otherSeq = (ASN1Sequence) ((ASN1TaggedObject) obj).getObject(); for( int i = 0; i < otherSeq.size(); i++ ) { other.add( (ASN1Primitive) otherSeq.getObjectAt(i) ); } //obj = ( auxSeq.size() > ++ix ) ? auxSeq.getObjectAt(ix) : null; // next obj } else other = Collections.emptyList(); aux = new X509Aux(alias, keyid, Collections.unmodifiableList(trust), Collections.unmodifiableList(reject), Collections.unmodifiableList(other)); } else { aux = null; } return new X509AuxCertificate(cert, aux); } catch (CertificateException e) { throw new IOException("failed to read aux cert: " + e, e); } } /** * Reads in a X509CRL. * * @return the X509CRL * @throws IOException if an I/O error occured */ private static X509CRL readCRL(BufferedReader in, String endMarker) throws IOException { final byte[] bytes = readBase64Bytes(in, endMarker); try { return (X509CRL) getX509CertificateFactory().generateCRL( new ByteArrayInputStream( bytes ) ); } catch (CRLException e) { throw new IOException("failed to read crl: " + e, e); } //catch (RuntimeException e) { // throw new IOException("problem parsing cert: " + e.toString(), e); //} } /** * Reads in a PKCS10 certification request. * * @return the certificate request. * @throws IOException if an I/O error occured */ private static PKCS10Request readCertificateRequest(BufferedReader in, String endMarker) throws IOException { final byte[] bytes = readBase64Bytes(in, endMarker); try { return new PKCS10Request( bytes ); } catch (RuntimeException e) { throw new IOException("problem parsing cert: " + e.toString(), e); } } /** * Reads in a PKCS7 object. This returns a ContentInfo object suitable for use with the CMS * API. * * @return the X509Certificate * @throws IOException if an I/O error occured */ private static CMSSignedData readPKCS7(BufferedReader in, char[] p, String endMarker) throws IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); String line; StringBuilder buffer = new StringBuilder(); while ( (line = in.readLine()) != null ) { if ( line.contains(endMarker) ) break; buffer.append( line.trim() ); final int len = buffer.length(); Base64.decode( buffer.substring(0, (len / 4) * 4), bytes ); buffer.delete(0, (len / 4) * 4); } if (buffer.length() != 0) { throw new IOException("base64 data appears to be truncated"); } if (line == null) throw new IOException(endMarker + " not found"); try { ASN1InputStream aIn = new ASN1InputStream(bytes.toByteArray()); return new CMSSignedData(ContentInfo.getInstance(aIn.readObject())); } catch (CMSException e) { throw new IOException("problem parsing PKCS7 object: " + e, e); } } public static KeyFactory getKeyFactory(final AlgorithmIdentifier algId) throws NoSuchAlgorithmException { final ASN1ObjectIdentifier algIdentifier = algId.getAlgorithm(); String algorithm = null; if ( X9ObjectIdentifiers.id_ecPublicKey.equals(algIdentifier) ) { algorithm = "ECDSA"; } else if ( PKCSObjectIdentifiers.rsaEncryption.equals(algIdentifier) ) { algorithm = "RSA"; } else if ( X9ObjectIdentifiers.id_dsa.equals(algIdentifier) ) { algorithm = "DSA"; } if ( algorithm == null ) algorithm = algIdentifier.getId(); return SecurityHelper.getKeyFactory(algorithm); } private static CertificateFactory getX509CertificateFactory() { try { return SecurityHelper.getCertificateFactory("X.509"); } catch (CertificateException e) { throw new IllegalStateException(e); // X.509 not supported?! } } private static void writeHexEncoded(BufferedWriter out, byte[] bytes) throws IOException { bytes = Hex.encode(bytes); for (int i = 0; i != bytes.length; i++) { out.write((char)bytes[i]); } } private static void writeEncoded(BufferedWriter out, byte[] bytes, final int bytesLen) throws IOException { final char[] buf = new char[64]; bytes = Base64.encode(bytes, 0 ,bytesLen); for (int i = 0; i < bytes.length; i += buf.length) { int index = 0; while (index != buf.length) { if ((i + index) >= bytes.length) { break; } buf[index] = (char) bytes[i + index]; index++; } out.write(buf, 0, index); out.newLine(); } } private static byte[] readBase64Bytes(BufferedReader in, String endMarker) throws IOException { return Base64.decode( readLines(in, endMarker).toString() ); } private static StringBuilder readLines(final BufferedReader reader, final String endMarker) throws IOException { String line; StringBuilder lines = new StringBuilder(64); while ( ( line = reader.readLine() ) != null ) { if ( line.contains(endMarker) ) break; lines.append( line.trim() ); } if ( line == null ) { throw new IOException(endMarker + " not found"); } return lines; } }// PEM jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/PKey.java000066400000000000000000000036521313661621600265700ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.security.PrivateKey; /** * c: X509_OBJECT * * @author Ola Bini */ public class PKey extends X509Object { public /* final */ java.security.PrivateKey pkey; @Deprecated // not-used public PKey() { /* no-op */ } public PKey(PrivateKey pkey) { this.pkey = pkey; } public int type() { return X509Utils.X509_LU_PKEY; } }// X509_OBJECT_PKEY jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/PolicyTree.java000066400000000000000000000032231313661621600277710ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; /** * c: X509_POLICY_TREE * * @author Ola Bini */ /*public*/ class PolicyTree { // not-used }// X509_POLICY_TREE jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Purpose.java000066400000000000000000000355731313661621600273640ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.util.ArrayList; import java.util.List; import java.security.cert.CertificateException; /** * c: X509_PURPOSE * * @author Ola Bini */ public class Purpose { private static final String XKU_EMAIL_PROTECT = "1.3.6.1.5.5.7.3.4"; // Email protection private static final String XKU_SSL_CLIENT = "1.3.6.1.5.5.7.3.2"; // SSL Client Authentication private static final String[] XKU_SSL_SERVER = new String[]{ "1.3.6.1.5.5.7.3.1", // SSL Server Authentication "2.16.840.1.113730.4.1", // Netscape Server Gated Crypto "1.3.6.1.4.1.311.10.3.3" // Microsoft Server Gated Crypto }; static interface CheckPurposeFunction extends Function3 { int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException ; } public int purpose; public int trust; /* Default trust ID */ public int flags; CheckPurposeFunction checkPurpose; public String name; public String sname; public Object userData; private Purpose() {} Purpose(int p, int t, int f, CheckPurposeFunction cp, String n, String s, Object u) { this.purpose = p; this.trust = t; this.flags = f; this.checkPurpose = cp; this.name = n; this.sname = s; this.userData = u; } /** * c: X509_check_purpose */ public static int checkPurpose(X509AuxCertificate x, int id, int ca) throws CertificateException { if ( id == -1 ) return 1; int idx = getByID(id); if ( idx == -1 ) return -1; Purpose pt = getFirst(idx); return pt.checkPurpose.call(pt, x ,Integer.valueOf(ca)); } /** * c: X509_PURPOSE_set */ public static int set(int[] p, int purpose) { if(getByID(purpose) == -1) { X509Error.addError(X509Utils.X509V3_R_INVALID_PURPOSE); return 0; } p[0] = purpose; return 1; } private final static List xptable = new ArrayList(); /** * c: X509_PURPOSE_get_count */ public static int getCount() { return xptable.size() + xstandard.length; } /** * c: X509_PURPOSE_get0 */ public static Purpose getFirst(int idx) { if(idx < 0) { return null; } if(idx < xstandard.length) { return xstandard[idx]; } return xptable.get(idx - xstandard.length); } /** * c: X509_PURPOSE_get_by_sname */ public static int getBySName(String sname) { for(int i=0;i= X509Utils.X509_PURPOSE_MIN && (purpose <= X509Utils.X509_PURPOSE_MAX)) { return purpose - X509Utils.X509_PURPOSE_MIN; } int i = 0; for(Purpose p : xptable) { if(p.purpose == purpose) { return i + xstandard.length; } } return -1; } /** * c: X509_PURPOSE_add */ static int add(int id, int trust, int flags, CheckPurposeFunction ck, String name, String sname, Object arg) { flags &= ~X509Utils.X509_PURPOSE_DYNAMIC; flags |= X509Utils.X509_PURPOSE_DYNAMIC_NAME; int idx = getByID(id); Purpose ptmp; if(idx == -1) { ptmp = new Purpose(); ptmp.flags = X509Utils.X509_PURPOSE_DYNAMIC; } else { ptmp = getFirst(idx); } ptmp.name = name; ptmp.sname = sname; ptmp.flags &= X509Utils.X509_PURPOSE_DYNAMIC; ptmp.flags |= flags; ptmp.purpose = id; ptmp.trust = trust; ptmp.checkPurpose = ck; ptmp.userData = arg; if (idx == -1) { xptable.add(ptmp); } return 1; } /** * c: X509_PURPOSE_cleanup */ public static void cleanup() { xptable.clear(); } /** * c: X509_PURPOSE_get_id */ public int getID() { return purpose; } /** * c: X509_PURPOSE_get0_name */ public String getName() { return name; } /** * c: X509_PURPOSE_get0_sname */ public String getSName() { return sname; } /** * c: X509_PURPOSE_get_trust */ public int getTrust() { return trust; } /** * c: X509_check_ca */ public static int checkCA(X509AuxCertificate x) throws CertificateException { if(x.getKeyUsage() != null && !x.getKeyUsage()[5]) { // KEY_CERT_SIGN return 0; } if(x.getExtensionValue("2.5.29.19") != null) { // BASIC_CONSTRAINTS if(x.getBasicConstraints() != -1) { // is CA. return 1; } else { return 0; } } else { if(x.getVersion() == 1 && x.getIssuerX500Principal().equals(x.getSubjectX500Principal())) { // V1_ROOT return 3; } if(x.getKeyUsage() != null) { return 4; } Integer nsCertType = x.getNsCertType(); if (nsCertType != null && (nsCertType & X509Utils.NS_ANY_CA) != 0) { return 5; } return 0; } } /** * c: check_ssl_ca */ public static int checkSSLCA(X509AuxCertificate x) throws CertificateException { int ca_ret = checkCA(x); if(ca_ret == 0) { return 0; } Integer nsCertType = x.getNsCertType(); boolean v2 = nsCertType != null && (nsCertType & X509Utils.NS_SSL_CA) != 0; if(ca_ret != 5 || v2) { return ca_ret; } return 0; } /** * c: xku_reject: check if the cert must be rejected(true) or not */ public static boolean xkuReject(X509AuxCertificate x, String mustHaveXku) throws CertificateException { List xku = x.getExtendedKeyUsage(); return (xku != null) && !xku.contains(mustHaveXku); } public static boolean xkuReject(X509AuxCertificate x, String[] mustHaveOneOfXku) throws CertificateException { List xku = x.getExtendedKeyUsage(); if(xku == null) { return false; } for (String mustHaveXku : mustHaveOneOfXku) { if(xku.contains(mustHaveXku)) { return false; } } return true; } /** * c: ns_reject */ public static boolean nsReject(X509AuxCertificate x, int mustHaveCertType) throws CertificateException { Integer nsCertType = x.getNsCertType(); return (nsCertType != null) && (nsCertType & mustHaveCertType) == 0; } /** * c: purpose_smime */ public static int purposeSMIME(X509AuxCertificate x, int ca) throws CertificateException { if(xkuReject(x,XKU_EMAIL_PROTECT)) { return 0; // must allow email protection } if(ca != 0) { int ca_ret = checkCA(x); if(ca_ret == 0) { return 0; } Integer nsCertType = x.getNsCertType(); boolean v2 = nsCertType != null && (nsCertType & X509Utils.NS_SMIME_CA) != 0; if(ca_ret != 5 || v2) { return ca_ret; } else { return 0; } } Integer nsCertType = x.getNsCertType(); if (nsCertType != null) { if ((nsCertType & X509Utils.NS_SMIME) != 0) { return 1; } if ((nsCertType & X509Utils.NS_SSL_CLIENT) != 0) { return 2; } return 0; } return 1; } /** * c: check_purpose_ssl_client */ final static CheckPurposeFunction checkPurposeSSLClient = new CheckPurposeFunction() { public int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException { if ( xkuReject(x, XKU_SSL_CLIENT) ) { return 0; } if (ca.intValue() != 0) { return checkSSLCA(x); } if ( x.getKeyUsage() != null && ! x.getKeyUsage()[0] ) { return 0; } if ( nsReject(x, X509Utils.NS_SSL_CLIENT) ) { // when the cert has nsCertType, it must include NS_SSL_CLIENT return 0; } return 1; } }; /** * c: check_purpose_ssl_server */ final static CheckPurposeFunction checkPurposeSSLServer = new CheckPurposeFunction() { public int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException { if ( xkuReject(x, XKU_SSL_SERVER) ) { return 0; } if ( ca.intValue() != 0 ) { return checkSSLCA(x); } if ( nsReject(x, X509Utils.NS_SSL_SERVER) ) { // when the cert has nsCertType, it must include NS_SSL_SERVER return 0; } /* Now as for keyUsage: we'll at least need to sign OR encipher */ if ( x.getKeyUsage() != null && ! ( x.getKeyUsage()[0] || x.getKeyUsage()[2] ) ) { return 0; } return 1; } }; /** * c: check_purpose_ns_ssl_server */ final static CheckPurposeFunction checkPurposeNSSSLServer = new CheckPurposeFunction() { public int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException { int ret = checkPurposeSSLServer.call(purpose, x, ca); if ( ret == 0 || ca != 0 ) { return ret; } if ( x.getKeyUsage() != null && ! x.getKeyUsage()[2] ) { return 0; } return 1; } }; /** * c: check_purpose_smime_sign */ final static CheckPurposeFunction checkPurposeSMIMESign = new CheckPurposeFunction() { public int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException { int ret = purposeSMIME(x, ca); if ( ret == 0 || ca != 0 ) { return ret; } if ( x.getKeyUsage() != null && ( ! x.getKeyUsage()[0] || ! x.getKeyUsage()[1] ) ) { return 0; } return ret; } }; /** * c: check_purpose_smime_encrypt */ final static CheckPurposeFunction checkPurposeSMIMEEncrypt = new CheckPurposeFunction() { public int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException { int ret = purposeSMIME(x,ca); if ( ret == 0 || ca != 0 ) { return ret; } if ( x.getKeyUsage() != null && ! x.getKeyUsage()[2] ) { return 0; } return ret; } }; /** * c: check_purpose_crl_sign */ final static CheckPurposeFunction checkPurposeCRLSign = new CheckPurposeFunction() { public int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException { if ( ca.intValue() != 0 ) { int ca_ret = checkCA(x); if ( ca_ret != 2 ) { return ca_ret; } return 0; } if ( x.getKeyUsage() != null && ! x.getKeyUsage()[6] ) { return 0; } return 1; } }; /** * c: no_check */ final static CheckPurposeFunction noCheck = new CheckPurposeFunction() { public int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException { return 1; } }; /** * c: ocsp_helper */ final static CheckPurposeFunction oscpHelper = new CheckPurposeFunction() { public int call(Purpose purpose, X509AuxCertificate x, Integer ca) throws CertificateException { if ( ca.intValue() != 0 ) { return checkCA(x); } return 1; } }; private final static Purpose[] xstandard = new Purpose[] { new Purpose(X509Utils.X509_PURPOSE_SSL_CLIENT, X509Utils.X509_TRUST_SSL_CLIENT, 0, checkPurposeSSLClient, "SSL client", "sslclient", null), new Purpose(X509Utils.X509_PURPOSE_SSL_SERVER, X509Utils.X509_TRUST_SSL_SERVER, 0, checkPurposeSSLServer, "SSL server", "sslserver", null), new Purpose(X509Utils.X509_PURPOSE_NS_SSL_SERVER, X509Utils.X509_TRUST_SSL_SERVER, 0, checkPurposeNSSSLServer, "Netscape SSL server", "nssslserver", null), new Purpose(X509Utils.X509_PURPOSE_SMIME_SIGN, X509Utils.X509_TRUST_EMAIL, 0, checkPurposeSMIMESign, "S/MIME signing", "smimesign", null), new Purpose(X509Utils.X509_PURPOSE_SMIME_ENCRYPT, X509Utils.X509_TRUST_EMAIL, 0, checkPurposeSMIMEEncrypt, "S/MIME encryption", "smimeencrypt", null), new Purpose(X509Utils.X509_PURPOSE_CRL_SIGN, X509Utils.X509_TRUST_COMPAT, 0, checkPurposeCRLSign, "CRL signing", "crlsign", null), new Purpose(X509Utils.X509_PURPOSE_ANY, X509Utils.X509_TRUST_DEFAULT, 0, noCheck, "Any Purpose", "any", null), new Purpose(X509Utils.X509_PURPOSE_OCSP_HELPER, X509Utils.X509_TRUST_COMPAT, 0, oscpHelper, "OCSP helper", "ocsphelper", null), }; }// X509_PURPOSE jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Store.java000066400000000000000000000337511313661621600270170ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import static org.jruby.ext.openssl.x509store.X509Utils.X509_FILETYPE_DEFAULT; import static org.jruby.ext.openssl.x509store.X509Utils.X509_FILETYPE_PEM; import static org.jruby.ext.openssl.x509store.X509Utils.X509_R_CERT_ALREADY_IN_HASH_TABLE; import java.io.FileNotFoundException; import java.io.IOException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.net.ssl.X509TrustManager; import org.jruby.Ruby; /** * c: X509_STORE * * @author Ola Bini */ public class Store implements X509TrustManager { public static interface VerifyFunction extends Function1 { public static final VerifyFunction EMPTY = new VerifyFunction(){ public int call(StoreContext context) { return -1; } }; } public static interface VerifyCallbackFunction extends Function2 { public static final VerifyCallbackFunction EMPTY = new VerifyCallbackFunction(){ public int call(StoreContext context, Integer outcome) { return -1; } }; } static interface GetIssuerFunction extends Function3 { public static final GetIssuerFunction EMPTY = new GetIssuerFunction(){ public int call(StoreContext context, X509AuxCertificate[] issuer, X509AuxCertificate cert) { return -1; } }; } static interface CheckIssuedFunction extends Function3 { public static final CheckIssuedFunction EMPTY = new CheckIssuedFunction(){ public int call(StoreContext context, X509AuxCertificate cert, X509AuxCertificate issuer) throws Exception { return -1; } }; } static interface CheckRevocationFunction extends Function1 { public static final CheckRevocationFunction EMPTY = new CheckRevocationFunction(){ public int call(StoreContext context) { return -1; } }; } static interface GetCRLFunction extends Function3 { public static final GetCRLFunction EMPTY = new GetCRLFunction(){ public int call(StoreContext context, java.security.cert.X509CRL[] crls, X509AuxCertificate cert) { return -1; } }; } static interface CheckCRLFunction extends Function2 { public static final CheckCRLFunction EMPTY = new CheckCRLFunction(){ public int call(StoreContext context, java.security.cert.X509CRL crl) { return -1; } }; } static interface CertificateCRLFunction extends Function3 { public static final CertificateCRLFunction EMPTY = new CertificateCRLFunction(){ public int call(StoreContext context, java.security.cert.X509CRL crl, X509AuxCertificate cert) { return -1; } }; } static interface CleanupFunction extends Function1 { public static final CleanupFunction EMPTY = new CleanupFunction(){ public int call(StoreContext context) { return -1; } }; } // @Deprecated int cache = 1; // not-used private volatile X509Object[] objects = new X509Object[0]; private volatile Lookup[] certLookups = new Lookup[0]; public final VerifyParameter verifyParameter; VerifyFunction verify = VerifyFunction.EMPTY; VerifyCallbackFunction verifyCallback = VerifyCallbackFunction.EMPTY; GetIssuerFunction getIssuer = GetIssuerFunction.EMPTY; CheckIssuedFunction checkIssued = CheckIssuedFunction.EMPTY; CheckRevocationFunction checkRevocation = CheckRevocationFunction.EMPTY; GetCRLFunction getCRL = GetCRLFunction.EMPTY; CheckCRLFunction checkCRL = CheckCRLFunction.EMPTY; CertificateCRLFunction certificateCRL = CertificateCRLFunction.EMPTY; CleanupFunction cleanup = CleanupFunction.EMPTY; private final List extraData; /** * c: X509_STORE_new */ public Store() { verifyParameter = new VerifyParameter(); extraData = new ArrayList(10); this.extraData.add(null); this.extraData.add(null); this.extraData.add(null); this.extraData.add(null); this.extraData.add(null); this.extraData.add(null); this.extraData.add(null); this.extraData.add(null); this.extraData.add(null); } public List getObjects() { return Arrays.asList(objects); } public List getCertificateMethods() { return Arrays.asList(certLookups); } public VerifyParameter getVerifyParameter() { return verifyParameter; } public VerifyFunction getVerifyFunction() { return verify; } /** * c: X509_STORE_set_verify_func */ public void setVerifyFunction(VerifyFunction func) { verify = func; } public VerifyCallbackFunction getVerifyCallback() { return verifyCallback; } /** * c: X509_STORE_set_verify_cb_func */ public void setVerifyCallbackFunction(VerifyCallbackFunction func) { verifyCallback = func; } /** * c: X509_STORE_free */ public void free() throws Exception { for (Lookup lu : certLookups) { lu.shutdown(); lu.free(); } if (verifyParameter != null) { verifyParameter.free(); } } /** * c: X509_set_ex_data */ public int setExtraData(int idx, Object data) { synchronized (extraData) { extraData.set(idx, data); return 1; } } /** * c: X509_get_ex_data */ public Object getExtraData(int idx) { synchronized (extraData) { return extraData.get(idx); } } /** * c: X509_STORE_set_depth */ public int setDepth(int depth) { verifyParameter.setDepth(depth); return 1; } /** * c: X509_STORE_set_flags */ public int setFlags(long flags) { return verifyParameter.setFlags(flags); } /** * c: X509_STORE_set_purpose */ public int setPurpose(int purpose) { return verifyParameter.setPurpose(purpose); } /** * c: X509_STORE_set_trust */ public int setTrust(int trust) { return verifyParameter.setTrust(trust); } /** * c: X509_STORE_set1_param */ public int setParam(VerifyParameter pm) { return verifyParameter.set(verifyParameter); } /** * c: X509_STORE_add_lookup */ public Lookup addLookup(final Ruby runtime, final LookupMethod method) { final Lookup[] certLookups = this.certLookups; Lookup foundLookup = findLookupMethod(certLookups, method); if ( foundLookup != null ) return foundLookup; final Lookup newLookup = new Lookup(runtime, method); newLookup.store = this; synchronized (this) { final int length = this.certLookups.length; if ( certLookups.length != length ) { foundLookup = findLookupMethod(this.certLookups, method); if ( foundLookup != null ) return foundLookup; } Lookup[] newCertLookups = Arrays.copyOf(this.certLookups, length + 1); newCertLookups[length] = newLookup; this.certLookups = newCertLookups; } return newLookup; } private static Lookup findLookupMethod(final Lookup[] lookups, final LookupMethod method) { for ( final Lookup lookup : lookups ) { if ( lookup.method.equals(method) ) return lookup; } return null; } /** * c: X509_STORE_add_cert */ public int addCertificate(final X509Certificate cert) { if ( cert == null ) return 0; final Certificate certObj = new Certificate(StoreContext.ensureAux(cert)); final X509Object[] objects = this.objects; if ( matchedObject(objects, certObj) ) { X509Error.addError(X509_R_CERT_ALREADY_IN_HASH_TABLE); return 0; } return addObject(certObj, objects.length); } /** * c: X509_STORE_add_crl */ public int addCRL(final java.security.cert.CRL crl) { if ( crl == null ) return 0; final CRL crlObj = new CRL(); crlObj.crl = crl; final X509Object[] objects = this.objects; if ( matchedObject(objects, crlObj) ) { X509Error.addError(X509_R_CERT_ALREADY_IN_HASH_TABLE); return 0; } return addObject(crlObj, objects.length); } private static boolean matchedObject(final X509Object[] objects, final X509Object xObject) { for ( int i = 0; i< objects.length; i++ ) { if ( objects[i].matches(xObject) ) return true; } return false; } private synchronized int addObject(final X509Object xObject, final int prevLength) { final int length = objects.length; if ( length != prevLength ) { // something added concurrently if ( matchedObject(objects, xObject) ) { X509Error.addError(X509_R_CERT_ALREADY_IN_HASH_TABLE); return 0; } } X509Object[] newObjects = Arrays.copyOf(objects, length + 1); newObjects[ length ] = xObject; objects = newObjects; return 1; } /** * c: X509_STORE_load_locations */ public int loadLocations(Ruby runtime, final String file, final String path) throws Exception { if ( file != null ) { final Lookup lookup = addLookup( runtime, Lookup.fileLookup() ); if ( lookup == null ) { return 0; } if ( lookup.loadFile(new CertificateFile.Path(file, X509_FILETYPE_PEM)) != 1 ) { return 0; } } if ( path != null ) { final Lookup lookup = addLookup( runtime, Lookup.hashDirLookup() ); if ( lookup == null ) { return 0; } if ( lookup.addDir(new CertificateHashDir.Dir(path, X509_FILETYPE_PEM)) != 1 ) { return 0; } } if ( path == null && file == null ) return 0; return 1; } /** * c: X509_STORE_set_default_paths */ public int setDefaultPaths(Ruby runtime) throws Exception { Lookup lookup = addLookup(runtime, Lookup.fileLookup()); //if ( lookup == null ) return 0; try { lookup.loadFile(new CertificateFile.Path(null, X509_FILETYPE_DEFAULT)); } catch (FileNotFoundException e) { // set_default_paths ignores FileNotFound } catch (IOException e) { // this is for older jrubies as they do not have a // org.jruby.util.ResourceException.NotFound if (!e.getClass().getSimpleName().equals("NotFound")) { throw e; } // set_default_paths ignores FileNotFound } lookup = addLookup(runtime, Lookup.hashDirLookup()); //if ( lookup == null ) return 0; try { lookup.addDir(new CertificateHashDir.Dir(null, X509_FILETYPE_DEFAULT)); } catch (FileNotFoundException e) { // set_default_paths ignores FileNotFound } catch (IOException e) { if (!e.getClass().getSimpleName().equals("NotFound")) { throw e; } // set_default_paths ignores FileNotFound } X509Error.clearErrors(); return 1; } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) { } @Override public X509Certificate[] getAcceptedIssuers() { final X509Object[] objects = this.objects; final ArrayList issuers = new ArrayList(objects.length); for ( int i = 0; i< objects.length; i++ ) { final X509Object object = objects[i]; if ( object instanceof Certificate ) { issuers.add( ( (Certificate) object ).x509 ); } } return issuers.toArray( new X509Certificate[ issuers.size() ] ); } }// X509_STORE jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/StoreContext.java000066400000000000000000001272721313661621600303660ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.security.GeneralSecurityException; import java.security.PublicKey; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.cert.X509Extension; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Sequence; import org.jruby.ext.openssl.SecurityHelper; /** * c: X509_STORE_CTX * * @author Ola Bini */ public class StoreContext { private static final Integer ZERO = 0; private final Store store; private int currentMethod; X509AuxCertificate certificate; List untrusted; List crls; public VerifyParameter verifyParameter; public List otherContext; public StoreContext(final Store store) { this.store = store; } public static interface CheckPolicyFunction extends Function1 { public static final CheckPolicyFunction EMPTY = new CheckPolicyFunction(){ public int call(StoreContext context) { return -1; } }; } Store.VerifyFunction verify; Store.VerifyCallbackFunction verifyCallback; Store.GetIssuerFunction getIssuer; Store.CheckIssuedFunction checkIssued; Store.CheckRevocationFunction checkRevocation; Store.GetCRLFunction getCRL; Store.CheckCRLFunction checkCRL; Store.CertificateCRLFunction certificateCRL; CheckPolicyFunction checkPolicy; Store.CleanupFunction cleanup; public boolean isValid; public int lastUntrusted; public List chain; //List public PolicyTree tree; public int explicitPolicy; public int error; public int errorDepth; X509AuxCertificate currentCertificate; X509AuxCertificate currentIssuer; X509CRL currentCRL; List extraData; public Store getStore() { return store; } /** * c: X509_STORE_CTX_set_depth */ public void setDepth(int depth) { verifyParameter.setDepth(depth); } /** * c: X509_STORE_CTX_set_app_data */ public void setApplicationData(Object data) { setExtraData(0, data); } /** * c: X509_STORE_CTX_get_app_data */ public Object getApplicationData() { return getExtraData(0); } /** * c: X509_STORE_CTX_get1_issuer */ int getFirstIssuer(final X509AuxCertificate[] issuers, final X509AuxCertificate x) throws Exception { final Name xn = new Name( x.getIssuerX500Principal() ); final X509Object[] s_obj = new X509Object[1]; int ok = store == null ? 0 : getBySubject(X509Utils.X509_LU_X509, xn, s_obj); if ( ok != X509Utils.X509_LU_X509 ) { if ( ok == X509Utils.X509_LU_RETRY ) { X509Error.addError(X509Utils.X509_R_SHOULD_RETRY); return -1; } else if ( ok != X509Utils.X509_LU_FAIL ) { return -1; } return 0; } X509Object obj = s_obj[0]; if ( checkIssued.call(this, x, ((Certificate) obj).x509) != 0 ) { issuers[0] = ((Certificate) obj).x509; return 1; } List objects = store.getObjects(); int idx = X509Object.indexBySubject(objects, X509Utils.X509_LU_X509, xn); if ( idx == -1 ) return 0; /* Look through all matching certificates for a suitable issuer */ for ( int i = idx; i < objects.size(); i++ ) { final X509Object pobj = objects.get(i); if ( pobj.type() != X509Utils.X509_LU_X509 ) { return 0; } final X509AuxCertificate x509 = ((Certificate) pobj).x509; if ( ! xn.equalTo( x509.getSubjectX500Principal() ) ) { return 0; } if ( checkIssued.call(this, x, x509) != 0 ) { issuers[0] = x509; return 1; } } return 0; } public static List ensureAux(final Collection input) { if ( input == null ) return null; List out = new ArrayList(input.size()); for ( X509Certificate cert : input ) out.add( ensureAux(cert) ); return out; } public static List ensureAux(final X509Certificate[] input) { if ( input == null ) return null; List out = new ArrayList(input.length); for ( X509Certificate cert : input ) out.add( ensureAux(cert) ); return out; } public static X509AuxCertificate ensureAux(final X509Certificate input) { if ( input == null ) return null; if ( input instanceof X509AuxCertificate ) { return (X509AuxCertificate) input; } return new X509AuxCertificate(input); } /** * c: X509_STORE_CTX_init */ public int init(X509AuxCertificate cert, List chain) { int ret = 1; this.currentMethod = 0; this.certificate = cert; this.untrusted = chain; this.crls = null; this.lastUntrusted = 0; this.otherContext = null; this.isValid = false; this.chain = null; this.error = 0; this.explicitPolicy = 0; this.errorDepth = 0; this.currentCertificate = null; this.currentIssuer = null; this.tree = null; this.verifyParameter = new VerifyParameter(); if ( store != null ) { ret = verifyParameter.inherit(store.verifyParameter); } else { verifyParameter.flags |= X509Utils.X509_VP_FLAG_DEFAULT | X509Utils.X509_VP_FLAG_ONCE; } if ( store != null ) { verifyCallback = store.getVerifyCallback(); cleanup = store.cleanup; } else { cleanup = Store.CleanupFunction.EMPTY; } if ( ret != 0 ) { ret = verifyParameter.inherit(VerifyParameter.lookup("default")); } if ( ret == 0 ) { X509Error.addError(X509Utils.ERR_R_MALLOC_FAILURE); return 0; } this.checkIssued = defaultCheckIssued; this.getIssuer = getFirstIssuer; this.verifyCallback = nullCallback; this.verify = internalVerify; this.checkRevocation = defaultCheckRevocation; this.getCRL = defaultGetCRL; this.checkCRL = defaultCheckCRL; this.certificateCRL = defaultCertificateCRL; if ( store != null ) { if ( store.checkIssued != null && store.checkIssued != Store.CheckIssuedFunction.EMPTY ) { this.checkIssued = store.checkIssued; } if ( store.getIssuer != null && store.getIssuer != Store.GetIssuerFunction.EMPTY ) { this.getIssuer = store.getIssuer; } if ( store.verifyCallback != null && store.verifyCallback != Store.VerifyCallbackFunction.EMPTY ) { this.verifyCallback = store.verifyCallback; } if ( store.verify != null && store.verify != Store.VerifyFunction.EMPTY) { this.verify = store.verify; } if ( store.checkRevocation != null && store.checkRevocation != Store.CheckRevocationFunction.EMPTY) { this.checkRevocation = store.checkRevocation; } if ( store.getCRL != null && store.getCRL != Store.GetCRLFunction.EMPTY) { this.getCRL = store.getCRL; } if( store.checkCRL != null && store.checkCRL != Store.CheckCRLFunction.EMPTY) { this.checkCRL = store.checkCRL; } if ( store.certificateCRL != null && store.certificateCRL != Store.CertificateCRLFunction.EMPTY) { this.certificateCRL = store.certificateCRL; } } this.checkPolicy = defaultCheckPolicy; // getExtraData(); return 1; } /** * c: X509_STORE_CTX_trusted_stack */ public void trustedStack(List sk) { otherContext = sk; getIssuer = getIssuerStack; } /** * c: X509_STORE_CTX_cleanup */ public void cleanup() throws Exception { if (cleanup != null && cleanup != Store.CleanupFunction.EMPTY) { cleanup.call(this); } verifyParameter = null; tree = null; chain = null; extraData = null; } /** * c: find_issuer */ public X509AuxCertificate findIssuer(final List certs, final X509AuxCertificate cert) throws Exception { for ( X509AuxCertificate issuer : certs ) { if ( checkIssued.call(this, cert, issuer) != 0 ) { return issuer; } } return null; } public List getExtraData() { if ( this.extraData != null ) return this.extraData; ArrayList extraData = new ArrayList(8); extraData.add(null); extraData.add(null); extraData.add(null); extraData.add(null); extraData.add(null); extraData.add(null); return this.extraData = extraData; } /** * c: X509_STORE_CTX_set_ex_data */ public int setExtraData(int idx, Object data) { getExtraData().set(idx, data); return 1; } /** * c: X509_STORE_CTX_get_ex_data */ public Object getExtraData(int idx) { return getExtraData().get(idx); } /** * c: X509_STORE_CTX_get_error */ public int getError() { return error; } /** * c: X509_STORE_CTX_set_error */ public void setError(int s) { this.error = s; } /** * c: X509_STORE_CTX_get_error_depth */ public int getErrorDepth() { return errorDepth; } /** * c: X509_STORE_CTX_get_current_cert */ public X509AuxCertificate getCurrentCertificate() { return currentCertificate; } public X509CRL getCurrentCRL() { return currentCRL; } /** * c: X509_STORE_CTX_get_chain */ public List getChain() { return chain; } /** * c: X509_STORE_CTX_get1_chain */ public List getFirstChain() { if ( chain == null ) return null; return new ArrayList(chain); } /** * c: X509_STORE_CTX_set_cert */ public void setCertificate(X509AuxCertificate x) { this.certificate = x; } public void setCertificate(X509Certificate x) { this.certificate = ensureAux(x); } /** * c: X509_STORE_CTX_set_chain */ public void setChain(List chain) { this.untrusted = ensureAux(chain); } public void setChain(X509Certificate[] sk) { this.untrusted = ensureAux(sk); } /** * c: X509_STORE_CTX_set0_crls */ public void setCRLs(List sk) { this.crls = sk; } /** * c: X509_STORE_CTX_set_purpose */ public int setPurpose(int purpose) { return purposeInherit(0, purpose, 0); } /** * c: X509_STORE_CTX_set_trust */ public int setTrust(int trust) { return purposeInherit(0, 0, trust); } /* private void resetSettingsToWithoutStore() { store = null; this.verifyParameter = new VerifyParameter(); this.verifyParameter.flags |= X509Utils.X509_VP_FLAG_DEFAULT | X509Utils.X509_VP_FLAG_ONCE; this.verifyParameter.inherit(VerifyParameter.lookup("default")); this.cleanup = Store.CleanupFunction.EMPTY; this.checkIssued = defaultCheckIssued; this.getIssuer = getFirstIssuer; this.verifyCallback = nullCallback; this.verify = internalVerify; this.checkRevocation = defaultCheckRevocation; this.getCRL = defaultGetCRL; this.checkCRL = defaultCheckCRL; this.certificateCRL = defaultCertificateCRL; } */ /** * c: SSL_CTX_load_verify_locations */ /* public int loadVerifyLocations(Ruby runtime, String CAfile, String CApath) { boolean reset = false; try { if ( store == null ) { reset = true; store = new Store(); this.verifyParameter.inherit(store.verifyParameter); verifyParameter.inherit(VerifyParameter.lookup("default")); this.cleanup = store.cleanup; if ( store.checkIssued != null && store.checkIssued != Store.CheckIssuedFunction.EMPTY ) { this.checkIssued = store.checkIssued; } if ( store.getIssuer != null && store.getIssuer != Store.GetIssuerFunction.EMPTY ) { this.getIssuer = store.getIssuer; } if ( store.verify != null && store.verify != Store.VerifyFunction.EMPTY ) { this.verify = store.verify; } if ( store.verifyCallback != null && store.verifyCallback != Store.VerifyCallbackFunction.EMPTY ) { this.verifyCallback = store.verifyCallback; } if ( store.checkRevocation != null && store.checkRevocation != Store.CheckRevocationFunction.EMPTY ) { this.checkRevocation = store.checkRevocation; } if ( store.getCRL != null && store.getCRL != Store.GetCRLFunction.EMPTY ) { this.getCRL = store.getCRL; } if ( store.checkCRL != null && store.checkCRL != Store.CheckCRLFunction.EMPTY ) { this.checkCRL = store.checkCRL; } if ( store.certificateCRL != null && store.certificateCRL != Store.CertificateCRLFunction.EMPTY ) { this.certificateCRL = store.certificateCRL; } } final int ret = store.loadLocations(runtime, CAfile, CApath); if ( ret == 0 && reset ) resetSettingsToWithoutStore(); return ret; } catch (Exception e) { if ( reset ) resetSettingsToWithoutStore(); return 0; } } */ /** * c: X509_STORE_CTX_purpose_inherit */ public int purposeInherit(int defaultPurpose,int purpose, int trust) { int idx; if(purpose == 0) { purpose = defaultPurpose; } if(purpose != 0) { idx = Purpose.getByID(purpose); if(idx == -1) { X509Error.addError(X509Utils.X509_R_UNKNOWN_PURPOSE_ID); return 0; } Purpose ptmp = Purpose.getFirst(idx); if(ptmp.trust == X509Utils.X509_TRUST_DEFAULT) { idx = Purpose.getByID(defaultPurpose); if(idx == -1) { X509Error.addError(X509Utils.X509_R_UNKNOWN_PURPOSE_ID); return 0; } ptmp = Purpose.getFirst(idx); } if(trust == 0) { trust = ptmp.trust; } } if(trust != 0) { idx = Trust.getByID(trust); if(idx == -1) { X509Error.addError(X509Utils.X509_R_UNKNOWN_TRUST_ID); return 0; } } if(purpose != 0 && verifyParameter.purpose == 0) { verifyParameter.purpose = purpose; } if(trust != 0 && verifyParameter.trust == 0) { verifyParameter.trust = trust; } return 1; } /** * c: X509_STORE_CTX_set_flags */ public void setFlags(long flags) { verifyParameter.setFlags(flags); } /** * c: X509_STORE_CTX_set_time */ public void setTime(long flags,Date t) { verifyParameter.setTime(t); } /** * c: X509_STORE_CTX_set_verify_cb */ public void setVerifyCallback(Store.VerifyCallbackFunction verifyCallback) { this.verifyCallback = verifyCallback; } /** * c: X509_STORE_CTX_get0_policy_tree */ PolicyTree getPolicyTree() { return tree; } /** * c: X509_STORE_CTX_get_explicit_policy */ public int getExplicitPolicy() { return explicitPolicy; } /** * c: X509_STORE_CTX_get0_param */ public VerifyParameter getParam() { return verifyParameter; } /** * c: X509_STORE_CTX_set0_param */ public void setParam(VerifyParameter param) { this.verifyParameter = param; } /** * c: X509_STORE_CTX_set_default */ public int setDefault(String name) { VerifyParameter p = VerifyParameter.lookup(name); if ( p == null ) return 0; return verifyParameter.inherit(p); } /** * c: X509_STORE_get_by_subject (it gets X509_STORE_CTX as the first parameter) */ public int getBySubject(int type,Name name,X509Object[] ret) throws Exception { Store c = store; X509Object tmp = X509Object.retrieveBySubject(c.getObjects(),type,name); if ( tmp == null ) { List certificateMethods = c.getCertificateMethods(); for(int i=currentMethod; i 0 ) { tmp = stmp[0]; break; } } currentMethod = 0; if ( tmp == null ) return 0; } ret[0] = tmp; return 1; } /** * c: X509_verify_cert */ public int verifyCertificate() throws Exception { X509AuxCertificate x, xtmp = null, chain_ss = null; //X509_NAME xn; int bad_chain = 0, depth, i, num; if ( certificate == null ) { X509Error.addError(X509Utils.X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); return -1; } // first we make sure the chain we are going to build is // present and that the first entry is in place if ( chain == null ) { chain = new ArrayList(); chain.add(certificate); lastUntrusted = 1; } // We use a temporary STACK so we can chop and hack at it List sktmp = null; if ( untrusted != null ) { sktmp = new ArrayList(untrusted); } num = chain.size(); x = chain.get(num - 1); depth = verifyParameter.depth; for(;;) { if ( depth < num ) break; if ( checkIssued.call(this, x, x) != 0 ) break; if ( sktmp != null ) { xtmp = findIssuer(sktmp, x); if ( xtmp != null ) { chain.add(xtmp); sktmp.remove(xtmp); lastUntrusted++; x = xtmp; num++; continue; } } break; } // at this point, chain should contain a list of untrusted // certificates. We now need to add at least one trusted one, // if possible, otherwise we complain. // Examine last certificate in chain and see if it is self signed. i = chain.size(); x = chain.get(i - 1); if ( checkIssued.call(this, x, x) != 0 ) { // we have a self signed certificate if ( chain.size() == 1 ) { // We have a single self signed certificate: see if // we can find it in the store. We must have an exact // match to avoid possible impersonation. X509AuxCertificate[] p_xtmp = new X509AuxCertificate[]{ xtmp }; int ok = getIssuer.call(this, p_xtmp, x); xtmp = p_xtmp[0]; if ( ok <= 0 || ! x.equals(xtmp) ) { error = X509Utils.V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; currentCertificate = x; errorDepth = i-1; bad_chain = 1; ok = verifyCallback.call(this, ZERO); if ( ok == 0 ) return ok; } else { // We have a match: replace certificate with store version // so we get any trust settings. x = xtmp; chain.set(i-1,x); lastUntrusted = 0; } } else { // extract and save self signed certificate for later use chain_ss = chain.remove(chain.size()-1); lastUntrusted--; num--; x = chain.get(num-1); } } // We now lookup certs from the certificate store for(;;) { // If we have enough, we break if ( depth < num ) break; //xn = new X509_NAME(x.getIssuerX500Principal()); // If we are self signed, we break if ( checkIssued.call(this, x, x) != 0 ) break; X509AuxCertificate[] p_xtmp = new X509AuxCertificate[]{ xtmp }; int ok = getIssuer.call(this, p_xtmp, x); xtmp = p_xtmp[0]; if ( ok < 0 ) return ok; if ( ok == 0 ) break; x = xtmp; chain.add(x); num++; } /* we now have our chain, lets check it... */ //xn = new X509_NAME(x.getIssuerX500Principal()); /* Is last certificate looked up self signed? */ if ( checkIssued.call(this, x, x) == 0 ) { if ( chain_ss == null || checkIssued.call(this, x, chain_ss) == 0 ) { if(lastUntrusted >= num) { error = X509Utils.V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; } else { error = X509Utils.V_ERR_UNABLE_TO_GET_ISSUER_CERT; } currentCertificate = x; } else { chain.add(chain_ss); num++; lastUntrusted = num; currentCertificate = chain_ss; error = X509Utils.V_ERR_SELF_SIGNED_CERT_IN_CHAIN; } errorDepth = num - 1; bad_chain = 1; int ok = verifyCallback.call(this, ZERO); if ( ok == 0 ) return ok; } // We have the chain complete: now we need to check its purpose int ok = checkChainExtensions(); if ( ok == 0 ) return ok; /* TODO: Check name constraints (from 1.0.0) */ // The chain extensions are OK: check trust if ( verifyParameter.trust > 0 ) ok = checkTrust(); if ( ok == 0 ) return ok; // Check revocation status: we do this after copying parameters // because they may be needed for CRL signature verification. ok = checkRevocation.call(this); if ( ok == 0 ) return ok; /* At this point, we have a chain and need to verify it */ if ( verify != null && verify != Store.VerifyFunction.EMPTY ) { ok = verify.call(this); } else { ok = internalVerify.call(this); } if ( ok == 0 ) return ok; /* TODO: RFC 3779 path validation, now that CRL check has been done (from 1.0.0) */ /* If we get this far evaluate policies */ if ( bad_chain == 0 && (verifyParameter.flags & X509Utils.V_FLAG_POLICY_CHECK) != 0 ) { ok = checkPolicy.call(this); } return ok; } private final static Set CRITICAL_EXTENSIONS = new HashSet(8); static { CRITICAL_EXTENSIONS.add("2.16.840.1.113730.1.1"); // netscape cert type, NID 71 CRITICAL_EXTENSIONS.add("2.5.29.15"); // key usage, NID 83 CRITICAL_EXTENSIONS.add("2.5.29.17"); // subject alt name, NID 85 CRITICAL_EXTENSIONS.add("2.5.29.19"); // basic constraints, NID 87 CRITICAL_EXTENSIONS.add("2.5.29.37"); // ext key usage, NID 126 CRITICAL_EXTENSIONS.add("1.3.6.1.5.5.7.1.14"); // proxy cert info, NID 661 } private static boolean supportsCriticalExtension(final String oid) { return CRITICAL_EXTENSIONS.contains(oid); } private static boolean unhandledCritical(final X509Extension ext) { final Set criticalOIDs = ext.getCriticalExtensionOIDs(); if ( criticalOIDs == null || criticalOIDs.size() == 0 ) { return false; } for ( final String oid : criticalOIDs ) { if ( ! supportsCriticalExtension(oid) ) return true; } return false; } /** * c: check_chain_extensions */ public int checkChainExtensions() throws Exception { int ok, must_be_ca; X509AuxCertificate x; int proxy_path_length = 0; int allow_proxy_certs = (verifyParameter.flags & X509Utils.V_FLAG_ALLOW_PROXY_CERTS) != 0 ? 1 : 0; must_be_ca = -1; try { final String allowProxyCerts = System.getenv("OPENSSL_ALLOW_PROXY_CERTS"); if ( allowProxyCerts != null && ! "false".equalsIgnoreCase(allowProxyCerts) ) { allow_proxy_certs = 1; } } catch (SecurityException e) { /* ignore if we can't use System.getenv */ } for ( int i = 0; i < lastUntrusted; i++ ) { int ret; x = chain.get(i); if ( (verifyParameter.flags & X509Utils.V_FLAG_IGNORE_CRITICAL) == 0 && unhandledCritical(x) ) { error = X509Utils.V_ERR_UNHANDLED_CRITICAL_EXTENSION; errorDepth = i; currentCertificate = x; ok = verifyCallback.call(this, ZERO); if ( ok == 0 ) return ok; } if ( allow_proxy_certs == 0 && x.getExtensionValue("1.3.6.1.5.5.7.1.14") != null ) { error = X509Utils.V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; errorDepth = i; currentCertificate = x; ok = verifyCallback.call(this, ZERO); if ( ok == 0 ) return ok; } ret = Purpose.checkCA(x); switch(must_be_ca) { case -1: if((verifyParameter.flags & X509Utils.V_FLAG_X509_STRICT) != 0 && ret != 1 && ret != 0) { ret = 0; error = X509Utils.V_ERR_INVALID_CA; } else { ret = 1; } break; case 0: if(ret != 0) { ret = 0; error = X509Utils.V_ERR_INVALID_NON_CA; } else { ret = 1; } break; default: if(ret == 0 || ((verifyParameter.flags & X509Utils.V_FLAG_X509_STRICT) != 0 && ret != 1)) { ret = 0; error = X509Utils.V_ERR_INVALID_CA; } else { ret = 1; } break; } if(ret == 0) { errorDepth = i; currentCertificate = x; ok = verifyCallback.call(this, ZERO); if ( ok == 0 ) return ok; } if(verifyParameter.purpose > 0) { ret = Purpose.checkPurpose(x,verifyParameter.purpose, must_be_ca > 0 ? 1 : 0); if(ret == 0 || ((verifyParameter.flags & X509Utils.V_FLAG_X509_STRICT) != 0 && ret != 1)) { error = X509Utils.V_ERR_INVALID_PURPOSE; errorDepth = i; currentCertificate = x; ok = verifyCallback.call(this, ZERO); if(ok == 0) { return ok; } } } if(i > 1 && x.getBasicConstraints() != -1 && x.getBasicConstraints() != Integer.MAX_VALUE && (i > (x.getBasicConstraints() + proxy_path_length + 1))) { error = X509Utils.V_ERR_PATH_LENGTH_EXCEEDED; errorDepth = i; currentCertificate = x; ok = verifyCallback.call(this, ZERO); if ( ok == 0 ) return ok; } if(x.getExtensionValue("1.3.6.1.5.5.7.1.14") != null) { ASN1Sequence pci = (ASN1Sequence)new ASN1InputStream(x.getExtensionValue("1.3.6.1.5.5.7.1.14")).readObject(); if(pci.size() > 0 && pci.getObjectAt(0) instanceof ASN1Integer) { int pcpathlen = ((ASN1Integer)pci.getObjectAt(0)).getValue().intValue(); if(i > pcpathlen) { error = X509Utils.V_ERR_PROXY_PATH_LENGTH_EXCEEDED; errorDepth = i; currentCertificate = x; ok = verifyCallback.call(this, ZERO); if ( ok == 0 ) return ok; } } proxy_path_length++; must_be_ca = 0; } else { must_be_ca = 1; } } return 1; } /** * c: X509_check_trust */ public int checkTrust() throws Exception { int i,ok; X509AuxCertificate x; i = chain.size()-1; x = chain.get(i); ok = Trust.checkTrust(x, verifyParameter.trust, 0); if ( ok == X509Utils.X509_TRUST_TRUSTED ) { return 1; } errorDepth = 1; currentCertificate = x; if ( ok == X509Utils.X509_TRUST_REJECTED ) { error = X509Utils.V_ERR_CERT_REJECTED; } else { error = X509Utils.V_ERR_CERT_UNTRUSTED; } return verifyCallback.call(this, ZERO); } /** * c: check_cert_time */ public int checkCertificateTime(X509AuxCertificate x) throws Exception { final Date pTime; if ( (verifyParameter.flags & X509Utils.V_FLAG_USE_CHECK_TIME) != 0 ) { pTime = this.verifyParameter.checkTime; } else { pTime = Calendar.getInstance().getTime(); } if ( ! x.getNotBefore().before(pTime) ) { error = X509Utils.V_ERR_CERT_NOT_YET_VALID; currentCertificate = x; if ( verifyCallback.call(this, ZERO) == 0 ) { return 0; } } if ( ! x.getNotAfter().after(pTime) ) { error = X509Utils.V_ERR_CERT_HAS_EXPIRED; currentCertificate = x; if ( verifyCallback.call(this, ZERO) == 0 ) { return 0; } } return 1; } /** * c: check_cert */ public int checkCertificate() throws Exception { final X509CRL[] crl = new X509CRL[1]; X509AuxCertificate x; int ok, cnum; cnum = errorDepth; x = chain.get(cnum); currentCertificate = x; ok = getCRL.call(this, crl, x); if ( ok == 0 ) { error = X509Utils.V_ERR_UNABLE_TO_GET_CRL; ok = verifyCallback.call(this, ZERO); currentCRL = null; return ok; } currentCRL = crl[0]; ok = checkCRL.call(this, crl[0]); if ( ok == 0 ) { currentCRL = null; return ok; } ok = certificateCRL.call(this, crl[0], x); currentCRL = null; return ok; } /** * c: check_crl_time */ public int checkCRLTime(X509CRL crl, int notify) throws Exception { currentCRL = crl; final Date pTime; if ( (verifyParameter.flags & X509Utils.V_FLAG_USE_CHECK_TIME) != 0 ) { pTime = this.verifyParameter.checkTime; } else { pTime = Calendar.getInstance().getTime(); } if ( ! crl.getThisUpdate().before(pTime) ) { error = X509Utils.V_ERR_CRL_NOT_YET_VALID; if ( notify == 0 || verifyCallback.call(this, ZERO) == 0 ) { return 0; } } if ( crl.getNextUpdate() != null && !crl.getNextUpdate().after(pTime) ) { error = X509Utils.V_ERR_CRL_HAS_EXPIRED; if ( notify == 0 || verifyCallback.call(this, ZERO) == 0 ) { return 0; } } currentCRL = null; return 1; } /** * c: get_crl_sk */ public int getCRLStack(X509CRL[] pcrl, Name name, List crls) throws Exception { X509CRL bestCrl = null; if ( crls != null ) { for ( final X509CRL crl : crls ) { if( ! name.equalTo( crl.getIssuerX500Principal() ) ) { continue; } if ( checkCRLTime(crl, 0) != 0 ) { pcrl[0] = crl; return 1; } bestCrl = crl; } } if ( bestCrl != null ) { pcrl[0] = bestCrl; } return 0; } final static Store.GetIssuerFunction getFirstIssuer = new Store.GetIssuerFunction() { public int call(StoreContext context, X509AuxCertificate[] issuer, X509AuxCertificate cert) throws Exception { return context.getFirstIssuer(issuer, cert); } }; /** * c: get_issuer_sk */ final static Store.GetIssuerFunction getIssuerStack = new Store.GetIssuerFunction() { public int call(StoreContext context, X509AuxCertificate[] issuer, X509AuxCertificate x) throws Exception { issuer[0] = context.findIssuer(context.otherContext, x); if ( issuer[0] != null ) { return 1; } else { return 0; } } }; /** * c: check_issued */ final static Store.CheckIssuedFunction defaultCheckIssued = new Store.CheckIssuedFunction() { public int call(StoreContext context, X509AuxCertificate cert, X509AuxCertificate issuer) throws Exception { int ret = X509Utils.checkIfIssuedBy(issuer, cert); if ( ret == X509Utils.V_OK ) return 1; if ( (context.verifyParameter.flags & X509Utils.V_FLAG_CB_ISSUER_CHECK) == 0 ) { return 0; } context.error = ret; context.currentCertificate = cert; context.currentIssuer = issuer; return context.verifyCallback.call(context, ZERO); } }; /** * c: null_callback */ final static Store.VerifyCallbackFunction nullCallback = new Store.VerifyCallbackFunction() { public int call(StoreContext context, Integer outcome) { return outcome.intValue(); } }; /** * c: internal_verify */ final static Store.VerifyFunction internalVerify = new Store.VerifyFunction() { public int call(final StoreContext context) throws Exception { Store.VerifyCallbackFunction verifyCallback = context.verifyCallback; int n = context.chain.size(); context.errorDepth = n - 1; n--; X509AuxCertificate xi = context.chain.get(n); X509AuxCertificate xs = null; int ok; if ( context.checkIssued.call(context,xi,xi) != 0 ) { xs = xi; } else { if ( n <= 0 ) { context.error = X509Utils.V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; context.currentCertificate = xi; ok = verifyCallback.call(context, ZERO); return ok; } else { n--; context.errorDepth = n; xs = context.chain.get(n); } } while ( n >= 0 ) { context.errorDepth = n; if ( ! xs.isValid() ) { try { xs.verify(xi.getPublicKey()); } catch(Exception e) { /* System.err.println("n: " + n); System.err.println("verifying: " + xs); System.err.println("verifying with issuer?: " + xi); System.err.println("verifying with issuer.key?: " + xi.getPublicKey()); System.err.println("exception: " + e); */ context.error = X509Utils.V_ERR_CERT_SIGNATURE_FAILURE; context.currentCertificate = xs; ok = verifyCallback.call(context, ZERO); if ( ok == 0 ) return ok; } } xs.setValid(true); ok = context.checkCertificateTime(xs); if ( ok == 0 ) return ok; context.currentIssuer = xi; context.currentCertificate = xs; ok = verifyCallback.call(context, Integer.valueOf(1)); if ( ok == 0 ) return ok; n--; if ( n >= 0 ) { xi = xs; xs = context.chain.get(n); } } ok = 1; return ok; } }; /** * c: check_revocation */ final static Store.CheckRevocationFunction defaultCheckRevocation = new Store.CheckRevocationFunction() { public int call(final StoreContext context) throws Exception { if ( (context.verifyParameter.flags & X509Utils.V_FLAG_CRL_CHECK) == 0 ) { return 1; } final int last; if ( (context.verifyParameter.flags & X509Utils.V_FLAG_CRL_CHECK_ALL) != 0 ) { last = context.chain.size() - 1; } else { last = 0; } int ok; for ( int i=0; i<=last; i++ ) { context.errorDepth = i; ok = context.checkCertificate(); if ( ok == 0 ) return 0; } return 1; } }; /** * c: get_crl */ final static Store.GetCRLFunction defaultGetCRL = new Store.GetCRLFunction() { public int call(final StoreContext context, final X509CRL[] crls, X509AuxCertificate x) throws Exception { final Name name = new Name( x.getIssuerX500Principal() ); final X509CRL[] crl = new X509CRL[1]; int ok = context.getCRLStack(crl, name, context.crls); if ( ok != 0 ) { crls[0] = crl[0]; return 1; } final X509Object[] xobj = new X509Object[1]; ok = context.getBySubject(X509Utils.X509_LU_CRL, name, xobj); if ( ok == 0 ) { if ( crl[0] != null ) { crls[0] = crl[0]; return 1; } return 0; } crls[0] = (X509CRL) ( (CRL) xobj[0] ).crl; return 1; } }; /** * c: check_crl */ final static Store.CheckCRLFunction defaultCheckCRL = new Store.CheckCRLFunction() { public int call(final StoreContext context, final X509CRL crl) throws Exception { final int errorDepth = context.errorDepth; final int lastInChain = context.chain.size() - 1; int ok; final X509AuxCertificate issuer; if ( errorDepth < lastInChain ) { issuer = context.chain.get(errorDepth + 1); } else { issuer = context.chain.get(lastInChain); if ( context.checkIssued.call(context,issuer,issuer) == 0 ) { context.error = X509Utils.V_ERR_UNABLE_TO_GET_CRL_ISSUER; ok = context.verifyCallback.call(context, ZERO); if ( ok == 0 ) return ok; } } if ( issuer != null ) { if ( issuer.getKeyUsage() != null && ! issuer.getKeyUsage()[6] ) { context.error = X509Utils.V_ERR_KEYUSAGE_NO_CRL_SIGN; ok = context.verifyCallback.call(context, ZERO); if ( ok == 0 ) return ok; } final PublicKey ikey = issuer.getPublicKey(); if ( ikey == null ) { context.error = X509Utils.V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; ok = context.verifyCallback.call(context, ZERO); if ( ok == 0 ) return ok; } else { try { SecurityHelper.verify(crl, ikey); } catch (GeneralSecurityException ex) { context.error = X509Utils.V_ERR_CRL_SIGNATURE_FAILURE; ok = context.verifyCallback.call(context, ZERO); if ( ok == 0 ) return ok; } } } ok = context.checkCRLTime(crl, 1); if ( ok == 0 ) return ok; return 1; } }; /** * c: cert_crl */ final static Store.CertificateCRLFunction defaultCertificateCRL = new Store.CertificateCRLFunction() { public int call(final StoreContext context, final X509CRL crl, X509AuxCertificate x) throws Exception { int ok; if ( crl.getRevokedCertificate( x.getSerialNumber() ) != null ) { context.error = X509Utils.V_ERR_CERT_REVOKED; ok = context.verifyCallback.call(context, ZERO); if ( ok == 0 ) return 0; } if ( (context.verifyParameter.flags & X509Utils.V_FLAG_IGNORE_CRITICAL) != 0 ) { return 1; } if ( crl.getCriticalExtensionOIDs() != null && crl.getCriticalExtensionOIDs().size() > 0 ) { context.error = X509Utils.V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; ok = context.verifyCallback.call(context, ZERO); if ( ok == 0 ) return 0; } return 1; } }; /** * c: check_policy */ final static CheckPolicyFunction defaultCheckPolicy = new CheckPolicyFunction() { public int call(StoreContext context) throws Exception { return 1; } }; }// X509_STORE_CTX jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/Trust.java000066400000000000000000000205001313661621600270300ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; /** * c: X509_TRUST * * @author Ola Bini */ public class Trust { static interface Checker extends Function3 {} public int trust; public int flags; private Checker checkTrust; private String name; private String arg1; private Object arg2; private Trust() {} Trust(int trust, int flags, Checker checkTrust, String n, String a1, Object a2) { this.trust = trust; this.flags = flags; this.checkTrust = checkTrust; this.name = n; this.arg1 = a1; this.arg2 = a2; } /** * c: X509_TRUST_set_default */ /* public static Checker setDefault(Checker trust) { Checker old_trust = defaultTrust; defaultTrust = trust; return old_trust; } */ private final static List trustable = new ArrayList(); /** * c: X509_check_trust */ public static int checkTrust(X509AuxCertificate x, int id, int flags) throws Exception { if ( id == -1 ) return 1; int idx = getByID(id); if (idx == -1) { return defaultTrust.call(Integer.toString(id), x, Integer.valueOf(flags)); } Trust pt = getFirst(idx); return pt.checkTrust.call(pt, x, Integer.valueOf(flags)); } /** * c: X509_TRUST_get_count */ public static int getCount() { return trustable.size() + trstandard.length; } /** * c: X509_TRUST_get0 */ public static Trust getFirst(int idx) { if(idx < 0) { return null; } if(idx < trstandard.length) { return trstandard[idx]; } return trustable.get(idx - trstandard.length); } /** * c: X509_TRUST_get_by_id */ public static int getByID(int id) { if ( id >= X509Utils.X509_TRUST_MIN && id <= X509Utils.X509_TRUST_MAX ) { return id - X509Utils.X509_TRUST_MIN; } int i = 0; for ( Trust t : trustable ) { if(t.trust == id) { return i + trstandard.length; } } return -1; } /** * c: X509_TRUST_set */ public static int set(int[] t, int trust) { if(getByID(trust) == -1) { X509Error.addError(X509Utils.X509_R_INVALID_TRUST); return 0; } t[0] = trust; return 1; } /** * c: X509_TRUST_add */ static int add(int id, int flags, Checker ck, String name, String arg1, Object arg2) { int idx; Trust trtmp; flags &= ~X509Utils.X509_TRUST_DYNAMIC; flags |= X509Utils.X509_TRUST_DYNAMIC_NAME; idx = getByID(id); if(idx == -1) { trtmp = new Trust(); trtmp.flags = X509Utils.X509_TRUST_DYNAMIC; } else { trtmp = getFirst(idx); } trtmp.name = name; trtmp.flags &= X509Utils.X509_TRUST_DYNAMIC; trtmp.flags |= flags; trtmp.trust = id; trtmp.checkTrust = ck; trtmp.arg1 = arg1; trtmp.arg2 = arg2; if(idx == -1) { trustable.add(trtmp); } return 1; } /** * c: X509_TRUST_cleanup */ public static void cleanup() { trustable.clear(); } /** * c: X509_TRUST_get_flags */ public int getFlags() { return flags; } /** * c: X509_TRUST_get0_name */ public String getName() { return name; } /** * c: X509_TRUST_get_trust */ public int getTrust() { return trust; } /** * c: trust_compat */ final static Checker trustCompatibe = new Checker() { public int call(final Trust trust, final X509AuxCertificate x, final Integer flags) throws CertificateException { Purpose.checkPurpose(x,-1,0); if ( x.getIssuerX500Principal().equals( x.getSubjectX500Principal() ) ) { // self signed return X509Utils.X509_TRUST_TRUSTED; } else { return X509Utils.X509_TRUST_UNTRUSTED; } } }; /** * c: trust_1oidany */ final static Checker trust1OIDAny = new Checker() { public int call(final Trust trust, final X509AuxCertificate x, final Integer flags) throws Exception { final X509Aux aux = x.aux; if ( aux != null && ( aux.trust.size() > 0 || aux.reject.size() > 0 ) ) { return objTrust.call(trust.arg1, x, flags); } return trustCompatibe.call(trust, x, flags); } }; /** * c: trust_1oid */ final static Checker trust1OID = new Checker() { public int call(final Trust trust, final X509AuxCertificate x, final Integer flags) throws Exception { if ( x.aux != null ) { return objTrust.call(trust.arg1, x, flags); } return X509Utils.X509_TRUST_UNTRUSTED; } }; /** * c: obj_trust */ final static Checker objTrust = new Checker() { public int call(final String id, final X509AuxCertificate x, final Integer flags) { final X509Aux aux = x.aux; if ( aux == null ) { return X509Utils.X509_TRUST_UNTRUSTED; } for ( String rejectId : aux.reject ) { if ( rejectId.equals(id) ) { return X509Utils.X509_TRUST_REJECTED; } } for ( String trustId : aux.trust ) { if ( trustId.equals(id) ) { return X509Utils.X509_TRUST_TRUSTED; } } return X509Utils.X509_TRUST_UNTRUSTED; } }; /** * c: default_trust */ static Checker defaultTrust = objTrust; private final static Trust[] trstandard = new Trust[] { new Trust(X509Utils.X509_TRUST_COMPAT, 0, trustCompatibe, "compatible", null, null), new Trust(X509Utils.X509_TRUST_SSL_CLIENT, 0, trust1OIDAny, "SSL Client", "1.3.6.1.5.5.7.3.2", null), new Trust(X509Utils.X509_TRUST_SSL_SERVER, 0, trust1OIDAny, "SSL Server", "1.3.6.1.5.5.7.3.1", null), new Trust(X509Utils.X509_TRUST_EMAIL, 0, trust1OIDAny, "S/MIME email", "1.3.6.1.5.5.7.3.4", null), new Trust(X509Utils.X509_TRUST_OBJECT_SIGN, 0, trust1OIDAny, "Object Signer", "1.3.6.1.5.5.7.3.3", null), new Trust(X509Utils.X509_TRUST_OCSP_SIGN, 0, trust1OID, "OCSP responder", "1.3.6.1.5.5.7.3.9", null), new Trust(X509Utils.X509_TRUST_OCSP_REQUEST, 0, trust1OID, "OCSP request", "1.3.6.1.5.5.7.48.1", null), }; }// X509_TRUST jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/VerifyParameter.java000066400000000000000000000230441313661621600310220ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.util.Date; import java.util.ArrayList; import java.util.List; import java.util.Iterator; import org.bouncycastle.asn1.ASN1Primitive; /** * c: X509_VERIFY_PARAM * * @author Ola Bini */ public class VerifyParameter { public String name; public Date checkTime; public long inheritFlags; public long flags; public int purpose; public int trust; public int depth; List policies; /** * c: X509_VERIFY_PARAM_new */ public VerifyParameter() { zero(); } public VerifyParameter(String n, long t, long i_f, long f, int p, int trs, int d, List pol) { this.name = n; this.checkTime = new Date(t); this.inheritFlags = i_f; this.flags = f; this.purpose = p; this.trust = trs; this.depth = d; this.policies = pol; } private void zero() { name = null; purpose = 0; trust = 0; inheritFlags = X509Utils.X509_VP_FLAG_DEFAULT; flags = 0; depth = -1; policies = null; } /** * c: X509_VERIFY_PARAM_free */ public void free() { zero(); } /** * c: X509_VERIFY_PARAM_inherit */ public int inherit(VerifyParameter src) { long inh_flags; boolean to_d, to_o; if(src == null) { return 1; } inh_flags = src.inheritFlags | this.inheritFlags; if((inh_flags & X509Utils.X509_VP_FLAG_ONCE) != 0) { this.inheritFlags = 0; } if((inh_flags & X509Utils.X509_VP_FLAG_LOCKED) != 0) { return 1; } to_d = ((inh_flags & X509Utils.X509_VP_FLAG_DEFAULT) != 0); to_o = ((inh_flags & X509Utils.X509_VP_FLAG_OVERWRITE) != 0); if(to_o || ((src.purpose != 0 && (to_d || this.purpose == 0)))) { this.purpose = src.purpose; } if(to_o || ((src.trust != 0 && (to_d || this.trust == 0)))) { this.trust = src.trust; } if(to_o || ((src.depth != -1 && (to_d || this.depth == -1)))) { this.depth = src.depth; } if(to_o || !((this.flags & X509Utils.V_FLAG_USE_CHECK_TIME) != 0)) { this.checkTime = src.checkTime; this.flags &= ~X509Utils.V_FLAG_USE_CHECK_TIME; } if((inh_flags & X509Utils.X509_VP_FLAG_RESET_FLAGS) != 0) { this.flags = 0; } this.flags |= src.flags; if(to_o || ((src.policies != null && (to_d || this.policies == null)))) { setPolicies(src.policies); } return 1; } /** * c: X509_VERIFY_PARAM_set1 */ public int set(VerifyParameter from) { inheritFlags |= X509Utils.X509_VP_FLAG_DEFAULT; return inherit(from); } /** * c: X509_VERIFY_PARAM_set1_name */ public int setName(String name) { this.name = name; return 1; } /** * c: X509_VERIFY_PARAM_set_flags */ public int setFlags(long flags) { this.flags |= flags; if((flags & X509Utils.V_FLAG_POLICY_MASK) == X509Utils.V_FLAG_POLICY_MASK) { this.flags |= X509Utils.V_FLAG_POLICY_CHECK; } return 1; } /** * c: X509_VERIFY_PARAM_clear_flags */ public int clearFlags(long flags) { this.flags &= ~flags; return 1; } /** * c: X509_VERIFY_PARAM_get_flags */ public long getFlags() { return flags; } /** * c: X509_VERIFY_PARAM_set_purpose */ public int setPurpose(int purpose) { int[] arg = new int[]{this.purpose}; int v = Purpose.set(arg,purpose); this.purpose = arg[0]; return v; } /** * c: X509_VERIFY_PARAM_set_trust */ public int setTrust(int trust) { int[] arg = new int[]{this.trust}; int v = Trust.set(arg,trust); this.trust = arg[0]; return v; } /** * c: X509_VERIFY_PARAM_set_depth */ public void setDepth(int depth) { this.depth = depth; } /** * c: X509_VERIFY_PARAM_set_time */ public void setTime(Date t) { this.checkTime = t; this.flags |= X509Utils.V_FLAG_USE_CHECK_TIME; } /** * c: X509_VERIFY_PARAM_add0_policy */ public int addPolicy(ASN1Primitive policy) { if (policies == null) { policies = new ArrayList(); } policies.add(policy); return 1; } /** * c: X509_VERIFY_PARAM_set1_policies */ public int setPolicies(List policies) { if (policies == null) { this.policies = null; return 1; } this.policies = new ArrayList(); this.policies.addAll(policies); this.flags |= X509Utils.V_FLAG_POLICY_CHECK; return 1; } /** * c: X509_VERIFY_PARAM_get_depth */ public int getDepth() { return depth; } /** * c: X509_VERIFY_PARAM_add0_table */ public int addTable() { for(Iterator iter = parameterTable.iterator();iter.hasNext();) { VerifyParameter v = iter.next(); if(this.name.equals(v.name)) { iter.remove(); } } parameterTable.add(this); return 1; } public static VerifyParameter lookup(String name) { for(VerifyParameter v : parameterTable) { if(name.equals(v.name)) { return v; } } for(VerifyParameter v : defaultTable) { if(name.equals(v.name)) { return v; } } return null; } /** * c: X509_VERIFY_PARAM_table_cleanup */ public static void tableCleanup() { parameterTable.clear(); } private final static VerifyParameter[] defaultTable = new VerifyParameter[] { new VerifyParameter( "default", /* X509 default parameters */ 0, /* Check time */ 0, /* internal flags */ 0, /* flags */ 0, /* purpose */ 0, /* trust */ 100, /* depth */ null /* policies */ ), new VerifyParameter( "pkcs7", /* SSL/TLS client parameters */ 0, /* Check time */ 0, /* internal flags */ 0, /* flags */ X509Utils.X509_PURPOSE_SMIME_SIGN, /* purpose */ X509Utils.X509_TRUST_EMAIL, /* trust */ -1, /* depth */ null /* policies */ ), new VerifyParameter( "ssl_client", /* SSL/TLS client parameters */ 0, /* Check time */ 0, /* internal flags */ 0, /* flags */ X509Utils.X509_PURPOSE_SSL_CLIENT, /* purpose */ X509Utils.X509_TRUST_SSL_CLIENT, /* trust */ -1, /* depth */ null /* policies */ ), new VerifyParameter( "ssl_server", /* SSL/TLS server parameters */ 0, /* Check time */ 0, /* internal flags */ 0, /* flags */ X509Utils.X509_PURPOSE_SSL_SERVER, /* purpose */ X509Utils.X509_TRUST_SSL_SERVER, /* trust */ -1, /* depth */ null /* policies */ )}; private final static List parameterTable = new ArrayList(); }// X509_VERIFY_PARAM jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/X509Aux.java000066400000000000000000000044441313661621600270430ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.util.List; import org.bouncycastle.asn1.ASN1Primitive; /** * @author Ola Bini */ final class X509Aux { final String alias; /* "friendly name" */ final byte[] keyid; /* key id of private key */ final List trust; // String of OID's /* trusted uses */ final List reject; // String of OID's /* rejected uses */ final List other; /* String of OID's of sigAlgs, other unspecified info */ X509Aux(final String alias, final byte[] keyid, final List trust, final List reject, final List other) { this.alias = alias; this.keyid = keyid; this.trust = trust; this.reject = reject; this.other = other; } }// X509_AUX jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/X509AuxCertificate.java000066400000000000000000000237611313661621600312110ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.io.IOException; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.util.Date; import java.util.Collection; import java.util.List; import java.util.Set; import java.security.Principal; import java.security.PublicKey; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.security.NoSuchProviderException; import java.security.SignatureException; import java.security.cert.CertificateException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.security.cert.CertificateFactory; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.jce.provider.X509CertificateObject; import org.jruby.ext.openssl.SecurityHelper; /** * Since regular X509Certificate doesn't represent the Aux part of a * certification, this class uses composition and extension to contain * both pieces of information. * * @author Ola Bini */ public class X509AuxCertificate extends X509Certificate implements Cloneable { private static final long serialVersionUID = -909543379295427515L; final X509Certificate cert; final X509Aux aux; private boolean valid = false; private int ex_flags = 0; public X509AuxCertificate(Certificate wrap) throws IOException, CertificateException { super(); CertificateFactory factory = SecurityHelper.getCertificateFactory("X.509"); ByteArrayInputStream bis = new ByteArrayInputStream(wrap.getEncoded()); this.cert = (X509Certificate) factory.generateCertificate(bis); this.aux = null; } public X509AuxCertificate(X509Certificate wrap) { this(wrap, null); } X509AuxCertificate(X509Certificate wrap, X509Aux aux) { super(); this.cert = wrap; this.aux = aux; } public final X509AuxCertificate clone() { try { return (X509AuxCertificate) super.clone(); } catch (CloneNotSupportedException ex) { throw new IllegalStateException(ex); } } final X509AuxCertificate cloneForCache() { final X509AuxCertificate clone = clone(); clone.valid = false; clone.ex_flags = 0; return clone; } public boolean isValid() { return valid; } public void setValid(boolean v) { this.valid = v; } public int getExFlags() { return ex_flags; } public void setExFlags(int ex_flags) { this.ex_flags = ex_flags; } // DELEGATES : @Override public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException { cert.checkValidity(); } @Override public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException { cert.checkValidity(date); } @Override public int getBasicConstraints() { return cert.getBasicConstraints(); } @Override public List getExtendedKeyUsage() throws CertificateParsingException { return cert.getExtendedKeyUsage(); } @Override public Collection> getIssuerAlternativeNames() throws CertificateParsingException { return cert.getIssuerAlternativeNames(); } @Override public Principal getIssuerDN() { return cert.getIssuerDN(); } @Override public boolean[] getIssuerUniqueID() { return cert.getIssuerUniqueID(); } @Override public X500Principal getIssuerX500Principal() { return cert.getIssuerX500Principal(); } @Override public boolean[] getKeyUsage() { return cert.getKeyUsage(); } @Override public Date getNotAfter() { return cert.getNotAfter(); } @Override public Date getNotBefore() { return cert.getNotBefore(); } @Override public BigInteger getSerialNumber() { return cert.getSerialNumber(); } @Override public String getSigAlgName() { return cert.getSigAlgName(); } @Override public String getSigAlgOID() { return cert.getSigAlgOID(); } @Override public byte[] getSigAlgParams() { return cert.getSigAlgParams(); } @Override public byte[] getSignature() { return cert.getSignature(); } @Override public Collection> getSubjectAlternativeNames() throws CertificateParsingException { return cert.getSubjectAlternativeNames(); } @Override public Principal getSubjectDN() { return cert.getSubjectDN(); } @Override public boolean[] getSubjectUniqueID() { return cert.getSubjectUniqueID(); } @Override public X500Principal getSubjectX500Principal() { return cert.getSubjectX500Principal(); } @Override public byte[] getTBSCertificate() throws CertificateEncodingException { return cert.getTBSCertificate(); } @Override public int getVersion() { return cert.getVersion(); } @Override public byte[] getEncoded() throws CertificateEncodingException { return cert.getEncoded(); } @Override public PublicKey getPublicKey() { return cert.getPublicKey(); } @Override public String toString() { return cert.toString(); } @Override public boolean equals(Object other) { if ( this == other ) return true; if ( other instanceof X509AuxCertificate ) { X509AuxCertificate o = (X509AuxCertificate) other; return this.cert.equals(o.cert) && ((this.aux == null) ? o.aux == null : this.aux.equals(o.aux)); } return false; } @Override public int hashCode() { int ret = cert.hashCode(); ret += 3 * (aux == null ? 1 : aux.hashCode()); return ret; } @Override public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { cert.verify(key); } @Override public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { cert.verify(key,sigProvider); } @Override public Set getCriticalExtensionOIDs() { return cert.getCriticalExtensionOIDs(); } @Override public byte[] getExtensionValue(String oid) { return cert.getExtensionValue(oid); } @Override public Set getNonCriticalExtensionOIDs() { return cert.getNonCriticalExtensionOIDs(); } @Override public boolean hasUnsupportedCriticalExtension() { return cert.hasUnsupportedCriticalExtension(); } public Integer getNsCertType() throws CertificateException { final String NS_CERT_TYPE_OID = "2.16.840.1.113730.1.1"; final byte[] bytes = getExtensionValue(NS_CERT_TYPE_OID); if ( bytes == null ) return null; try { Object o = new ASN1InputStream(bytes).readObject(); if ( o instanceof DERBitString ) { return ((DERBitString) o).intValue(); } if ( o instanceof DEROctetString ) { // just reads initial object for nsCertType definition and ignores trailing objects. ASN1InputStream in = new ASN1InputStream(((DEROctetString) o).getOctets()); o = in.readObject(); return ((DERBitString) o).intValue(); } else { throw new CertificateException("unknown type from ASN1InputStream.readObject: " + o); } } catch (IOException ioe) { throw new CertificateEncodingException(ioe.getMessage(), ioe); } } static boolean equalSubjects(final X509AuxCertificate cert1, final X509AuxCertificate cert2) { if ( cert1.cert == cert2.cert ) return true; if ( cert1.cert instanceof X509CertificateObject && cert2.cert instanceof X509CertificateObject ) { return cert1.cert.getSubjectDN().equals( cert2.cert.getSubjectDN() ); // less expensive on mem } // otherwise need to take the 'expensive' path : return cert1.getSubjectX500Principal().equals( cert2.getSubjectX500Principal() ); } }// X509AuxCertificate jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/X509Error.java000066400000000000000000000134631313661621600274000ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import static org.jruby.ext.openssl.x509store.X509Utils.*; /** * Provide a dynamically-growing list of X509 error messages. * * @author Ola Bini */ public class X509Error { public static String getMessage(int reason) { switch (reason) { case X509_R_BAD_X509_FILETYPE: return "bad x509 filetype"; case X509_R_BASE64_DECODE_ERROR: return "base64 decode error"; case X509_R_CANT_CHECK_DH_KEY: return "cant check dh key"; case X509_R_CERT_ALREADY_IN_HASH_TABLE: return "cert already in hash table"; case X509_R_ERR_ASN1_LIB: return "err asn1 lib"; case X509_R_INVALID_DIRECTORY: return "invalid directory"; case X509_R_INVALID_FIELD_NAME: return "invalid field name"; case X509_R_INVALID_TRUST: return "invalid trust"; case X509_R_KEY_TYPE_MISMATCH: return "key type mismatch"; case X509_R_KEY_VALUES_MISMATCH: return "key values mismatch"; case X509_R_LOADING_CERT_DIR: return "loading cert dir"; case X509_R_LOADING_DEFAULTS: return "loading defaults"; case X509_R_METHOD_NOT_SUPPORTED: return "method not supported"; case X509_R_NO_CERT_SET_FOR_US_TO_VERIFY: return "no cert set for us to verify"; case X509_R_PUBLIC_KEY_DECODE_ERROR: return "public key decode error"; case X509_R_PUBLIC_KEY_ENCODE_ERROR: return "public key encode error"; case X509_R_SHOULD_RETRY: return "should retry"; case X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN: return "unable to find parameters in chain"; case X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY: return "unable to get certs public key"; case X509_R_UNKNOWN_KEY_TYPE: return "unknown key type"; case X509_R_UNKNOWN_NID: return "unknown nid"; case X509_R_UNKNOWN_PURPOSE_ID: return "unknown purpose id"; case X509_R_UNKNOWN_TRUST_ID: return "unknown trust id"; case X509_R_UNSUPPORTED_ALGORITHM: return "unsupported algorithm"; case X509_R_WRONG_LOOKUP_TYPE: return "wrong lookup type"; case X509_R_WRONG_TYPE: return "wrong type"; default: return "(unknown X509 error)"; } } private static ThreadLocal> errors = new ThreadLocal>(); public static void addError(int reason) { getErrors().put(reason, getMessage(reason)); } public static void clearErrors() { synchronized (errors) { if ( errors.get() != null ) newErrorsMap(); } } public static Integer getLastError() { Map errorsMap = getErrorsImpl(false); if ( errorsMap == null || errorsMap.isEmpty() ) return null; final Iterator i = errorsMap.keySet().iterator(); Integer lastError = null; while ( i.hasNext() ) lastError = i.next(); if ( lastError != null ) i.remove(); // remove last return lastError; } public static String getLastErrorMessage() { final Integer lastError = getLastError(); return lastError == null ? null : getMessage(lastError); } public static Map getErrors() { return getErrorsImpl(true); } public static Map getErrorsImpl(boolean required) { Map errorsMap = errors.get(); if ( errorsMap == null && required ) { synchronized (errors) { errorsMap = errors.get(); if ( errorsMap == null ) errorsMap = newErrorsMap(); } } return errorsMap; } private static Map newErrorsMap() { Map map = new LinkedHashMap(8); errors.set(map); return map; } }// Err jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/X509Object.java000066400000000000000000000056271313661621600275200ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.util.Collection; import java.util.List; /** * c: X509_OBJECT * * @author Ola Bini */ public abstract class X509Object implements Comparable { /** * c: X509_OBJECT_idx_by_subject */ public static int indexBySubject(final List list, int type, Name name) { for ( int i = 0; i < list.size(); i++ ) { final X509Object obj = list.get(i); if ( type == obj.type() && obj.isName(name) ) return i; } return -1; } /** * c: X509_OBJECT_retrieve_by_subject */ public static X509Object retrieveBySubject(final Collection list, int type, Name name) { for ( X509Object obj : list ) { if ( type == obj.type() && obj.isName(name) ) return obj; } return null; } /** * c: X509_OBJECT_retrieve_match */ public static X509Object retrieveMatch(final Collection list, X509Object x) { for ( X509Object obj : list ) { if ( obj.matches(x) ) return obj; } return null; } public boolean isName(Name nm) { return false; } public boolean matches(X509Object o) { return false; } public abstract int type(); public int compareTo(X509Object other) { return type() - other.type(); } }// X509_OBJECT jruby-openssl-0.9.21/src/main/java/org/jruby/ext/openssl/x509store/X509Utils.java000066400000000000000000000674501313661621600274140ustar00rootroot00000000000000/***** BEGIN LICENSE BLOCK ***** * Version: EPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Eclipse Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/epl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Ola Bini * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the EPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the EPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.jruby.ext.openssl.x509store; import java.io.File; import java.io.IOException; import java.math.BigInteger; import java.util.Arrays; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DLSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.asn1.x500.X500Name; import org.jruby.util.SafePropertyAccessor; /** * Contains most of the functionality that beings with X509 in * crypty/x509/x509_def.c, crypty/x509/x509_txt.c and others. * * @author Ola Bini */ public abstract class X509Utils { private X509Utils() {} /** * c: X509_get_default_private_dir */ public static String getDefaultPrivateDir() { return X509_PRIVATE_DIR; } /** * c: X509_get_default_cert_area */ public static String getDefaultCertificateArea() { return X509_CERT_AREA; } /** * c: X509_get_default_cert_dir */ public static String getDefaultCertificateDirectory() { return X509_CERT_DIR; } /** * c: X509_get_default_cert_file */ public static String getDefaultCertificateFile() { return X509_CERT_FILE; } /** * c: X509_get_default_cert_dir_env */ public static String getDefaultCertificateDirectoryEnvironment() { return X509_CERT_DIR_EVP; } /** * c: X509_get_default_cert_file_env */ public static String getDefaultCertificateFileEnvironment() { return X509_CERT_FILE_EVP; } /** * c: X509_verify_cert_error_string */ public static String verifyCertificateErrorString(final int error) { switch (error) { case V_OK: return("ok"); case V_ERR_UNABLE_TO_GET_ISSUER_CERT: return("unable to get issuer certificate"); case V_ERR_UNABLE_TO_GET_CRL: return("unable to get certificate CRL"); case V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: return("unable to decrypt certificate's signature"); case V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: return("unable to decrypt CRL's signature"); case V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: return("unable to decode issuer public key"); case V_ERR_CERT_SIGNATURE_FAILURE: return("certificate signature failure"); case V_ERR_CRL_SIGNATURE_FAILURE: return("CRL signature failure"); case V_ERR_CERT_NOT_YET_VALID: return("certificate is not yet valid"); case V_ERR_CRL_NOT_YET_VALID: return("CRL is not yet valid"); case V_ERR_CERT_HAS_EXPIRED: return("certificate has expired"); case V_ERR_CRL_HAS_EXPIRED: return("CRL has expired"); case V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: return("format error in certificate's notBefore field"); case V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: return("format error in certificate's notAfter field"); case V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: return("format error in CRL's lastUpdate field"); case V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: return("format error in CRL's nextUpdate field"); case V_ERR_OUT_OF_MEM: return("out of memory"); case V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: return("self signed certificate"); case V_ERR_SELF_SIGNED_CERT_IN_CHAIN: return("self signed certificate in certificate chain"); case V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: return("unable to get local issuer certificate"); case V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: return("unable to verify the first certificate"); case V_ERR_CERT_CHAIN_TOO_LONG: return("certificate chain too long"); case V_ERR_CERT_REVOKED: return("certificate revoked"); case V_ERR_INVALID_CA: return ("invalid CA certificate"); case V_ERR_INVALID_NON_CA: return ("invalid non-CA certificate (has CA markings)"); case V_ERR_PATH_LENGTH_EXCEEDED: return ("path length constraint exceeded"); case V_ERR_PROXY_PATH_LENGTH_EXCEEDED: return("proxy path length constraint exceeded"); case V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: return("proxy cerificates not allowed, please set the appropriate flag"); case V_ERR_INVALID_PURPOSE: return ("unsupported certificate purpose"); case V_ERR_CERT_UNTRUSTED: return ("certificate not trusted"); case V_ERR_CERT_REJECTED: return ("certificate rejected"); case V_ERR_APPLICATION_VERIFICATION: return("application verification failure"); case V_ERR_SUBJECT_ISSUER_MISMATCH: return("subject issuer mismatch"); case V_ERR_AKID_SKID_MISMATCH: return("authority and subject key identifier mismatch"); case V_ERR_AKID_ISSUER_SERIAL_MISMATCH: return("authority and issuer serial number mismatch"); case V_ERR_KEYUSAGE_NO_CERTSIGN: return("key usage does not include certificate signing"); case V_ERR_UNABLE_TO_GET_CRL_ISSUER: return("unable to get CRL issuer certificate"); case V_ERR_UNHANDLED_CRITICAL_EXTENSION: return("unhandled critical extension"); case V_ERR_KEYUSAGE_NO_CRL_SIGN: return("key usage does not include CRL signing"); case V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: return("key usage does not include digital signature"); case V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: return("unhandled critical CRL extension"); case V_ERR_INVALID_EXTENSION: return("invalid or inconsistent certificate extension"); case V_ERR_INVALID_POLICY_EXTENSION: return("invalid or inconsistent certificate policy extension"); case V_ERR_NO_EXPLICIT_POLICY: return("no explicit policy"); default: return "error number " + error; } } private static ASN1Primitive get(DEROctetString str) throws IOException { return get( str.getOctets() ); } private static ASN1Primitive get(final byte[] input) throws IOException { return new ASN1InputStream(input).readObject(); } /** * c: X509_check_issued */ public static int checkIfIssuedBy(final X509AuxCertificate issuer, final X509AuxCertificate subject) throws IOException { if ( ! issuer.getSubjectX500Principal().equals(subject.getIssuerX500Principal()) ) { return V_ERR_SUBJECT_ISSUER_MISMATCH; } if ( subject.getExtensionValue("2.5.29.35") != null ) { //authorityKeyID // I hate ASN1 and DER Object key = get(subject.getExtensionValue("2.5.29.35")); if ( ! (key instanceof ASN1Sequence) ) key = get( (DEROctetString) key ); final ASN1Sequence seq = (ASN1Sequence) key; final AuthorityKeyIdentifier sakid; if ( seq.size() == 1 && (seq.getObjectAt(0) instanceof ASN1OctetString) ) { sakid = AuthorityKeyIdentifier.getInstance(new DLSequence(new DERTaggedObject(0, seq.getObjectAt(0)))); } else { sakid = AuthorityKeyIdentifier.getInstance(seq); } if ( sakid.getKeyIdentifier() != null ) { if ( issuer.getExtensionValue("2.5.29.14") != null ) { DEROctetString der = (DEROctetString) get(issuer.getExtensionValue("2.5.29.14")); SubjectKeyIdentifier iskid = SubjectKeyIdentifier.getInstance(get(der.getOctets())); if ( iskid.getKeyIdentifier() != null ) { if ( ! Arrays.equals( sakid.getKeyIdentifier(), iskid.getKeyIdentifier() ) ) { return V_ERR_AKID_SKID_MISMATCH; } } } } final BigInteger serialNumber = sakid.getAuthorityCertSerialNumber(); if ( serialNumber != null && ! serialNumber.equals(issuer.getSerialNumber()) ) { return V_ERR_AKID_ISSUER_SERIAL_MISMATCH; } if ( sakid.getAuthorityCertIssuer() != null ) { GeneralName[] gens = sakid.getAuthorityCertIssuer().getNames(); X500Name x500Name = null; for ( int i = 0; i < gens.length; i++ ) { if ( gens[i].getTagNo() == GeneralName.directoryName ) { ASN1Encodable name = gens[i].getName(); if ( name instanceof X500Name ) { x500Name = (X500Name) name; } else if ( name instanceof ASN1Sequence ) { x500Name = X500Name.getInstance((ASN1Sequence) name); } else { throw new RuntimeException("unknown name type: " + name); } break; } } if ( x500Name != null ) { if ( ! new Name(x500Name).equalTo( issuer.getIssuerX500Principal() ) ) { return V_ERR_AKID_ISSUER_SERIAL_MISMATCH; } } } } final boolean[] keyUsage = issuer.getKeyUsage(); if ( subject.getExtensionValue("1.3.6.1.5.5.7.1.14") != null ) { if ( keyUsage != null && ! keyUsage[0] ) { // KU_DIGITAL_SIGNATURE return V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; } } else if ( keyUsage != null && ! keyUsage[5] ) { // KU_KEY_CERT_SIGN return V_ERR_KEYUSAGE_NO_CERTSIGN; } return V_OK; } public static final String OPENSSLDIR; public static final String X509_CERT_AREA; public static final String X509_CERT_DIR; public static final String X509_CERT_FILE; public static final String X509_PRIVATE_DIR; static { // roughly following the ideas from https://www.happyassassin.net/2015/01/12/a-note-about-ssltls-trusted-certificate-stores-and-platforms/ // and falling back to trust store from java to be on the save side // TODO usability in limited environments should be tested/reviewed final String JAVA_HOME = SafePropertyAccessor.getProperty("java.home", ""); // if the default files/dirs exist we use them. with this a switch // from MRI to JRuby produces the same results. otherwise we use the // certs from JAVA_HOME. final String LINUX_CERT_AREA = "/etc/ssl"; final String MACOS_CERT_AREA = "/System/Library/OpenSSL"; String certArea, certDir, privateDir; String maybeCertFile; String maybePkiCertFile = "/etc/pki/tls/certs/ca-bundle.crt"; try { if (new File(LINUX_CERT_AREA).exists()) { certArea = LINUX_CERT_AREA; certDir = certArea + "/certs"; privateDir = certArea + "/private"; maybeCertFile = certDir + "/cert.pem"; } else if (new File(MACOS_CERT_AREA).exists()) { certArea = MACOS_CERT_AREA; certDir = certArea + "/certs"; privateDir = certArea + "/private"; maybeCertFile = certArea + "/cert.pem"; } else { certArea = JAVA_HOME + "/lib/security"; certDir = certArea; privateDir = certArea; maybeCertFile = maybePkiCertFile; } } catch (SecurityException e) { maybeCertFile = null; maybePkiCertFile = null; privateDir = certDir = certArea = JAVA_HOME + "/lib/security"; } X509_CERT_AREA = certArea; X509_CERT_DIR = certDir; X509_PRIVATE_DIR = privateDir; if (maybePkiCertFile != null && new File(maybePkiCertFile).exists()) { X509_CERT_FILE = maybePkiCertFile; } else if (maybeCertFile != null && new File(maybeCertFile).exists()) { X509_CERT_FILE = maybeCertFile; } else { X509_CERT_FILE = JAVA_HOME + "/lib/security/cacerts"; } // keep it with some meaninful content as it is a public constant OPENSSLDIR = X509_CERT_AREA; } public static final String X509_CERT_DIR_EVP = "SSL_CERT_DIR"; public static final String X509_CERT_FILE_EVP = "SSL_CERT_FILE"; public static final int X509_LU_RETRY=-1; public static final int X509_LU_FAIL=0; public static final int X509_LU_X509=1; public static final int X509_LU_CRL=2; public static final int X509_LU_PKEY=3; public static final int X509_FILETYPE_PEM = 1; public static final int X509_FILETYPE_ASN1 = 2; public static final int X509_FILETYPE_DEFAULT = 3; public static final int X509_L_FILE_LOAD = 1; public static final int X509_L_ADD_DIR = 2; public static final int V_OK = 0; public static final int V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2; public static final int V_ERR_UNABLE_TO_GET_CRL = 3; public static final int V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = 4; public static final int V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = 5; public static final int V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = 6; public static final int V_ERR_CERT_SIGNATURE_FAILURE = 7; public static final int V_ERR_CRL_SIGNATURE_FAILURE = 8; public static final int V_ERR_CERT_NOT_YET_VALID = 9; public static final int V_ERR_CERT_HAS_EXPIRED = 10; public static final int V_ERR_CRL_NOT_YET_VALID = 11; public static final int V_ERR_CRL_HAS_EXPIRED = 12; public static final int V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD = 13; public static final int V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD = 14; public static final int V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD = 15; public static final int V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 16; public static final int V_ERR_OUT_OF_MEM = 17; public static final int V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT = 18; public static final int V_ERR_SELF_SIGNED_CERT_IN_CHAIN = 19; public static final int V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY = 20; public static final int V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21; public static final int V_ERR_CERT_CHAIN_TOO_LONG = 22; public static final int V_ERR_CERT_REVOKED = 23; public static final int V_ERR_INVALID_CA = 24; public static final int V_ERR_PATH_LENGTH_EXCEEDED = 25; public static final int V_ERR_INVALID_PURPOSE = 26; public static final int V_ERR_CERT_UNTRUSTED = 27; public static final int V_ERR_CERT_REJECTED = 28; public static final int V_ERR_SUBJECT_ISSUER_MISMATCH = 29; public static final int V_ERR_AKID_SKID_MISMATCH = 30; public static final int V_ERR_AKID_ISSUER_SERIAL_MISMATCH = 31; public static final int V_ERR_KEYUSAGE_NO_CERTSIGN = 32; public static final int V_ERR_UNABLE_TO_GET_CRL_ISSUER = 33; public static final int V_ERR_UNHANDLED_CRITICAL_EXTENSION = 34; public static final int V_ERR_KEYUSAGE_NO_CRL_SIGN = 35; public static final int V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION = 36; public static final int V_ERR_INVALID_NON_CA = 37; public static final int V_ERR_PROXY_PATH_LENGTH_EXCEEDED = 38; public static final int V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE = 39; public static final int V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED = 40; public static final int V_ERR_INVALID_EXTENSION = 41; public static final int V_ERR_INVALID_POLICY_EXTENSION = 42; public static final int V_ERR_NO_EXPLICIT_POLICY = 43; public static final int V_ERR_APPLICATION_VERIFICATION = 50; public static final int V_FLAG_CB_ISSUER_CHECK = 0x1; public static final int V_FLAG_USE_CHECK_TIME = 0x2; public static final int V_FLAG_CRL_CHECK = 0x4; public static final int V_FLAG_CRL_CHECK_ALL = 0x8; public static final int V_FLAG_IGNORE_CRITICAL = 0x10; public static final int V_FLAG_STRICT = 0x20; public static final int V_FLAG_X509_STRICT = 0x20; public static final int V_FLAG_ALLOW_PROXY_CERTS = 0x40; public static final int V_FLAG_POLICY_CHECK = 0x80; public static final int V_FLAG_EXPLICIT_POLICY = 0x100; public static final int V_FLAG_INHIBIT_ANY = 0x200; public static final int V_FLAG_INHIBIT_MAP = 0x400; public static final int V_FLAG_NOTIFY_POLICY = 0x800; public static final int VP_FLAG_DEFAULT = 0x1; public static final int VP_FLAG_OVERWRITE = 0x2; public static final int VP_FLAG_RESET_FLAGS = 0x4; public static final int VP_FLAG_LOCKED = 0x8; public static final int VP_FLAG_ONCE = 0x10; /* Internal use: mask of policy related options */ public static final int V_FLAG_POLICY_MASK = (V_FLAG_POLICY_CHECK | V_FLAG_EXPLICIT_POLICY | V_FLAG_INHIBIT_ANY | V_FLAG_INHIBIT_MAP); public static final int X509_R_BAD_X509_FILETYPE = 100; public static final int X509_R_BASE64_DECODE_ERROR = 118; public static final int X509_R_CANT_CHECK_DH_KEY = 114; public static final int X509_R_CERT_ALREADY_IN_HASH_TABLE = 101; public static final int X509_R_ERR_ASN1_LIB = 102; public static final int X509_R_INVALID_DIRECTORY = 113; public static final int X509_R_INVALID_FIELD_NAME = 119; public static final int X509_R_INVALID_TRUST = 123; public static final int X509_R_KEY_TYPE_MISMATCH = 115; public static final int X509_R_KEY_VALUES_MISMATCH = 116; public static final int X509_R_LOADING_CERT_DIR = 103; public static final int X509_R_LOADING_DEFAULTS = 104; public static final int X509_R_NO_CERT_SET_FOR_US_TO_VERIFY = 105; public static final int X509_R_SHOULD_RETRY = 106; public static final int X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN = 107; public static final int X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY = 108; public static final int X509_R_UNKNOWN_KEY_TYPE = 117; public static final int X509_R_UNKNOWN_NID = 109; public static final int X509_R_UNKNOWN_PURPOSE_ID = 121; public static final int X509_R_UNKNOWN_TRUST_ID = 120; public static final int X509_R_UNSUPPORTED_ALGORITHM = 111; public static final int X509_R_WRONG_LOOKUP_TYPE = 112; public static final int X509_R_WRONG_TYPE = 122; public static final int X509_R_METHOD_NOT_SUPPORTED = 124; public static final int X509_R_PUBLIC_KEY_DECODE_ERROR = 125; public static final int X509_R_PUBLIC_KEY_ENCODE_ERROR = 126; public static final int X509_VP_FLAG_DEFAULT = 0x1; public static final int X509_VP_FLAG_OVERWRITE = 0x2; public static final int X509_VP_FLAG_RESET_FLAGS = 0x4; public static final int X509_VP_FLAG_LOCKED = 0x8; public static final int X509_VP_FLAG_ONCE = 0x10; public static final int X509_PURPOSE_SSL_CLIENT = 1; public static final int X509_PURPOSE_SSL_SERVER = 2; public static final int X509_PURPOSE_NS_SSL_SERVER = 3; public static final int X509_PURPOSE_SMIME_SIGN = 4; public static final int X509_PURPOSE_SMIME_ENCRYPT = 5; public static final int X509_PURPOSE_CRL_SIGN = 6; public static final int X509_PURPOSE_ANY = 7; public static final int X509_PURPOSE_OCSP_HELPER = 8; public static final int X509_PURPOSE_DYNAMIC = 0x1; public static final int X509_PURPOSE_DYNAMIC_NAME = 0x2; public static final int X509_PURPOSE_MIN = 1; public static final int X509_PURPOSE_MAX = 8; public static final int X509_TRUST_DEFAULT = -1; public static final int X509_TRUST_COMPAT = 1; public static final int X509_TRUST_SSL_CLIENT = 2; public static final int X509_TRUST_SSL_SERVER = 3; public static final int X509_TRUST_EMAIL = 4; public static final int X509_TRUST_OBJECT_SIGN = 5; public static final int X509_TRUST_OCSP_SIGN = 6; public static final int X509_TRUST_OCSP_REQUEST = 7; public static final int X509_TRUST_MIN = 1; public static final int X509_TRUST_MAX = 7; public static final int X509_TRUST_DYNAMIC = 1; public static final int X509_TRUST_DYNAMIC_NAME = 2; public static final int X509_TRUST_TRUSTED = 1; public static final int X509_TRUST_REJECTED = 2; public static final int X509_TRUST_UNTRUSTED = 3; public static final int NS_SSL_CLIENT=0x80; public static final int NS_SSL_SERVER=0x40; public static final int NS_SMIME=0x20; public static final int NS_OBJSIGN=0x10; public static final int NS_SSL_CA=0x04; public static final int NS_SMIME_CA=0x02; public static final int NS_OBJSIGN_CA=0x01; public static final int NS_ANY_CA=(NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA); public static final int X509V3_R_BAD_IP_ADDRESS = 118; public static final int X509V3_R_BAD_OBJECT = 119; public static final int X509V3_R_BN_DEC2BN_ERROR = 100; public static final int X509V3_R_BN_TO_ASN1_INTEGER_ERROR = 101; public static final int X509V3_R_DIRNAME_ERROR = 149; public static final int X509V3_R_DUPLICATE_ZONE_ID = 133; public static final int X509V3_R_ERROR_CONVERTING_ZONE = 131; public static final int X509V3_R_ERROR_CREATING_EXTENSION = 144; public static final int X509V3_R_ERROR_IN_EXTENSION = 128; public static final int X509V3_R_EXPECTED_A_SECTION_NAME = 137; public static final int X509V3_R_EXTENSION_EXISTS = 145; public static final int X509V3_R_EXTENSION_NAME_ERROR = 115; public static final int X509V3_R_EXTENSION_NOT_FOUND = 102; public static final int X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED = 103; public static final int X509V3_R_EXTENSION_VALUE_ERROR = 116; public static final int X509V3_R_ILLEGAL_EMPTY_EXTENSION = 151; public static final int X509V3_R_ILLEGAL_HEX_DIGIT = 113; public static final int X509V3_R_INCORRECT_POLICY_SYNTAX_TAG = 152; public static final int X509V3_R_INVALID_BOOLEAN_STRING = 104; public static final int X509V3_R_INVALID_EXTENSION_STRING = 105; public static final int X509V3_R_INVALID_NAME = 106; public static final int X509V3_R_INVALID_NULL_ARGUMENT = 107; public static final int X509V3_R_INVALID_NULL_NAME = 108; public static final int X509V3_R_INVALID_NULL_VALUE = 109; public static final int X509V3_R_INVALID_NUMBER = 140; public static final int X509V3_R_INVALID_NUMBERS = 141; public static final int X509V3_R_INVALID_OBJECT_IDENTIFIER = 110; public static final int X509V3_R_INVALID_OPTION = 138; public static final int X509V3_R_INVALID_POLICY_IDENTIFIER = 134; public static final int X509V3_R_INVALID_PROXY_POLICY_SETTING = 153; public static final int X509V3_R_INVALID_PURPOSE = 146; public static final int X509V3_R_INVALID_SECTION = 135; public static final int X509V3_R_INVALID_SYNTAX = 143; public static final int X509V3_R_ISSUER_DECODE_ERROR = 126; public static final int X509V3_R_MISSING_VALUE = 124; public static final int X509V3_R_NEED_ORGANIZATION_AND_NUMBERS = 142; public static final int X509V3_R_NO_CONFIG_DATABASE = 136; public static final int X509V3_R_NO_ISSUER_CERTIFICATE = 121; public static final int X509V3_R_NO_ISSUER_DETAILS = 127; public static final int X509V3_R_NO_POLICY_IDENTIFIER = 139; public static final int X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED = 154; public static final int X509V3_R_NO_PUBLIC_KEY = 114; public static final int X509V3_R_NO_SUBJECT_DETAILS = 125; public static final int X509V3_R_ODD_NUMBER_OF_DIGITS = 112; public static final int X509V3_R_OPERATION_NOT_DEFINED = 148; public static final int X509V3_R_OTHERNAME_ERROR = 147; public static final int X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED = 155; public static final int X509V3_R_POLICY_PATH_LENGTH = 156; public static final int X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED = 157; public static final int X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED = 158; public static final int X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY = 159; public static final int X509V3_R_SECTION_NOT_FOUND = 150; public static final int X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS = 122; public static final int X509V3_R_UNABLE_TO_GET_ISSUER_KEYID = 123; public static final int X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT = 111; public static final int X509V3_R_UNKNOWN_EXTENSION = 129; public static final int X509V3_R_UNKNOWN_EXTENSION_NAME = 130; public static final int X509V3_R_UNKNOWN_OPTION = 120; public static final int X509V3_R_UNSUPPORTED_OPTION = 117; public static final int X509V3_R_USER_TOO_LONG = 132; public static final int ERR_R_FATAL=64; public static final int ERR_R_MALLOC_FAILURE=(1|ERR_R_FATAL); public static final int ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED=(2|ERR_R_FATAL); public static final int ERR_R_PASSED_NULL_PARAMETER=(3|ERR_R_FATAL); public static final int ERR_R_INTERNAL_ERROR=(4|ERR_R_FATAL); public static final int ERR_R_DISABLED=(5|ERR_R_FATAL); public static final int EXFLAG_BCONS=0x1; public static final int EXFLAG_KUSAGE=0x2; public static final int EXFLAG_XKUSAGE=0x4; public static final int EXFLAG_NSCERT=0x8; public static final int EXFLAG_CA=0x10; public static final int EXFLAG_SS=0x20; public static final int EXFLAG_V1=0x40; public static final int EXFLAG_INVALID=0x80; public static final int EXFLAG_SET=0x100; public static final int EXFLAG_CRITICAL=0x200; public static final int EXFLAG_PROXY=0x400; public static final int EXFLAG_INVALID_POLICY=0x400; public static final int XKU_SSL_SERVER=0x1; public static final int XKU_SSL_CLIENT=0x2; public static final int XKU_SMIME=0x4; public static final int XKU_CODE_SIGN=0x8; public static final int XKU_SGC=0x8; public static final int XKU_OCSP_SIGN=0x20; public static final int XKU_TIMESTAMP=0x40; public static final int XKU_DVCS=0x80; public static final int XKU_ANYEKU=0x100; public static final int POLICY_FLAG_ANY_POLICY = 0x2; }// X509 jruby-openssl-0.9.21/src/test/000077500000000000000000000000001313661621600161725ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/integration/000077500000000000000000000000001313661621600205155ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/integration/Gemfile000066400000000000000000000002471313661621600220130ustar00rootroot00000000000000source 'https://rubygems.org' gem 'httpclient', :require => false gem 'trocla', '~> 0.2.3', :require => false group :development do gem 'rake', :require => nil endjruby-openssl-0.9.21/src/test/integration/ssl_test.rb000066400000000000000000000023321313661621600227020ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('../ruby/test_helper', File.dirname(__FILE__)) class IntegrationSSLTest < TestCase def test_connect_http_client_1 require 'httpclient' puts "\n" puts "------------------------------------------------------------" puts "-- HTTPClient.new.get 'https://www.bankofamerica.com'" puts "------------------------------------------------------------" puts HTTPClient.new.get('https://www.bankofamerica.com') end def test_connect_http_client_2 require 'httpclient' puts "\n" puts "------------------------------------------------------------" puts "-- HTTPClient.new.get 'https://google.co.uk'" puts "------------------------------------------------------------" puts HTTPClient.new.get('https://google.co.uk') end def test_connect_net_http_1 require 'uri'; require 'net/https' puts "\n" puts "------------------------------------------------------------" puts "-- Net::HTTP.new ... 'https://rubygems.org'" puts "------------------------------------------------------------" uri = URI.parse('https://rubygems.org') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true puts http.get('/') end endjruby-openssl-0.9.21/src/test/java/000077500000000000000000000000001313661621600171135ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/java/org/000077500000000000000000000000001313661621600177025ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/java/org/jruby/000077500000000000000000000000001313661621600210355ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/java/org/jruby/ext/000077500000000000000000000000001313661621600216355ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/java/org/jruby/ext/openssl/000077500000000000000000000000001313661621600233205ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/java/org/jruby/ext/openssl/CipherSpiFake.java000066400000000000000000000057221313661621600266460ustar00rootroot00000000000000/* * The MIT License * * Copyright 2014 Karol Bucek. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import javax.crypto.*; import java.security.*; import java.security.spec.AlgorithmParameterSpec; class CipherSpiFake extends CipherSpi { @Override protected void engineSetMode(String s) throws NoSuchAlgorithmException { } @Override protected void engineSetPadding(String s) throws NoSuchPaddingException { } @Override protected int engineGetBlockSize() { return 0; } @Override protected int engineGetOutputSize(int i) { return 0; } @Override protected byte[] engineGetIV() { return new byte[0]; } @Override protected AlgorithmParameters engineGetParameters() { return null; } @Override protected void engineInit(int i, Key key, SecureRandom secureRandom) throws InvalidKeyException { } @Override protected void engineInit(int i, Key key, AlgorithmParameterSpec algorithmParameterSpec, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException { } @Override protected void engineInit(int i, Key key, AlgorithmParameters algorithmParameters, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException { } @Override protected byte[] engineUpdate(byte[] bytes, int i, int i1) { return new byte[0]; } @Override protected int engineUpdate(byte[] bytes, int i, int i1, byte[] bytes1, int i2) throws ShortBufferException { return 0; } @Override protected byte[] engineDoFinal(byte[] bytes, int i, int i1) throws IllegalBlockSizeException, BadPaddingException { return new byte[0]; } @Override protected int engineDoFinal(byte[] bytes, int i, int i1, byte[] bytes1, int i2) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { return 0; } } jruby-openssl-0.9.21/src/test/java/org/jruby/ext/openssl/CipherTest.java000066400000000000000000000163331313661621600262430ustar00rootroot00000000000000 package org.jruby.ext.openssl; import org.junit.*; import static org.junit.Assert.*; /** * @author kares */ public class CipherTest { @Test public void ciphersGetLazyInitialized() { assertTrue( Cipher.Algorithm.supportedCiphers.isEmpty() ); assertFalse( Cipher.isSupportedCipher("UNKNOWN") ); assertFalse( Cipher.Algorithm.supportedCiphers.isEmpty() ); assertTrue( Cipher.Algorithm.supportedCiphers.get("DES") != null ); assertTrue( Cipher.isSupportedCipher("DES") ); assertTrue( Cipher.isSupportedCipher("des") ); assertTrue( Cipher.isSupportedCipher("AES") ); assertTrue( Cipher.isSupportedCipher("BF") ); assertTrue( Cipher.isSupportedCipher("des3") ); } @Test public void jsseToOssl() { String alg; alg = Cipher.Algorithm.javaToOssl("RC2/CBC/PKCS5Padding", 40); assertEquals("RC2-40-CBC", alg); alg = Cipher.Algorithm.javaToOssl("RC2/CFB/PKCS5Padding", 40); assertEquals("RC2-40-CFB", alg); alg = Cipher.Algorithm.javaToOssl("Blowfish", 60); assertEquals("BF-60-CBC", alg); alg = Cipher.Algorithm.javaToOssl("DESede", 24); assertEquals("DES-EDE3-CBC", alg); } @Test public void osslToJsse() { Cipher.Algorithm.supportedCiphers.clear(); Cipher.Algorithm.supportedCiphersAll = false; doTestOsslToJsse(); } @Test public void osslToJsseWithAllLoaded() { Cipher.Algorithm.allSupportedCiphers(); doTestOsslToJsse(); } private void doTestOsslToJsse() { Cipher.Algorithm alg; alg = Cipher.Algorithm.osslToJava("RC2-40-CBC"); assertEquals("RC2", alg.base); assertEquals("40", alg.version); assertEquals("CBC", alg.mode); assertEquals("RC2/CBC/PKCS5Padding", alg.getRealName()); System.out.println("running ..."); alg = Cipher.Algorithm.osslToJava("DES-EDE3-CBC"); assertEquals("DES", alg.base); assertEquals("EDE3", alg.version); assertEquals("CBC", alg.mode); assertEquals("DESede/CBC/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("DES3"); assertEquals("DES", alg.base); assertEquals("EDE3", alg.version); assertEquals("CBC", alg.mode); assertEquals("DESede/CBC/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("DES-EDE"); assertEquals("DES", alg.base); assertEquals("EDE", alg.version); assertEquals("ECB", alg.mode); assertEquals("DESede/ECB/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("DES-EDE3"); assertEquals("DES", alg.base); assertEquals("EDE3", alg.version); assertEquals("ECB", alg.mode); assertEquals("DESede/ECB/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("DES-EDE-CBC"); assertEquals("DES", alg.base); assertEquals("EDE", alg.version); assertEquals("CBC", alg.mode); assertEquals("DESede/CBC/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("DES-EDE3-CBC"); assertEquals("DES", alg.base); assertEquals("EDE3", alg.version); assertEquals("CBC", alg.mode); assertEquals("DESede/CBC/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("DES-EDE3-CFB"); assertEquals("DES", alg.base); assertEquals("EDE3", alg.version); assertEquals("CFB", alg.mode); assertEquals("DESede/CFB/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("DES-CFB"); assertEquals("DES", alg.base); assertEquals(null, alg.version); assertEquals("CFB", alg.mode); assertEquals("DES/CFB/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("DES3"); assertEquals("DES", alg.base); //assertEquals("EDE", alg.version); assertEquals("CBC", alg.mode); assertEquals("DESede/CBC/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("BF"); assertEquals("BF", alg.base); assertEquals("Blowfish/CBC/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("AES-128-XTS"); assertEquals("AES", alg.base); assertEquals("128", alg.version); assertEquals("XTS", alg.mode); assertEquals("PKCS5Padding", alg.getPadding()); assertEquals("AES/XTS/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("AES256"); assertEquals("AES", alg.base); assertEquals("256", alg.version); assertEquals("CBC", alg.mode); assertEquals("PKCS5Padding", alg.getPadding()); assertEquals("AES/CBC/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("AES-256-CBC-HMAC-SHA1"); assertEquals("AES", alg.base); assertEquals("CBC", alg.mode); assertEquals("256", alg.version); assertEquals("PKCS5Padding", alg.getPadding()); assertEquals("AES/CBC/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("RC4"); assertEquals("RC4", alg.base); assertEquals(null, alg.version); assertEquals(null, alg.mode); assertEquals(null, alg.getPadding()); assertEquals("RC4", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("RC4-40"); assertEquals("RC4", alg.base); assertEquals("40", alg.version); assertEquals(null, alg.mode); assertEquals(null, alg.getPadding()); assertEquals("RC4", alg.getRealName()); // keeps "invalid" modes : alg = Cipher.Algorithm.osslToJava("DES-3X3"); assertEquals("DES", alg.base); assertEquals(null, alg.version); assertEquals("3X3", alg.mode); assertEquals("DES/3X3/PKCS5Padding", alg.getRealName()); alg = Cipher.Algorithm.osslToJava("MES-123-XXX"); assertEquals("MES", alg.base); assertEquals("123", alg.version); assertEquals("XXX", alg.mode); assertEquals("MES/XXX/PKCS5Padding", alg.getRealName()); } @Test public void osslKeyIvLength() { int[] len; len = Cipher.Algorithm.osslKeyIvLength("RC2-40-CBC"); assertEquals(5, len[0]); assertEquals(8, len[1]); len = Cipher.Algorithm.osslKeyIvLength("DES-EDE3-CBC"); assertEquals(24, len[0]); assertEquals(8, len[1]); len = Cipher.Algorithm.osslKeyIvLength("DES"); assertEquals(8, len[0]); assertEquals(8, len[1]); len = Cipher.Algorithm.osslKeyIvLength("BF"); assertEquals(16, len[0]); assertEquals(8, len[1]); len = Cipher.Algorithm.osslKeyIvLength("CAST"); assertEquals(16, len[0]); assertEquals(8, len[1]); } @Test public void getAlgorithmBase() throws Exception { javax.crypto.Cipher cipher; String algBase; cipher = javax.crypto.Cipher.getInstance("DES/CBC/PKCS5Padding"); algBase = Cipher.Algorithm.getAlgorithmBase(cipher); assertEquals("DES", algBase); cipher = javax.crypto.Cipher.getInstance("DES"); algBase = Cipher.Algorithm.getAlgorithmBase(cipher); assertEquals("DES", algBase); } } jruby-openssl-0.9.21/src/test/java/org/jruby/ext/openssl/SecurityHelperTest.java000066400000000000000000000317241313661621600300010ustar00rootroot00000000000000 package org.jruby.ext.openssl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.fail; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.Security; import java.security.Signature; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * @author kares */ public class SecurityHelperTest { // @BeforeClass public static void setBouncyCastleProvider() { SecurityHelper.setBouncyCastleProvider(); } private Provider savedProvider; @Before public void saveSecurityProvider() { savedProvider = SecurityHelper.getSecurityProvider(); } @After public void restoreSecurityProvider() { SecurityHelper.securityProvider = savedProvider; } public void disableSecurityProvider() { SecurityHelper.securityProvider = null; SecurityHelper.setBouncyCastleProvider = false; } @Test public void injectCipherImpl() throws Exception { SecurityHelper.addCipher("fake", CipherSpiFake.class); javax.crypto.Cipher cipher = SecurityHelper.getCipher("fake"); assertEquals(cipher.getProvider(), savedProvider); java.lang.reflect.Field spi = cipher.getClass().getDeclaredField("spi"); spi.setAccessible(true); assertEquals(spi.get(cipher).getClass(), CipherSpiFake.class); } @Test public void injectSignatureImpl() throws Exception { SecurityHelper.addSignature("fake", SignatureSpiFake.class); Signature signature = SecurityHelper.getSignature("fake"); assertEquals(signature.getProvider(), savedProvider); assertEquals(signature.getClass(), SignatureSpiFake.class); } @Test public void usesBouncyCastleSecurityProviderByDefault() { assertNotNull(SecurityHelper.getSecurityProvider()); assertEquals("org.bouncycastle.jce.provider.BouncyCastleProvider", SecurityHelper.getSecurityProvider().getClass().getName() ); } @Test public void allowsToSetSecurityProvider() { final Provider provider; try { Class providerClass = Class.forName("sun.security.provider.Sun"); provider = (Provider) providerClass.newInstance(); } catch (Exception e) { System.out.println("allowsToSetSecurityProvider() skipped due: " + e); return; } SecurityHelper.setSecurityProvider(provider); assertSame(provider, SecurityHelper.getSecurityProvider()); } @Test public void doesNotRegisterBouncyCastleSecurityProviderByDefault() { SecurityHelper.getSecurityProvider(); assertNull(java.security.Security.getProvider("BC")); } @Test public void registersSecurityProviderWhenRequested() { SecurityHelper.setRegisterProvider(true); try { SecurityHelper.getSecurityProvider(); assertNotNull(java.security.Security.getProvider("BC")); } finally { java.security.Security.removeProvider("BC"); SecurityHelper.setRegisterProvider(false); } } // Standart java.security @Test public void testGetKeyFactory() throws Exception { assertNotNull( SecurityHelper.getKeyFactory("RSA") ); assertNotNull( SecurityHelper.getKeyFactory("DSA") ); } @Test public void testGetKeyFactoryWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getKeyFactory("RSA") ); assertNotNull( SecurityHelper.getKeyFactory("DSA") ); } @Test public void testGetKeyFactoryThrows() throws Exception { try { SecurityHelper.getKeyFactory("USA"); fail(); } catch (NoSuchAlgorithmException e) { // OK } try { SecurityHelper.getKeyFactory("USA", savedProvider); fail(); } catch (NoSuchAlgorithmException e) { // OK } } // @Test public void testGetKeyPairGenerator() throws Exception { assertNotNull( SecurityHelper.getKeyPairGenerator("RSA") ); assertNotNull( SecurityHelper.getKeyPairGenerator("DSA") ); assertNotNull( SecurityHelper.getKeyPairGenerator("RSA", savedProvider) ); } @Test public void testGetKeyPairGeneratorWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getKeyPairGenerator("RSA") ); assertNotNull( SecurityHelper.getKeyPairGenerator("DSA") ); } @Test public void testGetKeyPairGeneratorThrows() throws Exception { try { SecurityHelper.getKeyPairGenerator("USA"); fail(); } catch (NoSuchAlgorithmException e) { // OK } try { SecurityHelper.getKeyPairGenerator("USA", savedProvider); fail(); } catch (NoSuchAlgorithmException e) { // OK } } // @Test public void testGetKeyStore() throws Exception { assertNotNull( SecurityHelper.getKeyStore("PKCS12") ); assertNotNull( SecurityHelper.getKeyStore("PKCS12", savedProvider) ); } @Test public void testGetKeyStoreWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getKeyStore("PKCS12") ); } @Test public void testGetKeyStoreThrows() throws Exception { try { SecurityHelper.getKeyStore("PKCS42"); fail(); } catch (KeyStoreException e) { // OK } try { SecurityHelper.getKeyStore("PKCS42", savedProvider); fail(); } catch (KeyStoreException e) { // OK } } // @Test public void testGetMessageDigest() throws Exception { assertNotNull( SecurityHelper.getMessageDigest("MD5") ); assertNotNull( SecurityHelper.getMessageDigest("SHA-1") ); assertNotNull( SecurityHelper.getMessageDigest("MD5", savedProvider) ); } @Test public void testGetMessageDigestWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getMessageDigest("MD5") ); assertNotNull( SecurityHelper.getMessageDigest("SHA-1") ); } @Test public void testGetMessageDigestThrows() throws Exception { try { SecurityHelper.getMessageDigest("XXL"); fail(); } catch (NoSuchAlgorithmException e) { // OK } try { SecurityHelper.getMessageDigest("XXL", savedProvider); fail(); } catch (NoSuchAlgorithmException e) { // OK } } // @Test public void testGetSignature() throws Exception { assertNotNull( SecurityHelper.getSignature("NONEwithRSA") ); assertNotNull( SecurityHelper.getSignature("NONEwithRSA", savedProvider) ); } @Test public void testGetSignatureWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getSignature("NONEwithRSA") ); } @Test public void testGetSignatureThrows() throws Exception { try { SecurityHelper.getSignature("SOMEwithRSA"); fail(); } catch (NoSuchAlgorithmException e) { // OK } try { SecurityHelper.getSignature("SOMEwithRSA", savedProvider); fail(); } catch (NoSuchAlgorithmException e) { // OK } } // @Test public void testGetCertificateFactory() throws Exception { assertNotNull( SecurityHelper.getCertificateFactory("X.509") ); assertNotNull( SecurityHelper.getCertificateFactory("X.509", savedProvider) ); } @Test public void testGetCertificateFactoryWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getCertificateFactory("X.509") ); } @Test public void testGetCertificateFactoryThrows() throws Exception { try { SecurityHelper.getCertificateFactory("X.510"); fail(); } catch (CertificateException e) { // OK } try { SecurityHelper.getCertificateFactory("X.510", savedProvider); fail(); } catch (CertificateException e) { // OK } } @Test public void testGetSecureRandom() throws Exception { assertNotNull( SecurityHelper.getSecureRandom() ); } // JCE @Test public void testGetCipher() throws Exception { assertNotNull( SecurityHelper.getCipher("DES") ); assertNotNull( SecurityHelper.getCipher("AES") ); assertNotNull( SecurityHelper.getCipher("DES/CBC/PKCS5Padding") ); } @Test public void testGetCipherBC() throws Exception { assertNotNull( SecurityHelper.getCipher("AES", savedProvider) ); assertNotNull( SecurityHelper.getCipher("DES/CBC/PKCS5Padding", savedProvider) ); } @Test public void testGetCipherWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getCipher("DES") ); assertNotNull( SecurityHelper.getCipher("AES") ); } @Test public void testGetSecretKeyFactory() throws Exception { assertNotNull( SecurityHelper.getSecretKeyFactory("DES") ); assertNotNull( SecurityHelper.getSecretKeyFactory("DESede", savedProvider) ); } @Test public void testGetSecretKeyFactoryWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getSecretKeyFactory("DES") ); assertNotNull( SecurityHelper.getSecretKeyFactory("DESede") ); } @Test public void testGetSecretKeyFactoryThrows() throws Exception { try { SecurityHelper.getSecretKeyFactory("MESS"); fail(); } catch (NoSuchAlgorithmException e) { // OK } try { SecurityHelper.getSecretKeyFactory("MESS", savedProvider); fail(); } catch (NoSuchAlgorithmException e) { // OK } } // @Test public void testGetMac() throws Exception { assertNotNull( SecurityHelper.getMac("HmacMD5") ); assertNotNull( SecurityHelper.getMac("HmacSHA1") ); assertNotNull( SecurityHelper.getMac("HmacMD5", savedProvider) ); } @Test public void testGetMacWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getMac("HMacMD5") ); } @Test public void testGetMacThrows() throws Exception { try { SecurityHelper.getMac("HmacMDX"); fail(); } catch (NoSuchAlgorithmException e) { // OK } try { SecurityHelper.getMac("HmacMDX", savedProvider); fail(); } catch (NoSuchAlgorithmException e) { // OK } } // @Test public void testGetKeyGenerator() throws Exception { assertNotNull( SecurityHelper.getKeyGenerator("AES") ); assertNotNull( SecurityHelper.getKeyGenerator("AES", savedProvider) ); } @Test public void testGetKeyGeneratorWithoutBC() throws Exception { disableSecurityProvider(); assertNotNull( SecurityHelper.getKeyGenerator("AES") ); } @Test public void testGetKeyGeneratorThrows() throws Exception { try { SecurityHelper.getKeyGenerator("AMD"); fail(); } catch (NoSuchAlgorithmException e) { // OK } try { SecurityHelper.getKeyGenerator("AMD", savedProvider); fail(); } catch (NoSuchAlgorithmException e) { // OK } } @Test public void testCertificateFactoryProviderStaysConstant() throws Exception { Provider[] registeredProviders = Security.getProviders(); try { // clear previous providers for (Provider provider : registeredProviders) Security.removeProvider(provider.getName()); CertificateFactory certFactory1 = SecurityHelper.getCertificateFactory("X.509"); CertificateFactory certFactory2 = SecurityHelper.getCertificateFactory("X.509"); assertSame(certFactory1.getProvider(), certFactory2.getProvider()); } finally { // clear any added by the test for (Provider provider : Security.getProviders()) Security.removeProvider(provider.getName()); // restore previous providers for (Provider provider : registeredProviders) Security.addProvider(provider); } } } jruby-openssl-0.9.21/src/test/java/org/jruby/ext/openssl/SignatureSpiFake.java000066400000000000000000000042751313661621600273770ustar00rootroot00000000000000/* * The MIT License * * Copyright 2014 Karol Bucek. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.jruby.ext.openssl; import java.security.*; /** * Created by cmeier on 7/29/15. */ class SignatureSpiFake extends Signature { SignatureSpiFake() { super("fake"); } @Override protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { } @Override protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException { } @Override protected void engineUpdate(byte b) throws SignatureException { } @Override protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { } @Override protected byte[] engineSign() throws SignatureException { return new byte[0]; } @Override protected boolean engineVerify(byte[] sigBytes) throws SignatureException { return false; } @Override protected void engineSetParameter(String param, Object value) throws InvalidParameterException { } @Override protected Object engineGetParameter(String param) throws InvalidParameterException { return null; } } jruby-openssl-0.9.21/src/test/java/org/jruby/ext/openssl/security/000077500000000000000000000000001313661621600251675ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/java/org/jruby/ext/openssl/security/SecurityManager.java000066400000000000000000000044611313661621600311410ustar00rootroot00000000000000package org.jruby.ext.openssl.security; import org.jruby.Ruby; import org.jruby.RubyString; import org.jruby.runtime.builtin.IRubyObject; import java.util.ArrayList; import java.util.List; public class SecurityManager extends java.lang.SecurityManager { public static class RubyPermission { private final IRubyObject lambda; public RubyPermission(IRubyObject lambda) { this.lambda = lambda; } public boolean matches(java.security.Permission perm) { Ruby runtime = lambda.getRuntime(); return lambda.callMethod(runtime.getCurrentContext(), "call", new IRubyObject[] { RubyString.newString(runtime, perm.getClass().getSimpleName()), RubyString.newString(runtime, perm.getName()), RubyString.newString(runtime, perm.getActions()) }).isTrue(); } } /* public static SecurityManager install() { SecurityManager manager = new SecurityManager(); System.setSecurityManager(manager); return manager; } */ private boolean verbose = false; private boolean strict = false; private final List temporaryPermissions = new ArrayList(); @Override public void checkPermission(java.security.Permission perm) { for (RubyPermission permission: temporaryPermissions) { if (permission.matches(perm)) { return; } } if (strict) { logTrace(perm.toString() + " denied"); super.checkPermission(perm); } } public SecurityManager setStrict(boolean strict) { this.strict = strict; return this; } public SecurityManager permit(RubyPermission permission) { temporaryPermissions.add(permission); return this; } public SecurityManager revoke(RubyPermission permission) { temporaryPermissions.remove(permission); return this; } public SecurityManager setVerbosity(boolean verbose) { this.verbose = verbose; return this; } private void logTrace(String message) { if (verbose) { new Exception(message).printStackTrace(); } } } jruby-openssl-0.9.21/src/test/ossl/000077500000000000000000000000001313661621600171525ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ossl/ut_eof.rb000066400000000000000000000052521313661621600207640ustar00rootroot00000000000000require 'test/unit' module TestEOF def test_eof_0 open_file("") {|f| assert_equal("", f.read(0)) assert_equal("", f.read(0)) assert_equal("", f.read) assert_nil(f.read(0)) assert_nil(f.read(0)) } open_file("") {|f| assert_nil(f.read(1)) assert_equal("", f.read) assert_nil(f.read(1)) } open_file("") {|f| s = "x" assert_equal("", f.read(nil, s)) assert_equal("", s) } open_file("") {|f| s = "x" assert_nil(f.read(10, s)) assert_equal("", s) } end def test_eof_0_rw return unless respond_to? :open_file_rw open_file_rw("") {|f| assert_equal("", f.read) assert_equal("", f.read) assert_equal(0, f.syswrite("")) assert_equal("", f.read) } end def test_eof_1 open_file("a") {|f| assert_equal("", f.read(0)) assert_equal("a", f.read(1)) assert_equal("" , f.read(0)) assert_equal("" , f.read(0)) assert_equal("", f.read) assert_nil(f.read(0)) assert_nil(f.read(0)) } open_file("a") {|f| assert_equal("a", f.read(1)) assert_nil(f.read(1)) } open_file("a") {|f| assert_equal("a", f.read(2)) assert_nil(f.read(1)) assert_equal("", f.read) assert_nil(f.read(1)) } open_file("a") {|f| assert_equal("a", f.read) assert_nil(f.read(1)) assert_equal("", f.read) assert_nil(f.read(1)) } open_file("a") {|f| assert_equal("a", f.read(2)) assert_equal("", f.read) assert_equal("", f.read) } open_file("a") {|f| assert_equal("a", f.read) assert_nil(f.read(0)) } open_file("a") {|f| s = "x" assert_equal("a", f.read(nil, s)) assert_equal("a", s) } open_file("a") {|f| s = "x" assert_equal("a", f.read(10, s)) assert_equal("a", s) } end def test_eof_2 open_file("") {|f| assert_equal("", f.read) assert(f.eof?) } end def test_eof_3 open_file("") {|f| assert(f.eof?) } end module Seek def open_file_seek(content, pos) open_file(content) do |f| f.seek(pos) yield f end end def test_eof_0_seek open_file_seek("", 10) {|f| assert_equal(10, f.pos) assert_equal("", f.read(0)) assert_equal("", f.read) assert_nil(f.read(0)) assert_equal("", f.read) } end def test_eof_1_seek open_file_seek("a", 10) {|f| assert_equal("", f.read) assert_equal("", f.read) } open_file_seek("a", 1) {|f| assert_equal("", f.read) assert_equal("", f.read) } end end end jruby-openssl-0.9.21/src/test/ruby/000077500000000000000000000000001313661621600171535ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/dsa/000077500000000000000000000000001313661621600177225ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/dsa/private_key.pem000066400000000000000000000012341313661621600227470ustar00rootroot00000000000000-----BEGIN DSA PRIVATE KEY----- MIIBugIBAAKBgQDpdW60slBJrsrXrsputlqXFlT70CA0czpJZWbppiv4fed941TN /v/ICLjrNcsWXMbU5hb4faPrMZpAbUuIK+tMtJzz7sWMiINtso1FlQE/sUYBFqCv Tmkj52N0dPGsE7qmZ6ZknaJn6DbrAL569+5NIe9CR6cTtwL4IPWVXT3HQQIVAJqv o3Yrj85paNmGTIZfVt/oymAFAoGAb+S//7DQc6S/AK6r26BpQ/C4swSx1MTSl490 hBJw0Czns5djqz9QB6ELufshGES1gcDGrYIncxQTGw1tPoJVrA+kefPVbRaYs2qM HasEfM1GfILfu4XDBB4xAoFryjKizOu8MwEXTsPLiTe9MdiT90NfcgSyIty1FgFP ZSz0JLMCgYBmAYli6D4DGB05NCVXBWPiu42c78gGCgibrbvCXpozB22TdMWA41ho 7Oy7diBJLuJPUdmSsK++RE0bxlDl6QfmxTqfdb0ZUZ4u2bC9VeSM8ZtkbtxRpJGU p6znJdL83f05H2bhkKWI6a+vj894wRbtj+ube2UZPgKHFvkgdv732QIUKPp2Kkq+ UQDoq2xu7v84G0sFIhc= -----END DSA PRIVATE KEY----- jruby-openssl-0.9.21/src/test/ruby/dsa/test_dsa.rb000066400000000000000000000041571313661621600220640ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('../test_helper', File.dirname(__FILE__)) class TestDSA < TestCase def setup super self.class.disable_security_restrictions! require 'base64' end def test_dsa_param_accessors key_file = File.join(File.dirname(__FILE__), 'private_key.pem') key = OpenSSL::PKey::DSA.new(File.read(key_file)) [:priv_key, :pub_key, :p, :q, :g].each do |param| dsa = OpenSSL::PKey::DSA.new assert_nil(dsa.send(param)) value = key.send(param) dsa.send("#{param}=", value) assert_equal(value, dsa.send(param), param) end end def test_dsa_from_params_private_first key_file = File.join(File.dirname(__FILE__), 'private_key.pem') key = OpenSSL::PKey::DSA.new(File.read(key_file)) dsa = OpenSSL::PKey::DSA.new dsa.priv_key, dsa.p, dsa.q, dsa.g = key.priv_key, key.p, key.q, key.g assert(dsa.private?) assert(!dsa.public?) [:priv_key, :p, :q, :g].each do |param| assert_equal(key.send(param), dsa.send(param), param) end dsa.pub_key = key.pub_key assert(dsa.private?) assert(dsa.public?) [:priv_key, :pub_key, :p, :q, :g].each do |param| assert_equal(key.send(param), dsa.send(param), param) end end def test_dsa_from_params_public_first key_file = File.join(File.dirname(__FILE__), 'private_key.pem') key = OpenSSL::PKey::DSA.new(File.read(key_file)) dsa = OpenSSL::PKey::DSA.new dsa.pub_key, dsa.p, dsa.q, dsa.g = key.pub_key, key.p, key.q, key.g assert(!dsa.private?) assert(dsa.public?) [:pub_key, :p, :q, :g].each do |param| assert_equal(key.send(param), dsa.send(param), param) end dsa.priv_key = key.priv_key assert(dsa.private?) assert(dsa.public?) [:priv_key, :pub_key, :p, :q, :g].each do |param| assert_equal(key.send(param), dsa.send(param), param) end end def test_dsa_sys_sign_verify dsa = OpenSSL::PKey::DSA.new(1024) doc = 'Sign ME!' digest = OpenSSL::Digest::SHA1.digest(doc) sig = dsa.syssign(digest) puts sig.inspect if $VERBOSE assert dsa.sysverify(digest, sig).eql?(true) end end jruby-openssl-0.9.21/src/test/ruby/ec/000077500000000000000000000000001313661621600175425ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/ec/base64.rb000066400000000000000000000007521313661621600211570ustar00rootroot00000000000000require 'base64' Base64.module_eval do def self.strict_encode64(bin) [ bin ].pack("m0") end unless defined? Base64.strict_encode64 def self.urlsafe_encode64(bin) strict_encode64(bin).tr("+/", "-_") end unless defined? Base64.urlsafe_encode64 def self.strict_decode64(str) str.unpack("m0").first end unless defined? Base64.strict_decode64 def self.urlsafe_decode64(str) strict_decode64(str.tr("-_", "+/")) end unless defined? Base64.urlsafe_decode64 endjruby-openssl-0.9.21/src/test/ruby/ec/ece.rb000066400000000000000000000123441313661621600206270ustar00rootroot00000000000000class ECE KEY_LENGTH=16 TAG_LENGTH=16 NONCE_LENGTH=12 SHA256_LENGTH=32 def self.hmac_hash(key, input) digest = OpenSSL::Digest.new('sha256') OpenSSL::HMAC.digest(digest, key, input) end def self.hkdf_extract(salt, ikm) #ikm stays for input keying material hmac_hash(salt,ikm) end def self.get_info(type, client_public, server_public) cl_len_no = [client_public.size].pack('n') sv_len_no = [server_public.size].pack('n') "Content-Encoding: #{type}\x00P-256\x00#{cl_len_no}#{client_public}#{sv_len_no}#{server_public}" end def self.extract_key(params) raise "Salt must be 16-bytes long" unless params[:salt].length==16 input_key = params[:key] auth = false if params.has_key?(:auth) # Encrypted Content Encoding, March 11 2016, http://httpwg.org/http-extensions/draft-ietf-httpbis-encryption-encoding.html auth = true input = HKDF.new(input_key, {salt: params[:auth] , algorithm: 'sha256', info: "Content-Encoding: auth\x00"}) input_key = input.next_bytes(SHA256_LENGTH) secret = HKDF.new(input_key, {salt: params[:salt], algorithm: 'sha256', info: get_info("aesgcm", params[:user_public_key], params[:server_public_key])}) nonce = HKDF.new(input_key, salt: params[:salt], algorithm: 'sha256', info: get_info("nonce", params[:user_public_key], params[:server_public_key])) else secret = HKDF.new(input_key, {salt: params[:salt], algorithm: 'sha256', info: "Content-Encoding: aesgcm128"}) nonce = HKDF.new(input_key, salt: params[:salt], algorithm: 'sha256', info: "Content-Encoding: nonce") end {key: secret.next_bytes(KEY_LENGTH), nonce: nonce.next_bytes(NONCE_LENGTH), auth: auth} end def self.generate_nonce(nonce, counter) raise "Nonce must be #{NONCE_LENGTH} bytes long." unless nonce.length == NONCE_LENGTH output = nonce.dup integer = nonce[-6..-1].unpack('B*')[0].to_i(2) #taking last 6 bytes, treating as integer x = ((integer ^ counter) & 0xffffff) + ((((integer / 0x1000000) ^ (counter / 0x1000000)) & 0xffffff) * 0x1000000) bytestring = x.to_s(16).length < 12 ? "0"*(12-x.to_s(16).length)+x.to_s(16) : x.to_s(16) #it's for correct handling of cases when generated integer is less than 6 bytes output[-6..-1] = [bytestring].pack('H*') #without it packing would produce less than 6 bytes output #I didn't find pack directive for such usage, so there is a such solution end def self.encrypt(data, params) key = extract_key(params) rs = params[:rs] ? params [:rs] : 4096 padsize = params[:padsize] ? params [:padsize] : 0 raise "The rs parameter must be greater than 1." if rs <= 1 rs -=1 #this ensures encrypted data cannot be truncated result = "" pad_bytes = 1 if params[:auth] # old spec used 1 byte for padding, latest one always uses 2 bytes pad_bytes = 2 end counter = 0 (0..data.length).step(rs-pad_bytes+1) do |i| block = encrypt_record(key, counter, data[i..i+rs-pad_bytes], padsize) result += block counter +=1 end result end def self.decrypt(data, params) key = extract_key(params) rs = params[:rs] ? params [:rs] : 4096 raise "The rs parameter must be greater than 1." if rs <= 1 rs += TAG_LENGTH raise "Message is truncated" if data.length % rs == 0 result = "" counter = 0 (0..data.length).step(rs) do |i| block = decrypt_record(key, counter, data[i..i+rs-1]) result += block counter +=1 end result end def self.decrypt_record(params, counter, buffer, pad=0) gcm = OpenSSL::Cipher.new('aes-128-gcm') gcm.decrypt gcm.key = params[:key] gcm.iv = generate_nonce(params[:nonce], counter) pad_bytes = 1 if params[:auth] # old spec used 1 byte for padding, latest one always uses 2 bytes pad_bytes = 2 end raise "Block is too small" if buffer.length <= TAG_LENGTH+pad_bytes gcm.auth_tag = buffer[-TAG_LENGTH..-1] decrypted = gcm.update(buffer[0..-TAG_LENGTH-1]) + gcm.final if params[:auth] padding_length = decrypted[0..1].unpack("n")[0] raise "Padding is too big" if padding_length+2 > decrypted.length padding = decrypted[2..padding_length] raise "Wrong padding" unless padding = "\x00"*padding_length return decrypted[2+padding_length..-1] else padding_length = decrypted[0].unpack("C")[0] raise "Padding is too big" if padding_length+1 > decrypted.length padding = decrypted[1..padding_length] raise "Wrong padding" unless padding = "\x00"*padding_length return decrypted[1..-1] end end def self.encrypt_record(params, counter, buffer, pad=0) gcm = OpenSSL::Cipher.new('aes-128-gcm') gcm.encrypt gcm.key = params[:key] gcm.iv = generate_nonce(params[:nonce], counter) gcm.auth_data = "" padding = "" if params[:auth] padding = [pad].pack('n') + "\x00"*pad # 2 bytes, big endian, then n zero bytes of padding buf = padding+buffer record = gcm.update(buf) else record = gcm.update("\x00"+buffer) # 1 padding byte, not fully implemented end enc = record + gcm.final + gcm.auth_tag enc end end jruby-openssl-0.9.21/src/test/ruby/ec/hkdf.rb000066400000000000000000000032631313661621600210070ustar00rootroot00000000000000require 'stringio' class HKDF DefaultAlgorithm = 'SHA256' DefaultReadSize = 512 * 1024 def initialize(source, options = {}) source = StringIO.new(source) if source.is_a?(String) algorithm = options.fetch(:algorithm, DefaultAlgorithm) @digest = OpenSSL::Digest.new(algorithm) @info = options.fetch(:info, '') salt = options[:salt] salt = 0.chr * @digest.digest_length if salt.nil? or salt.empty? read_size = options.fetch(:read_size, DefaultReadSize) @prk = _generate_prk(salt, source, read_size) @position = 0 @blocks = [] @blocks << '' end def algorithm @digest.name end def max_length @max_length ||= @digest.digest_length * 255 end def seek(position) raise RangeError.new("cannot seek past #{max_length}") if position > max_length @position = position end def rewind seek(0) end def next_bytes(length) new_position = length + @position raise RangeError.new("requested #{length} bytes, only #{max_length} available") if new_position > max_length _generate_blocks(new_position) start = @position @position = new_position @blocks.join('').slice(start, length) end def next_hex_bytes(length) next_bytes(length).unpack('H*').first end def _generate_prk(salt, source, read_size) hmac = OpenSSL::HMAC.new(salt, @digest) while block = source.read(read_size) hmac.update(block) end hmac.digest end def _generate_blocks(length) start = @blocks.size block_count = (length.to_f / @digest.digest_length).ceil start.upto(block_count) do |n| @blocks << OpenSSL::HMAC.digest(@digest, @prk, @blocks[n - 1] + @info + n.chr) end end end jruby-openssl-0.9.21/src/test/ruby/ec/private_key.pem000066400000000000000000000002261313661621600225670ustar00rootroot00000000000000-----BEGIN EC PRIVATE KEY----- MD4CAQEEDrtUuJOpUTwJpjf3LJUuoAcGBSuBBAAGoSADHgAEe2LZ/iq6+RafJRYv bkJPniq3aSf9nv1Xu+DMMg== -----END EC PRIVATE KEY----- jruby-openssl-0.9.21/src/test/ruby/ec/private_key2.pem000066400000000000000000000005511313661621600226520ustar00rootroot00000000000000-----BEGIN EC PRIVATE KEY----- MIHaAgEBBEAJF2SrSI8nWVc9JR3qfvmwBpCmb0x5XUc8Tzc1KZ4DtJrg+5Ut6vQR QK7YIZifynst7q7DODVhgf/D16L8069GoAsGCSskAwMCCAEBDqGBhQOBggAEB/T1 u6sxFny3OW83HXVFXaBUkJtkyByyb3HNuFXSshr3VAozUbHtB8avShcy2jBTULd3 FOzTj5R/ME5egOG1fTMQRSxM85r/cSKFguiJkZGGWETwXvlJ7LRhy5GSeV2fgwLV TS/ljdy6ho/E+pfViDqIZa+FSTBhbB67TZlbJQw= -----END EC PRIVATE KEY----- jruby-openssl-0.9.21/src/test/ruby/ec/test_ec.rb000066400000000000000000000240331313661621600215170ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('../test_helper', File.dirname(__FILE__)) class TestEC < TestCase def test_read_pem key_file = File.join(File.dirname(__FILE__), 'private_key.pem') key = OpenSSL::PKey::EC.new(File.read(key_file)) assert_equal '3799522885287541632525744605009198', key.private_key.to_s if defined? JRUBY_VERSION #puts key.to_java.getPublicKey.to_s #x = key.to_java.getPublicKey.getW.getAffineX #y = key.to_java.getPublicKey.getW.getAffineY #puts 'X: ' + x.to_s #puts 'Y: ' + y.to_s end #puts exp = '120833863706476653138797887024101356894168914780792837123086246530098' #puts key.public_key.to_bn.to_s(16) assert_equal '120833863706476653138797887024101356894168914780792837123086246530098', key.public_key.to_bn.to_s assert_equal 'secp112r1', key.group.curve_name group = key.group # TODO seems to not match under JRuby+BC ?! #assert_equal "\x00\xF5\v\x02\x8EMinghuaQu)\x04rx?\xB1", group.seed assert_equal '1', group.cofactor.to_s assert_equal '112', group.degree.to_s assert_equal '4451685225093714776491891542548933', group.order.to_s #pem = key.to_pem #puts pem #assert_equal(pem, OpenSSL::PKey::EC.new(pem).to_pem) end def test_read_pem2 key_file = File.join(File.dirname(__FILE__), 'private_key2.pem') key = OpenSSL::PKey::EC.new(File.read(key_file)) assert_equal '476154198002596104803238069251020502662523042506824360051479804577598604971468345833166876271341274102391714812706759347009731580016190266434110134398790', key.private_key.to_s assert_equal '724664761298071194184067291718596276558181552214511004334530978676843312147340497441492810597004957502007504373782147802415558443578478808342286909152917608996652942169120263280723117356614533448503051685400082877326382909445989024396491709450773515529281107708539356521507912663674257568110287055756424062220', key.public_key.to_bn.to_s assert_equal 'brainpoolP512t1', key.group.curve_name group = key.group assert_equal nil, group.seed assert_equal '1', group.cofactor.to_s assert_equal '512', group.degree.to_s assert_equal '8948962207650232551656602815159153422162609644098354511344597187200057010413418528378981730643524959857451398370029280583094215613882043973354392115544169', group.order.to_s #signature = key.dsa_sign_asn1('foo') #puts signature.inspect end def test_point group = OpenSSL::PKey::EC::Group.new('prime256v1') client_public_key_bn = OpenSSL::BN.new('58089019511196532477248433747314139754458690644712400444716868601190212265537817278966641566813745621284958192417192818318052462970895792919572995957754854') binary = "\x04U\x1D6|\xA9\x14\eC\x13\x99b\x96\x9B\x94f\x8F\xB0o\xE2\xD3\xBC%\x8E\xE0Xn\xF2|R\x99b\xBD\xBFB\x8FS\xCF\x13\x7F\x8C\x03N\x96\x9D&\xB2\xE1\xBDQ\b\xCE\x94!s\x06.\xC5?\x96\xC7q\xDA\x8B\xE6" client_public_key = OpenSSL::PKey::EC::Point.new(group, client_public_key_bn) assert_equal binary, client_public_key.to_bn.to_s(2) end require File.expand_path('base64.rb', File.dirname(__FILE__)) def test_encrypt p256dh = "BNFege3oh74znsDbVkGf5CRAtLVUHlo5NTU9-inepE_HpUBWUq3FP_dJR-WDORPvKL7fM_AKyfYch-nKY7kDOe0=" group_name = 'prime256v1' server = OpenSSL::PKey::EC.new(group_name) # assert server.group.nil? # TODO MRI has a "null" group server.private_key = OpenSSL::BN.new('107411000028178101972699773683980269641478018566010848092863514011724406285076') # '62303413620263991527470772975506242387142677576794087805856701493545918209262092657150628139966331940997693252502978347289754390001755240229834360187731879' group = OpenSSL::PKey::EC::Group.new(group_name) client_public_key_bn = OpenSSL::BN.new(Base64.urlsafe_decode64(p256dh), 2) # puts client_public_key_bn client_public_key = OpenSSL::PKey::EC::Point.new(group, client_public_key_bn) expected = "\xC1\xF9\xF3\xA2-n\xD1z\xBB\xE0\xDA\xDF\xB6\xFF\x8A\xAAR\"\xA7\b\xED\x0E\x83\xAA\x03s\xB0\xECtN\xF4\xC3" assert_equal expected, server.dh_compute_key(client_public_key) end def test_encrypt_integration # inspired by WebPush require File.expand_path('ece.rb', File.dirname(__FILE__)) unless defined? ECE require File.expand_path('hkdf.rb', File.dirname(__FILE__)) unless defined? HKDF p256dh = Base64.urlsafe_encode64 generate_ecdh_key auth = Base64.urlsafe_encode64 Random.new.bytes(16) payload = Encryption.encrypt("Hello World", p256dh, auth) encrypted = payload.fetch(:ciphertext) decrypted_data = ECE.decrypt(encrypted, :key => payload.fetch(:shared_secret), :salt => payload.fetch(:salt), :server_public_key => payload.fetch(:server_public_key_bn), :user_public_key => Base64.urlsafe_decode64(p256dh), :auth => Base64.urlsafe_decode64(auth)) assert_equal "Hello World", decrypted_data end if RUBY_VERSION > '1.9' def generate_ecdh_key(group = 'prime256v1') curve = OpenSSL::PKey::EC.new(group) curve.generate_key str = curve.public_key.to_bn.to_s(2) puts "curve.public_key.to_bn.to_s(2): #{str.inspect}" if $VERBOSE str end private :generate_ecdh_key module Encryption # EC + (symmetric) AES GCM AAED encryption extend self def encrypt(message, p256dh, auth) group_name = "prime256v1" salt = Random.new.bytes(16) server = OpenSSL::PKey::EC.new(group_name) server.generate_key server_public_key_bn = server.public_key.to_bn group = OpenSSL::PKey::EC::Group.new(group_name) client_public_key_bn = OpenSSL::BN.new(Base64.urlsafe_decode64(p256dh), 2) #puts client_public_key_bn.to_s if $VERBOSE client_public_key = OpenSSL::PKey::EC::Point.new(group, client_public_key_bn) shared_secret = server.dh_compute_key(client_public_key) client_auth_token = Base64.urlsafe_decode64(auth) prk = HKDF.new(shared_secret, :salt => client_auth_token, :algorithm => 'SHA256', :info => "Content-Encoding: auth\0").next_bytes(32) context = create_context(client_public_key_bn, server_public_key_bn) content_encryption_key_info = create_info('aesgcm', context) content_encryption_key = HKDF.new(prk, :salt => salt, :info => content_encryption_key_info).next_bytes(16) nonce_info = create_info('nonce', context) nonce = HKDF.new(prk, :salt => salt, :info => nonce_info).next_bytes(12) ciphertext = encrypt_payload(message, content_encryption_key, nonce) { :ciphertext => ciphertext, :salt => salt, :shared_secret => shared_secret, :server_public_key_bn => convert16bit(server_public_key_bn) } end private def create_context(client_public_key, server_public_key) c = convert16bit(client_public_key) s = convert16bit(server_public_key) context = "\0" context += [c.bytesize].pack("n*") context += c context += [s.bytesize].pack("n*") context += s context end def encrypt_payload(plaintext, content_encryption_key, nonce) cipher = OpenSSL::Cipher.new('aes-128-gcm') cipher.encrypt cipher.key = content_encryption_key cipher.iv = nonce padding = cipher.update("\0\0") text = cipher.update(plaintext) e_text = padding + text + cipher.final e_tag = cipher.auth_tag e_text + e_tag end def create_info(type, context) info = "Content-Encoding: " info += type; info += "\0"; info += "P-256"; info += context info end def convert16bit(key) [key.to_s(16)].pack("H*") end end def setup super self.class.disable_security_restrictions! # @data1 = 'foo'; @data2 = 'bar' * 1000 # data too long for DSA sig @groups = []; @keys = [] OpenSSL::PKey::EC.builtin_curves.each do |curve, comment| next if curve.start_with?("Oakley") # Oakley curves are not suitable for ECDSA group = OpenSSL::PKey::EC::Group.new(curve) key = OpenSSL::PKey::EC.new(group) key.generate_key @groups << group; @keys << key end end def compare_keys(k1, k2) assert_equal(k1.to_pem, k2.to_pem) end def test_builtin_curves assert(!OpenSSL::PKey::EC.builtin_curves.empty?) end def test_curve_names @groups.each_with_index do |group, idx| key = @keys[idx] assert_equal(group.curve_name, key.group.curve_name) end end def test_check_key for key in @keys assert_equal(key.check_key, true) assert_equal(key.private_key?, true) assert_equal(key.public_key?, true) end end def test_group_encoding for group in @groups for meth in [:to_der, :to_pem] txt = group.send(meth) gr = OpenSSL::PKey::EC::Group.new(txt) assert_equal(txt, gr.send(meth)) assert_equal(group.generator.to_bn, gr.generator.to_bn) assert_equal(group.cofactor, gr.cofactor) assert_equal(group.order, gr.order) assert_equal(group.seed, gr.seed) assert_equal(group.degree, gr.degree) end end end if false # NOT-IMPLEMENTED def test_key_encoding for key in @keys group = key.group for meth in [:to_der, :to_pem] txt = key.send(meth) puts " #{key} #{key.group.curve_name} #{meth.inspect}" assert_equal(txt, OpenSSL::PKey::EC.new(txt).send(meth)) end bn = key.public_key.to_bn assert_equal(bn, OpenSSL::PKey::EC::Point.new(group, bn).to_bn) end end if false # NOT-IMPLEMENTED def test_set_keys for key in @keys k = OpenSSL::PKey::EC.new k.group = key.group k.private_key = key.private_key k.public_key = key.public_key compare_keys(key, k) end end if false # NOT-IMPLEMENTED TODO def test_dsa_sign_verify data1 = 'foo' for key in @keys sig = key.dsa_sign_asn1(data1) assert(key.dsa_verify_asn1(data1, sig)) end end if false # NOT-IMPLEMENTED # def test_dh_compute_key # for key in @keys # k = OpenSSL::PKey::EC.new(key.group) # k.generate_key # # puba = key.public_key # pubb = k.public_key # a = key.dh_compute_key(pubb) # b = k.dh_compute_key(puba) # assert_equal(a, b) # end # end endjruby-openssl-0.9.21/src/test/ruby/oaep/000077500000000000000000000000001313661621600200775ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/oaep/encrypted.key000066400000000000000000000015671313661621600226170ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDo6m+QZvYQ/xL0ElLgupK1QDcYL4f5PckwsNgS9pUvV7fzTqCH k8ThLxTk42MQ2McJsOeUJVP728KhymjFCqxgP4VuwRk9rpAl0+mhy6MPdyjyA6G1 4jrDWS65ysLchK4t/vwpEDz0SQlEoG1kMzllSm7zZS3XregA7DjNaUYQqwIDAQAB AoGBALGR6bRBit+yV5TUU3MZSrf8WQSLWDLgs/33FQSAEYSib4+DJke2lKbI6jkG UoSJgFUXFbaQLtMY2+3VDsMKPBdAge9gIdvbkC4yoKjLGm/FBDOxxZcfLpR+9OPq U3qM9D0CNuliBWI7Je+p/zs09HIYucpDXy9E18KA1KNF6rfhAkEA9KoNam6wAKnm vMzz31ws3RuIOUeo2rx6aaVY95+P9tTxd6U+pNkwxy1aCGP+InVSwlYNA1aQ4Axi /GdMIWMkxwJBAPO1CP7cQNZQmu7yusY+GUObDII5YK9WLaY4RAicn5378crPBFxv Ukqf9G6FHo7u88iTCIp+vwa3Hn9Tumg3iP0CQQDgUXWBasCVqzCxU5wY4tMDWjXY hpoLCpmVeRML3dDJt004rFm2HKe7Rhpw7PTZNQZOxUSjFeA4e0LaNf838UWLAkB8 QfbHM3ffjhOg96PhhjINdVWoZCb230LBOHj/xxPfUmFTHcBEfQIBSJMxcrBFAnLL 9qPpMXymqOFk3ETz9DTlAj8E0qGbp78aVbTOtuwEwNJII+RPw+Zkc+lKR+yaWkAz fIXw527NPHH3+rnBG72wyZr9ud4LAum9jh+5No1LQpk= -----END RSA PRIVATE KEY----- jruby-openssl-0.9.21/src/test/ruby/oaep/test_oaep.rb000066400000000000000000000013711313661621600224110ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('../test_helper', File.dirname(__FILE__)) class TestOaep < TestCase def setup super self.class.disable_security_restrictions! require 'base64' end def test_oaep_decrypt key = File::read(File.join(File.dirname(__FILE__), 'encrypted.key')) base64_cipher_text = "s+ydnGyGfJlH6FPB21tYeAeeMKcqLuybw7lxArZIEGRjMNSn2LHNzUEwX/H6FQan5lKQPZxxU1tBuFP6sP27ektEIXgoIQm+PdxilJnNPVoDA9Wff93MMa9JG3VMsc0kbUNMmJf6SQcJ+IB3OyBPZfPrz6wbkwM2zVm9Y/oqFWM=" # create cleaned up key object key = OpenSSL::PKey::RSA.new(key) cipher_text = Base64.decode64(base64_cipher_text) # assert_nothing_raised { key.private_decrypt(cipher_text, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) # } end end jruby-openssl-0.9.21/src/test/ruby/pkcs5/000077500000000000000000000000001313661621600202005ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/pkcs5/test_pbkdf2.rb000066400000000000000000000040721313661621600227370ustar00rootroot00000000000000require File.expand_path('../test_helper', File.dirname(__FILE__)) module Jopenssl class TestPKCS5 < TestCase def test_pbkdf2_hmac_sha1 pass = 'secret' salt = 'sugar0' iter = 42 keylen = 24 expected = "\a\xB6I\xE1)\xD8\xA6\x84\xC8D\b\xB2h(]\xBA\x87\xDE\e\xFC\x7F\e\xC3\x06" expected.force_encoding('ASCII-8BIT') if ''.respond_to?(:force_encoding) assert_equal expected, OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) end def test_pbkdf2_hmac_sha1_with_empty_salt pass = ' ' expected = "\x81\e\xE9F\xD8op\xA6\x9D\xF4=\tX\x13\x82D\xF7\xF3\x7F\xC8aFR+" expected.force_encoding('ASCII-8BIT') if ''.respond_to?(:force_encoding) assert_equal expected, OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, '', 16, 24) end def test_pbkdf2_hmac pass = 'SecreT2' salt = '0123456789001234567890' digest = OpenSSL::Digest::MD5.new expected = "\xC10D2\x8F\xEA}\xF7ag\xB5\xC8Ad\xFBN9Ff\x9D}\xA6\a\x86\x8F\xC4&HI\x85\x89U" expected.force_encoding('ASCII-8BIT') if ''.respond_to?(:force_encoding) assert_equal expected, OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, 120, 48, digest) assert_equal expected, OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, 120, 48, digest) digest = OpenSSL::Digest::SHA256.new expected = "}\xF4\xE3\xBF\xA7u\xB3[l\xE0(\x84\x96W\xFA\x00h\xA1l#\xB8\xC0Ptirz\v\xBA\x0Es\n<\xF8\xB5(\x85\xDA\xFE\x02y\x14\xB5A`\x8F\xA3\x03\x95\xA7G\xB4pU\xB6pf=Q\x1Fz\x12u\x83" expected.force_encoding('ASCII-8BIT') if ''.respond_to?(:force_encoding) assert_equal expected, OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, 100, 64, digest) expected = "\x03\x1C\x86\xC7N?\xC3\xBC\xF30W\xEC\x9B\x89I\x8D\xE6|\xA1Y\xEF\bt\xB4\x17\xA9\x87\xCB\xEA\x7F\x92\xDB\x88N@\xCB\x17\xDF\xC4\x8F\xE48L\x1Dy<\xD8\x9B\x8Cx\x85\x93\n\xA3`\xE9]\x90\xA2\x10I[\xE9\x84" expected.force_encoding('ASCII-8BIT') if ''.respond_to?(:force_encoding) assert_equal expected, OpenSSL::PKCS5.pbkdf2_hmac(pass, salt, 100, 64, 'SHA512') end end endjruby-openssl-0.9.21/src/test/ruby/pkcs7/000077500000000000000000000000001313661621600202025ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/pkcs7/pkcs7_mime_enveloped.message000066400000000000000000000013441313661621600256510ustar00rootroot00000000000000MIME-Version: 1.0 Message-Id: <00103112005203.00349@amyemily.ig.com> Date: Tue, 31 Oct 2000 12:00:52 -0600 (Central Standard Time) From: User1 To: User2 Subject: Example 5.3 Content-Type: application/pkcs7-mime; name=smime.p7m; smime-type=enveloped-data Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7m MIIBHgYJKoZIhvcNAQcDoIIBDzCCAQsCAQAxgcAwgb0CAQAwJjASMRAwDgYDVQQDEwdDYXJ sUlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUABIGAC3EN5nGIiJi2lsGPcP 2iJ97a4e8kbKQz36zg6Z2i0yx6zYC4mZ7mX7FBs3IWg+f6KgCLx3M1eCbWx8+MDFbbpXadC DgO8/nUkUNYeNxJtuzubGgzoyEd8Ch4H/dd9gdzTd+taTEgS0ipdSJuNnkVY4/M652jKKHR LFf02hosdR8wQwYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBAgtaMXpRwZRNYAgDsiSf8Z9P43 LrY4OxUk660cu1lXeCSFOSOpOJ7FuVyU= jruby-openssl-0.9.21/src/test/ruby/pkcs7/pkcs7_mime_signed.message000066400000000000000000000030741313661621600251430ustar00rootroot00000000000000MIME-Version: 1.0 To: User2@examples.com From: aliceDss@examples.com Subject: Example 4.9 Message-Id: <021031164540300.304@examples.com> Date: Thu, 31 Oct 2002 16:45:14 -0300 Content-Type: application/pkcs7-mime; smime-type=signed-data; name=smime.p7m Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7m MIIDmQYJKoZIhvcNAQcCoIIDijCCA4YCAQExCTAHBgUrDgMCGjAtBgkqhkiG9w0BBwGgIAQ eDQpUaGlzIGlzIHNvbWUgc2FtcGxlIGNvbnRlbnQuoIIC4DCCAtwwggKboAMCAQICAgDIMA kGByqGSM44BAMwEjEQMA4GA1UEAxMHQ2FybERTUzAeFw05OTA4MTcwMTEwNDlaFw0zOTEyM zEyMzU5NTlaMBMxETAPBgNVBAMTCEFsaWNlRFNTMIIBtjCCASsGByqGSM44BAEwggEeAoGB AIGNze2D6gqeOT7CSCij5EeT3Q7XqA7sU8WrhAhP/5Thc0h+DNbzREjR/p+vpKGJL+HZMMg 23j+bv7dM3F9piuR10DcMkQiVm96nXvn89J8v3UOoi1TxP7AHCEdNXYjDw7Wz41UIddU5dh DEeL3/nbCElzfy5FEbteQJllzzflvbAhUA4kemGkVmuBPG2o+4NyErYov3k80CgYAmONAUi TKqOfs+bdlLWWpMdiM5BAI1XPLLGjDDHlBd3ZtZ4s2qBT1YwHuiNrhuB699ikIlp/R1z0oI Xks+kPht6pzJIYo7dhTpzi5dowfNI4W4LzABfG1JiRGJNkS9+MiVSlNWteL5c+waYTYfEX/ Cve3RUP+YdMLRgUpgObo2OQOBhAACgYBc47ladRSWC6l63eM/qeysXty9txMRNKYWiSgRI9 k0hmd1dRMSPUNbb+VRv/qJ8qIbPiR9PQeNW2PIu0WloErjhdbOBoA/6CN+GvIkq1MauCcNH u8Iv2YUgFxirGX6FYvxuzTU0pY39mFHssQyhPB+QUD9RqdjTjPypeL08oPluKOBgTB/MAwG A1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMB8GA1UdIwQYMBaAFHBEPoIub4feStN14z0 gvEMrk/EfMB0GA1UdDgQWBBS+bKGz48H37UNwpM4TAeL945f+zTAfBgNVHREEGDAWgRRBbG ljZURTU0BleGFtcGxlLmNvbTAJBgcqhkjOOAQDAzAAMC0CFFUMpBkfQiuJcSIzjYNqtT1na 79FAhUAn2FTUlQLXLLd2ud2HeIQUltDXr0xYzBhAgEBMBgwEjEQMA4GA1UEAxMHQ2FybERT UwICAMgwBwYFKw4DAhowCQYHKoZIzjgEAwQuMCwCFD1cSW6LIUFzeXle3YI5SKSBer/sAhQ mCq7s/CTFHOEjgASeUjbMpx5g6A== jruby-openssl-0.9.21/src/test/ruby/pkcs7/pkcs7_multipart_signed.message000066400000000000000000000035651313661621600262420ustar00rootroot00000000000000MIME-Version: 1.0 To: User2@examples.com From: aliceDss@examples.com Subject: Example 4.8 Message-Id: <020906002550300.249@examples.com> Date: Fri, 06 Sep 2002 00:25:21 -0300 Content-Type: multipart/signed; micalg=SHA1; boundary="----=_NextBoundry____Fri,_06_Sep_2002_00:25:21"; protocol="application/pkcs7-signature" This is a multi-part message in MIME format. ------=_NextBoundry____Fri,_06_Sep_2002_00:25:21 This is some sample content. ------=_NextBoundry____Fri,_06_Sep_2002_00:25:21 Content-Type: application/pkcs7-mime; name=smime.p7s Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7s MIIDdwYJKoZIhvcNAQcCoIIDaDCCA2QCAQExCTAHBgUrDgMCGjALBgkqhkiG9w0BBwGgggL gMIIC3DCCApugAwIBAgICAMgwCQYHKoZIzjgEAzASMRAwDgYDVQQDEwdDYXJsRFNTMB4XDT k5MDgxNzAxMTA0OVoXDTM5MTIzMTIzNTk1OVowEzERMA8GA1UEAxMIQWxpY2VEU1MwggG2M IIBKwYHKoZIzjgEATCCAR4CgYEAgY3N7YPqCp45PsJIKKPkR5PdDteoDuxTxauECE//lOFz SH4M1vNESNH+n6+koYkv4dkwyDbeP5u/t0zcX2mK5HXQNwyRCJWb3qde+fz0ny/dQ6iLVPE /sAcIR01diMPDtbPjVQh11Tl2EMR4vf+dsISXN/LkURu15AmWXPN+W9sCFQDiR6YaRWa4E8 baj7g3IStii/eTzQKBgCY40BSJMqo5+z5t2UtZakx2IzkEAjVc8ssaMMMeUF3dm1nizaoFP VjAe6I2uG4Hr32KQiWn9HXPSgheSz6Q+G3qnMkhijt2FOnOLl2jB80jhbgvMAF8bUmJEYk2 RL34yJVKU1a14vlz7BphNh8Rf8K97dFQ/5h0wtGBSmA5ujY5A4GEAAKBgFzjuVp1FJYLqXr d4z+p7Kxe3L23ExE0phaJKBEj2TSGZ3V1ExI9Q1tv5VG/+onyohs+JH09B41bY8i7RaWgSu OF1s4GgD/oI34a8iSrUxq4Jw0e7wi/ZhSAXGKsZfoVi/G7NNTSljf2YUeyxDKE8H5BQP1Gp 2NOM/Kl4vTyg+W4o4GBMH8wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBsAwHwYDVR0j BBgwFoAUcEQ+gi5vh95K03XjPSC8QyuT8R8wHQYDVR0OBBYEFL5sobPjwfftQ3CkzhMB4v3 jl/7NMB8GA1UdEQQYMBaBFEFsaWNlRFNTQGV4YW1wbGUuY29tMAkGByqGSM44BAMDMAAwLQ IUVQykGR9CK4lxIjONg2q1PWdrv0UCFQCfYVNSVAtcst3a53Yd4hBSW0NevTFjMGECAQEwG DASMRAwDgYDVQQDEwdDYXJsRFNTAgIAyDAHBgUrDgMCGjAJBgcqhkjOOAQDBC4wLAIUM/mG f6gkgp9Z0XtRdGimJeB/BxUCFGFFJqwYRt1WYcIOQoGiaowqGzVI ------=_NextBoundry____Fri,_06_Sep_2002_00:25:21-- jruby-openssl-0.9.21/src/test/ruby/pkcs7/test_attribute.rb000066400000000000000000000015021313661621600235670ustar00rootroot00000000000000require File.expand_path('../test_helper', File.dirname(__FILE__)) module PKCS7Test class TestAttribute < TestCase OctetString = org.bouncycastle.asn1.DEROctetString Attribute = org.jruby.ext.openssl.impl.Attribute def test_attributes val = OctetString.new("foo".to_java_bytes) val2 = OctetString.new("bar".to_java_bytes) attr = Attribute.create(123, 444, val) assert_raise NoMethodError do attr.type = 12 end assert_raise NoMethodError do attr.value = val2 end assert_equal 123, attr.type assert_equal val, attr.set.get(0) attr2 = Attribute.create(123, 444, val) assert_equal attr, attr2 assert_not_equal Attribute.create(124, 444, val), attr assert_not_equal Attribute.create(123, 444, val2), attr end end end jruby-openssl-0.9.21/src/test/ruby/pkcs7/test_bio.rb000066400000000000000000000024751313661621600223470ustar00rootroot00000000000000require File.expand_path('../pkcs7_helper', File.dirname(__FILE__)) module PKCS7Test class TestBIO < TestCase def setup; require 'jopenssl/load' end def test_string_bio_simple bio = BIO::from_string("abc") arr = Java::byte[20].new read = bio.gets(arr, 10) assert_equal 3, read assert_equal "abc".to_java_bytes.to_a, arr.to_a[0...read] end def test_string_bio_simple_with_newline bio = BIO::from_string("abc\n") arr = Java::byte[20].new read = bio.gets(arr, 10) assert_equal 4, read assert_equal "abc\n".to_java_bytes.to_a, arr.to_a[0...read] end def test_string_bio_simple_with_newline_and_more_data bio = BIO::from_string("abc\nfoo\n\nbar") arr = Java::byte[20].new read = bio.gets(arr, 10) assert_equal 4, read assert_equal "abc\n".to_java_bytes.to_a, arr.to_a[0...read] read = bio.gets(arr, 10) assert_equal 4, read assert_equal "foo\n".to_java_bytes.to_a, arr.to_a[0...read] read = bio.gets(arr, 10) assert_equal 1, read assert_equal "\n".to_java_bytes.to_a, arr.to_a[0...read] read = bio.gets(arr, 10) assert_equal 3, read assert_equal "bar".to_java_bytes.to_a, arr.to_a[0...read] read = bio.gets(arr, 10) assert_equal 0, read end end end jruby-openssl-0.9.21/src/test/ruby/pkcs7/test_mime.rb000066400000000000000000000147421313661621600225250ustar00rootroot00000000000000require File.expand_path('../pkcs7_helper', File.dirname(__FILE__)) module PKCS7Test class TestMIME < TestCase def test_find_header_returns_null_on_nonexisting_header headers = [] assert_nil Mime::DEFAULT.find_header(headers, "foo") headers = [MimeHeader.new("blarg", "bluff")] assert_nil Mime::DEFAULT.find_header(headers, "foo") end def test_find_header_returns_the_header_with_the_same_name hdr = MimeHeader.new("one", "two") assert_equal hdr, Mime::DEFAULT.find_header([hdr], "one") end def test_find_param_returns_null_on_nonexisting_param assert_nil Mime::DEFAULT.find_param(MimeHeader.new("one", "two", []), "foo") assert_nil Mime::DEFAULT.find_param(MimeHeader.new("one", "two", [MimeParam.new("hi", "ho")]), "foo") end def test_find_param_returns_the_param_with_the_same_name par = MimeParam.new("hox", "box") hdr = MimeHeader.new("one", "two", [par]) assert_equal par, Mime::DEFAULT.find_param(hdr, "hox") end def test_simple_parse_headers bio = BIO::from_string("Foo: bar") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size assert_equal MimeHeader.new("Foo", "bar"), result[0] assert_equal "foo", result[0].name end def test_simple_parse_headers2 bio = BIO::from_string("Foo:bar") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size assert_equal MimeHeader.new("Foo", "bar"), result[0] assert_equal "foo", result[0].name end def test_simple_parse_headers3 bio = BIO::from_string("Foo: bar") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size assert_equal MimeHeader.new("Foo", "bar"), result[0] assert_equal "foo", result[0].name end def test_simple_parse_headers4 bio = BIO::from_string("Foo: bar\n") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size assert_equal MimeHeader.new("Foo", "bar"), result[0] assert_equal "foo", result[0].name end def test_simple_parse_headers5 bio = BIO::from_string(" Foo : bar \n") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size assert_equal MimeHeader.new("Foo", "bar"), result[0] assert_equal "foo", result[0].name end def test_simple_parse_headers6 bio = BIO::from_string("Foo: bar;\n") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size assert_equal MimeHeader.new("Foo", "bar"), result[0] assert_equal "foo", result[0].name end def test_simple_parse_headers7 bio = BIO::from_string("Foo: bar;\nFlurg: blarg") result = Mime::DEFAULT.parse_headers(bio) assert_equal 2, result.size assert_equal MimeHeader.new("Foo", "bar"), result[0] assert_equal MimeHeader.new("Flurg", "blarg"), result[1] assert_equal "foo", result[0].name assert_equal "flurg", result[1].name end def test_simple_parse_headers_quotes bio = BIO::from_string("Foo: \"bar\"") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size assert_equal MimeHeader.new("Foo", "bar"), result[0] assert_equal "foo", result[0].name end def test_simple_parse_headers_comment bio = BIO::from_string("Foo: (this is the right thing)ba(and this is the wrong one)r") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size assert_equal MimeHeader.new("Foo", "(this is the right thing)ba(and this is the wrong one)r"), result[0] assert_equal "foo", result[0].name end def test_parse_headers_with_param bio = BIO::from_string("Content-Type: Multipart/Related; boundary=MIME_boundary; type=text/xml") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size header = result[0] assert_equal "content-type", header.name assert_equal "multipart/related", header.value assert_equal [MimeParam.new("boundary","MIME_boundary"), MimeParam.new("type","text/xml")], header.params.to_a end def test_parse_headers_with_param_newline bio = BIO::from_string("Content-Type: Multipart/Related\n boundary=MIME_boundary; type=text/xml") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size header = result[0] assert_equal "content-type", header.name assert_equal "multipart/related", header.value assert_equal [MimeParam.new("boundary","MIME_boundary"), MimeParam.new("type","text/xml")], header.params.to_a end def test_parse_headers_with_param_newline_and_semicolon bio = BIO::from_string("Content-Type: Multipart/Related;\n boundary=MIME_boundary;\n Type=text/xml") result = Mime::DEFAULT.parse_headers(bio) assert_equal 1, result.size header = result[0] assert_equal "content-type", header.name assert_equal "multipart/related", header.value assert_equal [MimeParam.new("boundary","MIME_boundary"), MimeParam.new("type","text/xml")], header.params.to_a end def test_advanced_mime_message bio = BIO::from_string(MultipartSignedString) result = Mime::DEFAULT.parse_headers(bio) assert_equal "mime-version", result[0].name assert_equal "1.0", result[0].value assert_equal "to", result[1].name assert_equal "user2@examples.com", result[1].value assert_equal "from", result[2].name assert_equal "alicedss@examples.com", result[2].value assert_equal "subject", result[3].name assert_equal "example 4.8", result[3].value assert_equal "message-id", result[4].name assert_equal "<020906002550300.249@examples.com>", result[4].value assert_equal "date", result[5].name assert_equal "fri, 06 sep 2002 00:25:21 -0300", result[5].value assert_equal "content-type", result[6].name assert_equal "multipart/signed", result[6].value assert_equal "micalg", result[6].params[0].param_name assert_equal "SHA1", result[6].params[0].param_value assert_equal "boundary", result[6].params[1].param_name assert_equal "----=_NextBoundry____Fri,_06_Sep_2002_00:25:21", result[6].params[1].param_value assert_equal "protocol", result[6].params[2].param_name assert_equal "application/pkcs7-signature", result[6].params[2].param_value assert_equal 3, result[6].params.length assert_equal 7, result.length end end end jruby-openssl-0.9.21/src/test/ruby/pkcs7/test_pkcs7.rb000066400000000000000000000615131313661621600226230ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('../pkcs7_helper', File.dirname(__FILE__)) module PKCS7Test class TestPKCS7 < TestCase def test_is_signed p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed assert p7.signed? assert !p7.encrypted? assert !p7.enveloped? assert !p7.signed_and_enveloped? assert !p7.data? assert !p7.digest? end def test_is_encrypted p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert !p7.signed? assert p7.encrypted? assert !p7.enveloped? assert !p7.signed_and_enveloped? assert !p7.data? assert !p7.digest? end def test_is_enveloped p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped assert !p7.signed? assert !p7.encrypted? assert p7.enveloped? assert !p7.signed_and_enveloped? assert !p7.data? assert !p7.digest? end def test_is_signed_and_enveloped p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped assert !p7.signed? assert !p7.encrypted? assert !p7.enveloped? assert p7.signed_and_enveloped? assert !p7.data? assert !p7.digest? end def test_is_data p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert !p7.signed? assert !p7.encrypted? assert !p7.enveloped? assert !p7.signed_and_enveloped? assert p7.data? assert !p7.digest? end def test_is_digest p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest assert !p7.signed? assert !p7.encrypted? assert !p7.enveloped? assert !p7.signed_and_enveloped? assert !p7.data? assert p7.digest? end def test_set_detached p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed sign = Signed.new p7.sign = sign test_p7 = PKCS7.new test_p7.type = ASN1Registry::NID_pkcs7_data test_p7.data = OctetString.new("foo".to_java_bytes) sign.contents = test_p7 p7.detached = 2 assert_equal 1, p7.get_detached assert_equal nil, test_p7.get_data end def test_set_not_detached p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed sign = Signed.new p7.sign = sign test_p7 = PKCS7.new test_p7.type = ASN1Registry::NID_pkcs7_data data = OctetString.new("foo".to_java_bytes) test_p7.data = data sign.contents = test_p7 p7.detached = 0 assert_equal 0, p7.get_detached assert_equal data, test_p7.get_data end def test_is_detached p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed sign = Signed.new p7.sign = sign test_p7 = PKCS7.new test_p7.type = ASN1Registry::NID_pkcs7_data data = OctetString.new("foo".to_java_bytes) test_p7.data = data sign.contents = test_p7 p7.detached = 1 assert p7.detached? end def test_is_detached_with_wrong_type p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert !p7.detached? end def _test_encrypt_generates_enveloped_pkcs7_object p7 = PKCS7.encrypt([], "".to_java_bytes, nil, 0) assert !p7.signed? assert !p7.encrypted? assert p7.enveloped? assert !p7.signed_and_enveloped? assert !p7.data? assert !p7.digest? end def test_set_type_throws_exception_on_wrong_argument assert_raise_pkcs7_exception do # 42 is a value that is not one of the valid NID's for type PKCS7.new.type = 42 end end def test_set_type_signed p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed assert p7.signed? assert_equal 1, p7.get_sign.version assert_nil p7.get_data assert_nil p7.get_enveloped assert_nil p7.get_signed_and_enveloped assert_nil p7.get_digest assert_nil p7.get_encrypted assert_nil p7.get_other end OctetString = org.bouncycastle.asn1.DEROctetString def test_set_type_data p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert p7.data? assert_equal OctetString.new("".to_java_bytes), p7.get_data assert_nil p7.get_sign assert_nil p7.get_enveloped assert_nil p7.get_signed_and_enveloped assert_nil p7.get_digest assert_nil p7.get_encrypted assert_nil p7.get_other end def test_set_type_signed_and_enveloped p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped assert p7.signed_and_enveloped? assert_equal 1, p7.get_signed_and_enveloped.version assert_equal ASN1Registry::NID_pkcs7_data, p7.get_signed_and_enveloped.enc_data.content_type assert_nil p7.get_sign assert_nil p7.get_enveloped assert_nil p7.get_data assert_nil p7.get_digest assert_nil p7.get_encrypted assert_nil p7.get_other end def test_set_type_enveloped p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped assert p7.enveloped? assert_equal 0, p7.get_enveloped.version assert_equal ASN1Registry::NID_pkcs7_data, p7.get_enveloped.enc_data.content_type assert_nil p7.get_sign assert_nil p7.get_signed_and_enveloped assert_nil p7.get_data assert_nil p7.get_digest assert_nil p7.get_encrypted assert_nil p7.get_other end def test_set_type_encrypted p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert p7.encrypted? assert_equal 0, p7.get_encrypted.version assert_equal ASN1Registry::NID_pkcs7_data, p7.get_encrypted.enc_data.content_type assert_nil p7.get_sign assert_nil p7.get_signed_and_enveloped assert_nil p7.get_data assert_nil p7.get_digest assert_nil p7.get_enveloped assert_nil p7.get_other end def test_set_type_digest p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest assert p7.digest? assert_equal 0, p7.get_digest.version assert_nil p7.get_sign assert_nil p7.get_signed_and_enveloped assert_nil p7.get_data assert_nil p7.get_encrypted assert_nil p7.get_enveloped assert_nil p7.get_other end def test_set_cipher_on_non_enveloped_object p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest assert_raise_pkcs7_exception do p7.cipher = nil end p7.type = ASN1Registry::NID_pkcs7_encrypted assert_raise_pkcs7_exception do p7.cipher = nil end p7.type = ASN1Registry::NID_pkcs7_data assert_raise_pkcs7_exception do p7.cipher = nil end p7.type = ASN1Registry::NID_pkcs7_signed assert_raise_pkcs7_exception do p7.cipher = nil end end def test_set_cipher_on_enveloped_object p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped c = javax.crypto.Cipher.getInstance("RSA") cipher = CipherSpec.new(c, "RSA", 128) p7.cipher = cipher assert_equal cipher, p7.get_enveloped.enc_data.cipher end def test_set_cipher_on_signed_and_enveloped_object p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped c = javax.crypto.Cipher.getInstance("RSA") cipher = CipherSpec.new(c, "RSA", 128) p7.cipher = cipher assert_equal cipher, p7.get_signed_and_enveloped.enc_data.cipher end def test_add_recipient_info_to_something_that_cant_have_recipients p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed assert_raise_pkcs7_exception do p7.add_recipient(X509Cert) end p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert_raise_pkcs7_exception do p7.add_recipient(X509Cert) end p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert_raise_pkcs7_exception do p7.add_recipient(X509Cert) end p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest assert_raise_pkcs7_exception do p7.add_recipient(X509Cert) end end def test_add_recipient_info_to_enveloped_should_add_that_to_stack p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped ri = p7.add_recipient(X509Cert) assert_equal 1, p7.get_enveloped.recipient_info.size assert_equal ri, p7.get_enveloped.recipient_info.iterator.next end def test_add_recipient_info_to_signed_and_enveloped_should_add_that_to_stack p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped ri = p7.add_recipient(X509Cert) assert_equal 1, p7.get_signed_and_enveloped.recipient_info.size assert_equal ri, p7.get_signed_and_enveloped.recipient_info.iterator.next end def test_add_signer_to_something_that_cant_have_signers p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped assert_raise_pkcs7_exception do p7.add_signer(SignerInfoWithPkey.new(nil, nil, nil, nil, nil, nil, nil)) end p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert_raise_pkcs7_exception do p7.add_signer(SignerInfoWithPkey.new(nil, nil, nil, nil, nil, nil, nil)) end p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert_raise_pkcs7_exception do p7.add_signer(SignerInfoWithPkey.new(nil, nil, nil, nil, nil, nil, nil)) end p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest assert_raise_pkcs7_exception do p7.add_signer(SignerInfoWithPkey.new(nil, nil, nil, nil, nil, nil, nil)) end end def test_add_signer_to_signed_should_add_that_to_stack p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed si = SignerInfoWithPkey.new(nil, nil, nil, nil, nil, nil, nil) p7.add_signer(si) assert_equal 1, p7.get_sign.signer_info.size assert_equal si, p7.get_sign.signer_info.iterator.next end def test_add_signer_to_signed_and_enveloped_should_add_that_to_stack p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped si = SignerInfoWithPkey.new(nil, nil, nil, nil, nil, nil, nil) p7.add_signer(si) assert_equal 1, p7.get_signed_and_enveloped.signer_info.size assert_equal si, p7.get_signed_and_enveloped.signer_info.iterator.next end BIG_ONE = BigInteger::ONE.to_java def create_signer_info_with_algo(algo) md5 = AlgorithmIdentifier.new(ASN1Registry.nid2obj(4)) SignerInfoWithPkey.new( ASN1Integer.new(BIG_ONE), IssuerAndSerialNumber.new(X500Name.new("C=SE"), BIG_ONE), algo, DERSet.new, md5, DEROctetString.new([].to_java(:byte)), DERSet.new ) end def test_add_signer_to_signed_with_new_algo_should_add_that_algo_to_the_algo_list p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed # YES, these numbers are correct. Don't change them. They are OpenSSL internal NIDs md5 = AlgorithmIdentifier.new(ASN1Registry.nid2obj(4)) md4 = AlgorithmIdentifier.new(ASN1Registry.nid2obj(5)) si = create_signer_info_with_algo(md5) p7.add_signer(si) assert_equal md5, p7.get_sign.md_algs.iterator.next assert_equal 1, p7.get_sign.md_algs.size si = create_signer_info_with_algo(md5) p7.add_signer(si) assert_equal md5, p7.get_sign.md_algs.iterator.next assert_equal 1, p7.get_sign.md_algs.size si = create_signer_info_with_algo(md4) p7.add_signer(si) assert_equal 2, p7.get_sign.md_algs.size assert p7.get_sign.md_algs.contains(md4) assert p7.get_sign.md_algs.contains(md5) end def test_add_signer_to_signed_and_enveloped_with_new_algo_should_add_that_algo_to_the_algo_list p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped # YES, these numbers are correct. Don't change them. They are OpenSSL internal NIDs md5 = AlgorithmIdentifier.new(ASN1Registry.nid2obj(4)) md4 = AlgorithmIdentifier.new(ASN1Registry.nid2obj(5)) si = create_signer_info_with_algo(md5) p7.add_signer(si) assert_equal md5, p7.get_signed_and_enveloped.md_algs.iterator.next assert_equal 1, p7.get_signed_and_enveloped.md_algs.size si = create_signer_info_with_algo(md5) p7.add_signer(si) assert_equal md5, p7.get_signed_and_enveloped.md_algs.iterator.next assert_equal 1, p7.get_signed_and_enveloped.md_algs.size si = create_signer_info_with_algo(md4) p7.add_signer(si) assert_equal 2, p7.get_signed_and_enveloped.md_algs.size assert p7.get_signed_and_enveloped.md_algs.contains(md4) assert p7.get_signed_and_enveloped.md_algs.contains(md5) end def test_set_content_on_data_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert_raise_pkcs7_exception do p7.setContent(PKCS7.new) end end def test_set_content_on_enveloped_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped assert_raise_pkcs7_exception do p7.setContent(PKCS7.new) end end def test_set_content_on_signed_and_enveloped_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped assert_raise_pkcs7_exception do p7.setContent(PKCS7.new) end end def test_set_content_on_encrypted_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert_raise_pkcs7_exception do p7.setContent(PKCS7.new) end end def test_set_content_on_signed_sets_the_content p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed p7new = PKCS7.new p7.setContent(p7new) assert_equal p7new, p7.get_sign.contents end def test_set_content_on_digest_sets_the_content p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest p7new = PKCS7.new p7.setContent(p7new) assert_equal p7new, p7.get_digest.contents end def test_get_signer_info_on_digest_returns_null p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest assert_nil p7.signer_info end def test_get_signer_info_on_data_returns_null p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert_nil p7.signer_info end def test_get_signer_info_on_encrypted_returns_null p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert_nil p7.signer_info end def test_get_signer_info_on_enveloped_returns_null p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped assert_nil p7.signer_info end def test_get_signer_info_on_signed_returns_signer_info p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed assert_equal p7.get_sign.signer_info.object_id, p7.signer_info.object_id end def test_get_signer_info_on_signed_and_enveloped_returns_signer_info p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped assert_equal p7.get_signed_and_enveloped.signer_info.object_id, p7.signer_info.object_id end def test_content_new_on_data_raises_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert_raise_pkcs7_exception do p7.content_new(ASN1Registry::NID_pkcs7_data) end end def test_content_new_on_encrypted_raises_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert_raise_pkcs7_exception do p7.content_new(ASN1Registry::NID_pkcs7_data) end end def test_content_new_on_enveloped_raises_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped assert_raise_pkcs7_exception do p7.content_new(ASN1Registry::NID_pkcs7_data) end end def test_content_new_on_signed_and_enveloped_raises_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped assert_raise_pkcs7_exception do p7.content_new(ASN1Registry::NID_pkcs7_data) end end def test_content_new_on_digest_creates_new_content p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest p7.content_new(ASN1Registry::NID_pkcs7_signedAndEnveloped) assert p7.get_digest.contents.signed_and_enveloped? p7.content_new(ASN1Registry::NID_pkcs7_encrypted) assert p7.get_digest.contents.encrypted? end def test_content_new_on_signed_creates_new_content p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed p7.content_new(ASN1Registry::NID_pkcs7_signedAndEnveloped) assert p7.get_sign.contents.signed_and_enveloped? p7.content_new(ASN1Registry::NID_pkcs7_encrypted) assert p7.get_sign.contents.encrypted? end def test_add_certificate_on_data_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert_raise_pkcs7_exception do p7.add_certificate(X509Cert) end end def test_add_certificate_on_enveloped_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped assert_raise_pkcs7_exception do p7.add_certificate(X509Cert) end end def test_add_certificate_on_encrypted_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert_raise_pkcs7_exception do p7.add_certificate(X509Cert) end end def test_add_certificate_on_digest_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest assert_raise_pkcs7_exception do p7.add_certificate(X509Cert) end end def test_add_certificate_on_signed_adds_the_certificate p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed p7.add_certificate(X509Cert) assert_equal 1, p7.get_sign.cert.size assert_equal X509Cert, p7.get_sign.cert.iterator.next end def test_add_certificate_on_signed_and_enveloped_adds_the_certificate p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped p7.add_certificate(X509Cert) assert_equal 1, p7.get_signed_and_enveloped.cert.size assert_equal X509Cert, p7.get_signed_and_enveloped.cert.get(0) end def test_add_crl_on_data_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_data assert_raise_pkcs7_exception do p7.add_crl(X509CRL) end end def test_add_crl_on_enveloped_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_enveloped assert_raise_pkcs7_exception do p7.add_crl(X509CRL) end end def test_add_crl_on_encrypted_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_encrypted assert_raise_pkcs7_exception do p7.add_crl(X509CRL) end end def test_add_crl_on_digest_throws_exception p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_digest assert_raise_pkcs7_exception do p7.add_crl(X509CRL) end end def test_add_crl_on_signed_adds_the_crl p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signed p7.add_crl(X509CRL) assert_equal 1, p7.get_sign.crl.size assert_equal X509CRL, p7.get_sign.crl.iterator.next end def test_add_crl_on_signed_and_enveloped_adds_the_crl p7 = PKCS7.new p7.type = ASN1Registry::NID_pkcs7_signedAndEnveloped p7.add_crl(X509CRL) assert_equal 1, p7.get_signed_and_enveloped.crl.size assert_equal X509CRL, p7.get_signed_and_enveloped.crl.get(0) end EXISTING_PKCS7_DEF = "0\202\002 \006\t*\206H\206\367\r\001\a\003\240\202\002\0210\202\002\r\002\001\0001\202\001\2700\201\331\002\001\0000B0=1\0230\021\006\n\t\222&\211\223\362,d\001\031\026\003org1\0310\027\006\n\t\222&\211\223\362,d\001\031\026\truby-lang1\v0\t\006\003U\004\003\f\002CA\002\001\0020\r\006\t*\206H\206\367\r\001\001\001\005\000\004\201\200\213kF\330\030\362\237\363$\311\351\207\271+_\310sr\344\233N\200\233)\272\226\343\003\224OOf\372 \r\301{\206\367\241\270\006\240\254\3179F\232\231Q\232\225\347\373\233\032\375\360\035o\371\275p\306\v5Z)\263\037\302|\307\300\327\a\375\023G'Ax\313\346\261\254\227K\026\364\242\337\367\362rk\276\023\217m\326\343F\366I1\263\nLuNf\234\203\261\300\030\232Q\277\231\f0\030\001\332\021\0030\201\331\002\001\0000B0=1\0230\021\006\n\t\222&\211\223\362,d\001\031\026\003org1\0310\027\006\n\t\222&\211\223\362,d\001\031\026\truby-lang1\v0\t\006\003U\004\003\f\002CA\002\001\0030\r\006\t*\206H\206\367\r\001\001\001\005\000\004\201\200\215\223\3428\2440]\0278\016\230,\315\023Tg\325`\376~\353\304\020\243N{\326H\003\005\361q\224OI\310\2324-\341?\355&r\215\233\361\245jF\255R\271\203D\304v\325\265\243\321$\bSh\031i\eS\240\227\362\221\364\232\035\202\f?x\031\223D\004ZHD\355'g\243\037\236mJ\323\210\347\274m\324-\351\332\353#A\273\002\"h\aM\202\347\236\265\aI$@\240bt=<\212\2370L\006\t*\206H\206\367\r\001\a\0010\035\006\t`\206H\001e\003\004\001\002\004\020L?\325\372\\\360\366\372\237|W\333nnI\255\200 \253\234\252\263\006\335\037\320\350{s\352r\337\304\305\216\223k\003\376f\027_\201\035#*\002yM\334" EXISTING_PKCS7_1 = PKCS7::from_asn1(ASN1InputStream.new(EXISTING_PKCS7_DEF.to_java_bytes).read_object) def test_encrypt_integration_test certs = [X509Cert] c = Cipher.get_instance("AES", BCP.new) cipher = CipherSpec.new(c, "AES-128-CBC", 128) data = "aaaaa\nbbbbb\nccccc\n".to_java_bytes PKCS7::encrypt(certs, data, cipher, PKCS7::BINARY) end EXISTING_PKCS7_PEM = < e assert e end end end end jruby-openssl-0.9.21/src/test/ruby/pkcs7/test_smime.rb000066400000000000000000000140041313661621600226770ustar00rootroot00000000000000require File.expand_path('../pkcs7_helper', File.dirname(__FILE__)) module PKCS7Test class TestSMIME < TestCase def test_read_pkcs7_should_raise_error_when_parsing_headers_fails bio = BIO.new mime = Mime.impl { |name, *args| name == :parseHeaders ? nil : raise } begin SMIME.new(mime).readPKCS7(bio, nil) assert false rescue PKCS7Exception => e e = e.cause if e.is_a?(NativeException) assert_equal PKCS7::F_SMIME_READ_PKCS7, e.get_method assert_equal PKCS7::R_MIME_PARSE_ERROR, e.get_reason end end def test_read_pkcs7_should_raise_error_when_content_type_is_not_there bio = BIO.new mime = Mime.impl {} headers = ArrayList.new mime.expects(:parseHeaders).with(bio).returns(headers) mime.expects(:findHeader).with(headers, "content-type").returns(nil) begin SMIME.new(mime).readPKCS7(bio, nil) assert false rescue PKCS7Exception => e e = e.cause if e.is_a?(NativeException) assert_equal PKCS7::F_SMIME_READ_PKCS7, e.get_method assert_equal PKCS7::R_NO_CONTENT_TYPE, e.get_reason end mime = Mime.impl {} mime.expects(:parseHeaders).with(bio).returns(headers) mime.expects(:findHeader).with(headers, "content-type").returns(MimeHeader.new("content-type", nil)) begin SMIME.new(mime).readPKCS7(bio, nil) assert false rescue PKCS7Exception => e e = e.cause if e.is_a?(NativeException) assert_equal PKCS7::F_SMIME_READ_PKCS7, e.get_method assert_equal PKCS7::R_NO_CONTENT_TYPE, e.get_reason end end def test_read_pkcs7_should_set_the_second_arguments_contents_to_null_if_its_there mime = Mime.impl { |name, *args| name == :parseHeaders ? raise("parseHeaders") : raise } bio2 = BIO.new arr = [bio2].to_java BIO begin SMIME.new(mime).readPKCS7(nil, arr) rescue => e assert_equal 'parseHeaders', e.message end assert_nil arr[0] arr = [bio2, bio2].to_java BIO begin SMIME.new(mime).readPKCS7(nil, arr) rescue end assert_nil arr[0] assert_equal bio2, arr[1] end def test_read_pkcs7_should_call_methods_on_mime bio = BIO.new mime = Mime.impl do |name, *args| case name when :parseHeaders then ArrayList.new when :findHeader then if args[1] == 'content-type' MimeHeader.new(args[1], "application/pkcs7-mime") else raise args.inspect end end end begin SMIME.new(mime).readPKCS7(bio, nil) rescue java.lang.UnsupportedOperationException # This error is expected, since the bio used is not a real one end end def test_read_pkcs7_throws_correct_exception_if_wrong_content_type bio = BIO.new mime = Mime.impl do |name, *args| case name when :parseHeaders then ArrayList.new when :findHeader then if args[1] == 'content-type' MimeHeader.new(args[1], "foo") else raise args.inspect end end end begin SMIME.new(mime).readPKCS7(bio, nil) assert false rescue PKCS7Exception => e e = e.cause if e.is_a?(NativeException) assert_equal PKCS7::F_SMIME_READ_PKCS7, e.get_method assert_equal PKCS7::R_INVALID_MIME_TYPE, e.get_reason assert_equal "type: foo", e.error_data end end def test_read_pkcs7_with_multipart_should_fail_if_no_boundary_found bio = BIO.new hdr = MimeHeader.new("content-type", "multipart/signed") mime = Mime.impl do |name, *args| case name when :parseHeaders then ArrayList.new when :findHeader then if args[1] == 'content-type' hdr else raise args.inspect end end end hdr = MimeHeader.new("content-type", "multipart/signed") mime.expects(:findParam).with(hdr, "boundary").returns(nil) begin SMIME.new(mime).readPKCS7(bio, nil) assert false rescue PKCS7Exception => e e = e.cause if e.is_a?(NativeException) assert_equal PKCS7::F_SMIME_READ_PKCS7, e.get_method assert_equal PKCS7::R_NO_MULTIPART_BOUNDARY, e.get_reason end end def test_read_pkcs7_with_multipart_should_fail_if_null_boundary_value bio = BIO.new mime = Mime.impl {} headers = ArrayList.new hdr = MimeHeader.new("content-type", "multipart/signed") mime.expects(:parseHeaders).with(bio).returns(headers) mime.expects(:findHeader).with(headers, "content-type").returns(hdr) mime.expects(:findParam).with(hdr, "boundary").returns(MimeParam.new("boundary", nil)) begin SMIME.new(mime).readPKCS7(bio, nil) assert false rescue PKCS7Exception => e e = e.cause if e.is_a?(NativeException) assert_equal PKCS7::F_SMIME_READ_PKCS7, e.get_method assert_equal PKCS7::R_NO_MULTIPART_BOUNDARY, e.get_reason end end # TODO: redo this test to be an integration test def _test_read_pkcs7_happy_path_without_multipart bio = BIO.new mime = Mime.impl {} headers = ArrayList.new mime.expects(:parseHeaders).with(bio).returns(headers) mime.expects(:findHeader).with(headers, "content-type").returns(MimeHeader.new("content-type", "application/pkcs7-mime")) SMIME.new(mime).readPKCS7(bio, nil) end def test_read_pkcs7_happy_path_multipart bio = BIO::from_string(MultipartSignedString) mime = Mime::DEFAULT SMIME.new(mime).readPKCS7(bio, nil) end def test_read_pkcs7_happy_path_without_multipart_enveloped bio = BIO::from_string(MimeEnvelopedString) mime = Mime::DEFAULT SMIME.new(mime).readPKCS7(bio, nil) end def test_read_pkcs7_happy_path_without_multipart_signed bio = BIO::from_string(MimeSignedString) mime = Mime::DEFAULT SMIME.new(mime).readPKCS7(bio, nil) end end end jruby-openssl-0.9.21/src/test/ruby/pkcs7_helper.rb000066400000000000000000000114041313661621600220660ustar00rootroot00000000000000require File.expand_path('test_helper', File.dirname(__FILE__)) module PKCS7Test PKCS7 = org.jruby.ext.openssl.impl.PKCS7 unless defined?(PKCS7) Attribute = org.jruby.ext.openssl.impl.Attribute unless defined?(Attribute) CipherSpec = org.jruby.ext.openssl.impl.CipherSpec unless defined?(CipherSpec) Digest = org.jruby.ext.openssl.impl.Digest unless defined?(Digest) EncContent = org.jruby.ext.openssl.impl.EncContent unless defined?(EncContent) Encrypt = org.jruby.ext.openssl.impl.Encrypt unless defined?(Encrypt) Envelope = org.jruby.ext.openssl.impl.Envelope unless defined?(Envelope) IssuerAndSerial = org.jruby.ext.openssl.impl.IssuerAndSerial unless defined?(IssuerAndSerial) RecipInfo = org.jruby.ext.openssl.impl.RecipInfo unless defined?(RecipInfo) SignEnvelope = org.jruby.ext.openssl.impl.SignEnvelope unless defined?(SignEnvelope) Signed = org.jruby.ext.openssl.impl.Signed unless defined?(Signed) SMIME = org.jruby.ext.openssl.impl.SMIME unless defined?(SMIME) Mime = org.jruby.ext.openssl.impl.Mime unless defined?(Mime) MimeHeader = org.jruby.ext.openssl.impl.MimeHeader unless defined?(MimeHeader) MimeParam = org.jruby.ext.openssl.impl.MimeParam unless defined?(MimeParam) BIO = org.jruby.ext.openssl.impl.BIO unless defined?(BIO) PKCS7Exception = org.jruby.ext.openssl.impl.PKCS7Exception unless defined?(PKCS7Exception) ASN1Registry = org.jruby.ext.openssl.impl.ASN1Registry unless defined?(ASN1Registry) AlgorithmIdentifier = org.bouncycastle.asn1.x509.AlgorithmIdentifier unless defined?(AlgorithmIdentifier) SignerInfoWithPkey = org.jruby.ext.openssl.impl.SignerInfoWithPkey unless defined?(SignerInfoWithPkey) IssuerAndSerialNumber = org.bouncycastle.asn1.pkcs.IssuerAndSerialNumber unless defined?(IssuerAndSerialNumber) ASN1InputStream = org.bouncycastle.asn1.ASN1InputStream unless defined?(ASN1InputStream) X509AuxCertificate = org.jruby.ext.openssl.x509store.X509AuxCertificate unless defined?(X509AuxCertificate) ArrayList = java.util.ArrayList unless defined?(ArrayList) CertificateFactory = java.security.cert.CertificateFactory unless defined?(CertificateFactory) BCP = org.bouncycastle.jce.provider.BouncyCastleProvider unless defined?(BCP) ByteArrayInputStream = java.io.ByteArrayInputStream unless defined?(ByteArrayInputStream) BigInteger = java.math.BigInteger unless defined?(BigInteger) Cipher = javax.crypto.Cipher unless defined?(Cipher) ASN1Integer = org.bouncycastle.asn1.ASN1Integer DERSet = org.bouncycastle.asn1.DERSet DEROctetString = org.bouncycastle.asn1.DEROctetString X500Name = org.bouncycastle.asn1.x500.X500Name MimeEnvelopedString = File::read(File.join(File.dirname(__FILE__), 'pkcs7', 'pkcs7_mime_enveloped.message')) MimeSignedString = File::read(File.join(File.dirname(__FILE__), 'pkcs7', 'pkcs7_mime_signed.message')) MultipartSignedString = File::read(File.join(File.dirname(__FILE__), 'pkcs7', 'pkcs7_multipart_signed.message')) X509CertString = < '1.9' end jruby-openssl-0.9.21/src/test/ruby/ssl/test_helper.rb000066400000000000000000000206151313661621600226230ustar00rootroot00000000000000require File.expand_path('../test_helper', File.dirname(__FILE__)) module SSLTestHelper # RUBY = EnvUtil.rubybin SSL_SERVER = File.join(File.dirname(__FILE__), "ssl_server.rb") PORT = 20443 ITERATIONS = ($0 == __FILE__) ? 100 : 10 def setup; require 'openssl' @ca_key = OpenSSL::PKey::RSA.new TEST_KEY_RSA2048 @svr_key = OpenSSL::PKey::RSA.new TEST_KEY_RSA1024 @cli_key = OpenSSL::PKey::DSA.new TEST_KEY_DSA256 @ca = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA") @svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost") @cli = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost") ca_exts = [ [ "basicConstraints", "CA:TRUE", true ], [ "keyUsage", "cRLSign,keyCertSign", true ], ] ee_exts = [ [ "keyUsage", "keyEncipherment,digitalSignature", true ], ] now = Time.at(Time.now.to_i) @ca_cert = issue_cert(@ca, @ca_key, 1, now, now + 3600, ca_exts, nil, nil, OpenSSL::Digest::SHA1.new) @svr_cert = issue_cert(@svr, @svr_key, 2, now, now + 1800, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new) @cli_cert = issue_cert(@cli, @cli_key, 3, now, now + 1800, ee_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new) @server = nil end def start_server(port0, verify_mode, start_immediately, args = {}, &block) require 'socket' ctx_proc = args[:ctx_proc] server_proc = args[:server_proc] server_proc ||= method(:readwrite_loop) store = OpenSSL::X509::Store.new store.add_cert(@ca_cert) store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT context = OpenSSL::SSL::SSLContext.new context.cert_store = store # context.extra_chain_cert = [ ca_cert ] context.cert = @svr_cert context.key = @svr_key context.tmp_dh_callback = proc { OpenSSL::PKey::DH.new(TEST_KEY_DH1024) } context.verify_mode = verify_mode ctx_proc.call(context) if ctx_proc Socket.do_not_reverse_lookup = true tcp_server = nil port = port0 begin tcp_server = TCPServer.new("127.0.0.1", port) rescue Errno::EADDRINUSE port += 1 retry end ssls = OpenSSL::SSL::SSLServer.new(tcp_server, context) ssls.start_immediately = start_immediately begin server = Thread.new do Thread.current.abort_on_exception = true server_loop(context, ssls, server_proc) end $stderr.printf("%s started: pid=%d port=%d\n", SSL_SERVER, $$, port) #if $DEBUG block.call(server, port.to_i) ensure tcp_server_close(server, tcp_server) end end def tcp_server_close(thread, tcp_server) begin tcp_server.shutdown rescue Errno::ENOTCONN # when `Errno::ENOTCONN: Socket is not connected' on some platforms, # call #close instead of #shutdown. tcp_server.close tcp_server = nil end if (tcp_server) if thread thread.join(5) if thread.alive? thread.kill thread.join flunk("TCPServer was closed and SSLServer is still alive") unless $! end end ensure tcp_server.close if tcp_server end def tcp_server_close(thread, tcp_server) tcp_server.close if (tcp_server) if thread thread.join(5) if thread.alive? thread.kill thread.join flunk("TCPServer was closed and SSLServer is still alive") unless $! end end end if RUBY_VERSION < '1.9.0' || ( defined? JRUBY_VERSION && JRUBY_VERSION < '1.7.0' ) private :tcp_server_close def server_loop(context, server, server_proc) loop do ssl = nil begin ssl = server.accept rescue OpenSSL::SSL::SSLError retry end Thread.start do Thread.current.abort_on_exception = true server_proc.call(context, ssl) end end rescue Errno::EBADF, IOError, Errno::EINVAL, Errno::ECONNABORTED, Errno::ENOTSOCK, Errno::ECONNRESET end def server_connect(port, ctx = nil) sock = TCPSocket.new('127.0.0.1', port) ssl = ctx ? OpenSSL::SSL::SSLSocket.new(sock, ctx) : OpenSSL::SSL::SSLSocket.new(sock) ssl.sync_close = true ssl.connect yield ssl if block_given? ensure if ssl ssl.close elsif sock sock.close end end def starttls(ssl) ssl.puts("STARTTLS") #sleep 1 # When this line is eliminated, process on Cygwin blocks # # forever at ssl.connect. But I don't know why it does. ssl.connect end def readwrite_loop(context, ssl) while line = ssl.gets if line =~ /^STARTTLS$/ ssl.accept next end ssl.write(line) end rescue IOError, OpenSSL::SSL::SSLError ensure ssl.close rescue nil end TEST_KEY_RSA1024 = <<-_end_of_pem_ -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx aKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/ Q3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB AoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0 maDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T gnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572 74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE JiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX sOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII 8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA wa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi qRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD dPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA== -----END RSA PRIVATE KEY----- _end_of_pem_ TEST_KEY_RSA2048 = <<-_end_of_pem_ -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAuV9ht9J7k4NBs38jOXvvTKY9gW8nLICSno5EETR1cuF7i4pN s9I1QJGAFAX0BEO4KbzXmuOvfCpD3CU+Slp1enenfzq/t/e/1IRW0wkJUJUFQign 4CtrkJL+P07yx18UjyPlBXb81ApEmAB5mrJVSrWmqbjs07JbuS4QQGGXLc+Su96D kYKmSNVjBiLxVVSpyZfAY3hD37d60uG+X8xdW5v68JkRFIhdGlb6JL8fllf/A/bl NwdJOhVr9mESHhwGjwfSeTDPfd8ZLE027E5lyAVX9KZYcU00mOX+fdxOSnGqS/8J DRh0EPHDL15RcJjV2J6vZjPb0rOYGDoMcH+94wIDAQABAoIBAAzsamqfYQAqwXTb I0CJtGg6msUgU7HVkOM+9d3hM2L791oGHV6xBAdpXW2H8LgvZHJ8eOeSghR8+dgq PIqAffo4x1Oma+FOg3A0fb0evyiACyrOk+EcBdbBeLo/LcvahBtqnDfiUMQTpy6V seSoFCwuN91TSCeGIsDpRjbG1vxZgtx+uI+oH5+ytqJOmfCksRDCkMglGkzyfcl0 Xc5CUhIJ0my53xijEUQl19rtWdMnNnnkdbG8PT3LZlOta5Do86BElzUYka0C6dUc VsBDQ0Nup0P6rEQgy7tephHoRlUGTYamsajGJaAo1F3IQVIrRSuagi7+YpSpCqsW wORqorkCgYEA7RdX6MDVrbw7LePnhyuaqTiMK+055/R1TqhB1JvvxJ1CXk2rDL6G 0TLHQ7oGofd5LYiemg4ZVtWdJe43BPZlVgT6lvL/iGo8JnrncB9Da6L7nrq/+Rvj XGjf1qODCK+LmreZWEsaLPURIoR/Ewwxb9J2zd0CaMjeTwafJo1CZvcCgYEAyCgb aqoWvUecX8VvARfuA593Lsi50t4MEArnOXXcd1RnXoZWhbx5rgO8/ATKfXr0BK/n h2GF9PfKzHFm/4V6e82OL7gu/kLy2u9bXN74vOvWFL5NOrOKPM7Kg+9I131kNYOw Ivnr/VtHE5s0dY7JChYWE1F3vArrOw3T00a4CXUCgYEA0SqY+dS2LvIzW4cHCe9k IQqsT0yYm5TFsUEr4sA3xcPfe4cV8sZb9k/QEGYb1+SWWZ+AHPV3UW5fl8kTbSNb v4ng8i8rVVQ0ANbJO9e5CUrepein2MPL0AkOATR8M7t7dGGpvYV0cFk8ZrFx0oId U0PgYDotF/iueBWlbsOM430CgYEAqYI95dFyPI5/AiSkY5queeb8+mQH62sdcCCr vd/w/CZA/K5sbAo4SoTj8dLk4evU6HtIa0DOP63y071eaxvRpTNqLUOgmLh+D6gS Cc7TfLuFrD+WDBatBd5jZ+SoHccVrLR/4L8jeodo5FPW05A+9gnKXEXsTxY4LOUC 9bS4e1kCgYAqVXZh63JsMwoaxCYmQ66eJojKa47VNrOeIZDZvd2BPVf30glBOT41 gBoDG3WMPZoQj9pb7uMcrnvs4APj2FIhMU8U15LcPAj59cD6S6rWnAxO8NFK7HQG 4Jxg3JNNf8ErQoCHb1B3oVdXJkmbJkARoDpBKmTCgKtP8ADYLmVPQw== -----END RSA PRIVATE KEY----- _end_of_pem_ TEST_KEY_DSA256 = <<-_end_of_pem_ -----BEGIN DSA PRIVATE KEY----- MIH3AgEAAkEAhk2libbY2a8y2Pt21+YPYGZeW6wzaW2yfj5oiClXro9XMR7XWLkE 9B7XxLNFCS2gmCCdMsMW1HulaHtLFQmB2wIVAM43JZrcgpu6ajZ01VkLc93gu/Ed AkAOhujZrrKV5CzBKutKLb0GVyVWmdC7InoNSMZEeGU72rT96IjM59YzoqmD0pGM 3I1o4cGqg1D1DfM1rQlnN1eSAkBq6xXfEDwJ1mLNxF6q8Zm/ugFYWR5xcX/3wFiT b4+EjHP/DbNh9Vm5wcfnDBJ1zKvrMEf2xqngYdrV/3CiGJeKAhRvL57QvJZcQGvn ISNX5cMzFHRW3Q== -----END DSA PRIVATE KEY----- _end_of_pem_ TEST_KEY_DSA512 = <<-_end_of_pem_ -----BEGIN DSA PRIVATE KEY----- MIH4AgEAAkEA5lB4GvEwjrsMlGDqGsxrbqeFRh6o9OWt6FgTYiEEHaOYhkIxv0Ok RZPDNwOG997mDjBnvDJ1i56OmS3MbTnovwIVAJgub/aDrSDB4DZGH7UyarcaGy6D AkB9HdFw/3td8K4l1FZHv7TCZeJ3ZLb7dF3TWoGUP003RCqoji3/lHdKoVdTQNuR S/m6DlCwhjRjiQ/lBRgCLCcaAkEAjN891JBjzpMj4bWgsACmMggFf57DS0Ti+5++ Q1VB8qkJN7rA7/2HrCR3gTsWNb1YhAsnFsoeRscC+LxXoXi9OAIUBG98h4tilg6S 55jreJD3Se3slps= -----END DSA PRIVATE KEY----- _end_of_pem_ TEST_KEY_DH1024 = <<-_end_of_pem_ -----BEGIN DH PARAMETERS----- MIGHAoGBAKnKQ8MNK6nYZzLrrcuTsLxuiJGXoOO5gT+tljOTbHBuiktdMTITzIY0 pFxIvjG05D7HoBZQfrR0c92NGWPkAiCkhQKB8JCbPVzwNLDy6DZ0pmofDKrEsYHG AQjjxMXhwULlmuR/K+WwlaZPiLIBYalLAZQ7ZbOPeVkJ8ePao0eLAgEC -----END DH PARAMETERS----- _end_of_pem_ endjruby-openssl-0.9.21/src/test/ruby/ssl/test_ocsp.rb000066400000000000000000000311311313661621600223030ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('test_helper', File.dirname(__FILE__)) class TestOCSP < TestCase include SSLTestHelper def setup super # @ca_cert # | # @cert # |----------| # @cert2 @ocsp_cert now = Time.now ca_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA") @ca_key = OpenSSL::PKey::RSA.new TEST_KEY_RSA1024 ca_exts = [ ["basicConstraints", "CA:TRUE", true], ["keyUsage", "cRLSign,keyCertSign", true], ] @ca_cert = issue_cert(ca_subj, @ca_key, 1, now, now+1800, ca_exts, nil, nil, OpenSSL::Digest::SHA1.new) cert_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA2") @cert_key = OpenSSL::PKey::RSA.new TEST_KEY_RSA1024 cert_exts = [ ["basicConstraints", "CA:TRUE", true], ["keyUsage", "cRLSign,keyCertSign", true], ] @cert = issue_cert(cert_subj, @cert_key, 5, now, now+1800, cert_exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new) cert2_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCert") @cert2_key = OpenSSL::PKey::RSA.new TEST_KEY_RSA1024 cert2_exts = [] @cert2 = issue_cert(cert2_subj, @cert2_key, 10, now, now+1800, cert2_exts, @cert, @cert_key, OpenSSL::Digest::SHA1.new) ocsp_subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCAOCSP") @ocsp_key = OpenSSL::PKey::RSA.new TEST_KEY_RSA2048 ocsp_exts = [ ["extendedKeyUsage", "OCSPSigning", true], ] @ocsp_cert = issue_cert(ocsp_subj, @ocsp_key, 100, now, now+1800, ocsp_exts, @cert, @cert_key, OpenSSL::Digest::SHA1.new) end def test_new_certificate_id cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert) assert_kind_of OpenSSL::OCSP::CertificateId, cid assert_equal @cert.serial, cid.serial cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA256.new) assert_kind_of OpenSSL::OCSP::CertificateId, cid assert_equal @cert.serial, cid.serial end def test_certificate_id_issuer_name_hash cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert) assert_equal OpenSSL::Digest::SHA1.hexdigest(@cert.issuer.to_der), cid.issuer_name_hash assert_equal "d91f736ac4dc3242f0fb9b77a3149bd83c5c43d0", cid.issuer_name_hash end def test_certificate_id_issuer_key_hash cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert) assert_equal OpenSSL::Digest::SHA1.hexdigest(OpenSSL::ASN1.decode(@ca_cert.to_der).value[0].value[6].value[1].value), cid.issuer_key_hash assert_equal "d1fef9fbf8ae1bc160cbfa03e2596dd873089213", cid.issuer_key_hash end def test_certificate_id_hash_algorithm cid_sha1 = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) cid_sha256 = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA256.new) assert_equal "sha1", cid_sha1.hash_algorithm assert_equal "sha256", cid_sha256.hash_algorithm end def test_certificate_id_der cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert) der = cid.to_der asn1 = OpenSSL::ASN1.decode(der) # hash algorithm defaults to SHA-1 assert_equal OpenSSL::ASN1.ObjectId("SHA1").to_der, asn1.value[0].value[0].to_der assert_equal [cid.issuer_name_hash].pack("H*"), asn1.value[1].value assert_equal [cid.issuer_key_hash].pack("H*"), asn1.value[2].value assert_equal @cert.serial, asn1.value[3].value assert_equal der, OpenSSL::OCSP::CertificateId.new(der).to_der end def test_certificate_id_dup cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert) other = cid.dup.to_der assert_equal cid.to_der, other end def test_request_der request = OpenSSL::OCSP::Request.new cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) request.add_certid(cid) request.sign(@cert, @cert_key, [@ca_cert], 0) asn1 = OpenSSL::ASN1.decode(request.to_der) # TODO: ASN1#to_der seems to be missing some data... # assert_equal cid.to_der, asn1.value[0].value.find { |a| a.tag_class == :UNIVERSAL }.value[0].value[0].to_der assert_equal OpenSSL::ASN1.ObjectId("sha1WithRSAEncryption").to_der, asn1.value[1].value[0].value[0].value[0].to_der # assert_equal @cert.to_der, asn1.value[1].value[0].value[2].value[0].value[0].to_der # assert_equal @ca_cert.to_der, asn1.value[1].value[0].value[2].value[0].value[1].to_der # assert_equal asn1.to_der, OpenSSL::OCSP::Request.new(asn1.to_der).to_der end def test_request_sign_verify cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert) store = OpenSSL::X509::Store.new.add_cert(@ca_cert) # with signer cert req = OpenSSL::OCSP::Request.new.add_certid(cid) req.sign(@cert, @cert_key, []) assert_equal true, req.verify([], store) # without signer cert req = OpenSSL::OCSP::Request.new.add_certid(cid) req.sign(@cert, @cert_key, nil) assert_equal false, req.verify([@cert2], store) assert_equal false, req.verify([], store) # no signer assert_equal false, req.verify([], store, OpenSSL::OCSP::NOVERIFY) assert_equal true, req.verify([@cert], store, OpenSSL::OCSP::NOINTERN) ret = req.verify([@cert], store) if ret || OpenSSL::OPENSSL_VERSION =~ /OpenSSL/ && OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10002000 assert_equal true, ret else # RT2560; OCSP_request_verify() does not find signer cert from 'certs' when # OCSP_NOINTERN is not specified. # fixed by OpenSSL 1.0.1j, 1.0.2 and LibreSSL 2.4.2 pend "RT2560: ocsp_req_find_signer" end end def test_request_nonce req0 = OpenSSL::OCSP::Request.new req1 = OpenSSL::OCSP::Request.new.add_nonce("NONCE") req2 = OpenSSL::OCSP::Request.new.add_nonce("ABCDE") bres = OpenSSL::OCSP::BasicResponse.new assert_equal 2, req0.check_nonce(bres) bres.copy_nonce(req1) assert_equal 3, req0.check_nonce(bres) assert_equal 1, req1.check_nonce(bres) bres.add_nonce("NONCE") assert_equal 1, req1.check_nonce(bres) assert_equal 0, req2.check_nonce(bres) end def test_request_dup request = OpenSSL::OCSP::Request.new cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) request.add_certid(cid) assert_equal request.to_der, request.dup.to_der end def test_basic_response_der bres = OpenSSL::OCSP::BasicResponse.new cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, 0, nil, -300, 500, []) bres.add_nonce("NONCE") bres.sign(@ocsp_cert, @ocsp_key, [@ca_cert], 0) der = bres.to_der asn1 = OpenSSL::ASN1.decode(der) assert_equal OpenSSL::ASN1.Sequence([@ocsp_cert, @ca_cert]).to_der, asn1.value[3].value[0].to_der assert_equal der, OpenSSL::OCSP::BasicResponse.new(der).to_der rescue TypeError if /GENERALIZEDTIME/ =~ $!.message pend "OCSP_basic_sign() is broken" else raise end end def test_basic_response_sign_verify store = OpenSSL::X509::Store.new.add_cert(@ca_cert) # signed by CA bres = OpenSSL::OCSP::BasicResponse.new cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA256.new) bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, -400, -300, 500, []) bres.sign(@ca_cert, @ca_key, nil, 0, OpenSSL::Digest::SHA256.new) assert_equal false, bres.verify([], store) # signer not found assert_equal true, bres.verify([@ca_cert], store) bres.sign(@ca_cert, @ca_key, [], 0, OpenSSL::Digest::SHA256.new) assert_equal true, bres.verify([], store) # signed by OCSP signer bres = OpenSSL::OCSP::BasicResponse.new cid = OpenSSL::OCSP::CertificateId.new(@cert2, @cert) bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, -400, -300, 500, []) bres.sign(@ocsp_cert, @ocsp_key, [@cert]) assert_equal true, bres.verify([], store) assert_equal false, bres.verify([], store, OpenSSL::OCSP::NOCHAIN) # OpenSSL had a bug on this; test that our workaround works bres.sign(@ocsp_cert, @ocsp_key, []) assert_equal true, bres.verify([@cert], store) end def test_basic_response_dup bres = OpenSSL::OCSP::BasicResponse.new cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, 0, nil, -300, 500, []) bres.sign(@ocsp_cert, @ocsp_key, [@ca_cert], 0) assert_equal bres.to_der, bres.dup.to_der end def test_basic_response_response_operations bres = OpenSSL::OCSP::BasicResponse.new now = Time.at(Time.now.to_i) cid1 = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) cid2 = OpenSSL::OCSP::CertificateId.new(@ocsp_cert, @ca_cert, OpenSSL::Digest::SHA1.new) cid3 = OpenSSL::OCSP::CertificateId.new(@ca_cert, @ca_cert, OpenSSL::Digest::SHA1.new) bres.add_status(cid1, OpenSSL::OCSP::V_CERTSTATUS_REVOKED, OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, now - 400, -300, nil, nil) bres.add_status(cid2, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, nil, -300, 500, []) assert_equal 2, bres.responses.size single = bres.responses.first assert_equal cid1.to_der, single.certid.to_der assert_equal OpenSSL::OCSP::V_CERTSTATUS_REVOKED, single.cert_status assert_equal OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, single.revocation_reason assert_equal now - 400, single.revocation_time assert_in_delta (now - 301), single.this_update, 1 assert_equal nil, single.next_update assert_equal [], single.extensions assert_equal cid2.to_der, bres.find_response(cid2).certid.to_der assert_equal nil, bres.find_response(cid3) end def test_single_response_der bres = OpenSSL::OCSP::BasicResponse.new cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert) bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, nil, -300, 500, nil) single = bres.responses[0] der = single.to_der asn1 = OpenSSL::ASN1.decode(der) assert_equal :CONTEXT_SPECIFIC, asn1.value[1].tag_class assert_equal 0, asn1.value[1].tag # good assert_equal der, OpenSSL::OCSP::SingleResponse.new(der).to_der end def test_single_response_check_validity bres = OpenSSL::OCSP::BasicResponse.new cid1 = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) cid2 = OpenSSL::OCSP::CertificateId.new(@ocsp_cert, @ca_cert, OpenSSL::Digest::SHA1.new) bres.add_status(cid1, OpenSSL::OCSP::V_CERTSTATUS_REVOKED, OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, -400, -300, -50, []) bres.add_status(cid2, OpenSSL::OCSP::V_CERTSTATUS_REVOKED, OpenSSL::OCSP::REVOKED_STATUS_UNSPECIFIED, -400, -300, nil, []) bres.add_status(cid2, OpenSSL::OCSP::V_CERTSTATUS_GOOD, nil, nil, Time.now + 100, nil, nil) if bres.responses[2].check_validity # thisUpdate is in future; must fail # LibreSSL bug; skip for now pend "OCSP_check_validity() is broken" end single1 = bres.responses[0] assert_equal false, single1.check_validity assert_equal false, single1.check_validity(30) assert_equal true, single1.check_validity(60) single2 = bres.responses[1] assert_equal true, single2.check_validity assert_equal true, single2.check_validity(0, 500) assert_equal false, single2.check_validity(0, 200) end def test_response bres = OpenSSL::OCSP::BasicResponse.new cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, 0, nil, -300, 500, []) bres.sign(@ocsp_cert, @ocsp_key, []) res = OpenSSL::OCSP::Response.create(OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, bres) assert_equal bres.to_der, res.basic.to_der assert_equal OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, res.status end def test_response_der bres = OpenSSL::OCSP::BasicResponse.new cid = OpenSSL::OCSP::CertificateId.new(@cert, @ca_cert, OpenSSL::Digest::SHA1.new) bres.add_status(cid, OpenSSL::OCSP::V_CERTSTATUS_GOOD, 0, nil, -300, 500, []) bres.sign(@ocsp_cert, @ocsp_key, [@ca_cert], 0) res = OpenSSL::OCSP::Response.create(OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, bres) der = res.to_der asn1 = OpenSSL::ASN1.decode(der) assert_equal OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, asn1.value[0].value assert_equal OpenSSL::ASN1.ObjectId("basicOCSPResponse").to_der, asn1.value[1].value[0].value[0].to_der assert_equal bres.to_der, asn1.value[1].value[0].value[1].value assert_equal der, OpenSSL::OCSP::Response.new(der).to_der end def test_response_dup bres = OpenSSL::OCSP::BasicResponse.new bres.sign(@ocsp_cert, @ocsp_key, [@ca_cert], 0) res = OpenSSL::OCSP::Response.create(OpenSSL::OCSP::RESPONSE_STATUS_SUCCESSFUL, bres) assert_equal res.to_der, res.dup.to_der end end jruby-openssl-0.9.21/src/test/ruby/ssl/test_session.rb000066400000000000000000000016351313661621600230300ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('test_helper', File.dirname(__FILE__)) class TestSSLSession < TestCase include SSLTestHelper def test_session start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ctx = OpenSSL::SSL::SSLContext.new("TLSv1") ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx) ssl.sync_close = true ssl.connect assert ssl.session.is_a?(OpenSSL::SSL::Session) assert ssl.session.equal? session = ssl.session assert session.id.is_a?(String) assert_equal 32, session.id.length assert session.time.is_a?(Time) assert session.timeout >= 0 session.timeout = 5 assert_equal 5, session.timeout assert session == OpenSSL::SSL::Session.new(ssl) ssl.close end end def test_exposes_session_error OpenSSL::SSL::Session::SessionError end endjruby-openssl-0.9.21/src/test/ruby/ssl/test_socket.rb000066400000000000000000000116671313661621600226430ustar00rootroot00000000000000# frozen_string_literal: false require File.expand_path('test_helper', File.dirname(__FILE__)) class TestSSLSocket < TestCase def setup; super; require 'openssl' end def test_cipher io_stub = File.new __FILE__ socket = OpenSSL::SSL::SSLSocket.new(io_stub) assert_nil socket.cipher end def test_attr_methods io_stub = File.new __FILE__ socket = OpenSSL::SSL::SSLSocket.new(io_stub) assert socket.io assert_equal socket.io, socket.to_io assert ! socket.respond_to?(:'io=') # due compatibility : assert_equal socket.io, socket.instance_variable_get(:@io) assert socket.context assert ! socket.respond_to?(:'context=') # due compatibility : assert_equal socket.context, socket.instance_variable_get(:@context) assert_nil socket.hostname socket.hostname = '1.1.1.1' assert_equal '1.1.1.1', socket.hostname # MRI sync is false by default : # assert_equal false, socket.sync socket.sync = true assert_equal true, socket.sync # assert_equal false, socket.sync_close socket.sync_close = true assert_equal true, socket.sync_close socket.inspect end def test_sync_close_without_connect require 'socket' if RUBY_VERSION > '2.2' Socket.open(:INET, :STREAM) do |socket| assert ! socket.closed? ssl = OpenSSL::SSL::SSLSocket.new(socket) ssl.sync_close = true assert ! ssl.closed? ssl.close assert socket.closed? end else begin socket = UDPSocket.new :INET assert ! socket.closed? ssl = OpenSSL::SSL::SSLSocket.new(socket) ssl.sync_close = true assert ! ssl.closed? ssl.close assert socket.closed? ensure socket && socket.close rescue nil end end end include SSLTestHelper def test_ssl_sysread_blocking_error start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port| server_connect(port) do |ssl| ssl.write("abc\n") # assert_raise(TypeError) { eval 'ssl.sysread(4, exception: false)' } buf = '' assert_raise(ArgumentError) { eval 'ssl.sysread(4, buf, exception: false)' } assert_equal '', buf assert_equal buf.object_id, ssl.sysread(4, buf).object_id assert_equal "abc\n", buf end end end if RUBY_VERSION > '2.2' def test_read_nonblock_no_exception ssl_pair do |s1, s2| assert_equal :wait_readable, eval('s2.read_nonblock 10, exception: false') s1.write "abc\ndef\n" IO.select [ s2 ] ret = eval('s2.read_nonblock 2, exception: false') assert_equal "ab", ret assert_equal "c\n", s2.gets ret = eval('s2.read_nonblock 10, exception: false') assert_equal("def\n", ret) s1.close sleep 0.1 opts = { :exception => false } assert_equal nil, s2.read_nonblock(10, opts) end end if RUBY_VERSION > '2.2' def test_connect_non_connected; require 'socket' socket = OpenSSL::SSL::SSLSocket.new(Socket.new(:INET, :STREAM)) begin socket.connect_nonblock rescue => e assert_equal Errno::EPIPE, e.class puts e.inspect if $VERBOSE ensure socket.close end end if RUBY_VERSION > '2.2' def test_connect_nonblock ssl_server = server thread = Thread.new do ssl_server.accept.tap { ssl_server.close } end host = "127.0.0.1" ctx = OpenSSL::SSL::SSLContext.new() ctx.ciphers = "ADH" client = TCPSocket.new host, server_port(ssl_server) client = OpenSSL::SSL::SSLSocket.new(client, ctx) begin client.connect_nonblock rescue OpenSSL::SSL::SSLErrorWaitReadable => e # # puts e.inspect if $VERBOSE ensure thread.kill if thread.alive? client.close unless client.closed? end end if RUBY_VERSION > '2.2' private def server require 'socket' host = "127.0.0.1"; port = 0 ctx = OpenSSL::SSL::SSLContext.new() ctx.ciphers = "ADH" server = TCPServer.new(host, port) OpenSSL::SSL::SSLServer.new(server, ctx) end def client(port) require 'socket' host = "127.0.0.1" ctx = OpenSSL::SSL::SSLContext.new() ctx.ciphers = "ADH" client = TCPSocket.new(host, port) ssl = OpenSSL::SSL::SSLSocket.new(client, ctx) ssl.connect ssl.sync_close = true ssl end def server_port(ssl_server = server) ssl_server.to_io.local_address.ip_port end def ssl_pair ssl_server = server thread = Thread.new do ssl_server.accept.tap { ssl_server.close } end ssl_client = client server_port(ssl_server) ssl_socket = thread.value if block_given? begin yield ssl_client, ssl_socket ensure ssl_client.close unless ssl_client.closed? ssl_socket.close unless ssl_socket.closed? end else return ssl_client, ssl_socket end ensure thread.tap { thread.kill; thread.join } if thread && thread.alive? end endjruby-openssl-0.9.21/src/test/ruby/ssl/test_ssl.rb000066400000000000000000000166021313661621600221460ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('test_helper', File.dirname(__FILE__)) class TestSSL < TestCase include SSLTestHelper def test_context_default_constants assert OpenSSL::SSL::SSLContext::DEFAULT_PARAMS assert_equal 'SSLv23', OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ssl_version] assert_equal "ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW", OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:ciphers] assert_equal OpenSSL::SSL::VERIFY_PEER, OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:verify_mode] assert OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE assert OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE.is_a?(OpenSSL::X509::Store) end def test_post_connection_check sslerr = OpenSSL::SSL::SSLError start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect assert_raise(sslerr) { ssl.post_connection_check("localhost.localdomain") } assert_raise(sslerr) { ssl.post_connection_check("127.0.0.1") } assert ssl.post_connection_check("localhost") assert_raise(sslerr) { ssl.post_connection_check("foo.example.com") } cert = ssl.peer_cert assert ! OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain") assert ! OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1") assert OpenSSL::SSL.verify_certificate_identity(cert, "localhost") assert ! OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com") end now = Time.now exts = [ ["keyUsage","keyEncipherment,digitalSignature",true], ["subjectAltName","DNS:localhost.localdomain",false], ["subjectAltName","IP:127.0.0.1",false], ] @svr_cert = issue_cert(@svr, @svr_key, 4, now, now + 1800, exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new) start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect assert ssl.post_connection_check("localhost.localdomain") assert ssl.post_connection_check("127.0.0.1") assert_raise(sslerr) { ssl.post_connection_check("localhost") } assert_raise(sslerr) { ssl.post_connection_check("foo.example.com") } cert = ssl.peer_cert assert OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain") assert OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1") assert ! OpenSSL::SSL.verify_certificate_identity(cert, "localhost") assert ! OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com") end now = Time.now exts = [ [ "keyUsage", "keyEncipherment,digitalSignature", true ], [ "subjectAltName", "DNS:*.localdomain", false ], ] @svr_cert = issue_cert(@svr, @svr_key, 5, now, now + 1800, exts, @ca_cert, @ca_key, OpenSSL::Digest::SHA1.new) start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect assert ssl.post_connection_check("localhost.localdomain") assert_raise(sslerr) { ssl.post_connection_check("127.0.0.1") } assert_raise(sslerr) { ssl.post_connection_check("localhost") } assert_raise(sslerr) { ssl.post_connection_check("foo.example.com") } cert = ssl.peer_cert assert OpenSSL::SSL.verify_certificate_identity(cert, "localhost.localdomain") assert ! OpenSSL::SSL.verify_certificate_identity(cert, "127.0.0.1") assert ! OpenSSL::SSL.verify_certificate_identity(cert, "localhost") assert ! OpenSSL::SSL.verify_certificate_identity(cert, "foo.example.com") end end def test_ssl_version_tlsv1 ctx_proc = Proc.new do |ctx| ctx.ssl_version = "TLSv1" end start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect assert_equal("TLSv1", ssl.ssl_version) ssl.close end end def test_ssl_version_tlsv1_1 ctx_proc = Proc.new do |ctx| ctx.ssl_version = "TLSv1_1" end start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect assert_equal("TLSv1.1", ssl.ssl_version) ssl.close end end unless java6? # TLS1_1 is not supported by JDK 6 def test_ssl_version_tlsv1_2 ctx_proc = Proc.new do |ctx| ctx.ssl_version = "TLSv1_2" end start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, :ctx_proc => ctx_proc) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect assert_equal("TLSv1.2", ssl.ssl_version) ssl.close end end unless java6? # TLS1_2 is not supported by JDK 6 def test_read_nonblock_would_block start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect if defined? OpenSSL::SSL::SSLErrorWaitReadable begin ssl.read_nonblock(2) fail 'read would block error not raised!' rescue OpenSSL::SSL::SSLErrorWaitReadable => e assert_equal 'read would block', e.message end else begin ssl.read_nonblock(2) fail 'read would block error not raised!' rescue => e assert_equal 'read would block', e.message end end if RUBY_VERSION > '2.2' result = eval "ssl.read_nonblock(5, 'buff', exception: false)" assert_equal :wait_readable, result end result = ssl.sysread_nonblock(5, :exception => false) assert_equal :wait_readable, result ssl.close end end if RUBY_VERSION > '1.9' def test_connect_nonblock_would_block start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) if defined? OpenSSL::SSL::SSLErrorWaitReadable begin ssl.connect_nonblock fail 'read would block error not raised!' rescue OpenSSL::SSL::SSLErrorWaitReadable => e assert_equal 'read would block', e.message end else begin ssl.connect_nonblock fail 'read would block error not raised!' rescue => e assert_equal 'read would block', e.message end end if RUBY_VERSION > '2.2' result = eval "ssl.connect_nonblock(exception: false)" assert_equal :wait_readable, result end result = ssl.connect_nonblock(:exception => false) assert_equal :wait_readable, result ssl.close end end if RUBY_VERSION > '1.9' def test_renegotiation_cb num_handshakes = 0 renegotiation_cb = Proc.new { |ssl| num_handshakes += 1 } ctx_proc = Proc.new { |ctx| ctx.renegotiation_cb = renegotiation_cb } start_server(PORT, OpenSSL::SSL::VERIFY_NONE, true, {:ctx_proc => ctx_proc}) do |server, port| sock = TCPSocket.new("127.0.0.1", port) ssl = OpenSSL::SSL::SSLSocket.new(sock) ssl.connect assert_equal(1, num_handshakes) ssl.close end end end jruby-openssl-0.9.21/src/test/ruby/test_asn1.rb000066400000000000000000000504541313661621600214110ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('test_helper', File.dirname(__FILE__)) class TestASN1 < TestCase def test_encode_boolean encode_decode_test(OpenSSL::ASN1::Boolean, [true, false]) end def test_encode_integer ai = OpenSSL::ASN1::Integer.new( i = 42 ) assert_equal i, OpenSSL::ASN1.decode(ai.to_der).value ai = OpenSSL::ASN1::Integer.new( i = 0 ) assert_equal i, OpenSSL::ASN1.decode(ai.to_der).value ai = OpenSSL::ASN1::Integer.new( i = -1 ) assert_equal i, OpenSSL::ASN1.decode(ai.to_der).value ai = OpenSSL::ASN1::Integer.new( i = 2**4242 ) assert_equal i, OpenSSL::ASN1.decode(ai.to_der).value end def test_encode_nil #Primitives raise TypeError, Constructives NoMethodError assert_raise(TypeError) { OpenSSL::ASN1::Integer.new(nil).to_der } assert_raise(TypeError) { OpenSSL::ASN1::Boolean.new(nil).to_der } assert_raise(NoMethodError) { OpenSSL::ASN1::Set.new(nil).to_der } assert_raise(NoMethodError) { OpenSSL::ASN1::Sequence.new(nil).to_der } end def test_instantiate # nothing shall raise : OpenSSL::ASN1::Null.new(nil) OpenSSL::ASN1::EndOfContent.new OpenSSL::ASN1::OctetString.new('') end def test_constants universal_tag_name = ["EOC", "BOOLEAN", "INTEGER", "BIT_STRING", "OCTET_STRING", "NULL", "OBJECT", "OBJECT_DESCRIPTOR", "EXTERNAL", "REAL", "ENUMERATED", "EMBEDDED_PDV", "UTF8STRING", "RELATIVE_OID", nil, nil, "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", "GRAPHICSTRING", "ISO64STRING", "GENERALSTRING", "UNIVERSALSTRING", "CHARACTER_STRING", "BMPSTRING"] assert_equal universal_tag_name, OpenSSL::ASN1::UNIVERSAL_TAG_NAME end require 'pp' def _test_parse_infinite_length_sequence # borrowed from Krypt raw = [%w{30 80 04 01 01 02 01 01 00 00}.join("")].pack("H*") pp asn1 = OpenSSL::ASN1.decode(raw) assert_universal(OpenSSL::ASN1::SEQUENCE, asn1, true) seq = asn1.value assert_equal(3, seq.size) octet = seq[0] assert_universal(OpenSSL::ASN1::OCTET_STRING, octet) assert_equal("\1", octet.value) integer = seq[1] assert_universal(OpenSSL::ASN1::INTEGER, integer) assert_equal(1, integer.value) eoc = seq[2] assert_universal(0, eoc) assert_equal('', eoc.value) # assert_nil(eoc.value) assert_equal(raw, asn1.to_der) end def test_constructive oct = OpenSSL::ASN1::OctetString.new("") assert_equal "\x04\x00", oct.to_der eoc = OpenSSL::ASN1::EndOfContent.new int = OpenSSL::ASN1::Integer.new 1 set = OpenSSL::ASN1::Set.new([int, eoc]) set.infinite_length = true expected = "1\x80\x02\x01\x01\x00\x00" actual = set.to_der #puts "set expected: #{expected.to_java_bytes.inspect}" #puts "set actual: #{actual.to_java_bytes.inspect}" assert_equal expected, actual inner = OpenSSL::ASN1::Sequence.new([int, eoc]) inner.infinite_length = true expected = "0\x80\x02\x01\x01\x00\x00" actual = inner.to_der #puts "seq expected: #{expected.to_java_bytes.inspect}" #puts "seq actual: #{actual.to_java_bytes.inspect}" assert_equal expected, actual outer = OpenSSL::ASN1::Sequence.new([inner, eoc]) outer.infinite_length = true assert_equal "0\x800\x80\x02\x01\x01\x00\x00\x00\x00", outer.to_der end def test_constructive_nesting seq = OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new('DC'), OpenSSL::ASN1::IA5String.new('the-borg') ]) expected = "0\x16\x06\n\t\x92&\x89\x93\xF2,d\x01\x19\x16\bthe-borg" assert_equal expected, seq.to_der set = OpenSSL::ASN1::Set.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new('CN'), OpenSSL::ASN1::UTF8String('Queen_42') ]) ]) expected = "1\x110\x0F\x06\x03U\x04\x03\f\bQueen_42" assert_equal expected, set.to_der name = OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::Set.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new('DC'), OpenSSL::ASN1::IA5String.new('org') ]), OpenSSL::ASN1::Set.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new('DC'), OpenSSL::ASN1::IA5String.new('the-borg') ]), OpenSSL::ASN1::Set.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new('CN'), OpenSSL::ASN1::UTF8String('Queen_42') ]) ]) ]) ]) ]) name = OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::Set.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new('DC'), OpenSSL::ASN1::IA5String.new('org') ]), OpenSSL::ASN1::Set.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new('DC'), OpenSSL::ASN1::IA5String.new('the-borg') ]), OpenSSL::ASN1::Set.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ObjectId.new('CN'), OpenSSL::ASN1::UTF8String('Queen_42') ]) ]) ]) ]) ]) expected = "0B1@0\x11\x06\n\t\x92&\x89\x93\xF2,d\x01\x19\x16\x03org1+0\x16\x06\n\t\x92&\x89\x93\xF2,d\x01\x19\x16\bthe-borg1\x110\x0F\x06\x03U\x04\x03\f\bQueen_42" assert_equal expected, name.to_der end def test_raw_constructive eoc = OpenSSL::ASN1::EndOfContent.new #puts "eoc: #{eoc.inspect}" oct = OpenSSL::ASN1::OctetString.new("") #puts "oct: #{oct.inspect}" c = OpenSSL::ASN1::Constructive.new([oct, eoc], OpenSSL::ASN1::OCTET_STRING) assert_equal 4, c.tag c.infinite_length = true #puts "'empty' constructive octet: #{c.inspect} \n#{c.to_der.inspect}" assert_equal "$\x80\x04\x00\x00\x00", c.to_der partial1 = OpenSSL::ASN1::OctetString.new("\x01") partial2 = OpenSSL::ASN1::OctetString.new("\x02") inf_octets = OpenSSL::ASN1::Constructive.new( [ partial1, partial2, OpenSSL::ASN1::EndOfContent.new ], tag = OpenSSL::ASN1::OCTET_STRING, nil, :UNIVERSAL ) assert_equal false, inf_octets.infinite_length # The real value of inf_octets is "\x01\x02", i.e. the concatenation # of partial1 and partial2 inf_octets.infinite_length = true assert_equal true, inf_octets.infinite_length assert_equal tag, inf_octets.tag inf_octets.infinite_length = false assert_raise(OpenSSL::ASN1::ASN1Error) { inf_octets.to_der } inf_octets.infinite_length = true der = inf_octets.to_der #puts 'expected: ' + "$\x80\x04\x01\x01\x04\x01\x02\x00\x00".to_java_bytes.inspect #puts ' actual: ' + der.to_java_bytes.inspect assert_equal "$\x80\x04\x01\x01\x04\x01\x02\x00\x00", der end def test_constructive_decode der = "$\x80\x04\x01\x01\x04\x01\x02\x00\x00" asn1 = OpenSSL::ASN1.decode(der) assert asn1.instance_of?(OpenSSL::ASN1::Constructive), "expected Constructive got: #{asn1.class}" assert_equal 4, asn1.tag assert_equal :UNIVERSAL, asn1.tag_class assert_equal true, asn1.infinite_length first = asn1.value[0] assert first.instance_of?(OpenSSL::ASN1::OctetString), "expected OctetString got: #{first.class}" # NOTE: probably won;t pass this without writing a custom "parser" : #assert_equal "\x01", asn1.value[0].value #assert_equal "\x02", asn1.value[1].value #assert_equal "", asn1.value[2].value last = asn1.value.last assert last.instance_of?(OpenSSL::ASN1::EndOfContent), "expected EndOfContent got: #{last.class}" end TEST_KEY_RSA1024 = <<-_end_of_pem_ -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx aKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/ Q3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB AoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0 maDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T gnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572 74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE JiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX sOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII 8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA wa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi qRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD dPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA== -----END RSA PRIVATE KEY----- _end_of_pem_ def test_decode subj = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=TestCA") key = OpenSSL::PKey::RSA.new TEST_KEY_RSA1024 now = Time.at(Time.now.to_i) # suppress usec s = 0xdeadbeafdeadbeafdeadbeafdeadbeaf exts = [ ["basicConstraints","CA:TRUE,pathlen:1",true], ["keyUsage","keyCertSign, cRLSign",true], ["subjectKeyIdentifier","hash",false], ] dgst = OpenSSL::Digest::SHA1.new cert = issue_cert( # OpenSSL::TestUtils.issue_cert subj, key, s, now, now+3600, exts, nil, nil, dgst) asn1 = OpenSSL::ASN1.decode(cert) assert_equal(OpenSSL::ASN1::Sequence, asn1.class) assert_equal(3, asn1.value.size) tbs_cert, sig_alg, sig_val = *asn1.value assert_equal(OpenSSL::ASN1::Sequence, tbs_cert.class) assert_equal(8, tbs_cert.value.size) version = tbs_cert.value[0] assert_equal(:CONTEXT_SPECIFIC, version.tag_class) assert_equal(0, version.tag) assert_equal(1, version.value.size) assert_equal(OpenSSL::ASN1::Integer, version.value[0].class) assert_equal(2, version.value[0].value) serial = tbs_cert.value[1] assert_equal(OpenSSL::ASN1::Integer, serial.class) assert_equal(0xdeadbeafdeadbeafdeadbeafdeadbeaf, serial.value) sig = tbs_cert.value[2] assert_equal(OpenSSL::ASN1::Sequence, sig.class) assert_equal(2, sig.value.size) assert_equal(OpenSSL::ASN1::ObjectId, sig.value[0].class) assert_equal("1.2.840.113549.1.1.5", sig.value[0].oid) assert_equal(OpenSSL::ASN1::Null, sig.value[1].class) dn = tbs_cert.value[3] # issuer assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash) assert_equal(OpenSSL::ASN1::Sequence, dn.class) assert_equal(3, dn.value.size) assert_equal(OpenSSL::ASN1::Set, dn.value[0].class) assert_equal(OpenSSL::ASN1::Set, dn.value[1].class) assert_equal(OpenSSL::ASN1::Set, dn.value[2].class) assert_equal(1, dn.value[0].value.size) assert_equal(1, dn.value[1].value.size) assert_equal(1, dn.value[2].value.size) assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class) assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class) assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class) assert_equal(2, dn.value[0].value[0].value.size) assert_equal(2, dn.value[1].value[0].value.size) assert_equal(2, dn.value[2].value[0].value.size) oid, value = *dn.value[0].value[0].value assert_equal(OpenSSL::ASN1::ObjectId, oid.class) assert_equal("0.9.2342.19200300.100.1.25", oid.oid) assert_equal(OpenSSL::ASN1::IA5String, value.class) assert_equal("org", value.value) oid, value = *dn.value[1].value[0].value assert_equal(OpenSSL::ASN1::ObjectId, oid.class) assert_equal("0.9.2342.19200300.100.1.25", oid.oid) assert_equal(OpenSSL::ASN1::IA5String, value.class) assert_equal("ruby-lang", value.value) oid, value = *dn.value[2].value[0].value assert_equal(OpenSSL::ASN1::ObjectId, oid.class) assert_equal("2.5.4.3", oid.oid) assert_equal(OpenSSL::ASN1::UTF8String, value.class) assert_equal("TestCA", value.value) validity = tbs_cert.value[4] assert_equal(OpenSSL::ASN1::Sequence, validity.class) assert_equal(2, validity.value.size) assert_equal(OpenSSL::ASN1::UTCTime, validity.value[0].class) assert_equal(now, validity.value[0].value) assert_equal(OpenSSL::ASN1::UTCTime, validity.value[1].class) assert_equal(now+3600, validity.value[1].value) dn = tbs_cert.value[5] # subject assert_equal(subj, OpenSSL::X509::Name.new(dn)) assert_equal(subj.hash, OpenSSL::X509::Name.new(dn).hash) assert_equal(OpenSSL::ASN1::Sequence, dn.class) assert_equal(3, dn.value.size) assert_equal(OpenSSL::ASN1::Set, dn.value[0].class) assert_equal(OpenSSL::ASN1::Set, dn.value[1].class) assert_equal(OpenSSL::ASN1::Set, dn.value[2].class) assert_equal(1, dn.value[0].value.size) assert_equal(1, dn.value[1].value.size) assert_equal(1, dn.value[2].value.size) assert_equal(OpenSSL::ASN1::Sequence, dn.value[0].value[0].class) assert_equal(OpenSSL::ASN1::Sequence, dn.value[1].value[0].class) assert_equal(OpenSSL::ASN1::Sequence, dn.value[2].value[0].class) assert_equal(2, dn.value[0].value[0].value.size) assert_equal(2, dn.value[1].value[0].value.size) assert_equal(2, dn.value[2].value[0].value.size) oid, value = *dn.value[0].value[0].value assert_equal(OpenSSL::ASN1::ObjectId, oid.class) assert_equal("0.9.2342.19200300.100.1.25", oid.oid) assert_equal(OpenSSL::ASN1::IA5String, value.class) assert_equal("org", value.value) oid, value = *dn.value[1].value[0].value assert_equal(OpenSSL::ASN1::ObjectId, oid.class) assert_equal("0.9.2342.19200300.100.1.25", oid.oid) assert_equal(OpenSSL::ASN1::IA5String, value.class) assert_equal("ruby-lang", value.value) oid, value = *dn.value[2].value[0].value assert_equal(OpenSSL::ASN1::ObjectId, oid.class) assert_equal("2.5.4.3", oid.oid) assert_equal(OpenSSL::ASN1::UTF8String, value.class) assert_equal("TestCA", value.value) pkey = tbs_cert.value[6] assert_equal(OpenSSL::ASN1::Sequence, pkey.class) assert_equal(2, pkey.value.size) assert_equal(OpenSSL::ASN1::Sequence, pkey.value[0].class) assert_equal(2, pkey.value[0].value.size) assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class) assert_equal("1.2.840.113549.1.1.1", pkey.value[0].value[0].oid) assert_equal(OpenSSL::ASN1::BitString, pkey.value[1].class) assert_equal(0, pkey.value[1].unused_bits) spkey = OpenSSL::ASN1.decode(pkey.value[1].value) assert_equal(OpenSSL::ASN1::Sequence, spkey.class) assert_equal(2, spkey.value.size) assert_equal(OpenSSL::ASN1::Integer, spkey.value[0].class) assert_equal(143085709396403084580358323862163416700436550432664688288860593156058579474547937626086626045206357324274536445865308750491138538454154232826011964045825759324933943290377903384882276841880081931690695505836279972214003660451338124170055999155993192881685495391496854691199517389593073052473319331505702779271, spkey.value[0].value) assert_equal(OpenSSL::ASN1::Integer, spkey.value[1].class) assert_equal(65537, spkey.value[1].value) extensions = tbs_cert.value[7] assert_equal(:CONTEXT_SPECIFIC, extensions.tag_class) assert_equal(3, extensions.tag) assert_equal(1, extensions.value.size) assert_equal(OpenSSL::ASN1::Sequence, extensions.value[0].class) assert_equal(3, extensions.value[0].value.size) ext = extensions.value[0].value[0] # basicConstraints assert_equal(OpenSSL::ASN1::Sequence, ext.class) assert_equal(3, ext.value.size) assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class) assert_equal("2.5.29.19", ext.value[0].oid) assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class) assert_equal(true, ext.value[1].value) assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class) assert_equal "0\x06\x01\x01\xFF\x02\x01\x01", ext.value[2].value extv = OpenSSL::ASN1.decode(ext.value[2].value) assert_equal(OpenSSL::ASN1::Sequence, extv.class) assert_equal(2, extv.value.size) assert_equal(OpenSSL::ASN1::Boolean, extv.value[0].class) assert_equal(true, extv.value[0].value) assert_equal(OpenSSL::ASN1::Integer, extv.value[1].class) assert_equal(1, extv.value[1].value) ext = extensions.value[0].value[1] # keyUsage assert_equal(OpenSSL::ASN1::Sequence, ext.class) assert_equal(3, ext.value.size) assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class) assert_equal("2.5.29.15", ext.value[0].oid) assert_equal(OpenSSL::ASN1::Boolean, ext.value[1].class) assert_equal(true, ext.value[1].value) assert_equal(OpenSSL::ASN1::OctetString, ext.value[2].class) extv = OpenSSL::ASN1.decode(ext.value[2].value) assert_equal(OpenSSL::ASN1::BitString, extv.class) str = "\000"; str[0] = 0b00000110.chr assert_equal(str, extv.value) ext = extensions.value[0].value[2] # subjectKeyIdentifier assert_equal(OpenSSL::ASN1::Sequence, ext.class) assert_equal(2, ext.value.size) assert_equal(OpenSSL::ASN1::ObjectId, ext.value[0].class) assert_equal("2.5.29.14", ext.value[0].oid) assert_equal(OpenSSL::ASN1::OctetString, ext.value[1].class) assert OpenSSL::X509::Certificate.new( cert.to_der ).verify key octet_value = ext.value[1].value assert_equal "\x04\x14\xD1\xFE\xF9\xFB\xF8\xAE\e\xC1`\xCB\xFA\x03\xE2Ym\xD8s\b\x92\x13", octet_value extv = OpenSSL::ASN1.decode(octet_value) assert_equal(OpenSSL::ASN1::OctetString, extv.class) sha1 = OpenSSL::Digest::SHA1.new sha1.update(pkey.value[1].value) assert_equal(sha1.digest, extv.value) assert_equal(OpenSSL::ASN1::Sequence, sig_alg.class) assert_equal(2, sig_alg.value.size) assert_equal(OpenSSL::ASN1::ObjectId, pkey.value[0].value[0].class) assert_equal("1.2.840.113549.1.1.1", pkey.value[0].value[0].oid) assert_equal(OpenSSL::ASN1::Null, pkey.value[0].value[1].class) assert_equal(OpenSSL::ASN1::BitString, sig_val.class) cert_der = cert.to_der assert_equal 593, cert_der.size assert OpenSSL::X509::Certificate.new( cert_der ).verify key # running the same in MRI also fails #calulated_sig = key.sign(OpenSSL::Digest::SHA1.new, cert_der) #assert_equal calulated_sig, sig_val.value end def test_bit_string_infinite_length begin content = [ OpenSSL::ASN1::BitString.new("\x01"), OpenSSL::ASN1::EndOfContent.new() ] cons = OpenSSL::ASN1::Constructive.new content, OpenSSL::ASN1::BIT_STRING, nil, :UNIVERSAL cons.infinite_length = true expected = %w{ 23 80 03 02 00 01 00 00 } raw = [expected.join('')].pack('H*') assert_equal raw, cons.to_der # TODO for now we can no decode our own sh*t : #assert_equal raw, OpenSSL::ASN1.decode(raw).to_der end end def test_decode_all expected = %w{ 02 01 01 02 01 02 02 01 03 } raw = [expected.join('')].pack('H*') ary = OpenSSL::ASN1.decode_all(raw) assert_equal(3, ary.size) ary.each_with_index do |asn1, i| assert_universal(OpenSSL::ASN1::INTEGER, asn1) assert_equal(i + 1, asn1.value) end end def test_decode_application_specific raw = "0\x18\x02\x01\x01`\x13\x02\x01\x03\x04\to=Telstra\x80\x03ess" asn1 = OpenSSL::ASN1.decode(raw) pp asn1 if false assert_equal OpenSSL::ASN1::Sequence, asn1.class assert_equal 2, asn1.value.size assert_equal OpenSSL::ASN1::Integer, asn1.value[0].class assert_equal 1, asn1.value[0].value assert_equal OpenSSL::ASN1::ASN1Data, asn1.value[1].class assert_equal :APPLICATION, asn1.value[1].tag_class asn1_data = asn1.value[1] assert_equal 3, asn1_data.value.size assert_equal OpenSSL::ASN1::Integer, asn1_data.value[0].class assert_equal 3, asn1_data.value[0].value assert_equal OpenSSL::BN, asn1_data.value[0].value.class assert_equal OpenSSL::ASN1::OctetString, asn1_data.value[1].class assert_equal 'o=Telstra', asn1_data.value[1].value # assert_equal OpenSSL::ASN1::ASN1Data, asn1_data.value[2].class # assert_equal :CONTEXT_SPECIFIC, asn1_data.value[2].tag_class # assert_equal 'ess', asn1_data.value[2].value # assert_equal raw, asn1.to_der end private def assert_universal(tag, asn1, inf_len=false) assert_equal(tag, asn1.tag) assert_equal(:UNIVERSAL, asn1.tag_class) assert_equal(inf_len, asn1.infinite_length) end def encode_decode_test(type, values) values.each do |v| assert_equal(v, OpenSSL::ASN1.decode(type.new(v).to_der).value) end end end jruby-openssl-0.9.21/src/test/ruby/test_bn.rb000066400000000000000000000031521313661621600211370ustar00rootroot00000000000000require File.expand_path('test_helper', File.dirname(__FILE__)) class TestBN < TestCase def test_new bn = OpenSSL::BN.new('0') unless defined? JRUBY_VERSION assert_equal ( bn || OpenSSL::BN.new(0) ).to_s, '0' end def test_to_s bn = OpenSSL::BN.new('10') assert_equal bn.to_s(10), '10' assert_equal bn.to_s(16), '0A' bn = OpenSSL::BN.new('100') assert_equal bn.to_s(16), '64' assert_equal bn.to_s, '100' if defined? JRUBY_VERSION bn = OpenSSL::BN.new(-4242) assert_equal bn.to_s, '-4242' end end def test_comparable assert OpenSSL::BN.include? Comparable end def test_cmp bn1 = OpenSSL::BN.new('1') bn2 = OpenSSL::BN.new('1') bn3 = OpenSSL::BN.new('2') assert_equal(false, bn1 == nil) assert_equal(true, bn1 != nil) assert_equal(true, bn1 == bn2) assert_equal(false, bn1 == bn3) assert_equal(true, bn1.eql?(bn2)) assert_equal(false, bn1.eql?(bn3)) assert_equal(bn1.hash, bn2.hash) assert_not_equal(bn3.hash, bn1.hash) end if RUBY_VERSION >= '2.3' def test_to_bn bn = OpenSSL::BN.new('4224') assert_equal bn, 4224.to_bn assert_equal OpenSSL::BN, 1.to_bn.class bn = OpenSSL::BN.new('-1234567890') assert_equal bn, ( -1234567890 ).to_bn bn = OpenSSL::BN.new('1234567890123456789012345678901234567890') assert_equal bn, 1234567890123456789012345678901234567890.to_bn end def test_to_java assert_equal java.lang.Integer.new(42), OpenSSL::BN.new('42').to_java(:int) assert_equal java.math.BigInteger.valueOf(24), OpenSSL::BN.new('24').to_java end if defined? JRUBY_VERSION endjruby-openssl-0.9.21/src/test/ruby/test_cipher.rb000066400000000000000000000374201313661621600220170ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('test_helper', File.dirname(__FILE__)) class TestCipher < TestCase def setup super self.class.disable_security_restrictions! end def test_cipher_new OpenSSL::Cipher.new 'AES-256-CBC' # NOTE: MRI 1.9.3 raises RuntimeError : # RuntimeError: unsupported cipher algorithm (AES) # ... maybe we do not need to align that much ?! # NOTE: this raises in MRI : #assert_raise_cipher_error { OpenSSL::Cipher.new 'AES' } assert_raise_cipher_error { OpenSSL::Cipher.new 'AES-XXX' } assert_raise_cipher_error { OpenSSL::Cipher.new 'AES-128-XXX' } assert_raise_cipher_error { OpenSSL::Cipher.new 'SSS' } assert_raise(ArgumentError) { OpenSSL::Cipher.new } end def test_cipher_extended_support # NOTE: since 0.9.6 we allow the underlying JCE cipher algorithms # to work - although we won't report support for them in `ciphers` OpenSSL::Cipher.new 'PBEWithSHA1AndRC2_40-CBC' # Sun JCE #OpenSSL::Cipher.new 'RSA/ECB' # Sun JCE OpenSSL::Cipher.new 'RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING' # Sun JCE OpenSSL::Cipher.new 'RSA/ECB/OAEPWithSHA1AndMGF1Padding' # Sun JCE OpenSSL::Cipher.new 'DESedeWrap/CBC/NOPADDING' # Sun JCE OpenSSL::Cipher.new 'XTEA/CBC/PKCS7Padding' # BC OpenSSL::Cipher.new 'Noekeon/CBC/ZeroBytePadding' # BC end if defined? JRUBY_VERSION def test_named_classes OpenSSL::Cipher::AES.new '192-ECB' #assert_raise_cipher_error { OpenSSL::Cipher::AES.new '128' } OpenSSL::Cipher::AES.new 128, 'CBC' OpenSSL::Cipher::CAST5.new 'CFB' OpenSSL::Cipher::BF.new 'ECB' OpenSSL::Cipher::DES.new 'OFB' OpenSSL::Cipher::DES.new :EDE3, "CBC" assert_raise_cipher_error { OpenSSL::Cipher::DES.new '3X3' } OpenSSL::Cipher::RC2.new '64', 'CBC' OpenSSL::Cipher::RC2.new 'ECB' OpenSSL::Cipher::RC4.new '40' #OpenSSL::Cipher::RC4.new 'HMAC' if defined? JRUBY_VERSION #OpenSSL::Cipher::RC4.new 'HMAC-MD5' end def test_aes_classes # NOTE: ArgumentError: wrong number of arguments (0 for 1) on MRI OpenSSL::Cipher::AES128.new if defined? JRUBY_VERSION OpenSSL::Cipher::AES192.new 'CFB' OpenSSL::Cipher::AES256.new 'ECB' assert_raise_cipher_error { OpenSSL::Cipher::AES256.new 'XXX' } end def test_instantiate_supported_ciphers #puts OpenSSL::Cipher.ciphers.inspect #puts OpenSSL::Cipher.ciphers.size OpenSSL::Cipher.ciphers.each do |cipher_name| next if cipher_name.end_with?('wrap') # e.g. 'id-aes256-wrap' OpenSSL::Cipher.new cipher_name end end def test_excludes_cfb1_ciphers # due no support in BC for CFB-1 assert ! OpenSSL::Cipher.ciphers.find { |name| name =~ /CFB1/i } end if defined? JRUBY_VERSION def test_encrypt_decrypt_des_ede3_cbc # borrowed from OpenSSL suite c1 = OpenSSL::Cipher::Cipher.new("DES-EDE3-CBC") c2 = OpenSSL::Cipher::DES.new(:EDE3, "CBC") key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" iv = "\0\0\0\0\0\0\0\0" data = "DATA" c1.encrypt.pkcs5_keyivgen(key, iv) c2.encrypt.pkcs5_keyivgen(key, iv) s1 = c1.update(data) + c1.final s2 = c2.update(data) + c2.final assert_equal "\xC5q\x99)\x81\xE6\xE7\x06", s1 assert_equal(s1, s2, "encrypt") c1.decrypt.pkcs5_keyivgen(key, iv) c2.decrypt.pkcs5_keyivgen(key, iv) assert_equal(data, c1.update(s1) + c1.final, "decrypt") assert_equal(data, c2.update(s2) + c2.final, "decrypt") end def test_des_key_len cipher = OpenSSL::Cipher.new 'des' assert_equal 8, cipher.key_len cipher = OpenSSL::Cipher.new 'DES3' assert_equal 24, cipher.key_len cipher = OpenSSL::Cipher.new 'DES-CBC' assert_equal 8, cipher.key_len cipher = OpenSSL::Cipher.new 'des-ede3' assert_equal 24, cipher.key_len cipher = OpenSSL::Cipher.new 'des-ede' assert_equal 16, cipher.key_len cipher = OpenSSL::Cipher.new 'DES-EDE-CFB' assert_equal 16, cipher.key_len end def test_des_iv_len cipher = OpenSSL::Cipher.new 'des' assert_equal 8, cipher.iv_len cipher = OpenSSL::Cipher.new 'DES3' assert_equal 8, cipher.iv_len cipher = OpenSSL::Cipher.new 'DES-CBC' assert_equal 8, cipher.iv_len cipher = OpenSSL::Cipher.new 'des-ede3' assert_equal 0, cipher.iv_len cipher = OpenSSL::Cipher.new 'des-ede' assert_equal 0, cipher.iv_len cipher = OpenSSL::Cipher.new 'DES-EDE-CFB' assert_equal 8, cipher.iv_len end @@test_encrypt_decrypt_des_variations = nil def test_encrypt_decrypt_des_variations key = "\0\0\0\0\0\0\0\0" * 3 iv = "\0\0\0\0\0\0\0\0" data = "JPMNT" { # calculated on MRI 'des' => "b\x00<\xC0\x16\xAF\xDCd", 'des-cbc' => "b\x00<\xC0\x16\xAF\xDCd", #'des-cfb' => "\xE0\x9ER\xCC\xD8", #'des-ofb' => "\xE0\x9ER\xCC\xD8", 'des-ecb' => ".\x1E\xB3\x0E\xE0\xD2\x9DG", 'des-ede' => "@\x8B\x89}u\xB4\r\xA5", 'des-ede-cbc' => "\x99\x97\xBE(\xB9+f\xFA", #'des-ede-cfb' => "l\x02?\x16\x1A", #'des-ede-ofb' => "l\x02?\x16\x1A", ##'des-ede-ecb' => RuntimeError: unsupported cipher algorithm (des-ede-ecb) 'des-ede3' => "\xDC\xD4\xF4\xBDmF\xC26", # actually ECB 'des-ede3-cbc' => "\x8D\xE6\x17\xD0\x97\rR\x8C", #'des-ede3-cfb' => ",\x93^\xAD\x9C", #'des-ede3-ofb' => ",\x93^\xAD\x9C", ##'des-ede3-ecb' => unsupported cipher algorithm (des-ede3-ecb) 'des3' => "\x8D\xE6\x17\xD0\x97\rR\x8C" }.each do |name, expected| c = OpenSSL::Cipher.new name c.encrypt c.key = key c.iv = iv c.pkcs5_keyivgen(key, iv) assert_equal expected, c.update(data) + c.final, "failed: #{name}" end cipher = OpenSSL::Cipher::Cipher.new("DES-EDE3") cipher.encrypt.pkcs5_keyivgen(key, iv) secret = cipher.update(data) + cipher.final assert_equal "\xDC\xD4\xF4\xBDmF\xC26", secret cipher.decrypt.pkcs5_keyivgen(key, iv) assert_equal(data, cipher.update(secret) + cipher.final, "decrypt") data = "sa jej lubim alebo moj bicykel" cipher.encrypt.pkcs5_keyivgen(key, iv) secret = cipher.update(data) + cipher.final assert_equal "\xE9;\xDF\xEE/\x1D\xCB\xF9\xD1\xAF\xBC\xF0\x00\xA3\xDBsLxF2\xA4|\x11T\xD7&:\xD8\xF7\xA2\xD1b", secret cipher.decrypt.pkcs5_keyivgen(key, iv) assert_equal(data, cipher.update(secret) + cipher.final, "decrypt") cipher.padding = 0 data = "hehehehemehehehe" cipher.encrypt.pkcs5_keyivgen(key, iv) secret = cipher.update(data) + cipher.final assert_equal "v\r\xA4\xB3\x02\x18\xB5|A\x13\x87\xF1\xC0A\xC4U", secret cipher.decrypt.pkcs5_keyivgen(key, iv) assert_equal(data, cipher.update(secret) + cipher.final, "decrypt") # assuming Cipher.ciphers not cached - re-run the tests with cache : unless @@test_encrypt_decrypt_des_variations @@test_encrypt_decrypt_des_variations = true OpenSSL::Cipher.ciphers; test_encrypt_decrypt_des_variations end end def test_another_encrypt_des_ede3 cipher = OpenSSL::Cipher.new('DES-EDE3') cipher.encrypt # calculated on MRI : cipher.key = "\x1F\xFF&\xA4k\x8F^\xC80\txq'S\x93\xD2\xE3A\xEDT\xDCs\xFD<=G\a\x8F=\x8FhE" cipher.iv = "o\x15# \xD1\a\x90\xC7ZO\r[\xE2\x8F\v)# I6;\xE6\xB7h\xD3M\xDA\xA0\xD1\xDCy\xD2" assert_equal "\xE1\x8DZ>MEq\xEF\x1A\xAC\xB1ab\x0Ea\x81", (cipher.update('sup3rs33kr3t') + cipher.final) end def test_random cipher = OpenSSL::Cipher.new 'AES-128-OFB' org.jruby.ext.openssl.Cipher.class_eval do field_reader :key, :realIV end assert_equal nil, cipher.to_java.key assert_equal nil, cipher.to_java.realIV assert_equal 16, cipher.random_key.size assert_equal 16, cipher.to_java.key.length assert_equal 16, cipher.random_iv.size assert_equal 16, cipher.to_java.realIV.length end if defined? JRUBY_VERSION def test_cipher_init_default_key return skip('OpenSSL::Cipher key default not implemented') if defined? JRUBY_VERSION out = OpenSSL::Cipher::AES256.new("CBC").update "\1\2\3\4\5\6\7\8" assert_equal '', out # NOTE on MRI < 1.9.3 : [BUG] Segmentation fault return if RUBY_VERSION.index('1.8') == 0 && ! defined? JRUBY_VERSION #out = OpenSSL::Cipher::AES128.new("CFB").update "\0\0\0\0\0\0\0\0" #assert_equal "f\xE9K\xD4\xEF\x8A,;", out # NOTE: quite "crappy" MRI (ECB) behavior : out = OpenSSL::Cipher::AES192.new("ECB").update "1234567890" assert_equal '', out c = OpenSSL::Cipher.new("AES-128-ECB") c.encrypt assert_equal '', c.update('0') assert_equal "B\xF1c\xE2:\xE3\x84fd\xC1s\xDB\x889\x84\x8A", c.update('0' * 15) out = c.update '0' assert_equal "", out c.update('0' * 15) assert_equal "G\xDD\x11?\x9D\x99\xAD\xB0\x9F\xB2j\x01L\xD7\xA8\xBD", c.final c = OpenSSL::Cipher::AES128.new("ECB") assert_equal '', c.update('0') assert_equal '', c.update('0' * 15) out = c.update '0' assert_equal "\x9F\fr\xDB%9\xEC\x11\xF6\xBFt\x9F0\xF0\x8C\x0E", out end def assert_raise_cipher_error(&block) if defined? JRUBY_VERSION # TODO should we fix this? assert_raise OpenSSL::Cipher::CipherError, &block else assert_raise RuntimeError, &block end end def test_cipher_update_non_mod_length cipher = OpenSSL::Cipher.new 'AES-128-CFB1' cipher.encrypt # length = 50 cipher.iv = "8\xF2\xEF\xFC7\x97.\xE9\x02)\xED\x18\xA6h\x14\xD2Z0\x97\x8F\x0E\x04`6n\xD8\xB8\xED\x0E\x95\xF3\xBA\xFC\xB3\x16\xF0lC\x97;\xBB\xED\xF1\xEE\xCB\x869\x93k\xB5" cipher.key = "\xBB;\x1A\x82\xFB'\xFB\xE4\xFBDP\xD8\x16.\xD1\x0EF.\xFD;\x9B\x8C\xE2\xBC\x18\xAD\x80\xB2\xBB\xF7U\x90y\xD2y\xCA\xE07\xBE\x97\an@\xB9\xE97\xF3\x9DA\xBC" bytes = "\xACJ\xF5\xA6m\xE2\xE8W\x0Fy\x93\xEA\xCFA\x03\xCF" expected = ",=\xC0\xD2\xEF\xE7(u,e\xD6l\xB4\x8E\x13\x00" # from MRI actual = cipher.update(bytes) assert_equal expected, actual assert_equal 16, cipher.iv_len assert_equal 16, cipher.key_len end unless jruby? # blocked due #35 def test_cipher_update_mod_length cipher = OpenSSL::Cipher.new 'AES-128-CFB1' cipher.encrypt # length = 48 cipher.iv = '1' * 16 cipher.key = '0' * 16 bytes = "\xACJ\xF5\xA6m\xE2\xE8W\x0Fy\x93\xEA\xCFA\x03\xCF" expected = "\xDD\x88dDj\xB9\xE2\xC9\xC5\x97L\x84V\x18\xE0\x93" # from MRI actual = cipher.update(bytes) assert_equal expected, actual assert_equal 16, cipher.iv_len assert_equal 16, cipher.key_len end unless jruby? # blocked due #35 def test_encrypt_aes_cfb_4_incompatibility cipher = OpenSSL::Cipher.new 'aes-128-cfb' assert_equal cipher, cipher.encrypt length = 16 cipher.iv = '0' * length cipher.key = '1' * length bytes = '0000' expected = "f0@\x02" # from MRI actual = cipher.update(bytes) if jruby? # NOTE: ugly but this is as far as JCE gets us : ##assert_equal expected, actual #assert_equal expected, cipher.final else assert_equal expected, actual assert_equal "", cipher.final end end def test_aes_128_gcm cipher = OpenSSL::Cipher.new('aes-128-gcm') assert_equal cipher, cipher.encrypt cipher.key = '01' * 8 cipher.iv = '0' * 16 bytes = '0000' * 4 expected = "\xAC\xC8\x0E\xEDbX,\xB4\xCD\x02\x06O(p\xF8u" # from MRI actual = cipher.update(bytes) assert_equal expected, actual assert_equal "", cipher.final unless defined? JRUBY_VERSION cipher = OpenSSL::Cipher.new('aes-128-gcm') assert_equal cipher, cipher.encrypt cipher.key = '01' * 8 cipher.iv = '012345678' * 2 bytes = '0000' * 4 expected = "\xF3\xEF\xE6K\xBAJ\xAB=7m'\b\xE0\x06U\x9B" # from MRI actual = cipher.update(bytes) assert_equal expected, actual #assert_equal "", cipher.final unless defined? JRUBY_VERSION cipher = OpenSSL::Cipher.new('aes-128-gcm') assert_equal cipher, cipher.encrypt assert_equal 16, cipher.key_len assert_equal 12, cipher.iv_len cipher.key = '01' * 8 cipher.iv = '0' * 12 bytes = '0000' * 4 expected = "\xAC\xC8\x0E\xEDbX,\xB4\xCD\x02\x06O(p\xF8u" # from MRI actual = cipher.update(bytes) assert_equal expected, actual #assert_equal "", cipher.final cipher = OpenSSL::Cipher.new('aes-256-gcm') assert_equal cipher, cipher.encrypt assert_equal 32, cipher.key_len assert_equal 12, cipher.iv_len cipher.key = '01245678' * 4 cipher.iv = '0123456' * 2 bytes = '0101' * 8 expected = "\xA8I0\xF8\xCD?Z\xFD\x8E\"T\xF5\xF2\xC5\xC8\x05\xD4b\x85\xA3}'\xC99]\xC1\x16\x8B\x13\x9E-)" # from MRI actual = cipher.update(bytes) assert_equal expected, actual #assert_equal "", cipher.final end def test_aes_gcm ['aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm'].each do |algo| pt = "You should all use Authenticated Encryption!" cipher, key, iv = new_encryptor(algo) cipher.auth_data = "aad" ct = cipher.update(pt) + cipher.final tag = cipher.auth_tag assert_equal(16, tag.size) decipher = new_decryptor(algo, key, iv) decipher.auth_tag = tag decipher.auth_data = "aad" assert_equal(pt, decipher.update(ct) + decipher.final) end end def new_encryptor(algo) cipher = OpenSSL::Cipher.new(algo) cipher.encrypt key = cipher.random_key iv = cipher.random_iv [cipher, key, iv] end private :new_encryptor def new_decryptor(algo, key, iv) OpenSSL::Cipher.new(algo).tap do |cipher| cipher.decrypt cipher.key = key cipher.iv = iv end end private :new_decryptor def test_aes_128_gcm_with_auth_tag cipher = OpenSSL::Cipher.new('aes-128-gcm') cipher.encrypt #assert_equal 16, cipher.key_len #assert_equal 12, cipher.iv_len cipher.key = '01' * 8 cipher.iv = '1001' * 3 plaintext = "Hello World" padding = cipher.update("\0\0") text = cipher.update(plaintext) final = cipher.final; a_tag = cipher.auth_tag assert_equal "\xB5\xFD", padding unless defined? JRUBY_VERSION assert_equal "\xCCxqd\xDE\x92\x95\xAD0\xB4=", text unless defined? JRUBY_VERSION assert_equal "", final unless defined? JRUBY_VERSION assert_equal "\xB5\xFD\xCCxqd\xDE\x92\x95\xAD0\xB4=", padding + text + final assert_equal "\ay\xBA\x89\xC9\x91\xF8N\xB7\xD6\x17+\x0F\\\xF8N", a_tag assert_equal a_tag, cipher.auth_tag assert_raise(OpenSSL::Cipher::CipherError) { cipher.update("\0\0") } assert_equal a_tag, cipher.auth_tag assert_raise(OpenSSL::Cipher::CipherError) { cipher.final } end def test_encrypt_auth_data_non_gcm cipher = OpenSSL::Cipher.new 'aes-128-cfb' cipher.encrypt #length = 16 #cipher.iv = '0' * length #cipher.key = '1' * length assert_raise(OpenSSL::Cipher::CipherError) { cipher.auth_tag } end def test_encrypt_aes_cfb_16_incompatibility cipher = OpenSSL::Cipher.new 'AES-128-CFB' assert_equal cipher, cipher.encrypt length = 16 cipher.iv = '0' * length cipher.key = '1' * length bytes = '0000' * 4 expected = "f0@\x02\xF6\xA8\xC2\rt\xCC\x83\x8F8e\x19R" # from MRI actual = cipher.update(bytes) if jruby? # NOTE: ugly but this is as far as JCE gets us : ##assert_equal expected, actual #assert_equal expected, cipher.final else assert_equal expected, actual assert_equal "", cipher.final end end def test_encrypt_aes_cfb_20_incompatibility cipher = OpenSSL::Cipher.new 'AES-128-CFB' assert_equal cipher, cipher.encrypt length = 16 cipher.iv = '0' * length cipher.key = '1' * length bytes = '0000' * 5 expected = "f0@\x02\xF6\xA8\xC2\rt\xCC\x83\x8F8e\x19RZ\x8D5\xF8" # from MRI actual = cipher.update(bytes) if jruby? # NOTE: ugly but this is as far as JCE gets us : assert_equal expected[0...16], actual # since on Java the padding is handled internally by the Cipher # we get :( "Z\x8D5\xF8\x10S|\xB7_R\xA2\x921\x93\x14]" assert_equal expected[16..-1], cipher.final[0...4] else assert_equal expected, actual assert_equal "", cipher.final end end end jruby-openssl-0.9.21/src/test/ruby/test_digest.rb000066400000000000000000000073231313661621600220230ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('test_helper', File.dirname(__FILE__)) class TestDigest < TestCase def test_digest_classes OpenSSL::Digest::SHA.new.block_length OpenSSL::Digest::SHA1.new.block_length OpenSSL::Digest::SHA224.new.block_length # BC OpenSSL::Digest::SHA256.new.block_length OpenSSL::Digest::SHA384.new.block_length OpenSSL::Digest::SHA512.new.block_length OpenSSL::Digest::MD2.new.block_length OpenSSL::Digest::MD4.new.block_length # BC OpenSSL::Digest::MD5.new.block_length # NOTE: MDC2 not supported #OpenSSL::Digest::MDC2.new OpenSSL::Digest::RIPEMD160.new.block_length # BC OpenSSL::Digest::DSS.new.block_length OpenSSL::Digest::DSS1.new.block_length end def test_digest_extension # BC supports these - we shall allow any supported algorithms to work OpenSSL::Digest.new('RipeMD256').digest OpenSSL::Digest.new('SHA224').digest OpenSSL::Digest.new('SHA-384').digest #OpenSSL::Digest.new('SHA3').digest OpenSSL::Digest.new('Whirlpool').digest end if defined? JRUBY_VERSION def test_digest_helpers md5 = "\x1EJ\e\x03\xD1\xB6\xCD\x8A\x17J\x82ov\xE0\t\xF4" assert_equal md5, OpenSSL::Digest.digest('MD5', '0000000000000000') sha = "b02132081808b493c61e86626ee6c2e29326a662" assert_equal sha, OpenSSL::Digest.hexdigest('SHA1', '0000000000000000') end def setup require 'openssl' @d1 = OpenSSL::Digest::Digest::new("MD5") @d2 = OpenSSL::Digest::MD5.new require 'digest/md5' @md = Digest::MD5.new @data = "DATA" end def teardown @d1 = @d2 = @md = nil end def test_digest assert_equal(@md.digest, @d1.digest) assert_equal(@md.hexdigest, @d1.hexdigest) @d1 << @data @d2 << @data @md << @data assert_equal(@md.digest, @d1.digest) assert_equal(@md.hexdigest, @d1.hexdigest) assert_equal(@d1.digest, @d2.digest) assert_equal(@d1.hexdigest, @d2.hexdigest) assert_equal(@md.digest, OpenSSL::Digest::MD5.digest(@data)) assert_equal(@md.hexdigest, OpenSSL::Digest::MD5.hexdigest(@data)) end def test_eql assert(@d1 == @d2, "==") d = @d1.clone assert(d == @d1, "clone") end def test_info assert_equal("MD5", @d1.name, "name") assert_equal("MD5", @d2.name, "name") assert_equal(16, @d1.size, "size") end def test_dup @d1.update(@data) assert_equal(@d1.name, @d1.dup.name, "dup") assert_equal(@d1.name, @d1.clone.name, "clone") assert_equal(@d1.digest, @d1.clone.digest, "clone .digest") end def test_reset @d1.update(@data) dig1 = @d1.digest @d1.reset @d1.update(@data) dig2 = @d1.digest assert_equal(dig1, dig2, "reset") end def encode16(str) str.unpack("H*").first end def test_098_features sha224_a = "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5" sha256_a = "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" sha384_a = "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31" sha512_a = "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75" assert_equal(sha224_a, OpenSSL::Digest::SHA224.hexdigest("a")) assert_equal(sha256_a, OpenSSL::Digest::SHA256.hexdigest("a")) assert_equal(sha384_a, OpenSSL::Digest::SHA384.hexdigest("a")) assert_equal(sha512_a, OpenSSL::Digest::SHA512.hexdigest("a")) assert_equal(sha224_a, encode16(OpenSSL::Digest::SHA224.digest("a"))) assert_equal(sha256_a, encode16(OpenSSL::Digest::SHA256.digest("a"))) assert_equal(sha384_a, encode16(OpenSSL::Digest::SHA384.digest("a"))) assert_equal(sha512_a, encode16(OpenSSL::Digest::SHA512.digest("a"))) end endjruby-openssl-0.9.21/src/test/ruby/test_helper.rb000066400000000000000000000153031313661621600220200ustar00rootroot00000000000000require 'rubygems' unless defined? Gem require 'java' if defined? JRUBY_VERSION if bc_version = ENV['BC_VERSION'] # && respond_to?(:require_jar) require 'jar-dependencies' require_jar 'org.bouncycastle', 'bcpkix-jdk15on', bc_version require_jar 'org.bouncycastle', 'bcprov-jdk15on', bc_version Jars.freeze_loading if defined? Jars.freeze_loading puts Java::OrgBouncycastleJceProvider::BouncyCastleProvider.new.info if $VERBOSE else base_dir = File.expand_path('../../..', File.dirname(__FILE__)) jar = File.join(base_dir, 'lib/jopenssl.jar') raise "jopenssl.jar jar not found" unless jar; $CLASSPATH << jar jar = Dir[File.join(base_dir, 'lib/org/bouncycastle/**/bcprov-*.jar')].first raise "bcprov jar not found" unless jar; $CLASSPATH << jar jar = Dir[File.join(base_dir, 'lib/org/bouncycastle/**/bcpkix-*.jar')].first raise "bcpkix jar not found" unless jar; $CLASSPATH << jar end if defined? JRUBY_VERSION # NOTE: RUnit maven plugin (<= 1.0.5) does not handle test-unit well ! #begin # gem 'test-unit' #rescue LoadError # puts "gem 'test-unit' not available, will load built-in 'test/unit'" #end begin gem 'minitest' require 'minitest/autorun' # NOTE: deal with maven plugin 1.0.10 setting output (gone on minitest 5) : if Minitest.const_defined?(:Unit) && ! defined?(Minitest::Unit.output) Minitest::Unit.module_eval do @@report_path = nil def self.report_path; @@report_path end def self.output=(report_path) # called by the runit-maven-plugin Minitest.extensions << 'output' # add a plugin (MiniT calls #plugin_output_init) @@report_path = report_path end end Minitest.module_eval do def self.plugin_output_init(options) summary = self.reporter.reporters.find { |rr| rr.is_a?(Minitest::SummaryReporter) } if summary && Minitest::Unit.report_path summary = summary.dup summary.io = Minitest::Unit.report_path self.reporter.reporters << summary end end end end rescue LoadError end if defined? Minitest::Test TestCase = Minitest::Test else require 'test/unit' TestCase = Test::Unit::TestCase end TestCase.class_eval do def setup; require 'openssl' end alias assert_raise assert_raises unless method_defined?(:assert_raise) unless method_defined?(:skip) if method_defined?(:omit) alias skip omit else def skip(msg = nil) warn "Skipped: #{caller[0]} #{msg}" end end end unless method_defined?(:assert_not_equal) def assert_not_equal(expected, actual) assert expected != actual, "expected: #{expected} to not equal: #{actual} but did" end end unless method_defined?(:assert_nothing_raised) def assert_nothing_raised begin yield rescue => e assert false, "unexpected error raised: #{e.inspect}" end end end unless method_defined?(:assert_not_same) def assert_not_same(expected, actual) assert ! expected.equal?(actual), "expected: #{expected} to be same as: #{actual} but did" end end def self.disable_security_restrictions!; @@security_restrictions = nil end # do nothing on MRI @@security_restrictions = '' def self.disable_security_restrictions! debug = OpenSSL.debug begin OpenSSL.debug = true #org.jruby.ext.openssl.util.CryptoSecurity.unrestrictSecurity #org.jruby.ext.openssl.util.CryptoSecurity.setAllPermissionPolicy @@security_restrictions = OpenSSL.send :_disable_security_restrictions! ensure OpenSSL.debug = debug end end if defined? JRUBY_VERSION def self.disable_security_restrictions disable_security_restrictions! if @@security_restrictions.eql?('') end def self.security_restrictions? disable_security_restrictions; return @@security_restrictions end def self.java6?; java_version.last.to_i == 6 end def self.java7?; java_version.last.to_i == 7 end def self.java8?; java_version.last.to_i == 8 end def self.java_version return [] unless defined? JRUBY_VERSION ENV_JAVA[ 'java.specification.version' ].split('.') end def self.jruby?; !! defined?(JRUBY_VERSION) end def jruby?; self.class.jruby? end private def issue_cert(dn, key, serial, not_before, not_after, extensions, issuer, issuer_key, digest) cert = OpenSSL::X509::Certificate.new issuer = cert unless issuer issuer_key = key unless issuer_key cert.version = 2 cert.serial = serial cert.subject = dn cert.issuer = issuer.subject cert.public_key = key.public_key cert.not_before = not_before cert.not_after = not_after ef = OpenSSL::X509::ExtensionFactory.new ef.subject_certificate = cert ef.issuer_certificate = issuer extensions.each do |oid, value, critical| cert.add_extension ef.create_extension(oid, value, critical) end cert.sign(issuer_key, digest) cert end def issue_crl(revoke_info, serial, lastup, nextup, extensions, issuer, issuer_key, digest) crl = OpenSSL::X509::CRL.new crl.issuer = issuer.subject crl.version = 1 crl.last_update = lastup crl.next_update = nextup revoke_info.each{|rserial, time, reason_code| revoked = OpenSSL::X509::Revoked.new revoked.serial = rserial revoked.time = time enum = OpenSSL::ASN1::Enumerated(reason_code) ext = OpenSSL::X509::Extension.new("CRLReason", enum) revoked.add_extension(ext) crl.add_revoked(revoked) } ef = OpenSSL::X509::ExtensionFactory.new ef.issuer_certificate = issuer ef.crl = crl crlnum = OpenSSL::ASN1::Integer(serial) crl.add_extension(OpenSSL::X509::Extension.new("crlNumber", crlnum)) extensions.each do |oid, value, critical| crl.add_extension ef.create_extension(oid, value, critical) end crl.sign(issuer_key, digest) crl end end begin gem 'mocha' rescue LoadError => e warn "#{e} to run all tests please `gem install mocha'" else begin if defined? MiniTest require 'mocha/mini_test' else require 'mocha/test_unit' end rescue LoadError => e warn "current mocha version might not work (try `gem install mocha'): #{e}" end end if defined? JRUBY_VERSION # make sure our OpenSSL lib gets used not JRuby's unless ENV['BC_VERSION'] $LOAD_PATH.unshift(File.expand_path('../../../lib', File.dirname(__FILE__))) end end if ENV['OPENSSL_TEST_SUITE'].to_s == 'true' require 'jopenssl/load' if defined? JRUBY_VERSION base = File.expand_path('../ossl', File.dirname(__FILE__)) if ( sub = RUBY_VERSION[0, 3] ) == '2.0' sub = '1.9' end puts "loading (MRI) OpenSSL suite from: #{File.join(base, sub)}" Dir.glob("#{File.join(base, sub)}/**/test_*.rb").each do |test| require test end end jruby-openssl-0.9.21/src/test/ruby/test_hmac.rb000066400000000000000000000023161313661621600214510ustar00rootroot00000000000000require File.expand_path('test_helper', File.dirname(__FILE__)) class TestHMAC < TestCase def setup super @digest = OpenSSL::Digest::MD5 @key = "KEY" @data = "DATA" @h1 = OpenSSL::HMAC.new(@key, @digest.new) @h2 = OpenSSL::HMAC.new(@key, "MD5") end def test_to_s @h1.update(''); @h1.update('1234567890') assert_equal(@h1.hexdigest, @h1.to_s) assert_equal(@h2.hexdigest, @h2.to_s) end def test_reset data = 'He is my neighbor Nursultan Tuliagby. He is pain in my assholes.' @h1.update('4'); @h1.update('2') @h1.reset @h1.update(data) @h2.update(data) assert_equal(@h2.digest, @h1.digest) end def test_correct_digest assert_equal('c17c7b655b11574fea8d676a1fdc0ca8', @h2.hexdigest) # calculated on MRI @h2.update('DATA') assert_equal('9e50596c0fa1197f8587443a942d8afc', @h2.hexdigest) # calculated on MRI @h2.reset @h2.update("\xFF") # invalid utf-8 char assert_equal('0770623462e782b51bb0689a8ba4f3f1', @h2.hexdigest) # calcualted on MRI end def test_hexdigest_with_empty_key result = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('md5'), "", "foo") assert_equal "4acb10ca3965a14a080297db0921950c", result end end jruby-openssl-0.9.21/src/test/ruby/test_openssl.rb000066400000000000000000000044701313661621600222270ustar00rootroot00000000000000require File.expand_path('test_helper', File.dirname(__FILE__)) require 'openssl' class TestOpenSSL < TestCase # only test this when the gem is installed - i.e. during integration tests def test_gem_version assert_equal ENV['BC_VERSION'], Java::OrgBouncycastleJceProvider::BouncyCastleProvider.new.info.sub( /[^0-9.]*/, '' ) # we have a jruby-openssl gem loaded assert Gem.loaded_specs[ 'jruby-openssl' ] != nil assert Gem.loaded_specs[ 'jruby-openssl' ].full_gem_path.match( /!/ ) == nil end if ENV['BC_VERSION'] def test_version if RUBY_VERSION.index('1.8') assert_equal '1.0.0', OpenSSL::VERSION else assert_equal '1.1.0', OpenSSL::VERSION end assert OpenSSL::OPENSSL_VERSION.index('OpenSSL') if defined? JRUBY_VERSION assert_equal 0, OpenSSL::OPENSSL_VERSION.index('JRuby-OpenSSL ') end assert OpenSSL::OPENSSL_VERSION_NUMBER if RUBY_VERSION > '2.0' # MRI 2.3 openssl/utils.rb does this (and we shall pass) : assert defined?(OpenSSL::OPENSSL_LIBRARY_VERSION) assert /\AOpenSSL +0\./ !~ OpenSSL::OPENSSL_LIBRARY_VERSION #puts "OpenSSL::OPENSSL_LIBRARY_VERSION = #{OpenSSL::OPENSSL_LIBRARY_VERSION.inspect}" end end def test_debug debug = OpenSSL.debug assert (OpenSSL.debug == true || OpenSSL.debug == false) assert OpenSSL.debug= true assert_equal true, OpenSSL.debug ensure OpenSSL.debug = debug end def test_stubs OpenSSL.deprecated_warning_flag OpenSSL.check_func(:func, :header) OpenSSL.fips_mode = false end def test_Digest digest = OpenSSL.Digest('MD5') assert_equal OpenSSL::Digest::MD5, digest end end # unless defined? OpenSSL::OPENSSL_DUMMY class TestOpenSSLStub < TestCase def test_autoload_consts_error assert_raise(LoadError) { OpenSSL::ASN1 } assert_raise(LoadError) { OpenSSL::BN } assert_raise(LoadError) { OpenSSL::Cipher } assert_raise(LoadError) { OpenSSL::Config } assert_raise(LoadError) { OpenSSL::Netscape } assert_raise(LoadError) { OpenSSL::PKCS7 } assert_raise(LoadError) { OpenSSL::PKey } assert_raise(LoadError) { OpenSSL::Random } assert_raise(LoadError) { OpenSSL::SSL } assert_raise(LoadError) { OpenSSL::X509 } end end if defined? OpenSSL::OPENSSL_DUMMY # This test only makes sense if the gem isn't installedjruby-openssl-0.9.21/src/test/ruby/test_random.rb000066400000000000000000000012761313661621600220250ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('test_helper', File.dirname(__FILE__)) class TestRandom < TestCase def test_api assert_equal 24, OpenSSL::Random.random_bytes(24).size assert_equal 1024, OpenSSL::Random.random_bytes(1024).size OpenSSL::Random.seed OpenSSL::Random.random_bytes(24) assert_equal 42, OpenSSL::Random.random_bytes(42).size assert_equal true, OpenSSL::Random.status? assert_equal 24, OpenSSL::Random.pseudo_bytes(24).size assert_equal 1024, OpenSSL::Random.pseudo_bytes(1024).size end def test_stubs OpenSSL::Random.random_add('42', :entropy) OpenSSL::Random.egd('hello.rb') OpenSSL::Random.egd_bytes('hello.rb', 42) end endjruby-openssl-0.9.21/src/test/ruby/test_security.rb000066400000000000000000000107301313661621600224070ustar00rootroot00000000000000$CLASSPATH << File.expand_path('../../../pkg/test-classes', File.dirname(__FILE__)) class SecurityWrapper java_import 'org.jruby.ext.openssl.security.SecurityManager' attr_reader :java_manager def initialize(java_manager) @java_manager = java_manager end def install_security_manager java.lang.System.setSecurityManager java_manager end def allow(permissions_hash = nil, &block) if permissions_hash permissions = parse_hash_value(permissions_hash).uniq.map { |v| v.flatten } return allow do |expected_type, expected_name, expected_actions| permissions.any? do |parr| (type, name, actions) = *parr (type == expected_type && (name.nil? || name == expected_name) && (actions.nil? || actions == expected_actions)) end end end SecurityManager::RubyPermission.new(block).tap { |perm| java_manager.permit perm } end def with_permissions(hash) p = allow(hash) begin yield ensure java_manager.revoke p end end def permissive! java_manager.setStrict(false) self end def strict! java_manager.setStrict(true) self end def verbose! java_manager.setVerbosity true self end def silent! java_manager.setVerbosity false self end private def parse_hash_value(value) return [ value ].compact unless value.is_a?(Hash) value.reduce([]) { |arr, kv| arr += [ kv.first ].product(parse_hash_value(kv.last)) } end end Security = SecurityWrapper.new org.jruby.ext.openssl.security.SecurityManager.new Security.allow do |type, name, actions| case type when 'FilePermission' # Allow to read the FS (.rb, .pem, .class, ...) actions == "read" when 'LoggingPermission' # NOTE invokebinder initializes JUL : # https://github.com/headius/invokebinder/blob/master/src/main/java/com/headius/invokebinder/Binder.java#L70 name == "control" # ("java.util.logging.LoggingPermission" "control") when 'PropertyPermission' actions == "read" && [ "java.protocol.handler.pkgs", "sun.misc.ProxyGenerator.saveGeneratedFiles", # FFI needs to be able to read its properties /^jnr\.ffi\..*/, # Allow reading any jruby properties /^jruby/, # Allow knowledge about environment /^os\..*/, /^user\..*/, "sun.arch.data.model", "java.home", # Allow proxies /^sun.reflect.proxy.*/, # NOTE invokebinder initializes JUL : "sun.util.logging.disableCallerCheck" ].any? { |read_permission| read_permission === name } when 'RuntimePermission' # Allow loading of native libraries name =~ /^loadLibrary\..*\.so$/ || name == "loadLibrary.nio" || # jnr.posix needs this name == "accessDeclaredMembers" || name == "createClassLoader" || # Let Main do System.exit name == "exitVM.1" || name =~ /^accessClassInPackage\.sun.*$/ || # Not sure what this is about name == "getProtectionDomain" || name == "fileSystemProvider" when 'ReflectPermission' # JRuby makes heavy usage of reflection for dynamic invocation, etc name == "suppressAccessChecks" else false end end ## Security.install_security_manager if ENV['INSTALL_SECURITY_MANAGER'].eql?('true') ## Security.strict!.with_permissions({ "SecurityPermission" => [ "getProperty.keystore.type", "putProviderProperty.SunJGSS", "putProviderProperty.SunEC-Internal", "putProviderProperty.BC", "insertProvider.BC" ], # OpenSSL uses java.text.SimpleDateFormat that needs to load this "RuntimePermission" => "accessClassInPackage.sun.util.resources", "PropertyPermission" => { "com.sun.security.preserveOldDCEncoding" => "read", "sun.security.key.serial.interop" => "read", # Maybe this should be global? "java.nio.file.spi.DefaultFileSystemProvider" => "read", # SimpleDateFormat again "sun.timezone.ids.oldmapping" => "read", "sun.nio.fs.chdirAllowed" => "read", # java.util.TimeZone.getDefault memoizes the default in property "user.timezone" => "write" } }) do require 'openssl' end ## Security.permissive! if manager = java.lang.System.getSecurityManager puts "using permissive! security with installed manager: #{manager}" end jruby-openssl-0.9.21/src/test/ruby/test_security_helper.rb000066400000000000000000000026201313661621600237450ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('test_helper', File.dirname(__FILE__)) class TestSecurityHelper < TestCase def setup; require 'openssl'; require 'java' super end def test_cert_factory_provider_leak # GH-94 assert provider = org.jruby.ext.openssl.SecurityHelper.getSecurityProvider assert_equal 'BC', provider.name factory1 = org.jruby.ext.openssl.SecurityHelper.getCertificateFactory('X.509') factory2 = org.jruby.ext.openssl.SecurityHelper.getCertificateFactory('X.509') assert_not_same factory1, factory2 assert_equal 'BC', factory1.provider.name assert_equal 'BC', factory2.provider.name # assert_same factory1.getProvider, factory2.getProvider java.security.cert.CertificateFactory.class_eval do field_reader :certFacSpi end spi1 = factory1.certFacSpi; spi2 = factory2.certFacSpi if spi1.is_a? org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory.class_eval do field_reader :bcHelper end if (spi1.bcHelper rescue nil) org.bouncycastle.jcajce.util.ProviderJcaJceHelper.class_eval do field_reader :provider rescue nil end if spi1.bcHelper.respond_to?(:provider) assert_same spi1.bcHelper.provider, spi2.bcHelper.provider end end end end if defined? JRUBY_VERSION endjruby-openssl-0.9.21/src/test/ruby/x509/000077500000000000000000000000001313661621600176605ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/x509/EntrustnetSecureServerCertificationAuthority.pem000066400000000000000000000033141313661621600315120ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= -----END CERTIFICATE----- jruby-openssl-0.9.21/src/test/ruby/x509/SETUP.txt000066400000000000000000000004611313661621600213220ustar00rootroot00000000000000$ /usr/lib/ssl/misc/CA.sh -newca $ /usr/lib/ssl/misc/CA.sh -newreq $ /usr/lib/ssl/misc/CA.sh -sign Signed certificate is in newcert.pem $ keytool -import -file demoCA/cacert.pem -alias demoCA -keystore javastore.ts -storepass javastore Trust this certificate? [no]: y Certificate was added to keystorejruby-openssl-0.9.21/src/test/ruby/x509/ca.crt000066400000000000000000000023541313661621600207610ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIJAPDDJ9RadMXtMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMRwwGgYDVQQKDBNEZW1vIENlcnQg QXV0aG9yaXR5MRAwDgYDVQQDDAdkZW1vLmNhMB4XDTE2MTEwNDEwMTk1M1oXDTE5 MTEwNDEwMTk1M1owUjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx HDAaBgNVBAoME0RlbW8gQ2VydCBBdXRob3JpdHkxEDAOBgNVBAMMB2RlbW8uY2Ew ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMRtKAJKnnzXa9quZTErpK BZaUY9XGBm+Fzn0VLUEmHdLd2tU17IDdlOy35Eu24i30csCgxb/zurlf/KK+wPe+ ORw7k1IyheYpAMefO4rB7XfjjcD2HJjBCpiFuAy1V7p16W/yh63fNjIgkluzhYoY 8dXa5jsIUhW0ZTvA1Pkhnvb5Iuc9Ht4fe9kWvAZYJjv/FkbDL0OZpFsBeJ4ehm3D W2OCj3YhVFATf6hv2S9ylmTmDLxbnmSp8eBUfwTWQflWxOcGWjjDmpH9jamZuFCc HXviYqsiS//8q5Q7upgda5YRCgZrOF1hUYBvajKoiJELqJSLu1FBgvnpgRd5IiA3 AgMBAAGjUDBOMB0GA1UdDgQWBBS6XumQO1v2eaLTZQnFOWrnQ2v4PTAfBgNVHSME GDAWgBS6XumQO1v2eaLTZQnFOWrnQ2v4PTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBCwUAA4IBAQBgK6cDSR9nCrM0EoBPs54eEqV3YUU7b22SEMWhwjrHtaV8jL12 yfvbnw/7id88A/iHnQEEdUUdL0NqttZsQ920tMS6JpkAXwL8LM6vo3+WCY0ERuoq efWYaCigMR3CKtOCMyBO38b32WXXmVbOx8VLAKjkU0rih/52k1dJ0glEzqZ7Omlt Al5+hgAl6r9HMIi+GqIStxLH3QROQfY/Sa2aWNFyFyGJ4sIAWEsRsASUm8LcJo92 SP0sLkwkyCkkPB78Os56W5LhFNSi0KGdD5LL1C/eOTYLrvqYRcTaABoTzyLRTukz jqUw967yke1++Kq+SwYwhfUxb8EZpfSRYSxT -----END CERTIFICATE-----jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/000077500000000000000000000000001313661621600210105ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/cacert.pem000066400000000000000000000103411313661621600227530ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 17348753982565434861 (0xf0c327d45a74c5ed) Signature Algorithm: sha256WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Demo Cert Authority, CN=demo.ca Validity Not Before: Nov 4 10:19:53 2016 GMT Not After : Nov 4 10:19:53 2019 GMT Subject: C=AU, ST=Some-State, O=Demo Cert Authority, CN=demo.ca Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:cc:46:d2:80:24:a9:e7:cd:76:bd:aa:e6:53:12: ba:4a:05:96:94:63:d5:c6:06:6f:85:ce:7d:15:2d: 41:26:1d:d2:dd:da:d5:35:ec:80:dd:94:ec:b7:e4: 4b:b6:e2:2d:f4:72:c0:a0:c5:bf:f3:ba:b9:5f:fc: a2:be:c0:f7:be:39:1c:3b:93:52:32:85:e6:29:00: c7:9f:3b:8a:c1:ed:77:e3:8d:c0:f6:1c:98:c1:0a: 98:85:b8:0c:b5:57:ba:75:e9:6f:f2:87:ad:df:36: 32:20:92:5b:b3:85:8a:18:f1:d5:da:e6:3b:08:52: 15:b4:65:3b:c0:d4:f9:21:9e:f6:f9:22:e7:3d:1e: de:1f:7b:d9:16:bc:06:58:26:3b:ff:16:46:c3:2f: 43:99:a4:5b:01:78:9e:1e:86:6d:c3:5b:63:82:8f: 76:21:54:50:13:7f:a8:6f:d9:2f:72:96:64:e6:0c: bc:5b:9e:64:a9:f1:e0:54:7f:04:d6:41:f9:56:c4: e7:06:5a:38:c3:9a:91:fd:8d:a9:99:b8:50:9c:1d: 7b:e2:62:ab:22:4b:ff:fc:ab:94:3b:ba:98:1d:6b: 96:11:0a:06:6b:38:5d:61:51:80:6f:6a:32:a8:88: 91:0b:a8:94:8b:bb:51:41:82:f9:e9:81:17:79:22: 20:37 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: BA:5E:E9:90:3B:5B:F6:79:A2:D3:65:09:C5:39:6A:E7:43:6B:F8:3D X509v3 Authority Key Identifier: keyid:BA:5E:E9:90:3B:5B:F6:79:A2:D3:65:09:C5:39:6A:E7:43:6B:F8:3D X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha256WithRSAEncryption 60:2b:a7:03:49:1f:67:0a:b3:34:12:80:4f:b3:9e:1e:12:a5: 77:61:45:3b:6f:6d:92:10:c5:a1:c2:3a:c7:b5:a5:7c:8c:bd: 76:c9:fb:db:9f:0f:fb:89:df:3c:03:f8:87:9d:01:04:75:45: 1d:2f:43:6a:b6:d6:6c:43:dd:b4:b4:c4:ba:26:99:00:5f:02: fc:2c:ce:af:a3:7f:96:09:8d:04:46:ea:2a:79:f5:98:68:28: a0:31:1d:c2:2a:d3:82:33:20:4e:df:c6:f7:d9:65:d7:99:56: ce:c7:c5:4b:00:a8:e4:53:4a:e2:87:fe:76:93:57:49:d2:09: 44:ce:a6:7b:3a:69:6d:02:5e:7e:86:00:25:ea:bf:47:30:88: be:1a:a2:12:b7:12:c7:dd:04:4e:41:f6:3f:49:ad:9a:58:d1: 72:17:21:89:e2:c2:00:58:4b:11:b0:04:94:9b:c2:dc:26:8f: 76:48:fd:2c:2e:4c:24:c8:29:24:3c:1e:fc:3a:ce:7a:5b:92: e1:14:d4:a2:d0:a1:9d:0f:92:cb:d4:2f:de:39:36:0b:ae:fa: 98:45:c4:da:00:1a:13:cf:22:d1:4e:e9:33:8e:a5:30:f7:ae: f2:91:ed:7e:f8:aa:be:4b:06:30:85:f5:31:6f:c1:19:a5:f4: 91:61:2c:53 -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIJAPDDJ9RadMXtMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMRwwGgYDVQQKDBNEZW1vIENlcnQg QXV0aG9yaXR5MRAwDgYDVQQDDAdkZW1vLmNhMB4XDTE2MTEwNDEwMTk1M1oXDTE5 MTEwNDEwMTk1M1owUjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx HDAaBgNVBAoME0RlbW8gQ2VydCBBdXRob3JpdHkxEDAOBgNVBAMMB2RlbW8uY2Ew ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMRtKAJKnnzXa9quZTErpK BZaUY9XGBm+Fzn0VLUEmHdLd2tU17IDdlOy35Eu24i30csCgxb/zurlf/KK+wPe+ ORw7k1IyheYpAMefO4rB7XfjjcD2HJjBCpiFuAy1V7p16W/yh63fNjIgkluzhYoY 8dXa5jsIUhW0ZTvA1Pkhnvb5Iuc9Ht4fe9kWvAZYJjv/FkbDL0OZpFsBeJ4ehm3D W2OCj3YhVFATf6hv2S9ylmTmDLxbnmSp8eBUfwTWQflWxOcGWjjDmpH9jamZuFCc HXviYqsiS//8q5Q7upgda5YRCgZrOF1hUYBvajKoiJELqJSLu1FBgvnpgRd5IiA3 AgMBAAGjUDBOMB0GA1UdDgQWBBS6XumQO1v2eaLTZQnFOWrnQ2v4PTAfBgNVHSME GDAWgBS6XumQO1v2eaLTZQnFOWrnQ2v4PTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBCwUAA4IBAQBgK6cDSR9nCrM0EoBPs54eEqV3YUU7b22SEMWhwjrHtaV8jL12 yfvbnw/7id88A/iHnQEEdUUdL0NqttZsQ920tMS6JpkAXwL8LM6vo3+WCY0ERuoq efWYaCigMR3CKtOCMyBO38b32WXXmVbOx8VLAKjkU0rih/52k1dJ0glEzqZ7Omlt Al5+hgAl6r9HMIi+GqIStxLH3QROQfY/Sa2aWNFyFyGJ4sIAWEsRsASUm8LcJo92 SP0sLkwkyCkkPB78Os56W5LhFNSi0KGdD5LL1C/eOTYLrvqYRcTaABoTzyLRTukz jqUw967yke1++Kq+SwYwhfUxb8EZpfSRYSxT -----END CERTIFICATE----- jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/careq.pem000066400000000000000000000017201313661621600226060ustar00rootroot00000000000000-----BEGIN CERTIFICATE REQUEST----- MIIClzCCAX8CAQAwUjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx HDAaBgNVBAoME0RlbW8gQ2VydCBBdXRob3JpdHkxEDAOBgNVBAMMB2RlbW8uY2Ew ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMRtKAJKnnzXa9quZTErpK BZaUY9XGBm+Fzn0VLUEmHdLd2tU17IDdlOy35Eu24i30csCgxb/zurlf/KK+wPe+ ORw7k1IyheYpAMefO4rB7XfjjcD2HJjBCpiFuAy1V7p16W/yh63fNjIgkluzhYoY 8dXa5jsIUhW0ZTvA1Pkhnvb5Iuc9Ht4fe9kWvAZYJjv/FkbDL0OZpFsBeJ4ehm3D W2OCj3YhVFATf6hv2S9ylmTmDLxbnmSp8eBUfwTWQflWxOcGWjjDmpH9jamZuFCc HXviYqsiS//8q5Q7upgda5YRCgZrOF1hUYBvajKoiJELqJSLu1FBgvnpgRd5IiA3 AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAdjOJT6TBALLbsVs28b3k9zk+89QZ CRI7zs3jBc1xbCTYp9qTWP6JHKzNAzs1Md2ZkC4J98MdmVwq/9TJLXFUjYRwlxKe QIkLhHw2jPKZ6ELRB8E3sWHiWFZ/yNzKk4P6nAgNjWhzH0LK1yfb0JyI/mNLLGEf s7Ao+sQuSie83cMx9qccDtNh5Rd+tUXS4eGNcN/W5BrqqPKkznEl1yyeeY3Cdm37 3db4TPSiVjoMK1UnufqU9fRJ5cpC9QT7GUk2x3yXD9vf913on9AO1Oo05Q9qHMX+ 3ea18pDu8yeWbsovmvf2n9gI8I8+Gbv1QE/kzzXCtGSrqgdDVf4UqLsVuw== -----END CERTIFICATE REQUEST----- jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/index.txt000066400000000000000000000003431313661621600226600ustar00rootroot00000000000000V 191104101953Z F0C327D45A74C5ED unknown /C=AU/ST=Some-State/O=Demo Cert Authority/CN=demo.ca V 171104103219Z F0C327D45A74C5EE unknown /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=example.com/emailAddress=hi@example.com jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/index.txt.attr000066400000000000000000000000251313661621600236260ustar00rootroot00000000000000unique_subject = yes jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/index.txt.attr.old000066400000000000000000000000251313661621600244030ustar00rootroot00000000000000unique_subject = yes jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/index.txt.old000066400000000000000000000001371313661621600234360ustar00rootroot00000000000000V 191104101953Z F0C327D45A74C5ED unknown /C=AU/ST=Some-State/O=Demo Cert Authority/CN=demo.ca jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/private/000077500000000000000000000000001313661621600224625ustar00rootroot00000000000000jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/private/cakey.pem000066400000000000000000000034521313661621600242650ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIKTGpQgsbXdwCAggA MBQGCCqGSIb3DQMHBAgBzf9P1JYH3wSCBMjSuxf3yYg+PcmAKtAl6M4piLfzIEqO 79iKi7nqlZ+Z8BOyWeNRzd70IUru0XrPyD+wLH1CN2MXtDff3z5JVAG8CaDPS79+ 6yrgMn8jgMHTT/bxZiTncFy4RxvP8+ug3UlUXyhnTUW+peyWMerzx8+mUH5FIhIN KsCFnKEMFY58z/mdOIaX/zrBbnHTR94BSGBycor1UNLiT51CupTOzwUxyOiI6cm9 sRtvAenY5O6LK4yKlg9S8w7Fh+3k1dWn5VjSIwSuCJTsWkuidXL70K/yv2vY0/MI dqsQCeoZli57+W8+OK+KgPifQPwovuEnCGb3EtNzIPMjyAL4D+yiBJb8KtHk/591 fJo6n9eFY++vm/TAVI0brY6/l4ltejWXMPTeh6tVnJ+HXv/R+ws85fZCGr0dJZcQ A4gV4bsOrnxxSGkaw8NVfxy2Nr4xsoZItKAHPXfaXMbJZcv+rbpFWp2lNRyGLNP2 SWJ91eqdN/zYg3flS9gxIQSB+JBzf9Z3XSW7LRlqLy/aIEsPgCj0hMSjiRyGpeaL J38ljBeK3+BPMT88k/OQYUlbIKkBfIHpjB5r9Gpm6J6RcGZx27DqZCKdkFo75V37 ECl2EzGOJUprIynjszJlfaFzhTckupxPxUxZamL/Uazjby8yWQ07MvHse0Oq1ejL 0eK5IjpbkNOk16YoR1MGNEm4XSrc8E8u9CkHcnrTl0nzkJNWo+p4IgfUuSIsYLxZ bZm0czMNo+R4+Bo8yULiOSXDOjEKlKGW+SFxNKrtjRxzvOAG6VRPlBVO6Jemj3fI z+19eFPdze6nvHVmwNO3kYMh2bRgVgCG+jQ4B4bVAFy+bd5scWmu/1kAxsEDy9lL ahZCfkFuBBSK4EoeuEZDyOYtmlSwIkzm0wqdQuhZ+URuPbwfv8MRkHjaThDdrdrU bO8J3j2AJYikYPYtN+Ts4GiP+r88qhjdh0FsuGQzOKaTSgNAySfv5zaRKo50YKoK ie+6xniRJNWW81Qd5MwBLy/UZc7dzbtm3nu766ARTjJOkZfcOvD/vhb8UlZjBRNF VyOljZA7PU2cmJ9akDi3spEckNJcWKWThQzJJ4TXHu8dMQEwT7SmZTBua8AjNYPV whEVVbbDKTK1nZMsc/IQYcqauYCijO0gkQ2KC2RL9KR0CrTj87OCqrZTwDMmND5A bqLEZR0rdjMhvZKo17gOOSpaFnPLcbNmyv+oMq/MxY6zlT43LVDveH/p/cKYkSxf PT5pl0Jiqd46ZA86X0DIV8yPc44QMhB4dA24M148jKrEQxXQ7Zw2ZLR6cqo8u56R weEY3+2H6kXWVjT8Bz0X2ZB39V/3k3ZiDQ2VUsaJvcveoOBv0k+sZdPaQW+mN52R ZTQME5Q73mI3IUOukTlJg3G71IzEQLmdLaOuCPoqVHdmBzl3RKfUvmQ59Qe41bum nGjWh2Rxl3MPkGYQ2b1mpgbjhGIHb4pkFXwHL0yeh1wC5hIYEc0WwbW3OuUdX0aM qb2EHUWsA7CdQVWhQ0/aZYTsAALYOza01XhxDgrtMWWDPe52yzscpIBLpDJp/cm2 IxrPtQT1xlymrCw8ipEAxtC1QKtNe/9HAlnFFogExM/9/NgIqWf6cHZk6SQuYNkG ldw= -----END ENCRYPTED PRIVATE KEY----- jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/private/cakey.pem.passwd000066400000000000000000000000061313661621600255550ustar00rootroot00000000000000cakey jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/serial000066400000000000000000000000211313661621600222030ustar00rootroot00000000000000F0C327D45A74C5EF jruby-openssl-0.9.21/src/test/ruby/x509/demoCA/serial.old000066400000000000000000000000211313661621600227600ustar00rootroot00000000000000F0C327D45A74C5EE jruby-openssl-0.9.21/src/test/ruby/x509/digicert.pem000066400000000000000000000032741313661621600221630ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/ LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy /Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k 8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2 MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg 4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa 2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs 1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1 oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn 8TUoE6smftX3eg== -----END CERTIFICATE----- jruby-openssl-0.9.21/src/test/ruby/x509/gibberish.pem000066400000000000000000000000411313661621600223140ustar00rootroot00000000000000something but not any pem sectionjruby-openssl-0.9.21/src/test/ruby/x509/javastore.ts000066400000000000000000000016721313661621600222340ustar00rootroot00000000000000þíþídemocaX.ïXéX.509{0‚w0‚_  ðÃ'ÔZtÅí0  *†H†÷  0R1 0 UAU10U Some-State10U Demo Cert Authority10U demo.ca0 161104101953Z 191104101953Z0R1 0 UAU10U Some-State10U Demo Cert Authority10U demo.ca0‚"0  *†H†÷ ‚0‚ ‚ÌFÒ€$©çÍv½ªæSºJ–”cÕÆo…Î}-A&ÒÝÚÕ5ì€Ý”ì·äK¶â-ôrÀ Å¿óº¹_ü¢¾À÷¾9;“R2…æ)ÇŸ;ŠÁíwãÀö˜Á ˜…¸ µWºuéoò‡­ß62 ’[³…ŠñÕÚæ;R´e;ÀÔù!žöù"ç=Þ{Ù¼X&;ÿFÃ/C™¤[xž†mÃ[c‚v!TP¨oÙ/r–dæ ¼[žd©ñàTÖAùVÄçZ8Ú‘ý©™¸Pœ{âb«"Kÿü«”;º˜k– k8]aQ€oj2¨ˆ‘ ¨”‹»QA‚ùéy" 7£P0N0Uº^é;[öy¢Óe Å9jçCkø=0U#0€º^é;[öy¢Óe Å9jçCkø=0 U0ÿ0  *†H†÷  ‚`+§Ig ³4€O³ž¥waE;om’Å¡Â:ǵ¥|Œ½vÉûÛŸû‰ß<ø‡uE/Cj¶ÖlCÝ´´Äº&™_ü,ί£– Fê*yõ˜h( 1Â*Ó‚3 N߯÷Ùe×™VÎÇÅK¨äSJâ‡þv“WIÒ DΦ{:im^~†%ê¿G0ˆ¾¢·ÇÝNAö?I­šXÑr!‰âÂXK°”›ÂÜ&vHý,.L$È)$<ü:Îz[’áԢС’ËÔ/Þ96 ®ú˜EÄÚÏ"ÑNé3Ž¥0÷®ò‘í~øª¾K0…õ1oÁ¥ô‘a,S¾Awy¢Æ´¨àJAÈ"|úÉjruby-openssl-0.9.21/src/test/ruby/x509/newcert.pem000066400000000000000000000107061313661621600220360ustar00rootroot00000000000000Certificate: Data: Version: 3 (0x2) Serial Number: 17348753982565434862 (0xf0c327d45a74c5ee) Signature Algorithm: sha256WithRSAEncryption Issuer: C=AU, ST=Some-State, O=Demo Cert Authority, CN=demo.ca Validity Not Before: Nov 4 10:32:19 2016 GMT Not After : Nov 4 10:32:19 2017 GMT Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=example.com/emailAddress=hi@example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:d9:cd:60:d5:31:26:2d:c8:b2:d1:01:b4:fc:25: fc:ba:02:e0:8d:3d:36:f6:1b:dd:7c:b6:87:65:4c: b0:f5:a6:90:d6:86:1d:c9:7b:6f:67:96:0a:bb:cc: 62:9f:d8:c6:f9:2f:ea:32:07:37:2d:5c:39:ce:81: b6:af:ab:55:40:ff:2e:03:8d:e6:01:a8:e0:8c:c4: f0:dc:81:7f:63:0a:c2:fb:58:c4:fe:98:de:e8:c7: 86:fb:5c:d9:f4:1b:8e:bf:bd:86:21:99:99:b2:ec: 35:82:31:30:c0:09:f0:8a:eb:12:e7:1f:f0:fc:5b: 8b:31:a9:ac:aa:07:23:dc:71:15:d3:59:5f:c9:68: 4c:5e:3a:9a:61:9f:51:db:87:e6:60:4f:e2:79:bf: bf:75:be:41:63:81:2a:d3:94:7b:db:38:6e:ce:06: 40:25:df:46:bf:b1:9d:9f:d2:4f:2a:27:fc:82:4c: 71:ff:5a:b2:db:77:2a:a7:d7:5e:54:e5:bf:ff:37: fa:85:8b:39:fb:9d:74:a0:98:6a:73:f2:e9:af:c9: 1a:73:41:5c:46:c5:56:5e:89:24:7e:d6:9a:2a:d6: 3c:fe:ba:09:7d:e1:2f:b8:70:62:c1:35:1e:bf:1a: f0:e4:5e:d8:1d:e6:76:05:ce:4b:51:89:7d:2c:9e: 06:69 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: DA:44:51:9F:2F:1F:50:18:A9:22:D3:6E:B3:5E:94:FD:E2:55:2E:46 X509v3 Authority Key Identifier: keyid:BA:5E:E9:90:3B:5B:F6:79:A2:D3:65:09:C5:39:6A:E7:43:6B:F8:3D Signature Algorithm: sha256WithRSAEncryption ba:8b:d6:6a:de:d1:94:98:f7:e9:4b:85:b3:85:50:41:83:cc: c8:de:2d:da:41:62:35:0b:fc:5c:dd:bf:f6:e1:22:b7:29:43: 3f:f9:14:a2:15:36:6b:c7:21:38:fb:bd:01:ac:d1:82:57:7f: 10:0f:c7:ef:c6:45:7d:e6:9c:c9:bd:e8:12:a5:41:fb:07:26: c2:38:5c:6f:82:c3:e2:47:a2:ec:f8:36:c5:70:26:81:f9:a5: 6a:8f:f0:08:08:b2:a0:b1:03:38:d6:fd:00:af:99:f7:d6:7c: 9b:65:68:2b:23:de:41:1d:95:07:b8:54:51:f2:fc:1a:58:74: bb:a2:c5:ef:38:1f:97:a3:93:57:5e:d9:00:eb:74:22:08:7d: 05:a8:5e:5e:dd:6e:83:51:0b:8e:b0:42:b0:92:ed:cb:47:83: 2e:2b:c2:2c:17:d7:ab:73:bb:51:e5:a5:d7:00:69:4c:fe:ad: 64:8b:13:b7:06:e4:e9:79:1f:2c:6e:29:96:86:7c:ee:24:ca: bb:71:09:77:b4:d6:dd:59:99:8a:9e:23:cb:42:08:aa:7c:6e: 63:4b:f9:e9:95:85:58:8e:40:63:e9:d6:ae:e5:1d:51:92:74: 5a:24:e6:80:0c:2b:4b:e2:dd:b8:c7:08:bb:ee:34:1c:88:f3: 99:15:3a:03 -----BEGIN CERTIFICATE----- MIIDyjCCArKgAwIBAgIJAPDDJ9RadMXuMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMRwwGgYDVQQKDBNEZW1vIENlcnQg QXV0aG9yaXR5MRAwDgYDVQQDDAdkZW1vLmNhMB4XDTE2MTEwNDEwMzIxOVoXDTE3 MTEwNDEwMzIxOVowejELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLZXhh bXBsZS5jb20xHTAbBgkqhkiG9w0BCQEWDmhpQGV4YW1wbGUuY29tMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2c1g1TEmLciy0QG0/CX8ugLgjT029hvd fLaHZUyw9aaQ1oYdyXtvZ5YKu8xin9jG+S/qMgc3LVw5zoG2r6tVQP8uA43mAajg jMTw3IF/YwrC+1jE/pje6MeG+1zZ9BuOv72GIZmZsuw1gjEwwAnwiusS5x/w/FuL Mamsqgcj3HEV01lfyWhMXjqaYZ9R24fmYE/ieb+/db5BY4Eq05R72zhuzgZAJd9G v7Gdn9JPKif8gkxx/1qy23cqp9deVOW//zf6hYs5+510oJhqc/Lpr8kac0FcRsVW XokkftaaKtY8/roJfeEvuHBiwTUevxrw5F7YHeZ2Bc5LUYl9LJ4GaQIDAQABo3sw eTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBD ZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU2kRRny8fUBipItNus16U/eJVLkYwHwYDVR0j BBgwFoAUul7pkDtb9nmi02UJxTlq50Nr+D0wDQYJKoZIhvcNAQELBQADggEBALqL 1mre0ZSY9+lLhbOFUEGDzMjeLdpBYjUL/Fzdv/bhIrcpQz/5FKIVNmvHITj7vQGs 0YJXfxAPx+/GRX3mnMm96BKlQfsHJsI4XG+Cw+JHouz4NsVwJoH5pWqP8AgIsqCx AzjW/QCvmffWfJtlaCsj3kEdlQe4VFHy/BpYdLuixe84H5ejk1de2QDrdCIIfQWo Xl7dboNRC46wQrCS7ctHgy4rwiwX16tzu1HlpdcAaUz+rWSLE7cG5Ol5HyxuKZaG fO4kyrtxCXe01t1ZmYqeI8tCCKp8bmNL+emVhViOQGPp1q7lHVGSdFok5oAMK0vi 3bjHCLvuNByI85kVOgM= -----END CERTIFICATE----- jruby-openssl-0.9.21/src/test/ruby/x509/newkey.pem000066400000000000000000000034521313661621600216710ustar00rootroot00000000000000-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIHvU9fiprZqgCAggA MBQGCCqGSIb3DQMHBAgpGCqCz0DaDQSCBMjgmYU0osf3j8m6em+NXxEa3Oe6KSgX rCrOleLnMX9AT+Uk8QIJJKEc4Zb05HMQsb+CZRMjafulVm3Y2UxpRYDiRwvE5Lyj eDx8db54KIsQ17BmkLaOv0+BwPGnXeQ1x5soRLNBtuinI7cAbnTYXwKwVHRLX8W0 RXQvcc376skU5HzsVL5U8Y2Hs2Rk5Gj+PvuxmvDtwH1laS0lKvIIJ+L6KAr0sQyK c5wo9qJrun6aZcwIAJinotmBmEwQb4YTdl6NM1lJeYmivl3WlqcUG88KyznIzvQ4 Fa0GxYcbWRVjRTeHvowJU2SpNDZMd+5oHVW/qcUVroJFvTmc1tQ2Tb5oRVaZc2eu vdvLSsapUYsB/9wz+kPsVKxKduJfHIKtk6+EDRI84kuNweyJNWsEecUDMKIgWN7n v4vOXOcRqxu6Ymqx8+cF9o/GoyzRGaCMLjiYVm7ACqxF3yZ0HCF0bE6omHMZ/rqI eEIZmLBN/3xMfN+cnCewdw1WhdHMijsc24rVoht5nylp7SeDzmjiWFK5xEIDvdnD MkBjf4QgJjS9m77k//uZIWLR37jbMCtwMpM1G5KLwxBgQxDW3d7tsLTGrhFv5xTQ ct/XVGo5LqXcli5PEF7l8I3bRSDic13PagLsciTqkU8pswB1kUwylU9YLJCHGnJC chSfsLqffK8YqiF9aFqNZIlIoA5+JggavxXudQgcItdsRW1THMK1D3MzcWrxpDjA zq6I3YyYV7crFw3Q+uX9eiKepZNV/qOziyWXvMYTmHxYrZ+r3/p7q6hyzA5qWpBF zdiDhAa1LeJGy8XboFSngakAe+PN3i8XOrpKbrqOVeyLGCRZwmp7kvD0/PInRo4y zsGtj2Y359+Ez6N2P68/Vw/+XSDIdZnn/GD5M1Snzks8h8gCSckMNbnusjiZcyRp 8SOQoeJEVKITej43dF6H0Kn3ze7btSB4kTV64VMOE4reYufUZ0b2BwhtfZoYPOxv enXPhsuMgbkWeoeP/Cnn5GLFHQ93rVYyuIAiGpjefbC7TQVACpGFYi3fVt7qh0AU 7FETSTO5DPAeUjz0/9/vmmFHQH+n9FmUQV+aRx5Ll74OjWHDNOOVVykeOHDEDHQK 9EJv7JgtDKg8gTH/K0CgZfjFSfkRFWrhF0F6C54ZvEIVezKfaR8B7u3Ggq77U33D IuaZzju8ow6w4W5vpYGs4tSb7PF5W8wbZuxPebgW90vetom7lPlIxBxGHU5L+Yq5 E6w/8ADb3wkkb+ylnBwHZfJodwxnbaszCxGMSzWVlpdvaw5iDvR8dsi1lFDbg9m0 ox7KQaRSMZzbKJOpHZM+shYxZW/yf6vXqq2Wel/yutlOPfBU/E1KuMaprhrVlA9A gNuw2hzqpZj5+jb5HKwBjnEPJ4P9WDCG4sYKYNOnyMSn2+3BWI5ibq9H616jwauP zilDPK0amsj/MkuO5L6zY3v4BKTM4oFi+Su92l6pFxrp5bZ9pSV2Af0/skHfa2qs z7qJsekv4/WJP1KHCDK44jsmxITpkcZhi92SWOPtmkaBd6yDn+BK6X0y1jISkuH2 +yoZEqYkuCa3Mbj2S8woKQEdTsBNUTIKthXOiMnB4xBLaW+Nq02nMGCE/0Oi8ILV LdA= -----END ENCRYPTED PRIVATE KEY----- jruby-openssl-0.9.21/src/test/ruby/x509/newreq.pem000066400000000000000000000020051313661621600216610ustar00rootroot00000000000000-----BEGIN CERTIFICATE REQUEST----- MIICvzCCAacCAQAwejELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx ITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLZXhh bXBsZS5jb20xHTAbBgkqhkiG9w0BCQEWDmhpQGV4YW1wbGUuY29tMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2c1g1TEmLciy0QG0/CX8ugLgjT029hvd fLaHZUyw9aaQ1oYdyXtvZ5YKu8xin9jG+S/qMgc3LVw5zoG2r6tVQP8uA43mAajg jMTw3IF/YwrC+1jE/pje6MeG+1zZ9BuOv72GIZmZsuw1gjEwwAnwiusS5x/w/FuL Mamsqgcj3HEV01lfyWhMXjqaYZ9R24fmYE/ieb+/db5BY4Eq05R72zhuzgZAJd9G v7Gdn9JPKif8gkxx/1qy23cqp9deVOW//zf6hYs5+510oJhqc/Lpr8kac0FcRsVW XokkftaaKtY8/roJfeEvuHBiwTUevxrw5F7YHeZ2Bc5LUYl9LJ4GaQIDAQABoAAw DQYJKoZIhvcNAQELBQADggEBAEhApGp3IEs+Zlgrum2T23sTtSbEv4lhbtc7TJeP Hg49KJBqaBrNkB8onZH/2c3YakFHN49aR3O3q0qV4/1NtLITMG7fq3Cuollf4BJ+ 0PkaOgmscu2ZMIRBahWbNMDRQvLJpI1dmMsaViZsBgPRA0/I1FyYXE+gWDljdCQe ZAlzhEl1+sFNoMHWI3VtCOT8ZHgzg2bEQbONjYgz5dsYaSspBvlkzaUMzgf0xNlc pcBWR3hYLLcn7VvwPdFP3sKqUBi/jGec84C+mJuQbsMj16yc7ez7+f+D1svLW2vI avPpP4ew4s4TYmGMgBD2Qh1NtVXcK+fXVjSZif3zjKXiq1c= -----END CERTIFICATE REQUEST----- jruby-openssl-0.9.21/src/test/ruby/x509/revoked.crl000066400000000000000000000013561313661621600220260ustar00rootroot00000000000000-----BEGIN X509 CRL----- MIICATCCAasCAQEwDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCVVMxEDAOBgNV BAgMB0Zsb3JpZGExDjAMBgNVBAcMBU1pYW1pMRwwGgYDVQQKDBNyNTA5LWNlcnQt dmFsaWRhdG9yMRIwEAYDVQQDDAlsb2NhbGhvc3QXDTE0MDcwNzE3MzEzNVoXDTI0 MDcwNDE4MzEzNVowgeQwJAITBj4XOQip5iM9jsjNahP+ln2bNhcNMTQwMjExMTU0 MjMyWjAkAhMGPhffXa7qnjiOsKG+T59MXoICFw0xNDAyMTExNjE5MjNaMCQCEwY+ G/iZDaYOYqQNkUhWz2VDQQYXDTE0MDIxMTIwMTE0OVowJAITBj4b+xUAmYEJh7F0 Ek7YjFlzhhcNMTQwMjExMjAxMjIyWjAkAhMGPhv+d3hbmVhej514YzyCQvIOFw0x NDAyMTEyMDEzMDdaMCQCEwZMlT4VU+7hoQBdGcEGWKf/tEYXDTE0MDcwNzE4MzEz NVqgLzAtMAoGA1UdFAQDAgEGMB8GA1UdIwQYMBaAFJg2dyTKjan/rPrS2dVd1VDm 92pRMA0GCSqGSIb3DQEBBQUAA0EASi1yCsP5ZphMI7XsTE65XwB9ABNcP36UHtdV m9iz/ZQpSeFoTlokJyy6c4+fVVIiDDUbOOAdN0RWmgEqkhLCYA== -----END X509 CRL-----jruby-openssl-0.9.21/src/test/ruby/x509/test_x509cert.rb000066400000000000000000000421031313661621600226270ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('../test_helper', File.dirname(__FILE__)) class TestX509Certificate < TestCase def test_new cert = OpenSSL::X509::Certificate.new empty_name = OpenSSL::X509::Name.new assert_equal empty_name, cert.issuer assert_equal empty_name, cert.subject bn = OpenSSL::BN.new('0') unless defined? JRUBY_VERSION assert_equal bn || OpenSSL::BN.new(0), cert.serial assert_equal nil, cert.not_before assert_equal nil, cert.not_after assert_raise(OpenSSL::X509::CertificateError) { cert.public_key } end def test_alt_name_extension cert = OpenSSL::X509::Certificate.new cert.add_extension OpenSSL::X509::Extension.new('subjectAltName', 'email:self@jruby.org, IP:127.0.0.1', false) assert_equal 'email:self@jruby.org, IP:127.0.0.1', cert.extensions[0].value end def test_cert_extensions # JRUBY-3468 pem_cert = <= '2.0.0' || defined? JRUBY_VERSION assert crl.inspect.index('#= '2.0.0' || defined? JRUBY_VERSION assert ext.inspect.index('# '1.1.1.1.1.1', 'value' => 'foo', 'critical' => true } assert_equal hash, ext.to_h end def test_to_der # reproducing #389 ext = OpenSSL::X509::Extension.new('1.1.1.1.1.1', 'foo') mri_to_der = "0\f\x06\x05)\x01\x01\x01\x01\x04\x03foo" assert_equal mri_to_der, ext.to_der # MRI 1.8 "0\f\006\005)\001\001\001\001\004\003foo" # MRI 2.x "0\f\x06\x05)\x01\x01\x01\x01\x04\x03foo" dec = OpenSSL::ASN1.decode(ext.to_der) assert_instance_of OpenSSL::ASN1::Sequence, dec assert_equal 2, ( value = dec.value ).size assert_instance_of OpenSSL::ASN1::ObjectId, value[0] # assert_equal 4, value[0].tag assert_equal '1.1.1.1.1.1', value[0].value assert_instance_of OpenSSL::ASN1::OctetString, value[1] # assert_equal 6, value[1].tag assert_equal 'foo', value[1].value end def test_to_der_is_the_same_for_non_critical ext1 = OpenSSL::X509::Extension.new('1.1.1.1.1.1', 'foo') ext2 = OpenSSL::X509::Extension.new('1.1.1.1.1.1', 'foo', false) assert_equal ext1.to_der, ext2.to_der ext1.critical = nil assert_equal ext1.to_der, ext2.to_der ext1.critical = false assert_equal ext1.to_der, ext2.to_der ext1.critical = true assert ext1.to_der != ext2.to_der end def test_subject_alt_name_sign_to_pem domain_list = 'test.example.com,test2.example.com,example.com,www.example.com' rsa_key = OpenSSL::PKey::RSA.new(2048) csr = OpenSSL::X509::Request.new csr.subject = OpenSSL::X509::Name.new [ ["C", 'AU'], ["ST", "NSW"], ["O", 'org'], ["CN", 'www.example.com'] ] csr.public_key = rsa_key.public_key extensions = OpenSSL::ASN1::Set [ OpenSSL::ASN1::Sequence([ subject_alt_name(domain_list) ]) ] csr.add_attribute(OpenSSL::X509::Attribute.new('extReq', extensions)) csr.add_attribute(OpenSSL::X509::Attribute.new('msExtReq', extensions)) csr.sign rsa_key, OpenSSL::Digest::SHA256.new puts csr.to_text if $VERBOSE csr = OpenSSL::X509::Request.new pem = csr.to_pem assert_equal 2, csr.attributes.length ext_set = csr.attributes.first.value ; seq = ext_set.first.value assert_equal 'subjectAltName', seq.first.value.first.value dns = seq.first.value.last.value assert dns =~ /test.example.com.*?test2.example.com.*?example.com.*?www.example.com/ end def test_subject_alt_name_sequence extensions = OpenSSL::X509::ExtensionFactory.new ext = extensions.create_extension("subjectAltName", "email:foo@bar.com,DNS:a.b.com,email:baz@bar.com") assert_equal 'subjectAltName', ext.oid assert_equal 'email:foo@bar.com, DNS:a.b.com, email:baz@bar.com', ext.value mri_der = "0,\x06\x03U\x1D\x11\x04%0#\x81\vfoo@bar.com\x82\aa.b.com\x81\vbaz@bar.com" assert_equal mri_der, ext.to_der end def subject_alt_name(domains) ef = OpenSSL::X509::ExtensionFactory.new ef.create_extension("subjectAltName", domains.split(',').map { |d| "DNS: #{d}" }.join(',')) end private :subject_alt_name endjruby-openssl-0.9.21/src/test/ruby/x509/test_x509name.rb000066400000000000000000000035371313661621600226220ustar00rootroot00000000000000require File.expand_path('../test_helper', File.dirname(__FILE__)) class TestX509Name < TestCase def test_to_a_to_s dn = [ ["DC", "org"], ["DC", "jruby", 22], ["CN", "Karol Bucek"], ["UID", "kares"], ["emailAddress", "jruby@kares-x.org"], ["serialNumber", "1234567890"], ["street", "Edelenyska"], ['2.5.4.44', 'X'], ['2.5.4.65', 'BUBS'], ['postalCode', '04801', 22], ['postalAddress', 'Edelenyska 1, Roznava'], ] name = OpenSSL::X509::Name.new dn.each { |attr| name.add_entry(*attr) } ary = name.to_a exp_to_a = [ ["DC", "org", 22], ["DC", "jruby", 22], ["CN", "Karol Bucek", 12], ["UID", "kares", 12], ["emailAddress", "jruby@kares-x.org", 22], ["serialNumber", "1234567890", 19], ["street", "Edelenyska", 12], ['generationQualifier', 'X', 12], ['pseudonym', 'BUBS', 12], ['postalCode', '04801', 22], ['postalAddress', 'Edelenyska 1, Roznava', 12], ] assert_equal exp_to_a.size, ary.size exp_to_a.each_with_index do |el, i| assert_equal el, ary[i] end str = exp_to_a.map { |arr| "#{arr[0]}=#{arr[1]}" }.join('/') assert_equal "/#{str}", name.to_s end def test_raise_on_invalid_field_name name = OpenSSL::X509::Name.new name.add_entry 'invalidName', '' fail "expected to raise: #{name}" rescue OpenSSL::X509::NameError => e # # assert e.message.start_with? 'invalid field name' end def test_new_from_der der = "0A1\x130\x11\x06\n\t\x92&\x89\x93\xF2,d\x01\x19\x16\x03org1\x190\x17\x06\n\t\x92&\x89\x93\xF2,d\x01\x19\x16\truby-lang1\x0F0\r\x06\x03U\x04\x03\f\x06TestCA" name = OpenSSL::X509::Name.new der assert_equal [["DC", "org", 22], ["DC", "ruby-lang", 22], ["CN", "TestCA", 12]], name.to_a end endjruby-openssl-0.9.21/src/test/ruby/x509/test_x509req.rb000066400000000000000000000022471313661621600224660ustar00rootroot00000000000000require File.expand_path('../test_helper', File.dirname(__FILE__)) class TestX509Request < TestCase def test_csr_request_extensions key = OpenSSL::PKey::RSA.new(512) csr = OpenSSL::X509::Request.new csr.version = 0 csr.subject = OpenSSL::X509::Name.new [ ["CN", 'example.com'] ] csr.public_key = key.public_key names = OpenSSL::X509::ExtensionFactory.new. create_extension("subjectAltName", 'DNS:example.com', false) ext_req = OpenSSL::ASN1::Set [ OpenSSL::ASN1::Sequence([names]) ] csr.add_attribute OpenSSL::X509::Attribute.new("extReq", ext_req) csr.sign(key, OpenSSL::Digest::SHA256.new) # The combination of the extreq and the stringification / revivification # is what triggers the bad behaviour in the extension. (Any extended # request type should do, but this matches my observed problems) csr = OpenSSL::X509::Request.new(csr.to_s) assert_equal '/CN=example.com', csr.subject.to_s assert_equal 0, csr.version end def test_version csr = OpenSSL::X509::Request.new assert_equal 0, csr.version req = OpenSSL::X509::Request.new req.version = 1 assert_equal 1, req.version end endjruby-openssl-0.9.21/src/test/ruby/x509/test_x509revoked.rb000066400000000000000000000012321313661621600233270ustar00rootroot00000000000000# coding: US-ASCII require File.expand_path('../test_helper', File.dirname(__FILE__)) class TestX509Revoked < TestCase def setup; require 'openssl' end def test_new rev = OpenSSL::X509::Revoked.new assert_equal 0, rev.serial assert_equal nil, rev.time assert_equal [], rev.extensions if RUBY_VERSION >= '2.0.0' || defined? JRUBY_VERSION assert rev.inspect.index('# e assert_equal 'cert already in hash table', e.message end end def test_adding_pem_to_store debug = false #OpenSSL.debug = true # mimic what rubygems/request#add_rubygems_trusted_certs does to find the .pem certificates # 1.7: jruby-complete-1.7.22.jar!/META-INF/jruby.home/lib/ruby/shared # 9.0: /opt/local/rvm/rubies/jruby-9.0.4.0/lib/ruby/stdlib base = $LOAD_PATH.detect { |p| p =~ /ruby\/shared/ || p =~ /ruby\/stdlib/ } raise "rubygems home not detected in $LOAD_PATH" unless base pems = Dir[ File.join(base, 'rubygems/ssl_certs/*pem') ] # assert_equal( 9, pems.size ) # >= 11 on 9K pems.each do |pem| puts pem.inspect if debug store = OpenSSL::X509::Store.new cert = OpenSSL::X509::Certificate.new(File.read(pem)) assert ! store.verify(cert) store.add_file(pem) # only verify on self signed certifactes assert store.verify(cert) if pem !~ /COMODORSA|AddTrustExternalCARoot/ end end def test_verify @rsa1024 = OpenSSL::PKey::RSA.new SSLTestHelper::TEST_KEY_RSA1024 # OpenSSL::TestUtils::TEST_KEY_RSA1024 @rsa2048 = OpenSSL::PKey::RSA.new SSLTestHelper::TEST_KEY_RSA2048 # OpenSSL::TestUtils::TEST_KEY_RSA2048 @dsa256 = OpenSSL::PKey::DSA.new SSLTestHelper::TEST_KEY_DSA256 # OpenSSL::TestUtils::TEST_KEY_DSA256 @dsa512 = OpenSSL::PKey::DSA.new SSLTestHelper::TEST_KEY_DSA512 # OpenSSL::TestUtils::TEST_KEY_DSA512 @ca1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA1") @ca2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=CA2") @ee1 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE1") @ee2 = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=EE2") now = Time.at(Time.now.to_i) ca_exts = [ ["basicConstraints","CA:TRUE",true], ["keyUsage","cRLSign,keyCertSign",true], ] ee_exts = [ ["keyUsage","keyEncipherment,digitalSignature",true], ] ca1_cert = issue_cert(@ca1, @rsa2048, 1, now, now+3600, ca_exts, nil, nil, OpenSSL::Digest::SHA1.new) ca2_cert = issue_cert(@ca2, @rsa1024, 2, now, now+1800, ca_exts, ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new) ee1_cert = issue_cert(@ee1, @dsa256, 10, now, now+1800, ee_exts, ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new) ee2_cert = issue_cert(@ee2, @dsa512, 20, now, now+1800, ee_exts, ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new) ee3_cert = issue_cert(@ee2, @dsa512, 30, now-100, now-1, ee_exts, ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new) ee4_cert = issue_cert(@ee2, @dsa512, 40, now+1000, now+2000, ee_exts, ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new) revoke_info = [] crl1 = issue_crl(revoke_info, 1, now, now+1800, [], ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new) revoke_info = [ [2, now, 1], ] crl1_2 = issue_crl(revoke_info, 2, now, now+1800, [], ca1_cert, @rsa2048, OpenSSL::Digest::SHA1.new) revoke_info = [ [20, now, 1], ] crl2 = issue_crl(revoke_info, 1, now, now+1800, [], ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new) revoke_info = [] crl2_2 = issue_crl(revoke_info, 2, now-100, now-1, [], ca2_cert, @rsa1024, OpenSSL::Digest::SHA1.new) assert_equal(true, ca1_cert.verify(ca1_cert.public_key)) # self signed assert_equal(true, ca2_cert.verify(ca1_cert.public_key)) # issued by ca1 assert_equal(true, ee1_cert.verify(ca2_cert.public_key)) # issued by ca2 assert_equal(true, ee2_cert.verify(ca2_cert.public_key)) # issued by ca2 assert_equal(true, ee3_cert.verify(ca2_cert.public_key)) # issued by ca2 assert_equal(true, crl1.verify(ca1_cert.public_key)) # issued by ca1 assert_equal(true, crl1_2.verify(ca1_cert.public_key)) # issued by ca1 assert_equal(true, crl2.verify(ca2_cert.public_key)) # issued by ca2 assert_equal(true, crl2_2.verify(ca2_cert.public_key)) # issued by ca2 store = OpenSSL::X509::Store.new assert_equal(false, store.verify(ca1_cert)) assert_not_equal(OpenSSL::X509::V_OK, store.error) assert_equal(false, store.verify(ca2_cert)) assert_not_equal(OpenSSL::X509::V_OK, store.error) store.add_cert(ca1_cert) assert_equal(true, store.verify(ca2_cert)) assert_equal(OpenSSL::X509::V_OK, store.error) assert_equal("ok", store.error_string) chain = store.chain assert_equal(2, chain.size) assert_equal(@ca2.to_der, chain[0].subject.to_der) assert_equal(@ca1.to_der, chain[1].subject.to_der) store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT assert_equal(false, store.verify(ca2_cert)) assert_not_equal(OpenSSL::X509::V_OK, store.error) store.purpose = OpenSSL::X509::PURPOSE_CRL_SIGN assert_equal(true, store.verify(ca2_cert)) assert_equal(OpenSSL::X509::V_OK, store.error) store.add_cert(ca2_cert) store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT assert_equal(true, store.verify(ee1_cert)) assert_equal(true, store.verify(ee2_cert)) assert_equal(OpenSSL::X509::V_OK, store.error) assert_equal("ok", store.error_string) chain = store.chain assert_equal(3, chain.size) assert_equal(@ee2.to_der, chain[0].subject.to_der) assert_equal(@ca2.to_der, chain[1].subject.to_der) assert_equal(@ca1.to_der, chain[2].subject.to_der) assert_equal(false, store.verify(ee3_cert)) assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error) assert_match(/expire/i, store.error_string) assert_equal(false, store.verify(ee4_cert)) assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error) assert_match(/not yet valid/i, store.error_string) store = OpenSSL::X509::Store.new store.add_cert(ca1_cert) store.add_cert(ca2_cert) store.time = now + 1500 assert_equal(true, store.verify(ca1_cert)) assert_equal(true, store.verify(ca2_cert)) assert_equal(true, store.verify(ee4_cert)) store.time = now + 1900 assert_equal(true, store.verify(ca1_cert)) assert_equal(false, store.verify(ca2_cert)) assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error) assert_equal(false, store.verify(ee4_cert)) assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error) store.time = now + 4000 assert_equal(false, store.verify(ee1_cert)) assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error) assert_equal(false, store.verify(ee4_cert)) assert_equal(OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED, store.error) # the underlying X509 struct caches the result of the last # verification for signature and not-before. so the following code # rebuilds new objects to avoid site effect. store.time = Time.now - 4000 assert_equal(false, store.verify(OpenSSL::X509::Certificate.new(ca2_cert))) assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error) assert_equal(false, store.verify(OpenSSL::X509::Certificate.new(ee1_cert))) assert_equal(OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID, store.error) return unless defined?(OpenSSL::X509::V_FLAG_CRL_CHECK) store = OpenSSL::X509::Store.new store.purpose = OpenSSL::X509::PURPOSE_ANY store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK store.add_cert(ca1_cert) store.add_crl(crl1) # revoke no cert store.add_crl(crl2) # revoke ee2_cert assert_equal(true, store.verify(ca1_cert)) assert_equal(true, store.verify(ca2_cert)) assert_equal(true, store.verify(ee1_cert, [ca2_cert])) assert_equal(false, store.verify(ee2_cert, [ca2_cert])) store = OpenSSL::X509::Store.new store.purpose = OpenSSL::X509::PURPOSE_ANY store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK store.add_cert(ca1_cert) store.add_crl(crl1_2) # revoke ca2_cert store.add_crl(crl2) # revoke ee2_cert assert_equal(true, store.verify(ca1_cert)) assert_equal(false, store.verify(ca2_cert)) assert_equal(true, store.verify(ee1_cert, [ca2_cert]), "This test is expected to be success with OpenSSL 0.9.7c or later.") assert_equal(false, store.verify(ee2_cert, [ca2_cert])) store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL assert_equal(true, store.verify(ca1_cert)) assert_equal(false, store.verify(ca2_cert)) assert_equal(false, store.verify(ee1_cert, [ca2_cert])) assert_equal(false, store.verify(ee2_cert, [ca2_cert])) store = OpenSSL::X509::Store.new store.purpose = OpenSSL::X509::PURPOSE_ANY store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK|OpenSSL::X509::V_FLAG_CRL_CHECK_ALL store.add_cert(ca1_cert) store.add_cert(ca2_cert) store.add_crl(crl1) store.add_crl(crl2_2) # issued by ca2 but expired. assert_equal(true, store.verify(ca1_cert)) assert_equal(true, store.verify(ca2_cert)) assert_equal(false, store.verify(ee1_cert)) assert_equal(OpenSSL::X509::V_ERR_CRL_HAS_EXPIRED, store.error) assert_equal(false, store.verify(ee2_cert)) end end