diff options
Diffstat (limited to 'ext/openssl')
74 files changed, 17052 insertions, 8153 deletions
diff --git a/ext/openssl/History.md b/ext/openssl/History.md index db5050014e..419237ff16 100644 --- a/ext/openssl/History.md +++ b/ext/openssl/History.md @@ -1,3 +1,629 @@ +Version 4.0.0 +============= + +Compatibility +------------- + +* Ruby >= 2.7 +* OpenSSL >= 1.1.1, LibreSSL >= 3.9, and AWS-LC 1.66.0 + - Removed support for OpenSSL 1.0.2-1.1.0 and LibreSSL 3.1-3.8. + [[GitHub #835]](https://github.com/ruby/openssl/issues/835) + - Added support for AWS-LC. + [[GitHub #833]](https://github.com/ruby/openssl/issues/833) + + +Notable changes +--------------- + +* `OpenSSL::SSL` + - Reduce overhead when writing to `OpenSSL::SSL::SSLSocket`. `#syswrite` no + longer creates a temporary String object. + [[GitHub #831]](https://github.com/ruby/openssl/pull/831) + - Make `OpenSSL::SSL::SSLContext#min_version=` and `#max_version=` wrap the + corresponding OpenSSL APIs directly, and remove the fallback to SSL options. + [[GitHub #849]](https://github.com/ruby/openssl/pull/849) + - Add `OpenSSL::SSL::SSLContext#sigalgs=` and `#client_sigalgs=` for + specifying signature algorithms to use for connections. + [[GitHub #895]](https://github.com/ruby/openssl/pull/895) + - Rename `OpenSSL::SSL::SSLContext#ecdh_curves=` to `#groups=` following + the underlying OpenSSL API rename. This method is no longer specific to + ECDHE. The old method remains as an alias. + [[GitHub #900]](https://github.com/ruby/openssl/pull/900) + - Add `OpenSSL::SSL::SSLSocket#sigalg`, `#peer_sigalg`, and `#group` for + getting the signature algorithm and the key agreement group used in the + current connection. + [[GitHub #908]](https://github.com/ruby/openssl/pull/908) + - Enable `SSL_CTX_set_dh_auto()` for servers by default. + [[GitHub #924]](https://github.com/ruby/openssl/pull/924) + - Improve Ractor compatibility. Note that the internal-use constant + `OpenSSL::SSL::SSLContext::DEFAULT_PARAMS` is now frozen. + [[GitHub #925]](https://github.com/ruby/openssl/pull/925) +* `OpenSSL::PKey` + - Remove `OpenSSL::PKey::EC::Point#mul` support with array arguments. The + underlying OpenSSL API has been removed, and the method has been deprecated + since ruby/openssl v3.0.0. + [[GitHub #843]](https://github.com/ruby/openssl/pull/843) + - `OpenSSL::PKey::{RSA,DSA,DH}#params` uses `nil` to indicate missing fields + instead of the number `0`. + [[GitHub #774]](https://github.com/ruby/openssl/pull/774) + - Unify `OpenSSL::PKey::PKeyError` classes. The former subclasses + `OpenSSL::PKey::DHError`, `OpenSSL::PKey::DSAError`, + `OpenSSL::PKey::ECError`, and `OpenSSL::PKey::RSAError` have been merged + into a single class. + [[GitHub #929]](https://github.com/ruby/openssl/pull/929) +* `OpenSSL::Cipher` + - `OpenSSL::Cipher#encrypt` and `#decrypt` no longer accept arguments. + Passing passwords has been deprecated since Ruby 1.8.2 (released in 2004). + [[GitHub #887]](https://github.com/ruby/openssl/pull/887) + - `OpenSSL::Cipher#final` raises `OpenSSL::Cipher::AuthTagError` when the + integrity check fails for AEAD ciphers. `OpenSSL::Cipher::AuthTagError` is a + new subclass of `OpenSSL::Cipher::CipherError`, which was previously raised. + [[GitHub #939]](https://github.com/ruby/openssl/pull/939) + - `OpenSSL::Cipher.new` now raises `OpenSSL::Cipher::CipherError` instead of + `RuntimeError` when OpenSSL does not recognize the algorithm. + [[GitHub #958]](https://github.com/ruby/openssl/pull/958) + - Add support for "fetched" cipher algorithms with OpenSSL 3.0 or later. + [[GitHub #958]](https://github.com/ruby/openssl/pull/958) +* `OpenSSL::Digest` + - `OpenSSL::Digest.new` now raises `OpenSSL::Digest::DigestError` instead of + `RuntimeError` when OpenSSL does not recognize the algorithm. + [[GitHub #958]](https://github.com/ruby/openssl/pull/958) + - Add support for "fetched" digest algorithms with OpenSSL 3.0 or later. + [[GitHub #958]](https://github.com/ruby/openssl/pull/958) +* `OpenSSL::ASN1.decode` now assumes a 1950-2049 year range for `UTCTime` + according to RFC 5280. It previously used a 1969-2068 range. The encoder + has always used the 1950-2049 range. + [[GitHub #909]](https://github.com/ruby/openssl/pull/909) +* `OpenSSL::OpenSSLError`, the base class for all ruby/openssl errors, carry + an additional attribute `#errors` to keep the content of OpenSSL's error + queue. Also, add `#detailed_message` for Ruby 3.2 or later. + [[GitHub #976]](https://github.com/ruby/openssl/pull/976) +* `OpenSSL::PKCS7.new` raises `OpenSSL::PKCS7::PKCS7Error` instead of + `ArgumentError` on error to be consistent with other constructors. + [[GitHub #983]](https://github.com/ruby/openssl/pull/983) + + +Version 3.3.2 +============= + +Merged changes in 3.1.3 and 3.2.3. + + +Version 3.3.1 +============= + +Merged changes in 3.1.2 and 3.2.2. + + +Version 3.3.0 +============= + +Compatibility +------------- + +* Ruby version: 2.7 or later +* OpenSSL version: OpenSSL 1.0.2 or later, and LibreSSL 3.1 or later + +Notable changes +--------------- + +* `OpenSSL::SSL` + - `OpenSSL::SSL::SSLSocket#set_params` no longer sets `#min_version=` to TLS + 1.0 except when OpenSSL 1.0.2 is used. This has been done to disable + SSL 3.0, which is not supported by default in OpenSSL 1.1.0 or later, or in + LibreSSL. This lets it respect the system default if the system-wide + configuration file specifies a higher minimum protocol version. + [[GitHub #710]](https://github.com/ruby/openssl/pull/710) + - `OpenSSL::SSL::SSLSocket.new` no longer enables the `OpenSSL::SSL::OP_ALL` + SSL options by default and follows the system default. + [[GitHub #767]](https://github.com/ruby/openssl/pull/767) + - Add the following IO methods to `OpenSSL::SSL::SSLSocket`, which will pass + along to the underlying socket: `#local_address`, `#remote_address`, + `#close_on_exec=`, `#close_on_exec?`, `#wait`, `#wait_readable`, and + `#wait_writable`. + [[GitHub #708]](https://github.com/ruby/openssl/pull/708) + - Update `OpenSSL::SSL::SSLSocket#gets` to take the `chomp` keyword argument. + [[GitHub #708]](https://github.com/ruby/openssl/pull/708) + - Make `OpenSSL::SSL::SSLSocket` respect the `IO#timeout` value of the + underlying socket on Ruby 3.2 or later. `#timeout` and `#timeout=` methods + are also added. + [[GitHub #714]](https://github.com/ruby/openssl/pull/714) + - Add `OpenSSL::SSL::SSLSocket#close_read` and `#close_write`. + [[GitHub #743]](https://github.com/ruby/openssl/pull/743) + - Add `OpenSSL::Digest.digests` to get a list of all available digest + algorithms. + [[GitHub #726]](https://github.com/ruby/openssl/pull/726) + - Fix `OpenSSL::SSL::SSLSocket#read_nonblock` clearing the passed String + buffer when nothing can be read from the connection. + [[GitHub #739]](https://github.com/ruby/openssl/pull/739) +* Add `#to_text` methods to `OpenSSL::Timestamp::Response`, + `OpenSSL::Timestamp::Request`, `OpenSSL::Timestamp::TokenInfo`, and + `OpenSSL::PKCS7` to get a human-readable representation of the object. + [[GitHub #756]](https://github.com/ruby/openssl/pull/756) +* Add `OpenSSL::X509::Certificate#tbs_bytes` to get the DER encoding of the + TBSCertificate. + [[GitHub #753]](https://github.com/ruby/openssl/pull/753) +* Allow passing `nil` as the digest algorithm to `#sign` methods on + `OpenSSL::X509::Certificate`, `OpenSSL::X509::Request`, and + `OpenSSL::X509::CRL`. This adds supports for signing with EdDSA keys. + [[GitHub #761]](https://github.com/ruby/openssl/pull/761) + [[GitHub #804]](https://github.com/ruby/openssl/pull/804) +* Add `OpenSSL::SSL::SSLSocket#readbyte`. + [[GitHub #771]](https://github.com/ruby/openssl/pull/771) +* Change `OpenSSL::X509::Store#time=` to set the time to the `X509_VERIFY_PARAM` + in the `X509_STORE`. This allows `OpenSSL::Timestamp::Response#verify` to + verify a signature with the specified timestamp. + [[GitHub #770]](https://github.com/ruby/openssl/pull/770) +* Make `OpenSSL::PKCS7.encrypt`'s third parameter `cipher` mandatory. It had + an undocumented default value "RC2-40-CBC", which is not only insecure, but + also not supported in OpenSSL 3.0 or later. + [[GitHub #796]](https://github.com/ruby/openssl/pull/796) +* Make `OpenSSL::BN` shareable between ractors when frozen. + [[GitHub #808]](https://github.com/ruby/openssl/pull/808) +* Make `OpenSSL::Config` instances frozen by default, and make it shareable + between ractors. `OpenSSL::Config::DEFAULT_CONFIG_FILE` is also frozen. + [[GitHub #809]](https://github.com/ruby/openssl/pull/809) +* Add `OpenSSL::PKCS12#set_mac` to configure the MAC parameters and recalculate + a MAC for the content. + [[GitHub #788]](https://github.com/ruby/openssl/pull/788) + +And various non-user-visible changes and bug fixes. Please see the commit +history for more details. + + +Version 3.2.3 +============= + +Merged changes in 3.1.3. + + +Version 3.2.2 +============= + +Merged changes in 3.1.2. + + +Version 3.2.1 +============= + +Merged changes in 3.0.3. + + +Version 3.2.0 +============= + +Compatibility +------------- + +* Ruby >= 2.7 + - Support for Ruby 2.6 has been removed. Note that Ruby 2.6 reached the + end-of-life in 2022-04. + [[GitHub #639]](https://github.com/ruby/openssl/pull/639) +* OpenSSL >= 1.0.2 or LibreSSL >= 3.1 + +Notable changes +--------------- + +* Add a stub gemspec for JRuby, which depends on the `jruby-openssl` gem. + [[GitHub #598]](https://github.com/ruby/openssl/pull/598) +* Add support for the FIPS module in OpenSSL 3.0/3.1. + [[GitHub #608]](https://github.com/ruby/openssl/pull/608) +* Rework `OpenSSL::PKey` routines for loading DER or PEM encoded keys for better + compatibility with OpenSSL 3.0/3.1 with the FIPS module. + [[GitHub #615]](https://github.com/ruby/openssl/pull/615) + [[GitHub #669]](https://github.com/ruby/openssl/pull/669) +* Add `OpenSSL::Provider` module for loading and unloading OpenSSL 3 providers. + [[GitHub #635]](https://github.com/ruby/openssl/pull/635) +* Add `OpenSSL::PKey.new_raw_private_key`, `.new_raw_public_key`, + `OpenSSL::PKey::PKey#raw_private_key`, and `#raw_public_key` for public key + algorithms that use "raw private/public key", such as X25519 and Ed25519. + [[GitHub #646]](https://github.com/ruby/openssl/pull/646) +* Improve OpenSSL error messages to include additional information when + it is available in OpenSSL's error queue. + [[GitHub #648]](https://github.com/ruby/openssl/pull/648) +* Change `OpenSSL::SSL::SSLContext#ca_file=` and `#ca_path=` to raise + `OpenSSL::SSL::SSLError` instead of printing a warning message. + [[GitHub #659]](https://github.com/ruby/openssl/pull/659) +* Allow `OpenSSL::X509::ExtensionFactory#create_extension` to take OIDs in the + dotted-decimal notation. + [[GitHub #141]](https://github.com/ruby/openssl/pull/141) + + +Version 3.1.3 +============= + +Bug fixes +--------- + +* Fix missing NULL check for `EVP_PKEY_get0()` functions with OpenSSL 3.x. + [[GitHub #957]](https://github.com/ruby/openssl/pull/957) + + +Version 3.1.2 +============= + +Bug fixes +--------- + +* Fix crash when attempting to export an incomplete `OpenSSL::PKey::DSA` key. + [[GitHub #845]](https://github.com/ruby/openssl/issues/845) + [[GitHub #847]](https://github.com/ruby/openssl/pull/847) +* Remove the `OpenSSL::X509::V_FLAG_CRL_CHECK_ALL` flag from the default store + used by `OpenSSL::SSL::SSLContext#set_params`. It causes certificate + verification to fail with OpenSSL 3.6.0. It has no effect with any other + OpenSSL versions. + [[GitHub #949]](https://github.com/ruby/openssl/issues/949) + [[GitHub #950]](https://github.com/ruby/openssl/pull/950) + + +Version 3.1.1 +============= + +Merged changes in 3.0.3. + + +Version 3.1.0 +============= + +Ruby/OpenSSL 3.1 will be maintained for the lifetime of Ruby 3.2. + +Merged bug fixes in 2.2.3 and 3.0.2. Among the new features and changes are: + +Notable changes +--------------- + +* Add `OpenSSL::SSL::SSLContext#ciphersuites=` to allow setting TLS 1.3 cipher + suites. + [[GitHub #493]](https://github.com/ruby/openssl/pull/493) +* Add `OpenSSL::SSL::SSLSocket#export_keying_material` for exporting keying + material of the session, as defined in RFC 5705. + [[GitHub #530]](https://github.com/ruby/openssl/pull/530) +* Add `OpenSSL::SSL::SSLContext#keylog_cb=` for setting the TLS key logging + callback, which is useful for supporting NSS's SSLKEYLOGFILE debugging output. + [[GitHub #536]](https://github.com/ruby/openssl/pull/536) +* Remove the default digest algorithm from `OpenSSL::OCSP::BasicResponse#sign` + and `OpenSSL::OCSP::Request#sign`. Omitting the 5th parameter of these + methods used to be equivalent of specifying SHA-1. This default value is now + removed and we will let the underlying OpenSSL library decide instead. + [[GitHub #507]](https://github.com/ruby/openssl/pull/507) +* Add `OpenSSL::BN#mod_sqrt`. + [[GitHub #553]](https://github.com/ruby/openssl/pull/553) +* Allow calling `OpenSSL::Cipher#update` with an empty string. This was + prohibited to workaround an ancient bug in OpenSSL. + [[GitHub #568]](https://github.com/ruby/openssl/pull/568) +* Fix build on platforms without socket support, such as WASI. `OpenSSL::SSL` + will not be defined if OpenSSL is compiled with `OPENSSL_NO_SOCK`. + [[GitHub #558]](https://github.com/ruby/openssl/pull/558) +* Improve support for recent LibreSSL versions. This includes HKDF support in + LibreSSL 3.6 and Ed25519 support in LibreSSL 3.7. + + +Version 3.0.3 +============= + +Bug fixes +--------- + +* Fix a performance regression introduced in v2.1.3 on a buffered write to + `SSLSocket`. + [[GitHub #706]](https://github.com/ruby/openssl/pull/706) +* Fix `OpenSSL::PKCS7` to handle PKCS#7 structures without content. + [[GitHub #690]](https://github.com/ruby/openssl/pull/690) + [[GitHub #752]](https://github.com/ruby/openssl/pull/752) +* Fix `OpenSSL::ASN1::ObjectId#==` with OIDs without a known name. + [[GitHub #791]](https://github.com/ruby/openssl/issues/791) + [[GitHub #792]](https://github.com/ruby/openssl/pull/792) +* Fix `OpenSSL::X509::Certificate#crl_uris` to handle CDP with multiple CRL + URIs. + [[GitHub #775]](https://github.com/ruby/openssl/issues/775) + [[GitHub #776]](https://github.com/ruby/openssl/pull/776) +* Fix `OpenSSL::Cipher#update` to always make the output buffer `String` + independent. + [[Bug #20937]](https://bugs.ruby-lang.org/issues/20937) + [[GitHub #824]](https://github.com/ruby/openssl/pull/824) + + +Version 3.0.2 +============= + +Merged changes in 2.2.3. Additionally, the following issues are fixed by this +release. + +Bug fixes +--------- + +* Fix OpenSSL::PKey::EC#check_key not working correctly on OpenSSL 3.0. + [[GitHub #563]](https://github.com/ruby/openssl/issues/563) + [[GitHub #580]](https://github.com/ruby/openssl/pull/580) + + +Version 3.0.1 +============= + +Merged changes in 2.1.4 and 2.2.2. Additionally, the following issues are fixed +by this release. + +Bug fixes +--------- + +* Add missing type check in OpenSSL::PKey::PKey#sign's optional parameters. + [[GitHub #531]](https://github.com/ruby/openssl/pull/531) +* Work around OpenSSL 3.0's HMAC issues with a zero-length key. + [[GitHub #538]](https://github.com/ruby/openssl/pull/538) +* Fix a regression in OpenSSL::PKey::DSA.generate's default of 'q' size. + [[GitHub #483]](https://github.com/ruby/openssl/issues/483) + [[GitHub #539]](https://github.com/ruby/openssl/pull/539) +* Restore OpenSSL::PKey.read's ability to decode "openssl ecparam -genkey" + output when linked against OpenSSL 3.0. + [[GitHub #535]](https://github.com/ruby/openssl/pull/535) + [[GitHub #540]](https://github.com/ruby/openssl/pull/540) +* Restore error checks in OpenSSL::PKey::EC#{to_der,to_pem}. + [[GitHub #541]](https://github.com/ruby/openssl/pull/541) + + +Version 3.0.0 +============= + +Compatibility notes +------------------- + +* OpenSSL 1.0.1 and Ruby 2.3-2.5 are no longer supported. + [[GitHub #396]](https://github.com/ruby/openssl/pull/396) + [[GitHub #466]](https://github.com/ruby/openssl/pull/466) + +* OpenSSL 3.0 support is added. It is the first major version bump from OpenSSL + 1.1 and contains incompatible changes that affect Ruby/OpenSSL. + Note that OpenSSL 3.0 support is preliminary and not all features are + currently available: + [[GitHub #369]](https://github.com/ruby/openssl/issues/369) + + - Deprecate the ability to modify `OpenSSL::PKey::PKey` instances. OpenSSL 3.0 + made EVP_PKEY structure immutable, and hence the following methods are not + available when Ruby/OpenSSL is linked against OpenSSL 3.0. + [[GitHub #480]](https://github.com/ruby/openssl/pull/480) + + - `OpenSSL::PKey::RSA#set_key`, `#set_factors`, `#set_crt_params` + - `OpenSSL::PKey::DSA#set_pqg`, `#set_key` + - `OpenSSL::PKey::DH#set_pqg`, `#set_key`, `#generate_key!` + - `OpenSSL::PKey::EC#private_key=`, `#public_key=`, `#group=`, `#generate_key!` + + - Deprecate `OpenSSL::Engine`. The ENGINE API has been deprecated in OpenSSL 3.0 + in favor of the new "provider" concept and will be removed in a future + version. + [[GitHub #481]](https://github.com/ruby/openssl/pull/481) + +* `OpenSSL::SSL::SSLContext#tmp_ecdh_callback` has been removed. It has been + deprecated since v2.0.0 because it is incompatible with modern OpenSSL + versions. + [[GitHub #394]](https://github.com/ruby/openssl/pull/394) + +* `OpenSSL::SSL::SSLSocket#read` and `#write` now raise `OpenSSL::SSL::SSLError` + if called before a TLS connection is established. Historically, they + read/wrote unencrypted data to the underlying socket directly in that case. + [[GitHub #9]](https://github.com/ruby/openssl/issues/9) + [[GitHub #469]](https://github.com/ruby/openssl/pull/469) + + +Notable changes +--------------- + +* Enhance OpenSSL::PKey's common interface. + [[GitHub #370]](https://github.com/ruby/openssl/issues/370) + + - Key deserialization: Enhance `OpenSSL::PKey.read` to handle PEM encoding of + DH parameters, which used to be only deserialized by `OpenSSL::PKey::DH.new`. + [[GitHub #328]](https://github.com/ruby/openssl/issues/328) + - Key generation: Add `OpenSSL::PKey.generate_parameters` and + `OpenSSL::PKey.generate_key`. + [[GitHub #329]](https://github.com/ruby/openssl/issues/329) + - Public key signing: Enhance `OpenSSL::PKey::PKey#sign` and `#verify` to use + the new EVP_DigestSign() family to enable PureEdDSA support on OpenSSL 1.1.1 + or later. They also now take optional algorithm-specific parameters for more + control. + [[GitHub #329]](https://github.com/ruby/openssl/issues/329) + - Low-level public key signing and verification: Add + `OpenSSL::PKey::PKey#sign_raw`, `#verify_raw`, and `#verify_recover`. + [[GitHub #382]](https://github.com/ruby/openssl/issues/382) + - Public key encryption: Add `OpenSSL::PKey::PKey#encrypt` and `#decrypt`. + [[GitHub #382]](https://github.com/ruby/openssl/issues/382) + - Key agreement: Add `OpenSSL::PKey::PKey#derive`. + [[GitHub #329]](https://github.com/ruby/openssl/issues/329) + - Key comparison: Add `OpenSSL::PKey::PKey#compare?` to conveniently check + that two keys have common parameters and a public key. + [[GitHub #383]](https://github.com/ruby/openssl/issues/383) + +* Add `OpenSSL::BN#set_flags` and `#get_flags`. This can be used in combination + with `OpenSSL::BN::CONSTTIME` to force constant-time computation. + [[GitHub #417]](https://github.com/ruby/openssl/issues/417) + +* Add `OpenSSL::BN#abs` to get the absolute value of the BIGNUM. + [[GitHub #430]](https://github.com/ruby/openssl/issues/430) + +* Add `OpenSSL::SSL::SSLSocket#getbyte`. + [[GitHub #438]](https://github.com/ruby/openssl/issues/438) + +* Add `OpenSSL::SSL::SSLContext#tmp_dh=`. + [[GitHub #459]](https://github.com/ruby/openssl/pull/459) + +* Add `OpenSSL::X509::Certificate.load` to load a PEM-encoded and concatenated + list of X.509 certificates at once. + [[GitHub #441]](https://github.com/ruby/openssl/pull/441) + +* Change `OpenSSL::X509::Certificate.new` to attempt to deserialize the given + string first as DER encoding first and then as PEM encoding to ensure the + round-trip consistency. + [[GitHub #442]](https://github.com/ruby/openssl/pull/442) + +* Update various part of the code base to use the modern API. No breaking + changes are intended with this. This includes: + + - `OpenSSL::HMAC` uses the EVP API. + [[GitHub #371]](https://github.com/ruby/openssl/issues/371) + - `OpenSSL::Config` uses native OpenSSL API to parse config files. + [[GitHub #342]](https://github.com/ruby/openssl/issues/342) + + +Version 2.2.3 +============= + +Bug fixes +--------- + +* Fix serveral methods in OpenSSL::PKey::EC::Point attempting to raise an error + with an incorrect class, which would end up with a TypeError. + [[GitHub #570]](https://github.com/ruby/openssl/pull/570) +* Fix OpenSSL::PKey::EC::Point#eql? and OpenSSL::PKey::EC::Group#eql? + incorrectly treated OpenSSL's internal errors as "not equal". + [[GitHub #564]](https://github.com/ruby/openssl/pull/564) +* Fix build with LibreSSL 3.5 or later. + + +Version 2.2.2 +============= + +Merged changes in 2.1.4. + + +Version 2.2.1 +============= + +Merged changes in 2.1.3. Additionally, the following issues are fixed by this +release. + +Bug fixes +--------- + +* Fix crash in `OpenSSL::Timestamp::{Request,Response,TokenInfo}.new` when + invalid arguments are given. + [[GitHub #407]](https://github.com/ruby/openssl/pull/407) +* Fix `OpenSSL::Timestamp::Factory#create_timestamp` with LibreSSL on platforms + where `time_t` has a different size from `long`. + [[GitHub #454]](https://github.com/ruby/openssl/pull/454) + + +Version 2.2.0 +============= + +Compatibility notes +------------------- + +* Remove unsupported MDC2, DSS, DSS1, and SHA algorithms. +* Remove `OpenSSL::PKCS7::SignerInfo#name` alias for `#issuer`. + [[GitHub #266]](https://github.com/ruby/openssl/pull/266) +* Deprecate `OpenSSL::Config#add_value` and `#[]=` for future removal. + [[GitHub #322]](https://github.com/ruby/openssl/pull/322) + + +Notable changes +--------------- + +* Change default `OpenSSL::SSL::SSLServer#listen` backlog argument from + 5 to `Socket::SOMAXCONN`. + [[GitHub #286]](https://github.com/ruby/openssl/issues/286) +* Make `OpenSSL::HMAC#==` use a timing safe string comparison. + [[GitHub #284]](https://github.com/ruby/openssl/pull/284) +* Add support for SHA3 and BLAKE digests. + [[GitHub #282]](https://github.com/ruby/openssl/pull/282) +* Add `OpenSSL::SSL::SSLSocket.open` for opening a `TCPSocket` and + returning an `OpenSSL::SSL::SSLSocket` for it. + [[GitHub #225]](https://github.com/ruby/openssl/issues/225) +* Support marshalling of `OpenSSL::X509` and `OpenSSL::PKey` objects. + [[GitHub #281]](https://github.com/ruby/openssl/pull/281) + [[GitHub #363]](https://github.com/ruby/openssl/pull/363) +* Add `OpenSSL.secure_compare` for timing safe string comparison for + strings of possibly unequal length. + [[GitHub #280]](https://github.com/ruby/openssl/pull/280) +* Add `OpenSSL.fixed_length_secure_compare` for timing safe string + comparison for strings of equal length. + [[GitHub #269]](https://github.com/ruby/openssl/pull/269) +* Add `OpenSSL::SSL::SSLSocket#{finished_message,peer_finished_message}` + for last finished message sent and received. + [[GitHub #250]](https://github.com/ruby/openssl/pull/250) +* Add `OpenSSL::Timestamp` module for handing timestamp requests and + responses. + [[GitHub #204]](https://github.com/ruby/openssl/pull/204) +* Add helper methods for `OpenSSL::X509::Certificate`: + `find_extension`, `subject_key_identifier`, + `authority_key_identifier`, `crl_uris`, `ca_issuer_uris` and + `ocsp_uris`, and for `OpenSSL::X509::CRL`: + `find_extension` and `subject_key_identifier`. + [[GitHub #260]](https://github.com/ruby/openssl/pull/260) + [[GitHub #275]](https://github.com/ruby/openssl/pull/275) + [[GitHub #293]](https://github.com/ruby/openssl/pull/293) +* Add `OpenSSL::ECPoint#add` for performing elliptic curve point addition. + [[GitHub #261]](https://github.com/ruby/openssl/pull/261) +* Make `OpenSSL::PKey::RSA#{export,to_der}` check `key`, `factors`, and + `crt_params` to do proper private key serialization. + [[GitHub #258]](https://github.com/ruby/openssl/pull/258) +* Add `OpenSSL::SSL::{SSLSocket,SSLServer}#fileno`, returning the + underlying socket file descriptor number. + [[GitHub #247]](https://github.com/ruby/openssl/pull/247) +* Support client certificates with TLS 1.3, and support post-handshake + authentication with OpenSSL 1.1.1+. + [[GitHub #239]](https://github.com/ruby/openssl/pull/239) +* Add `OpenSSL::ASN1::ObjectId#==` for equality testing. +* Add `OpenSSL::X509::Extension#value_der` for the raw value of + the extension. + [[GitHub #234]](https://github.com/ruby/openssl/pull/234) +* Significantly reduce allocated memory in `OpenSSL::Buffering#do_write`. + [[GitHub #212]](https://github.com/ruby/openssl/pull/212) +* Ensure all valid IPv6 addresses are considered valid as elements + of subjectAlternativeName in certificates. + [[GitHub #185]](https://github.com/ruby/openssl/pull/185) +* Allow recipient's certificate to be omitted in PCKS7#decrypt. + [[GitHub #183]](https://github.com/ruby/openssl/pull/183) +* Add support for reading keys in PKCS #8 format and export via instance methods + added to `OpenSSL::PKey` classes: `private_to_der`, `private_to_pem`, + `public_to_der` and `public_to_pem`. + [[GitHub #297]](https://github.com/ruby/openssl/pull/297) + + +Version 2.1.4 +============= + +Bug fixes +--------- + +* Do not use pkg-config if --with-openssl-dir option is specified. + [[GitHub #486]](https://github.com/ruby/openssl/pull/486) + + +Version 2.1.3 +============= + +Bug fixes +--------- + +* Fix deprecation warnings on Ruby 3.0. +* Add ".include" directive support in `OpenSSL::Config`. + [[GitHub #216]](https://github.com/ruby/openssl/pull/216) +* Fix handling of IPv6 address SANs. + [[GitHub #185]](https://github.com/ruby/openssl/pull/185) +* Hostname verification failure with `OpenSSL::SSL::SSLContext#verify_hostname=` + sets a proper error code. + [[GitHub #350]](https://github.com/ruby/openssl/pull/350) +* Fix crash with `OpenSSL::BN.new(nil, 2)`. + [[Bug #15760]](https://bugs.ruby-lang.org/issues/15760) +* `OpenSSL::SSL::SSLSocket#sys{read,write}` prevent internal string buffers from + being modified by another thread. + [[GitHub #453]](https://github.com/ruby/openssl/pull/453) +* Fix misuse of input record separator in `OpenSSL::Buffering` where it was + for output. +* Fix wrong integer casting in `OpenSSL::PKey::EC#dsa_verify_asn1`. + [[GitHub #460]](https://github.com/ruby/openssl/pull/460) +* `extconf.rb` explicitly checks that OpenSSL's version number is 1.0.1 or + newer but also less than 3.0. Ruby/OpenSSL v2.1.x and v2.2.x will not support + OpenSSL 3.0 API. + [[GitHub #458]](https://github.com/ruby/openssl/pull/458) +* Activate `digest` gem correctly. `digest` library could go into an + inconsistent state if there are multiple versions of `digest` is installed + and `openssl` is `require`d before `digest`. + [[GitHub #463]](https://github.com/ruby/openssl/pull/463) +* Fix GC.compact compatibility. + [[GitHub #464]](https://github.com/ruby/openssl/issues/464) + [[GitHub #465]](https://github.com/ruby/openssl/pull/465) + + Version 2.1.2 ============= @@ -80,7 +706,7 @@ Security fixes Bug fixes --------- -* Fixed OpenSSL::PKey::*.{new,generate} immediately aborting if the thread is +* Fixed OpenSSL::PKey::\*.{new,generate} immediately aborting if the thread is interrupted. [[Bug #14882]](https://bugs.ruby-lang.org/issues/14882) [[GitHub #205]](https://github.com/ruby/openssl/pull/205) diff --git a/ext/openssl/depend b/ext/openssl/depend index 68cf357294..435f4a1c68 100644 --- a/ext/openssl/depend +++ b/ext/openssl/depend @@ -8,18 +8,176 @@ ossl.o: $(arch_hdrdir)/ruby/config.h ossl.o: $(hdrdir)/ruby.h ossl.o: $(hdrdir)/ruby/assert.h ossl.o: $(hdrdir)/ruby/backward.h +ossl.o: $(hdrdir)/ruby/backward/2/assume.h +ossl.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl.o: $(hdrdir)/ruby/backward/2/bool.h +ossl.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl.o: $(hdrdir)/ruby/backward/2/limits.h +ossl.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl.o: $(hdrdir)/ruby/defines.h ossl.o: $(hdrdir)/ruby/encoding.h ossl.o: $(hdrdir)/ruby/intern.h +ossl.o: $(hdrdir)/ruby/internal/abi.h +ossl.o: $(hdrdir)/ruby/internal/anyargs.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl.o: $(hdrdir)/ruby/internal/assume.h +ossl.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl.o: $(hdrdir)/ruby/internal/attr/const.h +ossl.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl.o: $(hdrdir)/ruby/internal/attr/error.h +ossl.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl.o: $(hdrdir)/ruby/internal/attr/format.h +ossl.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl.o: $(hdrdir)/ruby/internal/cast.h +ossl.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl.o: $(hdrdir)/ruby/internal/config.h +ossl.o: $(hdrdir)/ruby/internal/constant_p.h +ossl.o: $(hdrdir)/ruby/internal/core.h +ossl.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl.o: $(hdrdir)/ruby/internal/core/robject.h +ossl.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl.o: $(hdrdir)/ruby/internal/ctype.h +ossl.o: $(hdrdir)/ruby/internal/dllexport.h +ossl.o: $(hdrdir)/ruby/internal/dosish.h +ossl.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl.o: $(hdrdir)/ruby/internal/error.h +ossl.o: $(hdrdir)/ruby/internal/eval.h +ossl.o: $(hdrdir)/ruby/internal/event.h +ossl.o: $(hdrdir)/ruby/internal/fl_type.h +ossl.o: $(hdrdir)/ruby/internal/gc.h +ossl.o: $(hdrdir)/ruby/internal/glob.h +ossl.o: $(hdrdir)/ruby/internal/globals.h +ossl.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl.o: $(hdrdir)/ruby/internal/has/extension.h +ossl.o: $(hdrdir)/ruby/internal/has/feature.h +ossl.o: $(hdrdir)/ruby/internal/has/warning.h +ossl.o: $(hdrdir)/ruby/internal/intern/array.h +ossl.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl.o: $(hdrdir)/ruby/internal/intern/class.h +ossl.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl.o: $(hdrdir)/ruby/internal/intern/error.h +ossl.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl.o: $(hdrdir)/ruby/internal/intern/file.h +ossl.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl.o: $(hdrdir)/ruby/internal/intern/io.h +ossl.o: $(hdrdir)/ruby/internal/intern/load.h +ossl.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl.o: $(hdrdir)/ruby/internal/intern/object.h +ossl.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl.o: $(hdrdir)/ruby/internal/intern/process.h +ossl.o: $(hdrdir)/ruby/internal/intern/random.h +ossl.o: $(hdrdir)/ruby/internal/intern/range.h +ossl.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl.o: $(hdrdir)/ruby/internal/intern/re.h +ossl.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl.o: $(hdrdir)/ruby/internal/intern/select.h +ossl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl.o: $(hdrdir)/ruby/internal/intern/set.h +ossl.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl.o: $(hdrdir)/ruby/internal/intern/string.h +ossl.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl.o: $(hdrdir)/ruby/internal/intern/time.h +ossl.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl.o: $(hdrdir)/ruby/internal/interpreter.h +ossl.o: $(hdrdir)/ruby/internal/iterator.h +ossl.o: $(hdrdir)/ruby/internal/memory.h +ossl.o: $(hdrdir)/ruby/internal/method.h +ossl.o: $(hdrdir)/ruby/internal/module.h +ossl.o: $(hdrdir)/ruby/internal/newobj.h +ossl.o: $(hdrdir)/ruby/internal/scan_args.h +ossl.o: $(hdrdir)/ruby/internal/special_consts.h +ossl.o: $(hdrdir)/ruby/internal/static_assert.h +ossl.o: $(hdrdir)/ruby/internal/stdalign.h +ossl.o: $(hdrdir)/ruby/internal/stdbool.h +ossl.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl.o: $(hdrdir)/ruby/internal/symbol.h +ossl.o: $(hdrdir)/ruby/internal/value.h +ossl.o: $(hdrdir)/ruby/internal/value_type.h +ossl.o: $(hdrdir)/ruby/internal/variable.h +ossl.o: $(hdrdir)/ruby/internal/warning_push.h +ossl.o: $(hdrdir)/ruby/internal/xmalloc.h ossl.o: $(hdrdir)/ruby/io.h ossl.o: $(hdrdir)/ruby/missing.h ossl.o: $(hdrdir)/ruby/onigmo.h ossl.o: $(hdrdir)/ruby/oniguruma.h +ossl.o: $(hdrdir)/ruby/ractor.h ossl.o: $(hdrdir)/ruby/ruby.h ossl.o: $(hdrdir)/ruby/st.h ossl.o: $(hdrdir)/ruby/subst.h ossl.o: $(hdrdir)/ruby/thread.h -ossl.o: $(hdrdir)/ruby/thread_native.h ossl.o: openssl_missing.h ossl.o: ossl.c ossl.o: ossl.h @@ -37,23 +195,182 @@ ossl.o: ossl_ocsp.h ossl.o: ossl_pkcs12.h ossl.o: ossl_pkcs7.h ossl.o: ossl_pkey.h +ossl.o: ossl_provider.h ossl.o: ossl_rand.h ossl.o: ossl_ssl.h -ossl.o: ossl_version.h +ossl.o: ossl_ts.h ossl.o: ossl_x509.h -ossl.o: ruby_missing.h ossl_asn1.o: $(RUBY_EXTCONF_H) ossl_asn1.o: $(arch_hdrdir)/ruby/config.h ossl_asn1.o: $(hdrdir)/ruby.h ossl_asn1.o: $(hdrdir)/ruby/assert.h ossl_asn1.o: $(hdrdir)/ruby/backward.h +ossl_asn1.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_asn1.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_asn1.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_asn1.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_asn1.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_asn1.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_asn1.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_asn1.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_asn1.o: $(hdrdir)/ruby/defines.h ossl_asn1.o: $(hdrdir)/ruby/encoding.h ossl_asn1.o: $(hdrdir)/ruby/intern.h +ossl_asn1.o: $(hdrdir)/ruby/internal/abi.h +ossl_asn1.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_asn1.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_asn1.o: $(hdrdir)/ruby/internal/assume.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_asn1.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_asn1.o: $(hdrdir)/ruby/internal/cast.h +ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_asn1.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_asn1.o: $(hdrdir)/ruby/internal/config.h +ossl_asn1.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_asn1.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_asn1.o: $(hdrdir)/ruby/internal/ctype.h +ossl_asn1.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_asn1.o: $(hdrdir)/ruby/internal/dosish.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_asn1.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_asn1.o: $(hdrdir)/ruby/internal/error.h +ossl_asn1.o: $(hdrdir)/ruby/internal/eval.h +ossl_asn1.o: $(hdrdir)/ruby/internal/event.h +ossl_asn1.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_asn1.o: $(hdrdir)/ruby/internal/gc.h +ossl_asn1.o: $(hdrdir)/ruby/internal/glob.h +ossl_asn1.o: $(hdrdir)/ruby/internal/globals.h +ossl_asn1.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_asn1.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_asn1.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_asn1.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_asn1.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_asn1.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_asn1.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_asn1.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_asn1.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_asn1.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_asn1.o: $(hdrdir)/ruby/internal/iterator.h +ossl_asn1.o: $(hdrdir)/ruby/internal/memory.h +ossl_asn1.o: $(hdrdir)/ruby/internal/method.h +ossl_asn1.o: $(hdrdir)/ruby/internal/module.h +ossl_asn1.o: $(hdrdir)/ruby/internal/newobj.h +ossl_asn1.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_asn1.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_asn1.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_asn1.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_asn1.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_asn1.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_asn1.o: $(hdrdir)/ruby/internal/symbol.h +ossl_asn1.o: $(hdrdir)/ruby/internal/value.h +ossl_asn1.o: $(hdrdir)/ruby/internal/value_type.h +ossl_asn1.o: $(hdrdir)/ruby/internal/variable.h +ossl_asn1.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_asn1.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_asn1.o: $(hdrdir)/ruby/io.h ossl_asn1.o: $(hdrdir)/ruby/missing.h ossl_asn1.o: $(hdrdir)/ruby/onigmo.h ossl_asn1.o: $(hdrdir)/ruby/oniguruma.h +ossl_asn1.o: $(hdrdir)/ruby/ractor.h ossl_asn1.o: $(hdrdir)/ruby/ruby.h ossl_asn1.o: $(hdrdir)/ruby/st.h ossl_asn1.o: $(hdrdir)/ruby/subst.h @@ -75,23 +392,182 @@ ossl_asn1.o: ossl_ocsp.h ossl_asn1.o: ossl_pkcs12.h ossl_asn1.o: ossl_pkcs7.h ossl_asn1.o: ossl_pkey.h +ossl_asn1.o: ossl_provider.h ossl_asn1.o: ossl_rand.h ossl_asn1.o: ossl_ssl.h -ossl_asn1.o: ossl_version.h +ossl_asn1.o: ossl_ts.h ossl_asn1.o: ossl_x509.h -ossl_asn1.o: ruby_missing.h ossl_bio.o: $(RUBY_EXTCONF_H) ossl_bio.o: $(arch_hdrdir)/ruby/config.h ossl_bio.o: $(hdrdir)/ruby.h ossl_bio.o: $(hdrdir)/ruby/assert.h ossl_bio.o: $(hdrdir)/ruby/backward.h +ossl_bio.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_bio.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_bio.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_bio.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_bio.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_bio.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_bio.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_bio.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_bio.o: $(hdrdir)/ruby/defines.h ossl_bio.o: $(hdrdir)/ruby/encoding.h ossl_bio.o: $(hdrdir)/ruby/intern.h +ossl_bio.o: $(hdrdir)/ruby/internal/abi.h +ossl_bio.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_bio.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_bio.o: $(hdrdir)/ruby/internal/assume.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_bio.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_bio.o: $(hdrdir)/ruby/internal/cast.h +ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_bio.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_bio.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_bio.o: $(hdrdir)/ruby/internal/config.h +ossl_bio.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_bio.o: $(hdrdir)/ruby/internal/core.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_bio.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_bio.o: $(hdrdir)/ruby/internal/ctype.h +ossl_bio.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_bio.o: $(hdrdir)/ruby/internal/dosish.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_bio.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_bio.o: $(hdrdir)/ruby/internal/error.h +ossl_bio.o: $(hdrdir)/ruby/internal/eval.h +ossl_bio.o: $(hdrdir)/ruby/internal/event.h +ossl_bio.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_bio.o: $(hdrdir)/ruby/internal/gc.h +ossl_bio.o: $(hdrdir)/ruby/internal/glob.h +ossl_bio.o: $(hdrdir)/ruby/internal/globals.h +ossl_bio.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_bio.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_bio.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_bio.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_bio.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_bio.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_bio.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_bio.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_bio.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_bio.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_bio.o: $(hdrdir)/ruby/internal/iterator.h +ossl_bio.o: $(hdrdir)/ruby/internal/memory.h +ossl_bio.o: $(hdrdir)/ruby/internal/method.h +ossl_bio.o: $(hdrdir)/ruby/internal/module.h +ossl_bio.o: $(hdrdir)/ruby/internal/newobj.h +ossl_bio.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_bio.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_bio.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_bio.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_bio.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_bio.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_bio.o: $(hdrdir)/ruby/internal/symbol.h +ossl_bio.o: $(hdrdir)/ruby/internal/value.h +ossl_bio.o: $(hdrdir)/ruby/internal/value_type.h +ossl_bio.o: $(hdrdir)/ruby/internal/variable.h +ossl_bio.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_bio.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_bio.o: $(hdrdir)/ruby/io.h ossl_bio.o: $(hdrdir)/ruby/missing.h ossl_bio.o: $(hdrdir)/ruby/onigmo.h ossl_bio.o: $(hdrdir)/ruby/oniguruma.h +ossl_bio.o: $(hdrdir)/ruby/ractor.h ossl_bio.o: $(hdrdir)/ruby/ruby.h ossl_bio.o: $(hdrdir)/ruby/st.h ossl_bio.o: $(hdrdir)/ruby/subst.h @@ -113,23 +589,182 @@ ossl_bio.o: ossl_ocsp.h ossl_bio.o: ossl_pkcs12.h ossl_bio.o: ossl_pkcs7.h ossl_bio.o: ossl_pkey.h +ossl_bio.o: ossl_provider.h ossl_bio.o: ossl_rand.h ossl_bio.o: ossl_ssl.h -ossl_bio.o: ossl_version.h +ossl_bio.o: ossl_ts.h ossl_bio.o: ossl_x509.h -ossl_bio.o: ruby_missing.h ossl_bn.o: $(RUBY_EXTCONF_H) ossl_bn.o: $(arch_hdrdir)/ruby/config.h ossl_bn.o: $(hdrdir)/ruby.h ossl_bn.o: $(hdrdir)/ruby/assert.h ossl_bn.o: $(hdrdir)/ruby/backward.h +ossl_bn.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_bn.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_bn.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_bn.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_bn.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_bn.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_bn.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_bn.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_bn.o: $(hdrdir)/ruby/defines.h ossl_bn.o: $(hdrdir)/ruby/encoding.h ossl_bn.o: $(hdrdir)/ruby/intern.h +ossl_bn.o: $(hdrdir)/ruby/internal/abi.h +ossl_bn.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_bn.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_bn.o: $(hdrdir)/ruby/internal/assume.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_bn.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_bn.o: $(hdrdir)/ruby/internal/cast.h +ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_bn.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_bn.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_bn.o: $(hdrdir)/ruby/internal/config.h +ossl_bn.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_bn.o: $(hdrdir)/ruby/internal/core.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_bn.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_bn.o: $(hdrdir)/ruby/internal/ctype.h +ossl_bn.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_bn.o: $(hdrdir)/ruby/internal/dosish.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_bn.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_bn.o: $(hdrdir)/ruby/internal/error.h +ossl_bn.o: $(hdrdir)/ruby/internal/eval.h +ossl_bn.o: $(hdrdir)/ruby/internal/event.h +ossl_bn.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_bn.o: $(hdrdir)/ruby/internal/gc.h +ossl_bn.o: $(hdrdir)/ruby/internal/glob.h +ossl_bn.o: $(hdrdir)/ruby/internal/globals.h +ossl_bn.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_bn.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_bn.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_bn.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_bn.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_bn.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_bn.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_bn.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_bn.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_bn.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_bn.o: $(hdrdir)/ruby/internal/iterator.h +ossl_bn.o: $(hdrdir)/ruby/internal/memory.h +ossl_bn.o: $(hdrdir)/ruby/internal/method.h +ossl_bn.o: $(hdrdir)/ruby/internal/module.h +ossl_bn.o: $(hdrdir)/ruby/internal/newobj.h +ossl_bn.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_bn.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_bn.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_bn.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_bn.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_bn.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_bn.o: $(hdrdir)/ruby/internal/symbol.h +ossl_bn.o: $(hdrdir)/ruby/internal/value.h +ossl_bn.o: $(hdrdir)/ruby/internal/value_type.h +ossl_bn.o: $(hdrdir)/ruby/internal/variable.h +ossl_bn.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_bn.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_bn.o: $(hdrdir)/ruby/io.h ossl_bn.o: $(hdrdir)/ruby/missing.h ossl_bn.o: $(hdrdir)/ruby/onigmo.h ossl_bn.o: $(hdrdir)/ruby/oniguruma.h +ossl_bn.o: $(hdrdir)/ruby/ractor.h ossl_bn.o: $(hdrdir)/ruby/ruby.h ossl_bn.o: $(hdrdir)/ruby/st.h ossl_bn.o: $(hdrdir)/ruby/subst.h @@ -151,23 +786,182 @@ ossl_bn.o: ossl_ocsp.h ossl_bn.o: ossl_pkcs12.h ossl_bn.o: ossl_pkcs7.h ossl_bn.o: ossl_pkey.h +ossl_bn.o: ossl_provider.h ossl_bn.o: ossl_rand.h ossl_bn.o: ossl_ssl.h -ossl_bn.o: ossl_version.h +ossl_bn.o: ossl_ts.h ossl_bn.o: ossl_x509.h -ossl_bn.o: ruby_missing.h ossl_cipher.o: $(RUBY_EXTCONF_H) ossl_cipher.o: $(arch_hdrdir)/ruby/config.h ossl_cipher.o: $(hdrdir)/ruby.h ossl_cipher.o: $(hdrdir)/ruby/assert.h ossl_cipher.o: $(hdrdir)/ruby/backward.h +ossl_cipher.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_cipher.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_cipher.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_cipher.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_cipher.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_cipher.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_cipher.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_cipher.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_cipher.o: $(hdrdir)/ruby/defines.h ossl_cipher.o: $(hdrdir)/ruby/encoding.h ossl_cipher.o: $(hdrdir)/ruby/intern.h +ossl_cipher.o: $(hdrdir)/ruby/internal/abi.h +ossl_cipher.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_cipher.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_cipher.o: $(hdrdir)/ruby/internal/assume.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_cipher.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_cipher.o: $(hdrdir)/ruby/internal/cast.h +ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_cipher.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_cipher.o: $(hdrdir)/ruby/internal/config.h +ossl_cipher.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_cipher.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_cipher.o: $(hdrdir)/ruby/internal/ctype.h +ossl_cipher.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_cipher.o: $(hdrdir)/ruby/internal/dosish.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_cipher.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_cipher.o: $(hdrdir)/ruby/internal/error.h +ossl_cipher.o: $(hdrdir)/ruby/internal/eval.h +ossl_cipher.o: $(hdrdir)/ruby/internal/event.h +ossl_cipher.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_cipher.o: $(hdrdir)/ruby/internal/gc.h +ossl_cipher.o: $(hdrdir)/ruby/internal/glob.h +ossl_cipher.o: $(hdrdir)/ruby/internal/globals.h +ossl_cipher.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_cipher.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_cipher.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_cipher.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_cipher.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_cipher.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_cipher.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_cipher.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_cipher.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_cipher.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_cipher.o: $(hdrdir)/ruby/internal/iterator.h +ossl_cipher.o: $(hdrdir)/ruby/internal/memory.h +ossl_cipher.o: $(hdrdir)/ruby/internal/method.h +ossl_cipher.o: $(hdrdir)/ruby/internal/module.h +ossl_cipher.o: $(hdrdir)/ruby/internal/newobj.h +ossl_cipher.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_cipher.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_cipher.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_cipher.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_cipher.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_cipher.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_cipher.o: $(hdrdir)/ruby/internal/symbol.h +ossl_cipher.o: $(hdrdir)/ruby/internal/value.h +ossl_cipher.o: $(hdrdir)/ruby/internal/value_type.h +ossl_cipher.o: $(hdrdir)/ruby/internal/variable.h +ossl_cipher.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_cipher.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_cipher.o: $(hdrdir)/ruby/io.h ossl_cipher.o: $(hdrdir)/ruby/missing.h ossl_cipher.o: $(hdrdir)/ruby/onigmo.h ossl_cipher.o: $(hdrdir)/ruby/oniguruma.h +ossl_cipher.o: $(hdrdir)/ruby/ractor.h ossl_cipher.o: $(hdrdir)/ruby/ruby.h ossl_cipher.o: $(hdrdir)/ruby/st.h ossl_cipher.o: $(hdrdir)/ruby/subst.h @@ -189,23 +983,182 @@ ossl_cipher.o: ossl_ocsp.h ossl_cipher.o: ossl_pkcs12.h ossl_cipher.o: ossl_pkcs7.h ossl_cipher.o: ossl_pkey.h +ossl_cipher.o: ossl_provider.h ossl_cipher.o: ossl_rand.h ossl_cipher.o: ossl_ssl.h -ossl_cipher.o: ossl_version.h +ossl_cipher.o: ossl_ts.h ossl_cipher.o: ossl_x509.h -ossl_cipher.o: ruby_missing.h ossl_config.o: $(RUBY_EXTCONF_H) ossl_config.o: $(arch_hdrdir)/ruby/config.h ossl_config.o: $(hdrdir)/ruby.h ossl_config.o: $(hdrdir)/ruby/assert.h ossl_config.o: $(hdrdir)/ruby/backward.h +ossl_config.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_config.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_config.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_config.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_config.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_config.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_config.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_config.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_config.o: $(hdrdir)/ruby/defines.h ossl_config.o: $(hdrdir)/ruby/encoding.h ossl_config.o: $(hdrdir)/ruby/intern.h +ossl_config.o: $(hdrdir)/ruby/internal/abi.h +ossl_config.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_config.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_config.o: $(hdrdir)/ruby/internal/assume.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_config.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_config.o: $(hdrdir)/ruby/internal/cast.h +ossl_config.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_config.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_config.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_config.o: $(hdrdir)/ruby/internal/config.h +ossl_config.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_config.o: $(hdrdir)/ruby/internal/core.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_config.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_config.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_config.o: $(hdrdir)/ruby/internal/ctype.h +ossl_config.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_config.o: $(hdrdir)/ruby/internal/dosish.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_config.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_config.o: $(hdrdir)/ruby/internal/error.h +ossl_config.o: $(hdrdir)/ruby/internal/eval.h +ossl_config.o: $(hdrdir)/ruby/internal/event.h +ossl_config.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_config.o: $(hdrdir)/ruby/internal/gc.h +ossl_config.o: $(hdrdir)/ruby/internal/glob.h +ossl_config.o: $(hdrdir)/ruby/internal/globals.h +ossl_config.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_config.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_config.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_config.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_config.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_config.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_config.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_config.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_config.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_config.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_config.o: $(hdrdir)/ruby/internal/iterator.h +ossl_config.o: $(hdrdir)/ruby/internal/memory.h +ossl_config.o: $(hdrdir)/ruby/internal/method.h +ossl_config.o: $(hdrdir)/ruby/internal/module.h +ossl_config.o: $(hdrdir)/ruby/internal/newobj.h +ossl_config.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_config.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_config.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_config.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_config.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_config.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_config.o: $(hdrdir)/ruby/internal/symbol.h +ossl_config.o: $(hdrdir)/ruby/internal/value.h +ossl_config.o: $(hdrdir)/ruby/internal/value_type.h +ossl_config.o: $(hdrdir)/ruby/internal/variable.h +ossl_config.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_config.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_config.o: $(hdrdir)/ruby/io.h ossl_config.o: $(hdrdir)/ruby/missing.h ossl_config.o: $(hdrdir)/ruby/onigmo.h ossl_config.o: $(hdrdir)/ruby/oniguruma.h +ossl_config.o: $(hdrdir)/ruby/ractor.h ossl_config.o: $(hdrdir)/ruby/ruby.h ossl_config.o: $(hdrdir)/ruby/st.h ossl_config.o: $(hdrdir)/ruby/subst.h @@ -227,23 +1180,182 @@ ossl_config.o: ossl_ocsp.h ossl_config.o: ossl_pkcs12.h ossl_config.o: ossl_pkcs7.h ossl_config.o: ossl_pkey.h +ossl_config.o: ossl_provider.h ossl_config.o: ossl_rand.h ossl_config.o: ossl_ssl.h -ossl_config.o: ossl_version.h +ossl_config.o: ossl_ts.h ossl_config.o: ossl_x509.h -ossl_config.o: ruby_missing.h ossl_digest.o: $(RUBY_EXTCONF_H) ossl_digest.o: $(arch_hdrdir)/ruby/config.h ossl_digest.o: $(hdrdir)/ruby.h ossl_digest.o: $(hdrdir)/ruby/assert.h ossl_digest.o: $(hdrdir)/ruby/backward.h +ossl_digest.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_digest.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_digest.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_digest.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_digest.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_digest.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_digest.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_digest.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_digest.o: $(hdrdir)/ruby/defines.h ossl_digest.o: $(hdrdir)/ruby/encoding.h ossl_digest.o: $(hdrdir)/ruby/intern.h +ossl_digest.o: $(hdrdir)/ruby/internal/abi.h +ossl_digest.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_digest.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_digest.o: $(hdrdir)/ruby/internal/assume.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_digest.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_digest.o: $(hdrdir)/ruby/internal/cast.h +ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_digest.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_digest.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_digest.o: $(hdrdir)/ruby/internal/config.h +ossl_digest.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_digest.o: $(hdrdir)/ruby/internal/core.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_digest.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_digest.o: $(hdrdir)/ruby/internal/ctype.h +ossl_digest.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_digest.o: $(hdrdir)/ruby/internal/dosish.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_digest.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_digest.o: $(hdrdir)/ruby/internal/error.h +ossl_digest.o: $(hdrdir)/ruby/internal/eval.h +ossl_digest.o: $(hdrdir)/ruby/internal/event.h +ossl_digest.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_digest.o: $(hdrdir)/ruby/internal/gc.h +ossl_digest.o: $(hdrdir)/ruby/internal/glob.h +ossl_digest.o: $(hdrdir)/ruby/internal/globals.h +ossl_digest.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_digest.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_digest.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_digest.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_digest.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_digest.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_digest.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_digest.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_digest.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_digest.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_digest.o: $(hdrdir)/ruby/internal/iterator.h +ossl_digest.o: $(hdrdir)/ruby/internal/memory.h +ossl_digest.o: $(hdrdir)/ruby/internal/method.h +ossl_digest.o: $(hdrdir)/ruby/internal/module.h +ossl_digest.o: $(hdrdir)/ruby/internal/newobj.h +ossl_digest.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_digest.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_digest.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_digest.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_digest.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_digest.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_digest.o: $(hdrdir)/ruby/internal/symbol.h +ossl_digest.o: $(hdrdir)/ruby/internal/value.h +ossl_digest.o: $(hdrdir)/ruby/internal/value_type.h +ossl_digest.o: $(hdrdir)/ruby/internal/variable.h +ossl_digest.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_digest.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_digest.o: $(hdrdir)/ruby/io.h ossl_digest.o: $(hdrdir)/ruby/missing.h ossl_digest.o: $(hdrdir)/ruby/onigmo.h ossl_digest.o: $(hdrdir)/ruby/oniguruma.h +ossl_digest.o: $(hdrdir)/ruby/ractor.h ossl_digest.o: $(hdrdir)/ruby/ruby.h ossl_digest.o: $(hdrdir)/ruby/st.h ossl_digest.o: $(hdrdir)/ruby/subst.h @@ -265,23 +1377,182 @@ ossl_digest.o: ossl_ocsp.h ossl_digest.o: ossl_pkcs12.h ossl_digest.o: ossl_pkcs7.h ossl_digest.o: ossl_pkey.h +ossl_digest.o: ossl_provider.h ossl_digest.o: ossl_rand.h ossl_digest.o: ossl_ssl.h -ossl_digest.o: ossl_version.h +ossl_digest.o: ossl_ts.h ossl_digest.o: ossl_x509.h -ossl_digest.o: ruby_missing.h ossl_engine.o: $(RUBY_EXTCONF_H) ossl_engine.o: $(arch_hdrdir)/ruby/config.h ossl_engine.o: $(hdrdir)/ruby.h ossl_engine.o: $(hdrdir)/ruby/assert.h ossl_engine.o: $(hdrdir)/ruby/backward.h +ossl_engine.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_engine.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_engine.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_engine.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_engine.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_engine.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_engine.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_engine.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_engine.o: $(hdrdir)/ruby/defines.h ossl_engine.o: $(hdrdir)/ruby/encoding.h ossl_engine.o: $(hdrdir)/ruby/intern.h +ossl_engine.o: $(hdrdir)/ruby/internal/abi.h +ossl_engine.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_engine.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_engine.o: $(hdrdir)/ruby/internal/assume.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_engine.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_engine.o: $(hdrdir)/ruby/internal/cast.h +ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_engine.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_engine.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_engine.o: $(hdrdir)/ruby/internal/config.h +ossl_engine.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_engine.o: $(hdrdir)/ruby/internal/core.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_engine.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_engine.o: $(hdrdir)/ruby/internal/ctype.h +ossl_engine.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_engine.o: $(hdrdir)/ruby/internal/dosish.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_engine.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_engine.o: $(hdrdir)/ruby/internal/error.h +ossl_engine.o: $(hdrdir)/ruby/internal/eval.h +ossl_engine.o: $(hdrdir)/ruby/internal/event.h +ossl_engine.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_engine.o: $(hdrdir)/ruby/internal/gc.h +ossl_engine.o: $(hdrdir)/ruby/internal/glob.h +ossl_engine.o: $(hdrdir)/ruby/internal/globals.h +ossl_engine.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_engine.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_engine.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_engine.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_engine.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_engine.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_engine.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_engine.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_engine.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_engine.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_engine.o: $(hdrdir)/ruby/internal/iterator.h +ossl_engine.o: $(hdrdir)/ruby/internal/memory.h +ossl_engine.o: $(hdrdir)/ruby/internal/method.h +ossl_engine.o: $(hdrdir)/ruby/internal/module.h +ossl_engine.o: $(hdrdir)/ruby/internal/newobj.h +ossl_engine.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_engine.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_engine.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_engine.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_engine.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_engine.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_engine.o: $(hdrdir)/ruby/internal/symbol.h +ossl_engine.o: $(hdrdir)/ruby/internal/value.h +ossl_engine.o: $(hdrdir)/ruby/internal/value_type.h +ossl_engine.o: $(hdrdir)/ruby/internal/variable.h +ossl_engine.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_engine.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_engine.o: $(hdrdir)/ruby/io.h ossl_engine.o: $(hdrdir)/ruby/missing.h ossl_engine.o: $(hdrdir)/ruby/onigmo.h ossl_engine.o: $(hdrdir)/ruby/oniguruma.h +ossl_engine.o: $(hdrdir)/ruby/ractor.h ossl_engine.o: $(hdrdir)/ruby/ruby.h ossl_engine.o: $(hdrdir)/ruby/st.h ossl_engine.o: $(hdrdir)/ruby/subst.h @@ -303,23 +1574,182 @@ ossl_engine.o: ossl_ocsp.h ossl_engine.o: ossl_pkcs12.h ossl_engine.o: ossl_pkcs7.h ossl_engine.o: ossl_pkey.h +ossl_engine.o: ossl_provider.h ossl_engine.o: ossl_rand.h ossl_engine.o: ossl_ssl.h -ossl_engine.o: ossl_version.h +ossl_engine.o: ossl_ts.h ossl_engine.o: ossl_x509.h -ossl_engine.o: ruby_missing.h ossl_hmac.o: $(RUBY_EXTCONF_H) ossl_hmac.o: $(arch_hdrdir)/ruby/config.h ossl_hmac.o: $(hdrdir)/ruby.h ossl_hmac.o: $(hdrdir)/ruby/assert.h ossl_hmac.o: $(hdrdir)/ruby/backward.h +ossl_hmac.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_hmac.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_hmac.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_hmac.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_hmac.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_hmac.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_hmac.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_hmac.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_hmac.o: $(hdrdir)/ruby/defines.h ossl_hmac.o: $(hdrdir)/ruby/encoding.h ossl_hmac.o: $(hdrdir)/ruby/intern.h +ossl_hmac.o: $(hdrdir)/ruby/internal/abi.h +ossl_hmac.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_hmac.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_hmac.o: $(hdrdir)/ruby/internal/assume.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_hmac.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_hmac.o: $(hdrdir)/ruby/internal/cast.h +ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_hmac.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_hmac.o: $(hdrdir)/ruby/internal/config.h +ossl_hmac.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_hmac.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_hmac.o: $(hdrdir)/ruby/internal/ctype.h +ossl_hmac.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_hmac.o: $(hdrdir)/ruby/internal/dosish.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_hmac.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_hmac.o: $(hdrdir)/ruby/internal/error.h +ossl_hmac.o: $(hdrdir)/ruby/internal/eval.h +ossl_hmac.o: $(hdrdir)/ruby/internal/event.h +ossl_hmac.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_hmac.o: $(hdrdir)/ruby/internal/gc.h +ossl_hmac.o: $(hdrdir)/ruby/internal/glob.h +ossl_hmac.o: $(hdrdir)/ruby/internal/globals.h +ossl_hmac.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_hmac.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_hmac.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_hmac.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_hmac.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_hmac.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_hmac.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_hmac.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_hmac.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_hmac.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_hmac.o: $(hdrdir)/ruby/internal/iterator.h +ossl_hmac.o: $(hdrdir)/ruby/internal/memory.h +ossl_hmac.o: $(hdrdir)/ruby/internal/method.h +ossl_hmac.o: $(hdrdir)/ruby/internal/module.h +ossl_hmac.o: $(hdrdir)/ruby/internal/newobj.h +ossl_hmac.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_hmac.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_hmac.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_hmac.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_hmac.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_hmac.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_hmac.o: $(hdrdir)/ruby/internal/symbol.h +ossl_hmac.o: $(hdrdir)/ruby/internal/value.h +ossl_hmac.o: $(hdrdir)/ruby/internal/value_type.h +ossl_hmac.o: $(hdrdir)/ruby/internal/variable.h +ossl_hmac.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_hmac.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_hmac.o: $(hdrdir)/ruby/io.h ossl_hmac.o: $(hdrdir)/ruby/missing.h ossl_hmac.o: $(hdrdir)/ruby/onigmo.h ossl_hmac.o: $(hdrdir)/ruby/oniguruma.h +ossl_hmac.o: $(hdrdir)/ruby/ractor.h ossl_hmac.o: $(hdrdir)/ruby/ruby.h ossl_hmac.o: $(hdrdir)/ruby/st.h ossl_hmac.o: $(hdrdir)/ruby/subst.h @@ -341,23 +1771,182 @@ ossl_hmac.o: ossl_ocsp.h ossl_hmac.o: ossl_pkcs12.h ossl_hmac.o: ossl_pkcs7.h ossl_hmac.o: ossl_pkey.h +ossl_hmac.o: ossl_provider.h ossl_hmac.o: ossl_rand.h ossl_hmac.o: ossl_ssl.h -ossl_hmac.o: ossl_version.h +ossl_hmac.o: ossl_ts.h ossl_hmac.o: ossl_x509.h -ossl_hmac.o: ruby_missing.h ossl_kdf.o: $(RUBY_EXTCONF_H) ossl_kdf.o: $(arch_hdrdir)/ruby/config.h ossl_kdf.o: $(hdrdir)/ruby.h ossl_kdf.o: $(hdrdir)/ruby/assert.h ossl_kdf.o: $(hdrdir)/ruby/backward.h +ossl_kdf.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_kdf.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_kdf.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_kdf.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_kdf.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_kdf.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_kdf.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_kdf.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_kdf.o: $(hdrdir)/ruby/defines.h ossl_kdf.o: $(hdrdir)/ruby/encoding.h ossl_kdf.o: $(hdrdir)/ruby/intern.h +ossl_kdf.o: $(hdrdir)/ruby/internal/abi.h +ossl_kdf.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_kdf.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_kdf.o: $(hdrdir)/ruby/internal/assume.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_kdf.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_kdf.o: $(hdrdir)/ruby/internal/cast.h +ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_kdf.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_kdf.o: $(hdrdir)/ruby/internal/config.h +ossl_kdf.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_kdf.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_kdf.o: $(hdrdir)/ruby/internal/ctype.h +ossl_kdf.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_kdf.o: $(hdrdir)/ruby/internal/dosish.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_kdf.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_kdf.o: $(hdrdir)/ruby/internal/error.h +ossl_kdf.o: $(hdrdir)/ruby/internal/eval.h +ossl_kdf.o: $(hdrdir)/ruby/internal/event.h +ossl_kdf.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_kdf.o: $(hdrdir)/ruby/internal/gc.h +ossl_kdf.o: $(hdrdir)/ruby/internal/glob.h +ossl_kdf.o: $(hdrdir)/ruby/internal/globals.h +ossl_kdf.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_kdf.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_kdf.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_kdf.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_kdf.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_kdf.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_kdf.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_kdf.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_kdf.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_kdf.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_kdf.o: $(hdrdir)/ruby/internal/iterator.h +ossl_kdf.o: $(hdrdir)/ruby/internal/memory.h +ossl_kdf.o: $(hdrdir)/ruby/internal/method.h +ossl_kdf.o: $(hdrdir)/ruby/internal/module.h +ossl_kdf.o: $(hdrdir)/ruby/internal/newobj.h +ossl_kdf.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_kdf.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_kdf.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_kdf.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_kdf.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_kdf.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_kdf.o: $(hdrdir)/ruby/internal/symbol.h +ossl_kdf.o: $(hdrdir)/ruby/internal/value.h +ossl_kdf.o: $(hdrdir)/ruby/internal/value_type.h +ossl_kdf.o: $(hdrdir)/ruby/internal/variable.h +ossl_kdf.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_kdf.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_kdf.o: $(hdrdir)/ruby/io.h ossl_kdf.o: $(hdrdir)/ruby/missing.h ossl_kdf.o: $(hdrdir)/ruby/onigmo.h ossl_kdf.o: $(hdrdir)/ruby/oniguruma.h +ossl_kdf.o: $(hdrdir)/ruby/ractor.h ossl_kdf.o: $(hdrdir)/ruby/ruby.h ossl_kdf.o: $(hdrdir)/ruby/st.h ossl_kdf.o: $(hdrdir)/ruby/subst.h @@ -379,23 +1968,182 @@ ossl_kdf.o: ossl_ocsp.h ossl_kdf.o: ossl_pkcs12.h ossl_kdf.o: ossl_pkcs7.h ossl_kdf.o: ossl_pkey.h +ossl_kdf.o: ossl_provider.h ossl_kdf.o: ossl_rand.h ossl_kdf.o: ossl_ssl.h -ossl_kdf.o: ossl_version.h +ossl_kdf.o: ossl_ts.h ossl_kdf.o: ossl_x509.h -ossl_kdf.o: ruby_missing.h ossl_ns_spki.o: $(RUBY_EXTCONF_H) ossl_ns_spki.o: $(arch_hdrdir)/ruby/config.h ossl_ns_spki.o: $(hdrdir)/ruby.h ossl_ns_spki.o: $(hdrdir)/ruby/assert.h ossl_ns_spki.o: $(hdrdir)/ruby/backward.h +ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_ns_spki.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ns_spki.o: $(hdrdir)/ruby/defines.h ossl_ns_spki.o: $(hdrdir)/ruby/encoding.h ossl_ns_spki.o: $(hdrdir)/ruby/intern.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/abi.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/assume.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/cast.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/config.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/ctype.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/dosish.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/error.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/eval.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/event.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/gc.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/glob.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/globals.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/iterator.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/memory.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/method.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/module.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/newobj.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/symbol.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/value.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/value_type.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/variable.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_ns_spki.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_ns_spki.o: $(hdrdir)/ruby/io.h ossl_ns_spki.o: $(hdrdir)/ruby/missing.h ossl_ns_spki.o: $(hdrdir)/ruby/onigmo.h ossl_ns_spki.o: $(hdrdir)/ruby/oniguruma.h +ossl_ns_spki.o: $(hdrdir)/ruby/ractor.h ossl_ns_spki.o: $(hdrdir)/ruby/ruby.h ossl_ns_spki.o: $(hdrdir)/ruby/st.h ossl_ns_spki.o: $(hdrdir)/ruby/subst.h @@ -417,23 +2165,182 @@ ossl_ns_spki.o: ossl_ocsp.h ossl_ns_spki.o: ossl_pkcs12.h ossl_ns_spki.o: ossl_pkcs7.h ossl_ns_spki.o: ossl_pkey.h +ossl_ns_spki.o: ossl_provider.h ossl_ns_spki.o: ossl_rand.h ossl_ns_spki.o: ossl_ssl.h -ossl_ns_spki.o: ossl_version.h +ossl_ns_spki.o: ossl_ts.h ossl_ns_spki.o: ossl_x509.h -ossl_ns_spki.o: ruby_missing.h ossl_ocsp.o: $(RUBY_EXTCONF_H) ossl_ocsp.o: $(arch_hdrdir)/ruby/config.h ossl_ocsp.o: $(hdrdir)/ruby.h ossl_ocsp.o: $(hdrdir)/ruby/assert.h ossl_ocsp.o: $(hdrdir)/ruby/backward.h +ossl_ocsp.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_ocsp.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_ocsp.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_ocsp.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_ocsp.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_ocsp.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_ocsp.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_ocsp.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ocsp.o: $(hdrdir)/ruby/defines.h ossl_ocsp.o: $(hdrdir)/ruby/encoding.h ossl_ocsp.o: $(hdrdir)/ruby/intern.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/abi.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/assume.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/cast.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/config.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/ctype.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/dosish.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/error.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/eval.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/event.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/gc.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/glob.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/globals.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/iterator.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/memory.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/method.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/module.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/newobj.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/symbol.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/value.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/value_type.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/variable.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_ocsp.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_ocsp.o: $(hdrdir)/ruby/io.h ossl_ocsp.o: $(hdrdir)/ruby/missing.h ossl_ocsp.o: $(hdrdir)/ruby/onigmo.h ossl_ocsp.o: $(hdrdir)/ruby/oniguruma.h +ossl_ocsp.o: $(hdrdir)/ruby/ractor.h ossl_ocsp.o: $(hdrdir)/ruby/ruby.h ossl_ocsp.o: $(hdrdir)/ruby/st.h ossl_ocsp.o: $(hdrdir)/ruby/subst.h @@ -455,23 +2362,182 @@ ossl_ocsp.o: ossl_ocsp.h ossl_ocsp.o: ossl_pkcs12.h ossl_ocsp.o: ossl_pkcs7.h ossl_ocsp.o: ossl_pkey.h +ossl_ocsp.o: ossl_provider.h ossl_ocsp.o: ossl_rand.h ossl_ocsp.o: ossl_ssl.h -ossl_ocsp.o: ossl_version.h +ossl_ocsp.o: ossl_ts.h ossl_ocsp.o: ossl_x509.h -ossl_ocsp.o: ruby_missing.h ossl_pkcs12.o: $(RUBY_EXTCONF_H) ossl_pkcs12.o: $(arch_hdrdir)/ruby/config.h ossl_pkcs12.o: $(hdrdir)/ruby.h ossl_pkcs12.o: $(hdrdir)/ruby/assert.h ossl_pkcs12.o: $(hdrdir)/ruby/backward.h +ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_pkcs12.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkcs12.o: $(hdrdir)/ruby/defines.h ossl_pkcs12.o: $(hdrdir)/ruby/encoding.h ossl_pkcs12.o: $(hdrdir)/ruby/intern.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/abi.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/assume.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/cast.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/config.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/ctype.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/dosish.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/error.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/eval.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/event.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/gc.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/glob.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/globals.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/iterator.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/memory.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/method.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/module.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/newobj.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/symbol.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/value.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/value_type.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/variable.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_pkcs12.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_pkcs12.o: $(hdrdir)/ruby/io.h ossl_pkcs12.o: $(hdrdir)/ruby/missing.h ossl_pkcs12.o: $(hdrdir)/ruby/onigmo.h ossl_pkcs12.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkcs12.o: $(hdrdir)/ruby/ractor.h ossl_pkcs12.o: $(hdrdir)/ruby/ruby.h ossl_pkcs12.o: $(hdrdir)/ruby/st.h ossl_pkcs12.o: $(hdrdir)/ruby/subst.h @@ -493,23 +2559,182 @@ ossl_pkcs12.o: ossl_pkcs12.c ossl_pkcs12.o: ossl_pkcs12.h ossl_pkcs12.o: ossl_pkcs7.h ossl_pkcs12.o: ossl_pkey.h +ossl_pkcs12.o: ossl_provider.h ossl_pkcs12.o: ossl_rand.h ossl_pkcs12.o: ossl_ssl.h -ossl_pkcs12.o: ossl_version.h +ossl_pkcs12.o: ossl_ts.h ossl_pkcs12.o: ossl_x509.h -ossl_pkcs12.o: ruby_missing.h ossl_pkcs7.o: $(RUBY_EXTCONF_H) ossl_pkcs7.o: $(arch_hdrdir)/ruby/config.h ossl_pkcs7.o: $(hdrdir)/ruby.h ossl_pkcs7.o: $(hdrdir)/ruby/assert.h ossl_pkcs7.o: $(hdrdir)/ruby/backward.h +ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_pkcs7.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkcs7.o: $(hdrdir)/ruby/defines.h ossl_pkcs7.o: $(hdrdir)/ruby/encoding.h ossl_pkcs7.o: $(hdrdir)/ruby/intern.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/abi.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/assume.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/cast.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/config.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/ctype.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/dosish.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/error.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/eval.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/event.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/gc.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/glob.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/globals.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/iterator.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/memory.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/method.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/module.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/newobj.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/symbol.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/value.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/value_type.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/variable.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_pkcs7.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_pkcs7.o: $(hdrdir)/ruby/io.h ossl_pkcs7.o: $(hdrdir)/ruby/missing.h ossl_pkcs7.o: $(hdrdir)/ruby/onigmo.h ossl_pkcs7.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkcs7.o: $(hdrdir)/ruby/ractor.h ossl_pkcs7.o: $(hdrdir)/ruby/ruby.h ossl_pkcs7.o: $(hdrdir)/ruby/st.h ossl_pkcs7.o: $(hdrdir)/ruby/subst.h @@ -531,23 +2756,182 @@ ossl_pkcs7.o: ossl_pkcs12.h ossl_pkcs7.o: ossl_pkcs7.c ossl_pkcs7.o: ossl_pkcs7.h ossl_pkcs7.o: ossl_pkey.h +ossl_pkcs7.o: ossl_provider.h ossl_pkcs7.o: ossl_rand.h ossl_pkcs7.o: ossl_ssl.h -ossl_pkcs7.o: ossl_version.h +ossl_pkcs7.o: ossl_ts.h ossl_pkcs7.o: ossl_x509.h -ossl_pkcs7.o: ruby_missing.h ossl_pkey.o: $(RUBY_EXTCONF_H) ossl_pkey.o: $(arch_hdrdir)/ruby/config.h ossl_pkey.o: $(hdrdir)/ruby.h ossl_pkey.o: $(hdrdir)/ruby/assert.h ossl_pkey.o: $(hdrdir)/ruby/backward.h +ossl_pkey.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_pkey.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_pkey.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_pkey.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_pkey.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_pkey.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_pkey.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_pkey.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey.o: $(hdrdir)/ruby/defines.h ossl_pkey.o: $(hdrdir)/ruby/encoding.h ossl_pkey.o: $(hdrdir)/ruby/intern.h +ossl_pkey.o: $(hdrdir)/ruby/internal/abi.h +ossl_pkey.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_pkey.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_pkey.o: $(hdrdir)/ruby/internal/assume.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_pkey.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_pkey.o: $(hdrdir)/ruby/internal/cast.h +ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_pkey.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_pkey.o: $(hdrdir)/ruby/internal/config.h +ossl_pkey.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_pkey.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_pkey.o: $(hdrdir)/ruby/internal/ctype.h +ossl_pkey.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_pkey.o: $(hdrdir)/ruby/internal/dosish.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_pkey.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_pkey.o: $(hdrdir)/ruby/internal/error.h +ossl_pkey.o: $(hdrdir)/ruby/internal/eval.h +ossl_pkey.o: $(hdrdir)/ruby/internal/event.h +ossl_pkey.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_pkey.o: $(hdrdir)/ruby/internal/gc.h +ossl_pkey.o: $(hdrdir)/ruby/internal/glob.h +ossl_pkey.o: $(hdrdir)/ruby/internal/globals.h +ossl_pkey.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_pkey.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_pkey.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_pkey.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_pkey.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_pkey.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_pkey.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_pkey.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_pkey.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_pkey.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_pkey.o: $(hdrdir)/ruby/internal/iterator.h +ossl_pkey.o: $(hdrdir)/ruby/internal/memory.h +ossl_pkey.o: $(hdrdir)/ruby/internal/method.h +ossl_pkey.o: $(hdrdir)/ruby/internal/module.h +ossl_pkey.o: $(hdrdir)/ruby/internal/newobj.h +ossl_pkey.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_pkey.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_pkey.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_pkey.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_pkey.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_pkey.o: $(hdrdir)/ruby/internal/symbol.h +ossl_pkey.o: $(hdrdir)/ruby/internal/value.h +ossl_pkey.o: $(hdrdir)/ruby/internal/value_type.h +ossl_pkey.o: $(hdrdir)/ruby/internal/variable.h +ossl_pkey.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_pkey.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_pkey.o: $(hdrdir)/ruby/io.h ossl_pkey.o: $(hdrdir)/ruby/missing.h ossl_pkey.o: $(hdrdir)/ruby/onigmo.h ossl_pkey.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey.o: $(hdrdir)/ruby/ractor.h ossl_pkey.o: $(hdrdir)/ruby/ruby.h ossl_pkey.o: $(hdrdir)/ruby/st.h ossl_pkey.o: $(hdrdir)/ruby/subst.h @@ -569,23 +2953,182 @@ ossl_pkey.o: ossl_pkcs12.h ossl_pkey.o: ossl_pkcs7.h ossl_pkey.o: ossl_pkey.c ossl_pkey.o: ossl_pkey.h +ossl_pkey.o: ossl_provider.h ossl_pkey.o: ossl_rand.h ossl_pkey.o: ossl_ssl.h -ossl_pkey.o: ossl_version.h +ossl_pkey.o: ossl_ts.h ossl_pkey.o: ossl_x509.h -ossl_pkey.o: ruby_missing.h ossl_pkey_dh.o: $(RUBY_EXTCONF_H) ossl_pkey_dh.o: $(arch_hdrdir)/ruby/config.h ossl_pkey_dh.o: $(hdrdir)/ruby.h ossl_pkey_dh.o: $(hdrdir)/ruby/assert.h ossl_pkey_dh.o: $(hdrdir)/ruby/backward.h +ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_pkey_dh.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey_dh.o: $(hdrdir)/ruby/defines.h ossl_pkey_dh.o: $(hdrdir)/ruby/encoding.h ossl_pkey_dh.o: $(hdrdir)/ruby/intern.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/abi.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/assume.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/cast.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/config.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/ctype.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/dosish.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/error.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/eval.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/event.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/gc.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/glob.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/globals.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/iterator.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/memory.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/method.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/module.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/newobj.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/symbol.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/value.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/value_type.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/variable.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_pkey_dh.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_pkey_dh.o: $(hdrdir)/ruby/io.h ossl_pkey_dh.o: $(hdrdir)/ruby/missing.h ossl_pkey_dh.o: $(hdrdir)/ruby/onigmo.h ossl_pkey_dh.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey_dh.o: $(hdrdir)/ruby/ractor.h ossl_pkey_dh.o: $(hdrdir)/ruby/ruby.h ossl_pkey_dh.o: $(hdrdir)/ruby/st.h ossl_pkey_dh.o: $(hdrdir)/ruby/subst.h @@ -607,23 +3150,182 @@ ossl_pkey_dh.o: ossl_pkcs12.h ossl_pkey_dh.o: ossl_pkcs7.h ossl_pkey_dh.o: ossl_pkey.h ossl_pkey_dh.o: ossl_pkey_dh.c +ossl_pkey_dh.o: ossl_provider.h ossl_pkey_dh.o: ossl_rand.h ossl_pkey_dh.o: ossl_ssl.h -ossl_pkey_dh.o: ossl_version.h +ossl_pkey_dh.o: ossl_ts.h ossl_pkey_dh.o: ossl_x509.h -ossl_pkey_dh.o: ruby_missing.h ossl_pkey_dsa.o: $(RUBY_EXTCONF_H) ossl_pkey_dsa.o: $(arch_hdrdir)/ruby/config.h ossl_pkey_dsa.o: $(hdrdir)/ruby.h ossl_pkey_dsa.o: $(hdrdir)/ruby/assert.h ossl_pkey_dsa.o: $(hdrdir)/ruby/backward.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey_dsa.o: $(hdrdir)/ruby/defines.h ossl_pkey_dsa.o: $(hdrdir)/ruby/encoding.h ossl_pkey_dsa.o: $(hdrdir)/ruby/intern.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/abi.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/assume.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/cast.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/config.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/ctype.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/dosish.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/error.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/eval.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/event.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/gc.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/glob.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/globals.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/iterator.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/memory.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/method.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/module.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/newobj.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/symbol.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/value.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/value_type.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/variable.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_pkey_dsa.o: $(hdrdir)/ruby/io.h ossl_pkey_dsa.o: $(hdrdir)/ruby/missing.h ossl_pkey_dsa.o: $(hdrdir)/ruby/onigmo.h ossl_pkey_dsa.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey_dsa.o: $(hdrdir)/ruby/ractor.h ossl_pkey_dsa.o: $(hdrdir)/ruby/ruby.h ossl_pkey_dsa.o: $(hdrdir)/ruby/st.h ossl_pkey_dsa.o: $(hdrdir)/ruby/subst.h @@ -645,23 +3347,182 @@ ossl_pkey_dsa.o: ossl_pkcs12.h ossl_pkey_dsa.o: ossl_pkcs7.h ossl_pkey_dsa.o: ossl_pkey.h ossl_pkey_dsa.o: ossl_pkey_dsa.c +ossl_pkey_dsa.o: ossl_provider.h ossl_pkey_dsa.o: ossl_rand.h ossl_pkey_dsa.o: ossl_ssl.h -ossl_pkey_dsa.o: ossl_version.h +ossl_pkey_dsa.o: ossl_ts.h ossl_pkey_dsa.o: ossl_x509.h -ossl_pkey_dsa.o: ruby_missing.h ossl_pkey_ec.o: $(RUBY_EXTCONF_H) ossl_pkey_ec.o: $(arch_hdrdir)/ruby/config.h ossl_pkey_ec.o: $(hdrdir)/ruby.h ossl_pkey_ec.o: $(hdrdir)/ruby/assert.h ossl_pkey_ec.o: $(hdrdir)/ruby/backward.h +ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_pkey_ec.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey_ec.o: $(hdrdir)/ruby/defines.h ossl_pkey_ec.o: $(hdrdir)/ruby/encoding.h ossl_pkey_ec.o: $(hdrdir)/ruby/intern.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/abi.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/assume.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/cast.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/config.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/ctype.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/dosish.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/error.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/eval.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/event.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/gc.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/glob.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/globals.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/iterator.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/memory.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/method.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/module.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/newobj.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/symbol.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/value.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/value_type.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/variable.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_pkey_ec.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_pkey_ec.o: $(hdrdir)/ruby/io.h ossl_pkey_ec.o: $(hdrdir)/ruby/missing.h ossl_pkey_ec.o: $(hdrdir)/ruby/onigmo.h ossl_pkey_ec.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey_ec.o: $(hdrdir)/ruby/ractor.h ossl_pkey_ec.o: $(hdrdir)/ruby/ruby.h ossl_pkey_ec.o: $(hdrdir)/ruby/st.h ossl_pkey_ec.o: $(hdrdir)/ruby/subst.h @@ -683,23 +3544,182 @@ ossl_pkey_ec.o: ossl_pkcs12.h ossl_pkey_ec.o: ossl_pkcs7.h ossl_pkey_ec.o: ossl_pkey.h ossl_pkey_ec.o: ossl_pkey_ec.c +ossl_pkey_ec.o: ossl_provider.h ossl_pkey_ec.o: ossl_rand.h ossl_pkey_ec.o: ossl_ssl.h -ossl_pkey_ec.o: ossl_version.h +ossl_pkey_ec.o: ossl_ts.h ossl_pkey_ec.o: ossl_x509.h -ossl_pkey_ec.o: ruby_missing.h ossl_pkey_rsa.o: $(RUBY_EXTCONF_H) ossl_pkey_rsa.o: $(arch_hdrdir)/ruby/config.h ossl_pkey_rsa.o: $(hdrdir)/ruby.h ossl_pkey_rsa.o: $(hdrdir)/ruby/assert.h ossl_pkey_rsa.o: $(hdrdir)/ruby/backward.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_pkey_rsa.o: $(hdrdir)/ruby/defines.h ossl_pkey_rsa.o: $(hdrdir)/ruby/encoding.h ossl_pkey_rsa.o: $(hdrdir)/ruby/intern.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/abi.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/assume.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/cast.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/config.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/ctype.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/dosish.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/error.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/eval.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/event.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/gc.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/glob.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/globals.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/iterator.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/memory.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/method.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/module.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/newobj.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/symbol.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/value.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/value_type.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/variable.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_pkey_rsa.o: $(hdrdir)/ruby/io.h ossl_pkey_rsa.o: $(hdrdir)/ruby/missing.h ossl_pkey_rsa.o: $(hdrdir)/ruby/onigmo.h ossl_pkey_rsa.o: $(hdrdir)/ruby/oniguruma.h +ossl_pkey_rsa.o: $(hdrdir)/ruby/ractor.h ossl_pkey_rsa.o: $(hdrdir)/ruby/ruby.h ossl_pkey_rsa.o: $(hdrdir)/ruby/st.h ossl_pkey_rsa.o: $(hdrdir)/ruby/subst.h @@ -721,23 +3741,379 @@ ossl_pkey_rsa.o: ossl_pkcs12.h ossl_pkey_rsa.o: ossl_pkcs7.h ossl_pkey_rsa.o: ossl_pkey.h ossl_pkey_rsa.o: ossl_pkey_rsa.c +ossl_pkey_rsa.o: ossl_provider.h ossl_pkey_rsa.o: ossl_rand.h ossl_pkey_rsa.o: ossl_ssl.h -ossl_pkey_rsa.o: ossl_version.h +ossl_pkey_rsa.o: ossl_ts.h ossl_pkey_rsa.o: ossl_x509.h -ossl_pkey_rsa.o: ruby_missing.h +ossl_provider.o: $(RUBY_EXTCONF_H) +ossl_provider.o: $(arch_hdrdir)/ruby/config.h +ossl_provider.o: $(hdrdir)/ruby.h +ossl_provider.o: $(hdrdir)/ruby/assert.h +ossl_provider.o: $(hdrdir)/ruby/backward.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_provider.o: $(hdrdir)/ruby/backward/2/stdarg.h +ossl_provider.o: $(hdrdir)/ruby/defines.h +ossl_provider.o: $(hdrdir)/ruby/encoding.h +ossl_provider.o: $(hdrdir)/ruby/intern.h +ossl_provider.o: $(hdrdir)/ruby/internal/abi.h +ossl_provider.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_provider.o: $(hdrdir)/ruby/internal/assume.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_provider.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_provider.o: $(hdrdir)/ruby/internal/cast.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_provider.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_provider.o: $(hdrdir)/ruby/internal/config.h +ossl_provider.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_provider.o: $(hdrdir)/ruby/internal/core.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_provider.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_provider.o: $(hdrdir)/ruby/internal/ctype.h +ossl_provider.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_provider.o: $(hdrdir)/ruby/internal/dosish.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_provider.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_provider.o: $(hdrdir)/ruby/internal/error.h +ossl_provider.o: $(hdrdir)/ruby/internal/eval.h +ossl_provider.o: $(hdrdir)/ruby/internal/event.h +ossl_provider.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_provider.o: $(hdrdir)/ruby/internal/gc.h +ossl_provider.o: $(hdrdir)/ruby/internal/glob.h +ossl_provider.o: $(hdrdir)/ruby/internal/globals.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_provider.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_provider.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_provider.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_provider.o: $(hdrdir)/ruby/internal/iterator.h +ossl_provider.o: $(hdrdir)/ruby/internal/memory.h +ossl_provider.o: $(hdrdir)/ruby/internal/method.h +ossl_provider.o: $(hdrdir)/ruby/internal/module.h +ossl_provider.o: $(hdrdir)/ruby/internal/newobj.h +ossl_provider.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_provider.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_provider.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_provider.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_provider.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_provider.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_provider.o: $(hdrdir)/ruby/internal/symbol.h +ossl_provider.o: $(hdrdir)/ruby/internal/value.h +ossl_provider.o: $(hdrdir)/ruby/internal/value_type.h +ossl_provider.o: $(hdrdir)/ruby/internal/variable.h +ossl_provider.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_provider.o: $(hdrdir)/ruby/internal/xmalloc.h +ossl_provider.o: $(hdrdir)/ruby/io.h +ossl_provider.o: $(hdrdir)/ruby/missing.h +ossl_provider.o: $(hdrdir)/ruby/onigmo.h +ossl_provider.o: $(hdrdir)/ruby/oniguruma.h +ossl_provider.o: $(hdrdir)/ruby/ractor.h +ossl_provider.o: $(hdrdir)/ruby/ruby.h +ossl_provider.o: $(hdrdir)/ruby/st.h +ossl_provider.o: $(hdrdir)/ruby/subst.h +ossl_provider.o: $(hdrdir)/ruby/thread.h +ossl_provider.o: openssl_missing.h +ossl_provider.o: ossl.h +ossl_provider.o: ossl_asn1.h +ossl_provider.o: ossl_bio.h +ossl_provider.o: ossl_bn.h +ossl_provider.o: ossl_cipher.h +ossl_provider.o: ossl_config.h +ossl_provider.o: ossl_digest.h +ossl_provider.o: ossl_engine.h +ossl_provider.o: ossl_hmac.h +ossl_provider.o: ossl_kdf.h +ossl_provider.o: ossl_ns_spki.h +ossl_provider.o: ossl_ocsp.h +ossl_provider.o: ossl_pkcs12.h +ossl_provider.o: ossl_pkcs7.h +ossl_provider.o: ossl_pkey.h +ossl_provider.o: ossl_provider.c +ossl_provider.o: ossl_provider.h +ossl_provider.o: ossl_rand.h +ossl_provider.o: ossl_ssl.h +ossl_provider.o: ossl_ts.h +ossl_provider.o: ossl_x509.h ossl_rand.o: $(RUBY_EXTCONF_H) ossl_rand.o: $(arch_hdrdir)/ruby/config.h ossl_rand.o: $(hdrdir)/ruby.h ossl_rand.o: $(hdrdir)/ruby/assert.h ossl_rand.o: $(hdrdir)/ruby/backward.h +ossl_rand.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_rand.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_rand.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_rand.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_rand.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_rand.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_rand.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_rand.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_rand.o: $(hdrdir)/ruby/defines.h ossl_rand.o: $(hdrdir)/ruby/encoding.h ossl_rand.o: $(hdrdir)/ruby/intern.h +ossl_rand.o: $(hdrdir)/ruby/internal/abi.h +ossl_rand.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_rand.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_rand.o: $(hdrdir)/ruby/internal/assume.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_rand.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_rand.o: $(hdrdir)/ruby/internal/cast.h +ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_rand.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_rand.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_rand.o: $(hdrdir)/ruby/internal/config.h +ossl_rand.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_rand.o: $(hdrdir)/ruby/internal/core.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_rand.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_rand.o: $(hdrdir)/ruby/internal/ctype.h +ossl_rand.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_rand.o: $(hdrdir)/ruby/internal/dosish.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_rand.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_rand.o: $(hdrdir)/ruby/internal/error.h +ossl_rand.o: $(hdrdir)/ruby/internal/eval.h +ossl_rand.o: $(hdrdir)/ruby/internal/event.h +ossl_rand.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_rand.o: $(hdrdir)/ruby/internal/gc.h +ossl_rand.o: $(hdrdir)/ruby/internal/glob.h +ossl_rand.o: $(hdrdir)/ruby/internal/globals.h +ossl_rand.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_rand.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_rand.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_rand.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_rand.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_rand.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_rand.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_rand.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_rand.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_rand.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_rand.o: $(hdrdir)/ruby/internal/iterator.h +ossl_rand.o: $(hdrdir)/ruby/internal/memory.h +ossl_rand.o: $(hdrdir)/ruby/internal/method.h +ossl_rand.o: $(hdrdir)/ruby/internal/module.h +ossl_rand.o: $(hdrdir)/ruby/internal/newobj.h +ossl_rand.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_rand.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_rand.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_rand.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_rand.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_rand.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_rand.o: $(hdrdir)/ruby/internal/symbol.h +ossl_rand.o: $(hdrdir)/ruby/internal/value.h +ossl_rand.o: $(hdrdir)/ruby/internal/value_type.h +ossl_rand.o: $(hdrdir)/ruby/internal/variable.h +ossl_rand.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_rand.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_rand.o: $(hdrdir)/ruby/io.h ossl_rand.o: $(hdrdir)/ruby/missing.h ossl_rand.o: $(hdrdir)/ruby/onigmo.h ossl_rand.o: $(hdrdir)/ruby/oniguruma.h +ossl_rand.o: $(hdrdir)/ruby/ractor.h ossl_rand.o: $(hdrdir)/ruby/ruby.h ossl_rand.o: $(hdrdir)/ruby/st.h ossl_rand.o: $(hdrdir)/ruby/subst.h @@ -758,24 +4134,183 @@ ossl_rand.o: ossl_ocsp.h ossl_rand.o: ossl_pkcs12.h ossl_rand.o: ossl_pkcs7.h ossl_rand.o: ossl_pkey.h +ossl_rand.o: ossl_provider.h ossl_rand.o: ossl_rand.c ossl_rand.o: ossl_rand.h ossl_rand.o: ossl_ssl.h -ossl_rand.o: ossl_version.h +ossl_rand.o: ossl_ts.h ossl_rand.o: ossl_x509.h -ossl_rand.o: ruby_missing.h ossl_ssl.o: $(RUBY_EXTCONF_H) ossl_ssl.o: $(arch_hdrdir)/ruby/config.h ossl_ssl.o: $(hdrdir)/ruby.h ossl_ssl.o: $(hdrdir)/ruby/assert.h ossl_ssl.o: $(hdrdir)/ruby/backward.h +ossl_ssl.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_ssl.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_ssl.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_ssl.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_ssl.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_ssl.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_ssl.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_ssl.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ssl.o: $(hdrdir)/ruby/defines.h ossl_ssl.o: $(hdrdir)/ruby/encoding.h ossl_ssl.o: $(hdrdir)/ruby/intern.h +ossl_ssl.o: $(hdrdir)/ruby/internal/abi.h +ossl_ssl.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_ssl.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_ssl.o: $(hdrdir)/ruby/internal/assume.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_ssl.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_ssl.o: $(hdrdir)/ruby/internal/cast.h +ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_ssl.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_ssl.o: $(hdrdir)/ruby/internal/config.h +ossl_ssl.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_ssl.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_ssl.o: $(hdrdir)/ruby/internal/ctype.h +ossl_ssl.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_ssl.o: $(hdrdir)/ruby/internal/dosish.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_ssl.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_ssl.o: $(hdrdir)/ruby/internal/error.h +ossl_ssl.o: $(hdrdir)/ruby/internal/eval.h +ossl_ssl.o: $(hdrdir)/ruby/internal/event.h +ossl_ssl.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_ssl.o: $(hdrdir)/ruby/internal/gc.h +ossl_ssl.o: $(hdrdir)/ruby/internal/glob.h +ossl_ssl.o: $(hdrdir)/ruby/internal/globals.h +ossl_ssl.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_ssl.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_ssl.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_ssl.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_ssl.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_ssl.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_ssl.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_ssl.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_ssl.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_ssl.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_ssl.o: $(hdrdir)/ruby/internal/iterator.h +ossl_ssl.o: $(hdrdir)/ruby/internal/memory.h +ossl_ssl.o: $(hdrdir)/ruby/internal/method.h +ossl_ssl.o: $(hdrdir)/ruby/internal/module.h +ossl_ssl.o: $(hdrdir)/ruby/internal/newobj.h +ossl_ssl.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_ssl.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_ssl.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_ssl.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_ssl.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ssl.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_ssl.o: $(hdrdir)/ruby/internal/symbol.h +ossl_ssl.o: $(hdrdir)/ruby/internal/value.h +ossl_ssl.o: $(hdrdir)/ruby/internal/value_type.h +ossl_ssl.o: $(hdrdir)/ruby/internal/variable.h +ossl_ssl.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_ssl.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_ssl.o: $(hdrdir)/ruby/io.h ossl_ssl.o: $(hdrdir)/ruby/missing.h ossl_ssl.o: $(hdrdir)/ruby/onigmo.h ossl_ssl.o: $(hdrdir)/ruby/oniguruma.h +ossl_ssl.o: $(hdrdir)/ruby/ractor.h ossl_ssl.o: $(hdrdir)/ruby/ruby.h ossl_ssl.o: $(hdrdir)/ruby/st.h ossl_ssl.o: $(hdrdir)/ruby/subst.h @@ -796,24 +4331,183 @@ ossl_ssl.o: ossl_ocsp.h ossl_ssl.o: ossl_pkcs12.h ossl_ssl.o: ossl_pkcs7.h ossl_ssl.o: ossl_pkey.h +ossl_ssl.o: ossl_provider.h ossl_ssl.o: ossl_rand.h ossl_ssl.o: ossl_ssl.c ossl_ssl.o: ossl_ssl.h -ossl_ssl.o: ossl_version.h +ossl_ssl.o: ossl_ts.h ossl_ssl.o: ossl_x509.h -ossl_ssl.o: ruby_missing.h ossl_ssl_session.o: $(RUBY_EXTCONF_H) ossl_ssl_session.o: $(arch_hdrdir)/ruby/config.h ossl_ssl_session.o: $(hdrdir)/ruby.h ossl_ssl_session.o: $(hdrdir)/ruby/assert.h ossl_ssl_session.o: $(hdrdir)/ruby/backward.h +ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_ssl_session.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_ssl_session.o: $(hdrdir)/ruby/defines.h ossl_ssl_session.o: $(hdrdir)/ruby/encoding.h ossl_ssl_session.o: $(hdrdir)/ruby/intern.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/abi.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/assume.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/cast.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/config.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/ctype.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/dosish.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/error.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/eval.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/event.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/gc.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/glob.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/globals.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/iterator.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/memory.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/method.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/module.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/newobj.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/symbol.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/value.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/value_type.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/variable.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_ssl_session.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_ssl_session.o: $(hdrdir)/ruby/io.h ossl_ssl_session.o: $(hdrdir)/ruby/missing.h ossl_ssl_session.o: $(hdrdir)/ruby/onigmo.h ossl_ssl_session.o: $(hdrdir)/ruby/oniguruma.h +ossl_ssl_session.o: $(hdrdir)/ruby/ractor.h ossl_ssl_session.o: $(hdrdir)/ruby/ruby.h ossl_ssl_session.o: $(hdrdir)/ruby/st.h ossl_ssl_session.o: $(hdrdir)/ruby/subst.h @@ -834,24 +4528,380 @@ ossl_ssl_session.o: ossl_ocsp.h ossl_ssl_session.o: ossl_pkcs12.h ossl_ssl_session.o: ossl_pkcs7.h ossl_ssl_session.o: ossl_pkey.h +ossl_ssl_session.o: ossl_provider.h ossl_ssl_session.o: ossl_rand.h ossl_ssl_session.o: ossl_ssl.h ossl_ssl_session.o: ossl_ssl_session.c -ossl_ssl_session.o: ossl_version.h +ossl_ssl_session.o: ossl_ts.h ossl_ssl_session.o: ossl_x509.h -ossl_ssl_session.o: ruby_missing.h +ossl_ts.o: $(RUBY_EXTCONF_H) +ossl_ts.o: $(arch_hdrdir)/ruby/config.h +ossl_ts.o: $(hdrdir)/ruby.h +ossl_ts.o: $(hdrdir)/ruby/assert.h +ossl_ts.o: $(hdrdir)/ruby/backward.h +ossl_ts.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_ts.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_ts.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_ts.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_ts.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_ts.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_ts.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_ts.o: $(hdrdir)/ruby/backward/2/stdarg.h +ossl_ts.o: $(hdrdir)/ruby/defines.h +ossl_ts.o: $(hdrdir)/ruby/encoding.h +ossl_ts.o: $(hdrdir)/ruby/intern.h +ossl_ts.o: $(hdrdir)/ruby/internal/abi.h +ossl_ts.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_ts.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_ts.o: $(hdrdir)/ruby/internal/assume.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_ts.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_ts.o: $(hdrdir)/ruby/internal/cast.h +ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_ts.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_ts.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_ts.o: $(hdrdir)/ruby/internal/config.h +ossl_ts.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_ts.o: $(hdrdir)/ruby/internal/core.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_ts.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_ts.o: $(hdrdir)/ruby/internal/ctype.h +ossl_ts.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_ts.o: $(hdrdir)/ruby/internal/dosish.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_ts.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_ts.o: $(hdrdir)/ruby/internal/error.h +ossl_ts.o: $(hdrdir)/ruby/internal/eval.h +ossl_ts.o: $(hdrdir)/ruby/internal/event.h +ossl_ts.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_ts.o: $(hdrdir)/ruby/internal/gc.h +ossl_ts.o: $(hdrdir)/ruby/internal/glob.h +ossl_ts.o: $(hdrdir)/ruby/internal/globals.h +ossl_ts.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_ts.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_ts.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_ts.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_ts.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_ts.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_ts.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_ts.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_ts.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_ts.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_ts.o: $(hdrdir)/ruby/internal/iterator.h +ossl_ts.o: $(hdrdir)/ruby/internal/memory.h +ossl_ts.o: $(hdrdir)/ruby/internal/method.h +ossl_ts.o: $(hdrdir)/ruby/internal/module.h +ossl_ts.o: $(hdrdir)/ruby/internal/newobj.h +ossl_ts.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_ts.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_ts.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_ts.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_ts.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_ts.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_ts.o: $(hdrdir)/ruby/internal/symbol.h +ossl_ts.o: $(hdrdir)/ruby/internal/value.h +ossl_ts.o: $(hdrdir)/ruby/internal/value_type.h +ossl_ts.o: $(hdrdir)/ruby/internal/variable.h +ossl_ts.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_ts.o: $(hdrdir)/ruby/internal/xmalloc.h +ossl_ts.o: $(hdrdir)/ruby/io.h +ossl_ts.o: $(hdrdir)/ruby/missing.h +ossl_ts.o: $(hdrdir)/ruby/onigmo.h +ossl_ts.o: $(hdrdir)/ruby/oniguruma.h +ossl_ts.o: $(hdrdir)/ruby/ractor.h +ossl_ts.o: $(hdrdir)/ruby/ruby.h +ossl_ts.o: $(hdrdir)/ruby/st.h +ossl_ts.o: $(hdrdir)/ruby/subst.h +ossl_ts.o: $(hdrdir)/ruby/thread.h +ossl_ts.o: openssl_missing.h +ossl_ts.o: ossl.h +ossl_ts.o: ossl_asn1.h +ossl_ts.o: ossl_bio.h +ossl_ts.o: ossl_bn.h +ossl_ts.o: ossl_cipher.h +ossl_ts.o: ossl_config.h +ossl_ts.o: ossl_digest.h +ossl_ts.o: ossl_engine.h +ossl_ts.o: ossl_hmac.h +ossl_ts.o: ossl_kdf.h +ossl_ts.o: ossl_ns_spki.h +ossl_ts.o: ossl_ocsp.h +ossl_ts.o: ossl_pkcs12.h +ossl_ts.o: ossl_pkcs7.h +ossl_ts.o: ossl_pkey.h +ossl_ts.o: ossl_provider.h +ossl_ts.o: ossl_rand.h +ossl_ts.o: ossl_ssl.h +ossl_ts.o: ossl_ts.c +ossl_ts.o: ossl_ts.h +ossl_ts.o: ossl_x509.h ossl_x509.o: $(RUBY_EXTCONF_H) ossl_x509.o: $(arch_hdrdir)/ruby/config.h ossl_x509.o: $(hdrdir)/ruby.h ossl_x509.o: $(hdrdir)/ruby/assert.h ossl_x509.o: $(hdrdir)/ruby/backward.h +ossl_x509.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509.o: $(hdrdir)/ruby/defines.h ossl_x509.o: $(hdrdir)/ruby/encoding.h ossl_x509.o: $(hdrdir)/ruby/intern.h +ossl_x509.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509.o: $(hdrdir)/ruby/internal/config.h +ossl_x509.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509.o: $(hdrdir)/ruby/internal/core.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509.o: $(hdrdir)/ruby/internal/error.h +ossl_x509.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509.o: $(hdrdir)/ruby/internal/event.h +ossl_x509.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509.o: $(hdrdir)/ruby/internal/method.h +ossl_x509.o: $(hdrdir)/ruby/internal/module.h +ossl_x509.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509.o: $(hdrdir)/ruby/internal/value.h +ossl_x509.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509.o: $(hdrdir)/ruby/io.h ossl_x509.o: $(hdrdir)/ruby/missing.h ossl_x509.o: $(hdrdir)/ruby/onigmo.h ossl_x509.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509.o: $(hdrdir)/ruby/ractor.h ossl_x509.o: $(hdrdir)/ruby/ruby.h ossl_x509.o: $(hdrdir)/ruby/st.h ossl_x509.o: $(hdrdir)/ruby/subst.h @@ -872,24 +4922,183 @@ ossl_x509.o: ossl_ocsp.h ossl_x509.o: ossl_pkcs12.h ossl_x509.o: ossl_pkcs7.h ossl_x509.o: ossl_pkey.h +ossl_x509.o: ossl_provider.h ossl_x509.o: ossl_rand.h ossl_x509.o: ossl_ssl.h -ossl_x509.o: ossl_version.h +ossl_x509.o: ossl_ts.h ossl_x509.o: ossl_x509.c ossl_x509.o: ossl_x509.h -ossl_x509.o: ruby_missing.h ossl_x509attr.o: $(RUBY_EXTCONF_H) ossl_x509attr.o: $(arch_hdrdir)/ruby/config.h ossl_x509attr.o: $(hdrdir)/ruby.h ossl_x509attr.o: $(hdrdir)/ruby/assert.h ossl_x509attr.o: $(hdrdir)/ruby/backward.h +ossl_x509attr.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509attr.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509attr.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509attr.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509attr.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509attr.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509attr.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509attr.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509attr.o: $(hdrdir)/ruby/defines.h ossl_x509attr.o: $(hdrdir)/ruby/encoding.h ossl_x509attr.o: $(hdrdir)/ruby/intern.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/config.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/error.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/event.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/method.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/module.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/value.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509attr.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509attr.o: $(hdrdir)/ruby/io.h ossl_x509attr.o: $(hdrdir)/ruby/missing.h ossl_x509attr.o: $(hdrdir)/ruby/onigmo.h ossl_x509attr.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509attr.o: $(hdrdir)/ruby/ractor.h ossl_x509attr.o: $(hdrdir)/ruby/ruby.h ossl_x509attr.o: $(hdrdir)/ruby/st.h ossl_x509attr.o: $(hdrdir)/ruby/subst.h @@ -910,24 +5119,183 @@ ossl_x509attr.o: ossl_ocsp.h ossl_x509attr.o: ossl_pkcs12.h ossl_x509attr.o: ossl_pkcs7.h ossl_x509attr.o: ossl_pkey.h +ossl_x509attr.o: ossl_provider.h ossl_x509attr.o: ossl_rand.h ossl_x509attr.o: ossl_ssl.h -ossl_x509attr.o: ossl_version.h +ossl_x509attr.o: ossl_ts.h ossl_x509attr.o: ossl_x509.h ossl_x509attr.o: ossl_x509attr.c -ossl_x509attr.o: ruby_missing.h ossl_x509cert.o: $(RUBY_EXTCONF_H) ossl_x509cert.o: $(arch_hdrdir)/ruby/config.h ossl_x509cert.o: $(hdrdir)/ruby.h ossl_x509cert.o: $(hdrdir)/ruby/assert.h ossl_x509cert.o: $(hdrdir)/ruby/backward.h +ossl_x509cert.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509cert.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509cert.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509cert.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509cert.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509cert.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509cert.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509cert.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509cert.o: $(hdrdir)/ruby/defines.h ossl_x509cert.o: $(hdrdir)/ruby/encoding.h ossl_x509cert.o: $(hdrdir)/ruby/intern.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/config.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/error.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/event.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/method.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/module.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/value.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509cert.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509cert.o: $(hdrdir)/ruby/io.h ossl_x509cert.o: $(hdrdir)/ruby/missing.h ossl_x509cert.o: $(hdrdir)/ruby/onigmo.h ossl_x509cert.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509cert.o: $(hdrdir)/ruby/ractor.h ossl_x509cert.o: $(hdrdir)/ruby/ruby.h ossl_x509cert.o: $(hdrdir)/ruby/st.h ossl_x509cert.o: $(hdrdir)/ruby/subst.h @@ -948,24 +5316,183 @@ ossl_x509cert.o: ossl_ocsp.h ossl_x509cert.o: ossl_pkcs12.h ossl_x509cert.o: ossl_pkcs7.h ossl_x509cert.o: ossl_pkey.h +ossl_x509cert.o: ossl_provider.h ossl_x509cert.o: ossl_rand.h ossl_x509cert.o: ossl_ssl.h -ossl_x509cert.o: ossl_version.h +ossl_x509cert.o: ossl_ts.h ossl_x509cert.o: ossl_x509.h ossl_x509cert.o: ossl_x509cert.c -ossl_x509cert.o: ruby_missing.h ossl_x509crl.o: $(RUBY_EXTCONF_H) ossl_x509crl.o: $(arch_hdrdir)/ruby/config.h ossl_x509crl.o: $(hdrdir)/ruby.h ossl_x509crl.o: $(hdrdir)/ruby/assert.h ossl_x509crl.o: $(hdrdir)/ruby/backward.h +ossl_x509crl.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509crl.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509crl.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509crl.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509crl.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509crl.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509crl.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509crl.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509crl.o: $(hdrdir)/ruby/defines.h ossl_x509crl.o: $(hdrdir)/ruby/encoding.h ossl_x509crl.o: $(hdrdir)/ruby/intern.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/config.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/error.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/event.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/method.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/module.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/value.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509crl.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509crl.o: $(hdrdir)/ruby/io.h ossl_x509crl.o: $(hdrdir)/ruby/missing.h ossl_x509crl.o: $(hdrdir)/ruby/onigmo.h ossl_x509crl.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509crl.o: $(hdrdir)/ruby/ractor.h ossl_x509crl.o: $(hdrdir)/ruby/ruby.h ossl_x509crl.o: $(hdrdir)/ruby/st.h ossl_x509crl.o: $(hdrdir)/ruby/subst.h @@ -986,24 +5513,183 @@ ossl_x509crl.o: ossl_ocsp.h ossl_x509crl.o: ossl_pkcs12.h ossl_x509crl.o: ossl_pkcs7.h ossl_x509crl.o: ossl_pkey.h +ossl_x509crl.o: ossl_provider.h ossl_x509crl.o: ossl_rand.h ossl_x509crl.o: ossl_ssl.h -ossl_x509crl.o: ossl_version.h +ossl_x509crl.o: ossl_ts.h ossl_x509crl.o: ossl_x509.h ossl_x509crl.o: ossl_x509crl.c -ossl_x509crl.o: ruby_missing.h ossl_x509ext.o: $(RUBY_EXTCONF_H) ossl_x509ext.o: $(arch_hdrdir)/ruby/config.h ossl_x509ext.o: $(hdrdir)/ruby.h ossl_x509ext.o: $(hdrdir)/ruby/assert.h ossl_x509ext.o: $(hdrdir)/ruby/backward.h +ossl_x509ext.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509ext.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509ext.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509ext.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509ext.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509ext.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509ext.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509ext.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509ext.o: $(hdrdir)/ruby/defines.h ossl_x509ext.o: $(hdrdir)/ruby/encoding.h ossl_x509ext.o: $(hdrdir)/ruby/intern.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/config.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/error.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/event.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/method.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/module.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/value.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509ext.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509ext.o: $(hdrdir)/ruby/io.h ossl_x509ext.o: $(hdrdir)/ruby/missing.h ossl_x509ext.o: $(hdrdir)/ruby/onigmo.h ossl_x509ext.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509ext.o: $(hdrdir)/ruby/ractor.h ossl_x509ext.o: $(hdrdir)/ruby/ruby.h ossl_x509ext.o: $(hdrdir)/ruby/st.h ossl_x509ext.o: $(hdrdir)/ruby/subst.h @@ -1024,24 +5710,183 @@ ossl_x509ext.o: ossl_ocsp.h ossl_x509ext.o: ossl_pkcs12.h ossl_x509ext.o: ossl_pkcs7.h ossl_x509ext.o: ossl_pkey.h +ossl_x509ext.o: ossl_provider.h ossl_x509ext.o: ossl_rand.h ossl_x509ext.o: ossl_ssl.h -ossl_x509ext.o: ossl_version.h +ossl_x509ext.o: ossl_ts.h ossl_x509ext.o: ossl_x509.h ossl_x509ext.o: ossl_x509ext.c -ossl_x509ext.o: ruby_missing.h ossl_x509name.o: $(RUBY_EXTCONF_H) ossl_x509name.o: $(arch_hdrdir)/ruby/config.h ossl_x509name.o: $(hdrdir)/ruby.h ossl_x509name.o: $(hdrdir)/ruby/assert.h ossl_x509name.o: $(hdrdir)/ruby/backward.h +ossl_x509name.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509name.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509name.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509name.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509name.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509name.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509name.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509name.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509name.o: $(hdrdir)/ruby/defines.h ossl_x509name.o: $(hdrdir)/ruby/encoding.h ossl_x509name.o: $(hdrdir)/ruby/intern.h +ossl_x509name.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509name.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509name.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509name.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509name.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509name.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509name.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509name.o: $(hdrdir)/ruby/internal/config.h +ossl_x509name.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509name.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509name.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509name.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509name.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509name.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509name.o: $(hdrdir)/ruby/internal/error.h +ossl_x509name.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509name.o: $(hdrdir)/ruby/internal/event.h +ossl_x509name.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509name.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509name.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509name.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509name.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509name.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509name.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509name.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509name.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509name.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509name.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509name.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509name.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509name.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509name.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509name.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509name.o: $(hdrdir)/ruby/internal/method.h +ossl_x509name.o: $(hdrdir)/ruby/internal/module.h +ossl_x509name.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509name.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509name.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509name.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509name.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509name.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509name.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509name.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509name.o: $(hdrdir)/ruby/internal/value.h +ossl_x509name.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509name.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509name.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509name.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509name.o: $(hdrdir)/ruby/io.h ossl_x509name.o: $(hdrdir)/ruby/missing.h ossl_x509name.o: $(hdrdir)/ruby/onigmo.h ossl_x509name.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509name.o: $(hdrdir)/ruby/ractor.h ossl_x509name.o: $(hdrdir)/ruby/ruby.h ossl_x509name.o: $(hdrdir)/ruby/st.h ossl_x509name.o: $(hdrdir)/ruby/subst.h @@ -1062,24 +5907,183 @@ ossl_x509name.o: ossl_ocsp.h ossl_x509name.o: ossl_pkcs12.h ossl_x509name.o: ossl_pkcs7.h ossl_x509name.o: ossl_pkey.h +ossl_x509name.o: ossl_provider.h ossl_x509name.o: ossl_rand.h ossl_x509name.o: ossl_ssl.h -ossl_x509name.o: ossl_version.h +ossl_x509name.o: ossl_ts.h ossl_x509name.o: ossl_x509.h ossl_x509name.o: ossl_x509name.c -ossl_x509name.o: ruby_missing.h ossl_x509req.o: $(RUBY_EXTCONF_H) ossl_x509req.o: $(arch_hdrdir)/ruby/config.h ossl_x509req.o: $(hdrdir)/ruby.h ossl_x509req.o: $(hdrdir)/ruby/assert.h ossl_x509req.o: $(hdrdir)/ruby/backward.h +ossl_x509req.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509req.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509req.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509req.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509req.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509req.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509req.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509req.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509req.o: $(hdrdir)/ruby/defines.h ossl_x509req.o: $(hdrdir)/ruby/encoding.h ossl_x509req.o: $(hdrdir)/ruby/intern.h +ossl_x509req.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509req.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509req.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509req.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509req.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509req.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509req.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509req.o: $(hdrdir)/ruby/internal/config.h +ossl_x509req.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509req.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509req.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509req.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509req.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509req.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509req.o: $(hdrdir)/ruby/internal/error.h +ossl_x509req.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509req.o: $(hdrdir)/ruby/internal/event.h +ossl_x509req.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509req.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509req.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509req.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509req.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509req.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509req.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509req.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509req.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509req.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509req.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509req.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509req.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509req.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509req.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509req.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509req.o: $(hdrdir)/ruby/internal/method.h +ossl_x509req.o: $(hdrdir)/ruby/internal/module.h +ossl_x509req.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509req.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509req.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509req.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509req.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509req.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509req.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509req.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509req.o: $(hdrdir)/ruby/internal/value.h +ossl_x509req.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509req.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509req.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509req.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509req.o: $(hdrdir)/ruby/io.h ossl_x509req.o: $(hdrdir)/ruby/missing.h ossl_x509req.o: $(hdrdir)/ruby/onigmo.h ossl_x509req.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509req.o: $(hdrdir)/ruby/ractor.h ossl_x509req.o: $(hdrdir)/ruby/ruby.h ossl_x509req.o: $(hdrdir)/ruby/st.h ossl_x509req.o: $(hdrdir)/ruby/subst.h @@ -1100,24 +6104,183 @@ ossl_x509req.o: ossl_ocsp.h ossl_x509req.o: ossl_pkcs12.h ossl_x509req.o: ossl_pkcs7.h ossl_x509req.o: ossl_pkey.h +ossl_x509req.o: ossl_provider.h ossl_x509req.o: ossl_rand.h ossl_x509req.o: ossl_ssl.h -ossl_x509req.o: ossl_version.h +ossl_x509req.o: ossl_ts.h ossl_x509req.o: ossl_x509.h ossl_x509req.o: ossl_x509req.c -ossl_x509req.o: ruby_missing.h ossl_x509revoked.o: $(RUBY_EXTCONF_H) ossl_x509revoked.o: $(arch_hdrdir)/ruby/config.h ossl_x509revoked.o: $(hdrdir)/ruby.h ossl_x509revoked.o: $(hdrdir)/ruby/assert.h ossl_x509revoked.o: $(hdrdir)/ruby/backward.h +ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509revoked.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509revoked.o: $(hdrdir)/ruby/defines.h ossl_x509revoked.o: $(hdrdir)/ruby/encoding.h ossl_x509revoked.o: $(hdrdir)/ruby/intern.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/config.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/error.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/event.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/method.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/module.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/value.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509revoked.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509revoked.o: $(hdrdir)/ruby/io.h ossl_x509revoked.o: $(hdrdir)/ruby/missing.h ossl_x509revoked.o: $(hdrdir)/ruby/onigmo.h ossl_x509revoked.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509revoked.o: $(hdrdir)/ruby/ractor.h ossl_x509revoked.o: $(hdrdir)/ruby/ruby.h ossl_x509revoked.o: $(hdrdir)/ruby/st.h ossl_x509revoked.o: $(hdrdir)/ruby/subst.h @@ -1138,24 +6301,183 @@ ossl_x509revoked.o: ossl_ocsp.h ossl_x509revoked.o: ossl_pkcs12.h ossl_x509revoked.o: ossl_pkcs7.h ossl_x509revoked.o: ossl_pkey.h +ossl_x509revoked.o: ossl_provider.h ossl_x509revoked.o: ossl_rand.h ossl_x509revoked.o: ossl_ssl.h -ossl_x509revoked.o: ossl_version.h +ossl_x509revoked.o: ossl_ts.h ossl_x509revoked.o: ossl_x509.h ossl_x509revoked.o: ossl_x509revoked.c -ossl_x509revoked.o: ruby_missing.h ossl_x509store.o: $(RUBY_EXTCONF_H) ossl_x509store.o: $(arch_hdrdir)/ruby/config.h ossl_x509store.o: $(hdrdir)/ruby.h ossl_x509store.o: $(hdrdir)/ruby/assert.h ossl_x509store.o: $(hdrdir)/ruby/backward.h +ossl_x509store.o: $(hdrdir)/ruby/backward/2/assume.h +ossl_x509store.o: $(hdrdir)/ruby/backward/2/attributes.h +ossl_x509store.o: $(hdrdir)/ruby/backward/2/bool.h +ossl_x509store.o: $(hdrdir)/ruby/backward/2/inttypes.h +ossl_x509store.o: $(hdrdir)/ruby/backward/2/limits.h +ossl_x509store.o: $(hdrdir)/ruby/backward/2/long_long.h +ossl_x509store.o: $(hdrdir)/ruby/backward/2/stdalign.h +ossl_x509store.o: $(hdrdir)/ruby/backward/2/stdarg.h ossl_x509store.o: $(hdrdir)/ruby/defines.h ossl_x509store.o: $(hdrdir)/ruby/encoding.h ossl_x509store.o: $(hdrdir)/ruby/intern.h +ossl_x509store.o: $(hdrdir)/ruby/internal/abi.h +ossl_x509store.o: $(hdrdir)/ruby/internal/anyargs.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/char.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/double.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/int.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/long.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/short.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +ossl_x509store.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +ossl_x509store.o: $(hdrdir)/ruby/internal/assume.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/artificial.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/cold.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/const.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/constexpr.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/deprecated.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/error.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/forceinline.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/format.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noalias.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noexcept.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noinline.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/nonnull.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/noreturn.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/packed_struct.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/pure.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/restrict.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/warning.h +ossl_x509store.o: $(hdrdir)/ruby/internal/attr/weakref.h +ossl_x509store.o: $(hdrdir)/ruby/internal/cast.h +ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is.h +ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +ossl_x509store.o: $(hdrdir)/ruby/internal/compiler_since.h +ossl_x509store.o: $(hdrdir)/ruby/internal/config.h +ossl_x509store.o: $(hdrdir)/ruby/internal/constant_p.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rarray.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rbasic.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rbignum.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rclass.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rdata.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rfile.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rhash.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/robject.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rregexp.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rstring.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rstruct.h +ossl_x509store.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +ossl_x509store.o: $(hdrdir)/ruby/internal/ctype.h +ossl_x509store.o: $(hdrdir)/ruby/internal/dllexport.h +ossl_x509store.o: $(hdrdir)/ruby/internal/dosish.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/coderange.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/ctype.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/encoding.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/pathname.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/re.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/sprintf.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/string.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/symbol.h +ossl_x509store.o: $(hdrdir)/ruby/internal/encoding/transcode.h +ossl_x509store.o: $(hdrdir)/ruby/internal/error.h +ossl_x509store.o: $(hdrdir)/ruby/internal/eval.h +ossl_x509store.o: $(hdrdir)/ruby/internal/event.h +ossl_x509store.o: $(hdrdir)/ruby/internal/fl_type.h +ossl_x509store.o: $(hdrdir)/ruby/internal/gc.h +ossl_x509store.o: $(hdrdir)/ruby/internal/glob.h +ossl_x509store.o: $(hdrdir)/ruby/internal/globals.h +ossl_x509store.o: $(hdrdir)/ruby/internal/has/attribute.h +ossl_x509store.o: $(hdrdir)/ruby/internal/has/builtin.h +ossl_x509store.o: $(hdrdir)/ruby/internal/has/c_attribute.h +ossl_x509store.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +ossl_x509store.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +ossl_x509store.o: $(hdrdir)/ruby/internal/has/extension.h +ossl_x509store.o: $(hdrdir)/ruby/internal/has/feature.h +ossl_x509store.o: $(hdrdir)/ruby/internal/has/warning.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/array.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/bignum.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/class.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/compar.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/complex.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/cont.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/dir.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/enum.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/enumerator.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/error.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/eval.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/file.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/hash.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/io.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/load.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/marshal.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/numeric.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/object.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/parse.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/proc.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/process.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/random.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/range.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/rational.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/re.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/ruby.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/select.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/set.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/signal.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/sprintf.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/string.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/struct.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/thread.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/time.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/variable.h +ossl_x509store.o: $(hdrdir)/ruby/internal/intern/vm.h +ossl_x509store.o: $(hdrdir)/ruby/internal/interpreter.h +ossl_x509store.o: $(hdrdir)/ruby/internal/iterator.h +ossl_x509store.o: $(hdrdir)/ruby/internal/memory.h +ossl_x509store.o: $(hdrdir)/ruby/internal/method.h +ossl_x509store.o: $(hdrdir)/ruby/internal/module.h +ossl_x509store.o: $(hdrdir)/ruby/internal/newobj.h +ossl_x509store.o: $(hdrdir)/ruby/internal/scan_args.h +ossl_x509store.o: $(hdrdir)/ruby/internal/special_consts.h +ossl_x509store.o: $(hdrdir)/ruby/internal/static_assert.h +ossl_x509store.o: $(hdrdir)/ruby/internal/stdalign.h +ossl_x509store.o: $(hdrdir)/ruby/internal/stdbool.h +ossl_x509store.o: $(hdrdir)/ruby/internal/stdckdint.h +ossl_x509store.o: $(hdrdir)/ruby/internal/symbol.h +ossl_x509store.o: $(hdrdir)/ruby/internal/value.h +ossl_x509store.o: $(hdrdir)/ruby/internal/value_type.h +ossl_x509store.o: $(hdrdir)/ruby/internal/variable.h +ossl_x509store.o: $(hdrdir)/ruby/internal/warning_push.h +ossl_x509store.o: $(hdrdir)/ruby/internal/xmalloc.h ossl_x509store.o: $(hdrdir)/ruby/io.h ossl_x509store.o: $(hdrdir)/ruby/missing.h ossl_x509store.o: $(hdrdir)/ruby/onigmo.h ossl_x509store.o: $(hdrdir)/ruby/oniguruma.h +ossl_x509store.o: $(hdrdir)/ruby/ractor.h ossl_x509store.o: $(hdrdir)/ruby/ruby.h ossl_x509store.o: $(hdrdir)/ruby/st.h ossl_x509store.o: $(hdrdir)/ruby/subst.h @@ -1176,10 +6498,10 @@ ossl_x509store.o: ossl_ocsp.h ossl_x509store.o: ossl_pkcs12.h ossl_x509store.o: ossl_pkcs7.h ossl_x509store.o: ossl_pkey.h +ossl_x509store.o: ossl_provider.h ossl_x509store.o: ossl_rand.h ossl_x509store.o: ossl_ssl.h -ossl_x509store.o: ossl_version.h +ossl_x509store.o: ossl_ts.h ossl_x509store.o: ossl_x509.h ossl_x509store.o: ossl_x509store.c -ossl_x509store.o: ruby_missing.h # AUTOGENERATED DEPENDENCIES END diff --git a/ext/openssl/deprecation.rb b/ext/openssl/deprecation.rb deleted file mode 100644 index 1d51d065a9..0000000000 --- a/ext/openssl/deprecation.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: false -module OpenSSL - def self.deprecated_warning_flag - unless flag = (@deprecated_warning_flag ||= nil) - if try_compile("", flag = "-Werror=deprecated-declarations") - $warnflags << " #{flag}" - else - flag = "" - end - @deprecated_warning_flag = flag - end - flag - end - - def self.check_func(func, header) - have_func(func, header, deprecated_warning_flag) - end - - def self.check_func_or_macro(func, header) - check_func(func, header) or - have_macro(func, header) && $defs.push("-DHAVE_#{func.upcase}") - end -end diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index 4f218562b1..a897c86b65 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -1,5 +1,5 @@ # -*- coding: us-ascii -*- -# frozen_string_literal: false +# frozen_string_literal: true =begin = Info 'OpenSSL for Ruby 2' project @@ -8,27 +8,43 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end require "mkmf" -require File.expand_path('../deprecation', __FILE__) -dir_config("openssl") -dir_config("kerberos") +ssl_dirs = dir_config("openssl") +dir_config_given = ssl_dirs.any? + +_, ssl_ldir = ssl_dirs +if ssl_ldir&.split(File::PATH_SEPARATOR)&.none? { |dir| File.directory?(dir) } + # According to the `mkmf.rb#dir_config`, the `--with-openssl-dir=<dir>` uses + # the value of the `File.basename(RbConfig::MAKEFILE_CONFIG["libdir"])` as a + # loaded library directory name. + ruby_ldir_name = File.basename(RbConfig::MAKEFILE_CONFIG["libdir"]) + + raise "OpenSSL library directory could not be found in '#{ssl_ldir}'. " \ + "You might want to fix this error in one of the following ways.\n" \ + " * Recompile OpenSSL by configuring it with --libdir=#{ruby_ldir_name} " \ + " to specify the OpenSSL library directory.\n" \ + " * Recompile Ruby by configuring it with --libdir=<dir> to specify the " \ + "Ruby library directory.\n" \ + " * Compile this openssl gem with --with-openssl-include=<dir> and " \ + "--with-openssl-lib=<dir> options to specify the OpenSSL include and " \ + "library directories." +end Logging::message "=== OpenSSL for Ruby configurator ===\n" -# Add -Werror=deprecated-declarations to $warnflags if available -OpenSSL.deprecated_warning_flag +$defs.push("-D""OPENSSL_SUPPRESS_DEPRECATED") -## -# Adds -DOSSL_DEBUG for compilation and some more targets when GCC is used -# To turn it on, use: --with-debug or --enable-debug -# -if with_config("debug") or enable_config("debug") - $defs.push("-DOSSL_DEBUG") -end +# Missing in TruffleRuby +have_func("rb_call_super_kw(0, NULL, 0)", "ruby.h") +# Ruby 3.1 +have_func("rb_io_descriptor", "ruby/io.h") +have_func("rb_io_maybe_wait(0, Qnil, Qnil, Qnil)", "ruby/io.h") +# Ruby 3.2 +have_func("rb_io_timeout", "ruby/io.h") Logging::message "=== Checking for system dependent stuff... ===\n" have_library("nsl", "t_open") @@ -37,13 +53,15 @@ if $mswin || $mingw have_library("ws2_32") end -Logging::message "=== Checking for required stuff... ===\n" -result = pkg_config("openssl") && have_header("openssl/ssl.h") +if $mingw + append_cflags '-D_FORTIFY_SOURCE=2' + append_ldflags '-fstack-protector' + have_library 'ssp' +end def find_openssl_library if $mswin || $mingw # required for static OpenSSL libraries - have_library("gdi32") # OpenSSL <= 1.0.2 (for RAND_screen()) have_library("crypt32") end @@ -60,12 +78,6 @@ def find_openssl_library return true end - # OpenSSL <= 1.0.2: libeay32.lib and ssleay32.lib. - if have_library("libeay32", "CRYPTO_malloc") && - have_library("ssleay32", "SSL_new") - return true - end - # LibreSSL: libcrypto-##.lib and libssl-##.lib, where ## is the ABI version # number. We have to find the version number out by scanning libpath. libpath = $LIBPATH.dup @@ -90,84 +102,81 @@ def find_openssl_library return false end -unless result - unless find_openssl_library - Logging::message "=== Checking for required stuff failed. ===\n" - Logging::message "Makefile wasn't created. Fix the errors above.\n" - raise "OpenSSL library could not be found. You might want to use " \ - "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \ - "is installed." - end +Logging::message "=== Checking for required stuff... ===\n" +pkg_config_found = !dir_config_given && pkg_config("openssl") && have_header("openssl/ssl.h") + +if !pkg_config_found && !find_openssl_library + Logging::message "=== Checking for required stuff failed. ===\n" + Logging::message "Makefile wasn't created. Fix the errors above.\n" + raise "OpenSSL library could not be found. You might want to use " \ + "--with-openssl-dir=<dir> option to specify the prefix where OpenSSL " \ + "is installed." end -unless checking_for("OpenSSL version is 1.0.1 or later") { - try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10001000L", "openssl/opensslv.h") } - raise "OpenSSL >= 1.0.1 or LibreSSL is required" +version_ok = if have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") + is_libressl = true + checking_for("LibreSSL version >= 3.9.0") { + try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x30900000L", "openssl/opensslv.h") } +else + is_openssl = true + checking_for("OpenSSL version >= 1.1.1") { + try_static_assert("OPENSSL_VERSION_NUMBER >= 0x10101000L", "openssl/opensslv.h") } +end +unless version_ok + raise "OpenSSL >= 1.1.1 or LibreSSL >= 3.9.0 is required" end -Logging::message "=== Checking for OpenSSL features... ===\n" -# compile options -have_func("RAND_egd") -engines = %w{builtin_engines openbsd_dev_crypto dynamic 4758cca aep atalla chil - cswift nuron sureware ubsec padlock capi gmp gost cryptodev aesni} -engines.each { |name| - OpenSSL.check_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h") -} - -if ($mswin || $mingw) && have_macro("LIBRESSL_VERSION_NUMBER", "openssl/opensslv.h") +# Prevent wincrypt.h from being included, which defines conflicting macro with openssl/x509.h +if is_libressl && ($mswin || $mingw) $defs.push("-DNOCRYPT") end -# added in 1.0.2 -have_func("EC_curve_nist2nid") -have_func("X509_REVOKED_dup") -have_func("X509_STORE_CTX_get0_store") -have_func("SSL_CTX_set_alpn_select_cb") -OpenSSL.check_func_or_macro("SSL_CTX_set1_curves_list", "openssl/ssl.h") -OpenSSL.check_func_or_macro("SSL_CTX_set_ecdh_auto", "openssl/ssl.h") -OpenSSL.check_func_or_macro("SSL_get_server_tmp_key", "openssl/ssl.h") -have_func("SSL_is_server") - -# added in 1.1.0 -if !have_struct_member("SSL", "ctx", "openssl/ssl.h") || - try_static_assert("LIBRESSL_VERSION_NUMBER >= 0x2070000fL", "openssl/opensslv.h") - $defs.push("-DHAVE_OPAQUE_OPENSSL") -end -have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API") -have_func("BN_GENCB_new") -have_func("BN_GENCB_free") -have_func("BN_GENCB_get_arg") -have_func("EVP_MD_CTX_new") -have_func("EVP_MD_CTX_free") -have_func("HMAC_CTX_new") -have_func("HMAC_CTX_free") -OpenSSL.check_func("RAND_pseudo_bytes", "openssl/rand.h") # deprecated -have_func("X509_STORE_get_ex_data") -have_func("X509_STORE_set_ex_data") -have_func("X509_CRL_get0_signature") -have_func("X509_REQ_get0_signature") -have_func("X509_REVOKED_get0_serialNumber") -have_func("X509_REVOKED_get0_revocationDate") -have_func("X509_get0_tbs_sigalg") -have_func("X509_STORE_CTX_get0_untrusted") -have_func("X509_STORE_CTX_get0_cert") -have_func("X509_STORE_CTX_get0_chain") -have_func("OCSP_SINGLERESP_get0_id") -have_func("SSL_CTX_get_ciphers") -have_func("X509_up_ref") -have_func("X509_CRL_up_ref") -have_func("X509_STORE_up_ref") -have_func("SSL_SESSION_up_ref") -have_func("EVP_PKEY_up_ref") -OpenSSL.check_func_or_macro("SSL_CTX_set_tmp_ecdh_callback", "openssl/ssl.h") # removed -OpenSSL.check_func_or_macro("SSL_CTX_set_min_proto_version", "openssl/ssl.h") -have_func("SSL_CTX_get_security_level") -have_func("X509_get0_notBefore") -have_func("SSL_SESSION_get_protocol_version") -have_func("EVP_PBE_scrypt") +Logging::message "=== Checking for OpenSSL features... ===\n" +evp_h = "openssl/evp.h".freeze +ts_h = "openssl/ts.h".freeze +ssl_h = "openssl/ssl.h".freeze + +# compile options +have_func("RAND_egd()", "openssl/rand.h") + +# added in OpenSSL 1.0.2, not in LibreSSL yet +have_func("SSL_CTX_set1_sigalgs_list(NULL, NULL)", ssl_h) +# added in OpenSSL 1.0.2, not in LibreSSL or AWS-LC yet +have_func("SSL_CTX_set1_client_sigalgs_list(NULL, NULL)", ssl_h) + +# added in 1.1.0, currently not in LibreSSL +have_func("EVP_PBE_scrypt(\"\", 0, (unsigned char *)\"\", 0, 0, 0, 0, 0, NULL, 0)", evp_h) + +# added in OpenSSL 1.1.1 and LibreSSL 3.5.0, then removed in LibreSSL 4.0.0 +have_func("EVP_PKEY_check(NULL)", evp_h) + +# added in 3.0.0 +have_func("SSL_CTX_set0_tmp_dh_pkey(NULL, NULL)", ssl_h) +have_func("ERR_get_error_all(NULL, NULL, NULL, NULL, NULL)", "openssl/err.h") +have_func("SSL_CTX_load_verify_file(NULL, \"\")", ssl_h) +have_func("BN_check_prime(NULL, NULL, NULL)", "openssl/bn.h") +have_func("EVP_MD_CTX_get0_md(NULL)", evp_h) +have_func("EVP_MD_CTX_get_pkey_ctx(NULL)", evp_h) +have_func("EVP_PKEY_eq(NULL, NULL)", evp_h) +have_func("EVP_PKEY_dup(NULL)", evp_h) + +# added in 3.2.0 +have_func("SSL_get0_group_name(NULL)", ssl_h) + +# added in 3.4.0 +have_func("TS_VERIFY_CTX_set0_certs(NULL, NULL)", ts_h) + +# added in 3.5.0 +have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h) Logging::message "=== Checking done. ===\n" +# Append flags from environment variables. +extcflags = ENV["RUBY_OPENSSL_EXTCFLAGS"] +append_cflags(extcflags.split) if extcflags +extldflags = ENV["RUBY_OPENSSL_EXTLDFLAGS"] +append_ldflags(extldflags.split) if extldflags + create_header create_makefile("openssl") Logging::message "Done.\n" diff --git a/ext/openssl/lib/openssl.rb b/ext/openssl/lib/openssl.rb index 0914282920..98fa8d39f2 100644 --- a/ext/openssl/lib/openssl.rb +++ b/ext/openssl/lib/openssl.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true =begin = Info 'OpenSSL for Ruby 2' project @@ -7,16 +7,35 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end require 'openssl.so' -require 'openssl/bn' -require 'openssl/pkey' -require 'openssl/cipher' -require 'openssl/config' -require 'openssl/digest' -require 'openssl/x509' -require 'openssl/ssl' -require 'openssl/pkcs5' +require_relative 'openssl/bn' +require_relative 'openssl/cipher' +require_relative 'openssl/digest' +require_relative 'openssl/hmac' +require_relative 'openssl/pkcs5' +require_relative 'openssl/pkey' +require_relative 'openssl/ssl' +require_relative 'openssl/version' +require_relative 'openssl/x509' + +module OpenSSL + # :call-seq: + # OpenSSL.secure_compare(string, string) -> true or false + # + # Constant time memory comparison. Inputs are hashed using SHA-256 to mask + # the length of the secret. Returns +true+ if the strings are identical, + # +false+ otherwise. + # + # This method is expensive due to the SHA-256 hashing. In most cases, where + # the input lengths are known to be equal or are not sensitive, + # OpenSSL.fixed_length_secure_compare should be used instead. + def self.secure_compare(a, b) + hashed_a = OpenSSL::Digest.digest('SHA256', a) + hashed_b = OpenSSL::Digest.digest('SHA256', b) + OpenSSL.fixed_length_secure_compare(hashed_a, hashed_b) && a == b + end +end diff --git a/ext/openssl/lib/openssl/bn.rb b/ext/openssl/lib/openssl/bn.rb index 8d1ebefb6e..e4889a140c 100644 --- a/ext/openssl/lib/openssl/bn.rb +++ b/ext/openssl/lib/openssl/bn.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true #-- # # = Ruby-space definitions that completes C-space funcs for BN @@ -10,7 +10,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL diff --git a/ext/openssl/lib/openssl/buffering.rb b/ext/openssl/lib/openssl/buffering.rb index 5d1586e594..1464a4292d 100644 --- a/ext/openssl/lib/openssl/buffering.rb +++ b/ext/openssl/lib/openssl/buffering.rb @@ -1,5 +1,5 @@ # coding: binary -# frozen_string_literal: false +# frozen_string_literal: true #-- #= Info # 'OpenSSL for Ruby 2' project @@ -8,7 +8,7 @@ # #= Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ ## @@ -22,6 +22,25 @@ module OpenSSL::Buffering include Enumerable + # A buffer which will retain binary encoding. + class Buffer < String + unless String.method_defined?(:append_as_bytes) + alias_method :_append, :<< + def append_as_bytes(string) + if string.encoding == Encoding::BINARY + _append(string) + else + _append(string.b) + end + + self + end + end + + undef_method :concat + undef_method :<< + end + ## # The "sync mode" of the SSLSocket. # @@ -40,7 +59,7 @@ module OpenSSL::Buffering def initialize(*) super @eof = false - @rbuffer = "" + @rbuffer = Buffer.new @sync = @io.sync end @@ -54,7 +73,7 @@ module OpenSSL::Buffering def fill_rbuff begin - @rbuffer << self.sysread(BLOCK_SIZE) + @rbuffer.append_as_bytes(self.sysread(BLOCK_SIZE)) rescue Errno::EAGAIN retry rescue EOFError @@ -70,14 +89,26 @@ module OpenSSL::Buffering nil else size = @rbuffer.size unless size - ret = @rbuffer[0, size] - @rbuffer[0, size] = "" - ret + @rbuffer.slice!(0, size) end end public + # call-seq: + # ssl.getbyte => 81 + # + # Get the next 8bit byte from `ssl`. Returns `nil` on EOF + def getbyte + read(1)&.ord + end + + # Get the next 8bit byte. Raises EOFError on EOF + def readbyte + raise EOFError if eof? + getbyte + end + ## # Reads _size_ bytes from the stream. If _buf_ is provided it must # reference a string which will receive the data. @@ -200,7 +231,7 @@ module OpenSSL::Buffering # # Unlike IO#gets the separator must be provided if a limit is provided. - def gets(eol=$/, limit=nil) + def gets(eol=$/, limit=nil, chomp: false) idx = @rbuffer.index(eol) until @eof break if idx @@ -215,7 +246,11 @@ module OpenSSL::Buffering if size && limit && limit >= 0 size = [size, limit].min end - consume_rbuff(size) + line = consume_rbuff(size) + if chomp && line + line.chomp!(eol) + end + line end ## @@ -312,18 +347,33 @@ module OpenSSL::Buffering # buffer is flushed to the underlying socket. def do_write(s) - @wbuffer = "" unless defined? @wbuffer - @wbuffer << s - @wbuffer.force_encoding(Encoding::BINARY) + @wbuffer = Buffer.new unless defined? @wbuffer + @wbuffer.append_as_bytes(s) + @sync ||= false - if @sync or @wbuffer.size > BLOCK_SIZE - until @wbuffer.empty? - begin - nwrote = syswrite(@wbuffer) - rescue Errno::EAGAIN - retry + buffer_size = @wbuffer.bytesize + if @sync or buffer_size > BLOCK_SIZE + nwrote = 0 + begin + while nwrote < buffer_size do + begin + chunk = if nwrote > 0 + @wbuffer.byteslice(nwrote, @wbuffer.bytesize) + else + @wbuffer + end + + nwrote += syswrite(chunk) + rescue Errno::EAGAIN + retry + end + end + ensure + if nwrote < @wbuffer.bytesize + @wbuffer[0, nwrote] = "" + else + @wbuffer.clear end - @wbuffer[0, nwrote] = "" end end end @@ -398,12 +448,12 @@ module OpenSSL::Buffering # See IO#puts for full details. def puts(*args) - s = "" + s = Buffer.new if args.empty? - s << "\n" + s.append_as_bytes("\n") end args.each{|arg| - s << arg.to_s + s.append_as_bytes(arg.to_s) s.sub!(/(?<!\n)\z/, "\n") } do_write(s) @@ -416,8 +466,8 @@ module OpenSSL::Buffering # See IO#print for full details. def print(*args) - s = "" - args.each{ |arg| s << arg.to_s } + s = Buffer.new + args.each{ |arg| s.append_as_bytes(arg.to_s) } do_write(s) nil end diff --git a/ext/openssl/lib/openssl/cipher.rb b/ext/openssl/lib/openssl/cipher.rb index af721b3a80..ab75ac8e1a 100644 --- a/ext/openssl/lib/openssl/cipher.rb +++ b/ext/openssl/lib/openssl/cipher.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true #-- # = Ruby-space predefined Cipher subclasses # @@ -9,7 +9,7 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL diff --git a/ext/openssl/lib/openssl/config.rb b/ext/openssl/lib/openssl/config.rb deleted file mode 100644 index 48d8be0069..0000000000 --- a/ext/openssl/lib/openssl/config.rb +++ /dev/null @@ -1,474 +0,0 @@ -# frozen_string_literal: false -=begin -= Ruby-space definitions that completes C-space funcs for Config - -= Info - Copyright (C) 2010 Hiroshi Nakamura <nahi@ruby-lang.org> - -= 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') - # #=> #<OpenSSL::Config sections=["default"]> - # 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') - # #=> #<OpenSSL::Config sections=["default"]> - # 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') - # #=> #<OpenSSL::Config sections=["default"]> - # 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 - # #=> #<OpenSSL::Config sections=[]> - # 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 - # #=> #<OpenSSL::Config sections=[]> - # 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) - # #=> #<OpenSSL::Config sections=["default"]> - # 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 diff --git a/ext/openssl/lib/openssl/digest.rb b/ext/openssl/lib/openssl/digest.rb index b6744de6bd..46ddfd6021 100644 --- a/ext/openssl/lib/openssl/digest.rb +++ b/ext/openssl/lib/openssl/digest.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true #-- # = Ruby-space predefined Digest subclasses # @@ -9,43 +9,37 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ module OpenSSL class Digest - alg = %w(MD2 MD4 MD5 MDC2 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512) - if OPENSSL_VERSION_NUMBER < 0x10100000 - alg += %w(DSS DSS1 SHA) - end - # Return the hash value computed with _name_ Digest. _name_ is either the # long name or short name of a supported digest algorithm. # - # === Examples + # === Example # # OpenSSL::Digest.digest("SHA256", "abc") - # - # which is equivalent to: - # - # OpenSSL::Digest::SHA256.digest("abc") def self.digest(name, data) super(data, name) end - alg.each{|name| + %w(MD4 MD5 RIPEMD160 SHA1 SHA224 SHA256 SHA384 SHA512).each do |name| klass = Class.new(self) { define_method(:initialize, ->(data = nil) {super(name, data)}) } + singleton = (class << klass; self; end) + singleton.class_eval{ - define_method(:digest){|data| new.digest(data) } - define_method(:hexdigest){|data| new.hexdigest(data) } + define_method(:digest) {|data| new.digest(data)} + define_method(:hexdigest) {|data| new.hexdigest(data)} } - const_set(name, klass) - } + + const_set(name.tr('-', '_'), klass) + end # Deprecated. # @@ -63,7 +57,7 @@ module OpenSSL # OpenSSL::Digest("MD5") # # => OpenSSL::Digest::MD5 # - # Digest("Foo") + # OpenSSL::Digest("Foo") # # => NameError: wrong constant name Foo def Digest(name) diff --git a/ext/openssl/lib/openssl/hmac.rb b/ext/openssl/lib/openssl/hmac.rb new file mode 100644 index 0000000000..c8c844d8d7 --- /dev/null +++ b/ext/openssl/lib/openssl/hmac.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +module OpenSSL + class HMAC + # Securely compare with another HMAC instance in constant time. + def ==(other) + return false unless HMAC === other + return false unless self.digest.bytesize == other.digest.bytesize + + OpenSSL.fixed_length_secure_compare(self.digest, other.digest) + end + + # :call-seq: + # hmac.base64digest -> string + # + # Returns the authentication code an a Base64-encoded string. + def base64digest + [digest].pack("m0") + end + + class << self + # :call-seq: + # HMAC.digest(digest, key, data) -> aString + # + # Returns the authentication code as a binary string. The _digest_ parameter + # specifies the digest algorithm to use. This may be a String representing + # the algorithm name or an instance of OpenSSL::Digest. + # + # === Example + # key = 'key' + # data = 'The quick brown fox jumps over the lazy dog' + # + # hmac = OpenSSL::HMAC.digest('SHA1', key, data) + # #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9" + def digest(digest, key, data) + hmac = new(key, digest) + hmac << data + hmac.digest + end + + # :call-seq: + # HMAC.hexdigest(digest, key, data) -> aString + # + # Returns the authentication code as a hex-encoded string. The _digest_ + # parameter specifies the digest algorithm to use. This may be a String + # representing the algorithm name or an instance of OpenSSL::Digest. + # + # === Example + # key = 'key' + # data = 'The quick brown fox jumps over the lazy dog' + # + # hmac = OpenSSL::HMAC.hexdigest('SHA1', key, data) + # #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" + def hexdigest(digest, key, data) + hmac = new(key, digest) + hmac << data + hmac.hexdigest + end + + # :call-seq: + # HMAC.base64digest(digest, key, data) -> aString + # + # Returns the authentication code as a Base64-encoded string. The _digest_ + # parameter specifies the digest algorithm to use. This may be a String + # representing the algorithm name or an instance of OpenSSL::Digest. + # + # === Example + # key = 'key' + # data = 'The quick brown fox jumps over the lazy dog' + # + # hmac = OpenSSL::HMAC.base64digest('SHA1', key, data) + # #=> "3nybhbi3iqa8ino29wqQcBydtNk=" + def base64digest(digest, key, data) + [digest(digest, key, data)].pack("m0") + end + end + end +end diff --git a/ext/openssl/lib/openssl/marshal.rb b/ext/openssl/lib/openssl/marshal.rb new file mode 100644 index 0000000000..eb8eda4748 --- /dev/null +++ b/ext/openssl/lib/openssl/marshal.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +#-- +# = Ruby-space definitions to add DER (de)serialization to classes +# +# = Info +# 'OpenSSL for Ruby 2' project +# Copyright (C) 2002 Michal Rokos <m.rokos@sh.cvut.cz> +# All rights reserved. +# +# = Licence +# This program is licensed under the same licence as Ruby. +# (See the file 'COPYING'.) +#++ +module OpenSSL + module Marshal + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + def _load(string) + new(string) + end + end + + def _dump(_level) + to_der + end + end +end diff --git a/ext/openssl/lib/openssl/pkcs5.rb b/ext/openssl/lib/openssl/pkcs5.rb index 959447df5e..8dedc4beef 100644 --- a/ext/openssl/lib/openssl/pkcs5.rb +++ b/ext/openssl/lib/openssl/pkcs5.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true #-- # Ruby/OpenSSL Project # Copyright (C) 2017 Ruby/OpenSSL Project Authors diff --git a/ext/openssl/lib/openssl/pkey.rb b/ext/openssl/lib/openssl/pkey.rb index 8a547c340d..39871e15dd 100644 --- a/ext/openssl/lib/openssl/pkey.rb +++ b/ext/openssl/lib/openssl/pkey.rb @@ -1,11 +1,321 @@ -# frozen_string_literal: false +# frozen_string_literal: true #-- # Ruby/OpenSSL Project # Copyright (C) 2017 Ruby/OpenSSL Project Authors #++ +require_relative 'marshal' + module OpenSSL::PKey + # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError. + DHError = PKeyError + + class DH + include OpenSSL::Marshal + + # :call-seq: + # dh.public_key -> dhnew + # + # Returns a new DH instance that carries just the \DH parameters. + # + # Contrary to the method name, the returned DH object contains only + # parameters and not the public key. + # + # This method is provided for backwards compatibility. In most cases, there + # is no need to call this method. + # + # For the purpose of re-generating the key pair while keeping the + # parameters, check OpenSSL::PKey.generate_key. + # + # Example: + # # OpenSSL::PKey::DH.generate by default generates a random key pair + # dh1 = OpenSSL::PKey::DH.generate(2048) + # p dh1.priv_key #=> #<OpenSSL::BN 1288347...> + # dhcopy = dh1.public_key + # p dhcopy.priv_key #=> nil + def public_key + DH.new(to_der) + end + + # :call-seq: + # dh.params -> hash + # + # Stores all parameters of key to a Hash. + # + # The hash has keys 'p', 'q', 'g', 'pub_key', and 'priv_key'. + def params + %w{p q g pub_key priv_key}.map { |name| + [name, send(name)] + }.to_h + end + + # :call-seq: + # dh.compute_key(pub_bn) -> string + # + # Returns a String containing a shared secret computed from the other + # party's public value. + # + # This method is provided for backwards compatibility, and calls #derive + # internally. + # + # === Parameters + # * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by + # DH#public_key as that contains the DH parameters only. + def compute_key(pub_bn) + # FIXME: This is constructing an X.509 SubjectPublicKeyInfo and is very + # inefficient + obj = OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.ObjectId("dhKeyAgreement"), + OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.Integer(p), + OpenSSL::ASN1.Integer(g), + ]), + ]), + OpenSSL::ASN1.BitString(OpenSSL::ASN1.Integer(pub_bn).to_der), + ]) + derive(OpenSSL::PKey.read(obj.to_der)) + end + + # :call-seq: + # dh.generate_key! -> self + # + # Generates a private and public key unless a private key already exists. + # If this DH instance was generated from public \DH parameters (e.g. by + # encoding the result of DH#public_key), then this method needs to be + # called first in order to generate the per-session keys before performing + # the actual key exchange. + # + # <b>Deprecated in version 3.0</b>. This method is incompatible with + # OpenSSL 3.0.0 or later. + # + # See also OpenSSL::PKey.generate_key. + # + # Example: + # # DEPRECATED USAGE: This will not work on OpenSSL 3.0 or later + # dh0 = OpenSSL::PKey::DH.new(2048) + # dh = dh0.public_key # #public_key only copies the DH parameters (contrary to the name) + # dh.generate_key! + # puts dh.private? # => true + # puts dh0.pub_key == dh.pub_key #=> false + # + # # With OpenSSL::PKey.generate_key + # dh0 = OpenSSL::PKey::DH.new(2048) + # dh = OpenSSL::PKey.generate_key(dh0) + # puts dh0.pub_key == dh.pub_key #=> false + def generate_key! + if OpenSSL::OPENSSL_VERSION_NUMBER >= 0x30000000 + raise PKeyError, "OpenSSL::PKey::DH is immutable on OpenSSL 3.0; " \ + "use OpenSSL::PKey.generate_key instead" + end + + unless priv_key + tmp = OpenSSL::PKey.generate_key(self) + set_key(tmp.pub_key, tmp.priv_key) + end + self + end + + class << self + # :call-seq: + # DH.generate(size, generator = 2) -> dh + # + # Creates a new DH instance from scratch by generating random parameters + # and a key pair. + # + # See also OpenSSL::PKey.generate_parameters and + # OpenSSL::PKey.generate_key. + # + # +size+:: + # The desired key size in bits. + # +generator+:: + # The generator. + def generate(size, generator = 2, &blk) + dhparams = OpenSSL::PKey.generate_parameters("DH", { + "dh_paramgen_prime_len" => size, + "dh_paramgen_generator" => generator, + }, &blk) + OpenSSL::PKey.generate_key(dhparams) + end + + # Handle DH.new(size, generator) form here; new(str) and new() forms + # are handled by #initialize + def new(*args, &blk) # :nodoc: + if args[0].is_a?(Integer) + generate(*args, &blk) + else + super + end + end + end + end + + # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError. + DSAError = PKeyError + + class DSA + include OpenSSL::Marshal + + # :call-seq: + # dsa.public_key -> dsanew + # + # Returns a new DSA instance that carries just the \DSA parameters and the + # public key. + # + # This method is provided for backwards compatibility. In most cases, there + # is no need to call this method. + # + # For the purpose of serializing the public key, to PEM or DER encoding of + # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and + # PKey#public_to_der. + def public_key + OpenSSL::PKey.read(public_to_der) + end + + # :call-seq: + # dsa.params -> hash + # + # Stores all parameters of key to a Hash. + # + # The hash has keys 'p', 'q', 'g', 'pub_key', and 'priv_key'. + def params + %w{p q g pub_key priv_key}.map { |name| + [name, send(name)] + }.to_h + end + + class << self + # :call-seq: + # DSA.generate(size) -> dsa + # + # Creates a new DSA instance by generating a private/public key pair + # from scratch. + # + # See also OpenSSL::PKey.generate_parameters and + # OpenSSL::PKey.generate_key. + # + # +size+:: + # The desired key size in bits. + def generate(size, &blk) + # FIPS 186-4 specifies four (L,N) pairs: (1024,160), (2048,224), + # (2048,256), and (3072,256). + # + # q size is derived here with compatibility with + # DSA_generator_parameters_ex() which previous versions of ruby/openssl + # used to call. + qsize = size >= 2048 ? 256 : 160 + dsaparams = OpenSSL::PKey.generate_parameters("DSA", { + "dsa_paramgen_bits" => size, + "dsa_paramgen_q_bits" => qsize, + }, &blk) + OpenSSL::PKey.generate_key(dsaparams) + end + + # Handle DSA.new(size) form here; new(str) and new() forms + # are handled by #initialize + def new(*args, &blk) # :nodoc: + if args[0].is_a?(Integer) + generate(*args, &blk) + else + super + end + end + end + + # :call-seq: + # dsa.syssign(string) -> string + # + # Computes and returns the \DSA signature of +string+, where +string+ is + # expected to be an already-computed message digest of the original input + # data. The signature is issued using the private key of this DSA instance. + # + # <b>Deprecated in version 3.0</b>. + # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. + # + # +string+:: + # A message digest of the original input data to be signed. + # + # Example: + # dsa = OpenSSL::PKey::DSA.new(2048) + # doc = "Sign me" + # digest = OpenSSL::Digest.digest('SHA1', doc) + # + # # With legacy #syssign and #sysverify: + # sig = dsa.syssign(digest) + # p dsa.sysverify(digest, sig) #=> true + # + # # With #sign_raw and #verify_raw: + # sig = dsa.sign_raw(nil, digest) + # p dsa.verify_raw(nil, sig, digest) #=> true + def syssign(string) + q or raise PKeyError, "incomplete DSA" + private? or raise PKeyError, "Private DSA key needed!" + sign_raw(nil, string) + end + + # :call-seq: + # dsa.sysverify(digest, sig) -> true | false + # + # Verifies whether the signature is valid given the message digest input. + # It does so by validating +sig+ using the public key of this DSA instance. + # + # <b>Deprecated in version 3.0</b>. + # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. + # + # +digest+:: + # A message digest of the original input data to be signed. + # +sig+:: + # A \DSA signature value. + def sysverify(digest, sig) + verify_raw(nil, sig, digest) + end + end + if defined?(EC) + # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError. + ECError = PKeyError + + class EC + include OpenSSL::Marshal + + # :call-seq: + # key.dsa_sign_asn1(data) -> String + # + # <b>Deprecated in version 3.0</b>. + # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. + def dsa_sign_asn1(data) + sign_raw(nil, data) + end + + # :call-seq: + # key.dsa_verify_asn1(data, sig) -> true | false + # + # <b>Deprecated in version 3.0</b>. + # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw instead. + def dsa_verify_asn1(data, sig) + verify_raw(nil, sig, data) + end + + # :call-seq: + # ec.dh_compute_key(pubkey) -> string + # + # Derives a shared secret by ECDH. _pubkey_ must be an instance of + # OpenSSL::PKey::EC::Point and must belong to the same group. + # + # This method is provided for backwards compatibility, and calls #derive + # internally. + def dh_compute_key(pubkey) + obj = OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.Sequence([ + OpenSSL::ASN1.ObjectId("id-ecPublicKey"), + group.to_der, + ]), + OpenSSL::ASN1.BitString(pubkey.to_octet_string(:uncompressed)), + ]) + derive(OpenSSL::PKey.read(obj.to_der)) + end + end + class EC::Point # :call-seq: # point.to_bn([conversion_form]) -> OpenSSL::BN @@ -22,4 +332,162 @@ module OpenSSL::PKey end end end + + # Alias of PKeyError. Before version 4.0.0, this was a subclass of PKeyError. + RSAError = PKeyError + + class RSA + include OpenSSL::Marshal + + # :call-seq: + # rsa.public_key -> rsanew + # + # Returns a new RSA instance that carries just the public key components. + # + # This method is provided for backwards compatibility. In most cases, there + # is no need to call this method. + # + # For the purpose of serializing the public key, to PEM or DER encoding of + # X.509 SubjectPublicKeyInfo format, check PKey#public_to_pem and + # PKey#public_to_der. + def public_key + OpenSSL::PKey.read(public_to_der) + end + + # :call-seq: + # rsa.params -> hash + # + # Stores all parameters of key to a Hash. + # + # The hash has keys 'n', 'e', 'd', 'p', 'q', 'dmp1', 'dmq1', and 'iqmp'. + def params + %w{n e d p q dmp1 dmq1 iqmp}.map { |name| + [name, send(name)] + }.to_h + end + + class << self + # :call-seq: + # RSA.generate(size, exponent = 65537) -> RSA + # + # Generates an \RSA keypair. + # + # See also OpenSSL::PKey.generate_key. + # + # +size+:: + # The desired key size in bits. + # +exponent+:: + # An odd Integer, normally 3, 17, or 65537. + def generate(size, exp = 0x10001, &blk) + OpenSSL::PKey.generate_key("RSA", { + "rsa_keygen_bits" => size, + "rsa_keygen_pubexp" => exp, + }, &blk) + end + + # Handle RSA.new(size, exponent) form here; new(str) and new() forms + # are handled by #initialize + def new(*args, &blk) # :nodoc: + if args[0].is_a?(Integer) + generate(*args, &blk) + else + super + end + end + end + + # :call-seq: + # rsa.private_encrypt(string) -> String + # rsa.private_encrypt(string, padding) -> String + # + # Encrypt +string+ with the private key. +padding+ defaults to + # PKCS1_PADDING, which is known to be insecure but is kept for backwards + # compatibility. The encrypted string output can be decrypted using + # #public_decrypt. + # + # <b>Deprecated in version 3.0</b>. + # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and + # PKey::PKey#verify_recover instead. + def private_encrypt(string, padding = PKCS1_PADDING) + n or raise PKeyError, "incomplete RSA" + private? or raise PKeyError, "private key needed." + sign_raw(nil, string, { + "rsa_padding_mode" => translate_padding_mode(padding), + }) + end + + # :call-seq: + # rsa.public_decrypt(string) -> String + # rsa.public_decrypt(string, padding) -> String + # + # Decrypt +string+, which has been encrypted with the private key, with the + # public key. +padding+ defaults to PKCS1_PADDING which is known to be + # insecure but is kept for backwards compatibility. + # + # <b>Deprecated in version 3.0</b>. + # Consider using PKey::PKey#sign_raw and PKey::PKey#verify_raw, and + # PKey::PKey#verify_recover instead. + def public_decrypt(string, padding = PKCS1_PADDING) + n or raise PKeyError, "incomplete RSA" + verify_recover(nil, string, { + "rsa_padding_mode" => translate_padding_mode(padding), + }) + end + + # :call-seq: + # rsa.public_encrypt(string) -> String + # rsa.public_encrypt(string, padding) -> String + # + # Encrypt +string+ with the public key. +padding+ defaults to + # PKCS1_PADDING, which is known to be insecure but is kept for backwards + # compatibility. The encrypted string output can be decrypted using + # #private_decrypt. + # + # <b>Deprecated in version 3.0</b>. + # Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead. + def public_encrypt(data, padding = PKCS1_PADDING) + n or raise PKeyError, "incomplete RSA" + encrypt(data, { + "rsa_padding_mode" => translate_padding_mode(padding), + }) + end + + # :call-seq: + # rsa.private_decrypt(string) -> String + # rsa.private_decrypt(string, padding) -> String + # + # Decrypt +string+, which has been encrypted with the public key, with the + # private key. +padding+ defaults to PKCS1_PADDING, which is known to be + # insecure but is kept for backwards compatibility. + # + # <b>Deprecated in version 3.0</b>. + # Consider using PKey::PKey#encrypt and PKey::PKey#decrypt instead. + def private_decrypt(data, padding = PKCS1_PADDING) + n or raise PKeyError, "incomplete RSA" + private? or raise PKeyError, "private key needed." + decrypt(data, { + "rsa_padding_mode" => translate_padding_mode(padding), + }) + end + + PKCS1_PADDING = 1 + SSLV23_PADDING = 2 + NO_PADDING = 3 + PKCS1_OAEP_PADDING = 4 + + private def translate_padding_mode(num) + case num + when PKCS1_PADDING + "pkcs1" + when SSLV23_PADDING + "sslv23" + when NO_PADDING + "none" + when PKCS1_OAEP_PADDING + "oaep" + else + raise PKeyError, "unsupported padding mode" + end + end + end end diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb index 355eb2ebbb..3268c126b9 100644 --- a/ext/openssl/lib/openssl/ssl.rb +++ b/ext/openssl/lib/openssl/ssl.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true =begin = Info 'OpenSSL for Ruby 2' project @@ -7,18 +7,21 @@ = Licence This program is licensed under the same licence as Ruby. - (See the file 'LICENCE'.) + (See the file 'COPYING'.) =end require "openssl/buffering" + +if defined?(OpenSSL::SSL) + require "io/nonblock" require "ipaddr" +require "socket" module OpenSSL module SSL class SSLContext DEFAULT_PARAMS = { # :nodoc: - :min_version => OpenSSL::SSL::TLS1_VERSION, :verify_mode => OpenSSL::SSL::VERIFY_PEER, :verify_hostname => true, :options => -> { @@ -29,28 +32,9 @@ module OpenSSL }.call } - if defined?(OpenSSL::PKey::DH) - DEFAULT_2048 = OpenSSL::PKey::DH.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_ - private_constant :DEFAULT_2048 - - DEFAULT_TMP_DH_CALLBACK = lambda { |ctx, is_export, keylen| # :nodoc: - warn "using default DH parameters." if $VERBOSE - DEFAULT_2048 - } - end - - if !(OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") && - OpenSSL::OPENSSL_VERSION_NUMBER >= 0x10100000) + if !OpenSSL::OPENSSL_VERSION.start_with?("OpenSSL") DEFAULT_PARAMS.merge!( + min_version: OpenSSL::SSL::TLS1_VERSION, ciphers: %w{ ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-GCM-SHA256 @@ -82,24 +66,13 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 AES256-SHA256 AES128-SHA AES256-SHA - }.join(":"), + }.join(":").freeze, ) end + DEFAULT_PARAMS.freeze DEFAULT_CERT_STORE = OpenSSL::X509::Store.new # :nodoc: DEFAULT_CERT_STORE.set_default_paths - DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL - - # 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 # A callback invoked at connect time to distinguish between multiple # server names. @@ -119,8 +92,9 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 # that this form is deprecated. New applications should use #min_version= # and #max_version= as necessary. def initialize(version = nil) - self.options |= OpenSSL::SSL::OP_ALL self.ssl_version = version if version + self.verify_mode = OpenSSL::SSL::VERIFY_NONE + self.verify_hostname = false end ## @@ -137,54 +111,24 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 # used. def set_params(params={}) params = DEFAULT_PARAMS.merge(params) - self.options = params.delete(:options) # set before min_version/max_version + self.options |= params.delete(:options) # set before min_version/max_version 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 + if not defined?(Ractor) or Ractor.current == Ractor.main + self.cert_store = DEFAULT_CERT_STORE + else + self.cert_store = Ractor.current[:__openssl_default_store__] ||= + OpenSSL::X509::Store.new.tap { |store| + store.set_default_paths + } + end end end return params end # call-seq: - # ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION - # ctx.min_version = :TLS1_2 - # ctx.min_version = nil - # - # Sets the lower bound on the supported SSL/TLS protocol version. The - # version may be specified by an integer constant named - # OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version". - # - # Be careful that you don't overwrite OpenSSL::SSL::OP_NO_{SSL,TLS}v* - # options by #options= once you have called #min_version= or - # #max_version=. - # - # === Example - # ctx = OpenSSL::SSL::SSLContext.new - # ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION - # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION - # - # sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx) - # sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2 - def min_version=(version) - set_minmax_proto_version(version, @max_proto_version ||= nil) - @min_proto_version = version - end - - # call-seq: - # ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION - # ctx.max_version = :TLS1_2 - # ctx.max_version = nil - # - # Sets the upper bound of the supported SSL/TLS protocol version. See - # #min_version= for the possible values. - def max_version=(version) - set_minmax_proto_version(@min_proto_version ||= nil, version) - @max_proto_version = version - end - - # call-seq: # ctx.ssl_version = :TLSv1 # ctx.ssl_version = "SSLv23" # @@ -208,8 +152,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 end version = METHODS_MAP[meth.intern] or raise ArgumentError, "unknown SSL method `%s'" % meth - set_minmax_proto_version(version, version) - @min_proto_version = @max_proto_version = version + self.min_version = self.max_version = version end METHODS_MAP = { @@ -231,6 +174,11 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 end module SocketForwarder + # The file descriptor for the socket. + def fileno + to_io.fileno + end + def addr to_io.addr end @@ -239,6 +187,14 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 to_io.peeraddr end + def local_address + to_io.local_address + end + + def remote_address + to_io.remote_address + end + def setsockopt(level, optname, optval) to_io.setsockopt(level, optname, optval) end @@ -258,6 +214,36 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 def do_not_reverse_lookup=(flag) to_io.do_not_reverse_lookup = flag end + + def close_on_exec=(value) + to_io.close_on_exec = value + end + + def close_on_exec? + to_io.close_on_exec? + end + + def wait(*args) + to_io.wait(*args) + end + + def wait_readable(*args) + to_io.wait_readable(*args) + end + + def wait_writable(*args) + to_io.wait_writable(*args) + end + + if IO.method_defined?(:timeout) + def timeout + to_io.timeout + end + + def timeout=(value) + to_io.timeout=(value) + end + end end def verify_certificate_identity(cert, hostname) @@ -408,6 +394,32 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 nil end + # Close the stream for reading. + # This method is ignored by OpenSSL as there is no reasonable way to + # implement it, but exists for compatibility with IO. + def close_read + # Unsupported and ignored. + # Just don't read any more. + end + + # Closes the stream for writing. The behavior of this method depends on + # the version of OpenSSL and the TLS protocol in use. + # + # - Sends a 'close_notify' alert to the peer. + # - Does not wait for the peer's 'close_notify' alert in response. + # + # In TLS 1.2 and earlier: + # - On receipt of a 'close_notify' alert, responds with a 'close_notify' + # alert of its own and close down the connection immediately, + # discarding any pending writes. + # + # Therefore, on TLS 1.2, this method will cause the connection to be + # completely shut down. On TLS 1.3, the connection will remain open for + # reading only. + def close_write + stop + end + private def using_anon_cipher? @@ -420,14 +432,6 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 @context.client_cert_cb end - def tmp_dh_callback - @context.tmp_dh_callback || OpenSSL::SSL::SSLContext::DEFAULT_TMP_DH_CALLBACK - end - - def tmp_ecdh_callback - @context.tmp_ecdh_callback - end - def session_new_cb @context.session_new_cb end @@ -435,6 +439,38 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 def session_get_cb @context.session_get_cb end + + class << self + + # call-seq: + # open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil) + # + # Creates a new instance of SSLSocket. + # _remote\_host_ and _remote\_port_ are used to open TCPSocket. + # If _local\_host_ and _local\_port_ are specified, + # then those parameters are used on the local end to establish the connection. + # If _context_ is provided, + # the SSL Sockets initial params will be taken from the context. + # + # === Examples + # + # sock = OpenSSL::SSL::SSLSocket.open('localhost', 443) + # sock.connect # Initiates a connection to localhost:443 + # + # with SSLContext: + # + # ctx = OpenSSL::SSL::SSLContext.new + # sock = OpenSSL::SSL::SSLSocket.open('localhost', 443, context: ctx) + # sock.connect # Initiates a connection to localhost:443 with SSLContext + def open(remote_host, remote_port, local_host=nil, local_port=nil, context: nil) + sock = ::TCPSocket.open(remote_host, remote_port, local_host, local_port) + if context.nil? + return OpenSSL::SSL::SSLSocket.new(sock) + else + return OpenSSL::SSL::SSLSocket.new(sock, context) + end + end + end end ## @@ -453,7 +489,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 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] + session_id = prng.bytes(16).unpack1('H*') @ctx.session_id_context = session_id end @start_immediately = true @@ -465,7 +501,7 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 end # See TCPServer#listen for details. - def listen(backlog=5) + def listen(backlog=Socket::SOMAXCONN) @svr.listen(backlog) end @@ -502,3 +538,5 @@ YoaOffgTf5qxiwkjnlVZQc3whgnEt9FpVMvQ9eknyeGB5KHfayAc3+hUAvI3/Cr3 end end end + +end diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb new file mode 100644 index 0000000000..88570562e2 --- /dev/null +++ b/ext/openssl/lib/openssl/version.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module OpenSSL + # The version string of Ruby/OpenSSL. + VERSION = "4.0.0" +end diff --git a/ext/openssl/lib/openssl/x509.rb b/ext/openssl/lib/openssl/x509.rb index 98358f90da..66765ffeab 100644 --- a/ext/openssl/lib/openssl/x509.rb +++ b/ext/openssl/lib/openssl/x509.rb @@ -1,4 +1,4 @@ -# frozen_string_literal: false +# frozen_string_literal: true #-- # = Ruby-space definitions that completes C-space funcs for X509 and subclasses # @@ -9,9 +9,11 @@ # # = Licence # This program is licensed under the same licence as Ruby. -# (See the file 'LICENCE'.) +# (See the file 'COPYING'.) #++ +require_relative 'marshal' + module OpenSSL module X509 class ExtensionFactory @@ -41,6 +43,8 @@ module OpenSSL end class Extension + include OpenSSL::Marshal + def ==(other) return false unless Extension === other to_der == other.to_der @@ -60,9 +64,146 @@ module OpenSSL def to_a [ self.oid, self.value, self.critical? ] end + + module Helpers + def find_extension(oid) + extensions.find { |e| e.oid == oid } + end + end + + module SubjectKeyIdentifier + include Helpers + + # Get the subject's key identifier from the subjectKeyIdentifier + # exteension, as described in RFC5280 Section 4.2.1.2. + # + # Returns the binary String key identifier or nil or raises + # ASN1::ASN1Error. + def subject_key_identifier + ext = find_extension("subjectKeyIdentifier") + return nil if ext.nil? + + ski_asn1 = ASN1.decode(ext.value_der) + if ext.critical? || ski_asn1.tag_class != :UNIVERSAL || ski_asn1.tag != ASN1::OCTET_STRING + raise ASN1::ASN1Error, "invalid extension" + end + + ski_asn1.value + end + end + + module AuthorityKeyIdentifier + include Helpers + + # Get the issuing certificate's key identifier from the + # authorityKeyIdentifier extension, as described in RFC5280 + # Section 4.2.1.1 + # + # Returns the binary String keyIdentifier or nil or raises + # ASN1::ASN1Error. + def authority_key_identifier + ext = find_extension("authorityKeyIdentifier") + return nil if ext.nil? + + aki_asn1 = ASN1.decode(ext.value_der) + if ext.critical? || aki_asn1.tag_class != :UNIVERSAL || aki_asn1.tag != ASN1::SEQUENCE + raise ASN1::ASN1Error, "invalid extension" + end + + key_id = aki_asn1.value.find do |v| + v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0 + end + + key_id.nil? ? nil : key_id.value + end + end + + module CRLDistributionPoints + include Helpers + + # Get the distributionPoint fullName URI from the certificate's CRL + # distribution points extension, as described in RFC 5280 Section + # 4.2.1.13. + # + # Returns an array of strings or nil or raises ASN1::ASN1Error. + def crl_uris + ext = find_extension("crlDistributionPoints") + return nil if ext.nil? + + cdp_asn1 = ASN1.decode(ext.value_der) + if cdp_asn1.tag_class != :UNIVERSAL || cdp_asn1.tag != ASN1::SEQUENCE + raise ASN1::ASN1Error, "invalid extension" + end + + crl_uris = cdp_asn1.flat_map do |crl_distribution_point| + distribution_point = crl_distribution_point.value.find do |v| + v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0 + end + full_name = distribution_point&.value&.find do |v| + v.tag_class == :CONTEXT_SPECIFIC && v.tag == 0 + end + full_name&.value&.select do |v| + v.tag_class == :CONTEXT_SPECIFIC && v.tag == 6 # uniformResourceIdentifier + end + end + + crl_uris.empty? ? nil : crl_uris.map(&:value) + end + end + + module AuthorityInfoAccess + include Helpers + + # Get the information and services for the issuer from the certificate's + # authority information access extension exteension, as described in RFC5280 + # Section 4.2.2.1. + # + # Returns an array of strings or nil or raises ASN1::ASN1Error. + def ca_issuer_uris + aia_asn1 = parse_aia_asn1 + return nil if aia_asn1.nil? + + ca_issuer = aia_asn1.value.select do |authority_info_access| + authority_info_access.value.first.value == "caIssuers" + end + + ca_issuer&.map(&:value)&.map(&:last)&.map(&:value) + end + + # Get the URIs for OCSP from the certificate's authority information access + # extension exteension, as described in RFC5280 Section 4.2.2.1. + # + # Returns an array of strings or nil or raises ASN1::ASN1Error. + def ocsp_uris + aia_asn1 = parse_aia_asn1 + return nil if aia_asn1.nil? + + ocsp = aia_asn1.value.select do |authority_info_access| + authority_info_access.value.first.value == "OCSP" + end + + ocsp&.map(&:value)&.map(&:last)&.map(&:value) + end + + private + + def parse_aia_asn1 + ext = find_extension("authorityInfoAccess") + return nil if ext.nil? + + aia_asn1 = ASN1.decode(ext.value_der) + if ext.critical? || aia_asn1.tag_class != :UNIVERSAL || aia_asn1.tag != ASN1::SEQUENCE + raise ASN1::ASN1Error, "invalid extension" + end + + aia_asn1 + end + end end class Name + include OpenSSL::Marshal + module RFC2253DN Special = ',=+<>#;' HexChar = /[0-9a-fA-F]/ @@ -138,11 +279,29 @@ module OpenSSL end class << self + # Parses the UTF-8 string representation of a distinguished name, + # according to RFC 2253. + # + # See also #to_utf8 for the opposite operation. def parse_rfc2253(str, template=OBJECT_TYPE_TEMPLATE) ary = OpenSSL::X509::Name::RFC2253DN.scan(str) self.new(ary, template) end + # Parses the string representation of a distinguished name. Two + # different forms are supported: + # + # - \OpenSSL format (<tt>X509_NAME_oneline()</tt>) used by + # <tt>#to_s</tt>. For example: <tt>/DC=com/DC=example/CN=nobody</tt> + # - \OpenSSL format (<tt>X509_NAME_print()</tt>) + # used by <tt>#to_s(OpenSSL::X509::Name::COMPAT)</tt>. For example: + # <tt>DC=com, DC=example, CN=nobody</tt> + # + # Neither of them is standardized and has quirks and inconsistencies + # in handling of escaped characters or multi-valued RDNs. + # + # Use of this method is discouraged in new applications. See + # Name.parse_rfc2253 and #to_utf8 for the alternative. def parse_openssl(str, template=OBJECT_TYPE_TEMPLATE) if str.start_with?("/") # /A=B/C=D format @@ -166,6 +325,8 @@ module OpenSSL end class Attribute + include OpenSSL::Marshal + def ==(other) return false unless Attribute === other to_der == other.to_der @@ -179,6 +340,21 @@ module OpenSSL end class Certificate + include OpenSSL::Marshal + include Extension::SubjectKeyIdentifier + include Extension::AuthorityKeyIdentifier + include Extension::CRLDistributionPoints + include Extension::AuthorityInfoAccess + + def inspect + "#<#{self.class}: " \ + "subject=#{subject.inspect}, " \ + "issuer=#{issuer.inspect}, " \ + "serial=#{serial.inspect}, " \ + "not_before=#{not_before.inspect rescue "(error)"}, " \ + "not_after=#{not_after.inspect rescue "(error)"}>" + end + def pretty_print(q) q.object_group(self) { q.breakable @@ -189,9 +365,16 @@ module OpenSSL q.text 'not_after='; q.pp self.not_after } end + + def self.load_file(path) + load(File.binread(path)) + end end class CRL + include OpenSSL::Marshal + include Extension::AuthorityKeyIdentifier + def ==(other) return false unless CRL === other to_der == other.to_der @@ -206,6 +389,8 @@ module OpenSSL end class Request + include OpenSSL::Marshal + def ==(other) return false unless Request === other to_der == other.to_der diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec index 295379fb6c..7072d599d8 100644 --- a/ext/openssl/openssl.gemspec +++ b/ext/openssl/openssl.gemspec @@ -1,29 +1,28 @@ -# -*- encoding: utf-8 -*- +Gem::Specification.new do |spec| + spec.name = "openssl" + spec.version = "4.0.0" + spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"] + spec.email = ["ruby-core@ruby-lang.org"] + spec.summary = %q{SSL/TLS and general-purpose cryptography for Ruby} + spec.description = %q{OpenSSL for Ruby provides access to SSL/TLS and general-purpose cryptography based on the OpenSSL library.} + spec.homepage = "https://github.com/ruby/openssl" + spec.licenses = ["Ruby", "BSD-2-Clause"] -Gem::Specification.new do |s| - s.name = "openssl" - s.version = "2.1.2" + if Gem::Platform === spec.platform and spec.platform =~ 'java' or RUBY_ENGINE == 'jruby' + spec.platform = "java" + spec.files = [] + spec.add_runtime_dependency('jruby-openssl', '~> 0.14') + else + spec.files = Dir.glob(["lib/**/*.rb", "ext/**/*.{c,h,rb}", "*.md"], base: File.expand_path("..", __FILE__)) + + ["BSDL", "COPYING"] + spec.require_paths = ["lib"] + spec.extensions = ["ext/openssl/extconf.rb"] + end - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.metadata = { "msys2_mingw_dependencies" => "openssl" } if s.respond_to? :metadata= - s.require_paths = ["lib"] - s.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"] - s.date = "2018-10-17" - s.description = "It wraps the OpenSSL library." - s.email = ["ruby-core@ruby-lang.org"] - s.extensions = ["ext/openssl/extconf.rb"] - s.extra_rdoc_files = ["README.md", "CONTRIBUTING.md", "History.md"] - s.files = ["BSDL", "CONTRIBUTING.md", "History.md", "LICENSE.txt", "README.md", "ext/openssl/deprecation.rb", "ext/openssl/extconf.rb", "ext/openssl/openssl_missing.c", "ext/openssl/openssl_missing.h", "ext/openssl/ossl.c", "ext/openssl/ossl.h", "ext/openssl/ossl_asn1.c", "ext/openssl/ossl_asn1.h", "ext/openssl/ossl_bio.c", "ext/openssl/ossl_bio.h", "ext/openssl/ossl_bn.c", "ext/openssl/ossl_bn.h", "ext/openssl/ossl_cipher.c", "ext/openssl/ossl_cipher.h", "ext/openssl/ossl_config.c", "ext/openssl/ossl_config.h", "ext/openssl/ossl_digest.c", "ext/openssl/ossl_digest.h", "ext/openssl/ossl_engine.c", "ext/openssl/ossl_engine.h", "ext/openssl/ossl_hmac.c", "ext/openssl/ossl_hmac.h", "ext/openssl/ossl_kdf.c", "ext/openssl/ossl_kdf.h", "ext/openssl/ossl_ns_spki.c", "ext/openssl/ossl_ns_spki.h", "ext/openssl/ossl_ocsp.c", "ext/openssl/ossl_ocsp.h", "ext/openssl/ossl_pkcs12.c", "ext/openssl/ossl_pkcs12.h", "ext/openssl/ossl_pkcs7.c", "ext/openssl/ossl_pkcs7.h", "ext/openssl/ossl_pkey.c", "ext/openssl/ossl_pkey.h", "ext/openssl/ossl_pkey_dh.c", "ext/openssl/ossl_pkey_dsa.c", "ext/openssl/ossl_pkey_ec.c", "ext/openssl/ossl_pkey_rsa.c", "ext/openssl/ossl_rand.c", "ext/openssl/ossl_rand.h", "ext/openssl/ossl_ssl.c", "ext/openssl/ossl_ssl.h", "ext/openssl/ossl_ssl_session.c", "ext/openssl/ossl_version.h", "ext/openssl/ossl_x509.c", "ext/openssl/ossl_x509.h", "ext/openssl/ossl_x509attr.c", "ext/openssl/ossl_x509cert.c", "ext/openssl/ossl_x509crl.c", "ext/openssl/ossl_x509ext.c", "ext/openssl/ossl_x509name.c", "ext/openssl/ossl_x509req.c", "ext/openssl/ossl_x509revoked.c", "ext/openssl/ossl_x509store.c", "ext/openssl/ruby_missing.h", "lib/openssl.rb", "lib/openssl/bn.rb", "lib/openssl/buffering.rb", "lib/openssl/cipher.rb", "lib/openssl/config.rb", "lib/openssl/digest.rb", "lib/openssl/pkcs5.rb", "lib/openssl/pkey.rb", "lib/openssl/ssl.rb", "lib/openssl/x509.rb"] - s.homepage = "https://github.com/ruby/openssl" - s.licenses = ["Ruby"] - s.rdoc_options = ["--main", "README.md"] - s.required_ruby_version = Gem::Requirement.new(">= 2.3.0") - s.rubygems_version = "3.0.0.beta1" - s.summary = "OpenSSL provides SSL, TLS and general purpose cryptography." + spec.extra_rdoc_files = Dir["*.md"] + spec.rdoc_options = ["--main", "README.md"] - s.add_runtime_dependency("ipaddr", [">= 0"]) - s.add_development_dependency("rake", [">= 0"]) - s.add_development_dependency("rake-compiler", [">= 0"]) - s.add_development_dependency("test-unit", ["~> 3.0"]) - s.add_development_dependency("rdoc", [">= 0"]) + spec.required_ruby_version = ">= 2.7.0" + + spec.metadata["msys2_mingw_dependencies"] = "openssl" end diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c deleted file mode 100644 index b36ef0288e..0000000000 --- a/ext/openssl/openssl_missing.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#include RUBY_EXTCONF_H - -#include <string.h> /* memcpy() */ -#if !defined(OPENSSL_NO_ENGINE) -# include <openssl/engine.h> -#endif -#if !defined(OPENSSL_NO_HMAC) -# include <openssl/hmac.h> -#endif -#include <openssl/x509_vfy.h> - -#include "openssl_missing.h" - -/* added in 1.0.2 */ -#if !defined(OPENSSL_NO_EC) -#if !defined(HAVE_EC_CURVE_NIST2NID) -static struct { - const char *name; - int nid; -} nist_curves[] = { - {"B-163", NID_sect163r2}, - {"B-233", NID_sect233r1}, - {"B-283", NID_sect283r1}, - {"B-409", NID_sect409r1}, - {"B-571", NID_sect571r1}, - {"K-163", NID_sect163k1}, - {"K-233", NID_sect233k1}, - {"K-283", NID_sect283k1}, - {"K-409", NID_sect409k1}, - {"K-571", NID_sect571k1}, - {"P-192", NID_X9_62_prime192v1}, - {"P-224", NID_secp224r1}, - {"P-256", NID_X9_62_prime256v1}, - {"P-384", NID_secp384r1}, - {"P-521", NID_secp521r1} -}; - -int -ossl_EC_curve_nist2nid(const char *name) -{ - size_t i; - for (i = 0; i < (sizeof(nist_curves) / sizeof(nist_curves[0])); i++) { - if (!strcmp(nist_curves[i].name, name)) - return nist_curves[i].nid; - } - return NID_undef; -} -#endif -#endif - -/*** added in 1.1.0 ***/ -#if !defined(HAVE_HMAC_CTX_NEW) -HMAC_CTX * -ossl_HMAC_CTX_new(void) -{ - HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); - if (!ctx) - return NULL; - HMAC_CTX_init(ctx); - return ctx; -} -#endif - -#if !defined(HAVE_HMAC_CTX_FREE) -void -ossl_HMAC_CTX_free(HMAC_CTX *ctx) -{ - if (ctx) { - HMAC_CTX_cleanup(ctx); - OPENSSL_free(ctx); - } -} -#endif - -#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) -void -ossl_X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg) -{ - if (psig != NULL) - *psig = crl->signature; - if (palg != NULL) - *palg = crl->sig_alg; -} -#endif - -#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) -void -ossl_X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig, - const X509_ALGOR **palg) -{ - if (psig != NULL) - *psig = req->signature; - if (palg != NULL) - *palg = req->sig_alg; -} -#endif diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 09998214e1..6592f9ccea 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -5,218 +5,28 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_OPENSSL_MISSING_H_) #define _OSSL_OPENSSL_MISSING_H_ #include "ruby/config.h" -/* added in 1.0.2 */ -#if !defined(OPENSSL_NO_EC) -#if !defined(HAVE_EC_CURVE_NIST2NID) -int ossl_EC_curve_nist2nid(const char *); -# define EC_curve_nist2nid ossl_EC_curve_nist2nid -#endif -#endif - -#if !defined(HAVE_X509_REVOKED_DUP) -# define X509_REVOKED_dup(rev) (X509_REVOKED *)ASN1_dup((i2d_of_void *)i2d_X509_REVOKED, \ - (d2i_of_void *)d2i_X509_REVOKED, (char *)(rev)) -#endif - -#if !defined(HAVE_X509_STORE_CTX_GET0_STORE) -# define X509_STORE_CTX_get0_store(x) ((x)->ctx) -#endif - -#if !defined(HAVE_SSL_IS_SERVER) -# define SSL_is_server(s) ((s)->server) -#endif - -/* added in 1.1.0 */ -#if !defined(HAVE_BN_GENCB_NEW) -# define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB))) -#endif - -#if !defined(HAVE_BN_GENCB_FREE) -# define BN_GENCB_free(cb) OPENSSL_free(cb) -#endif - -#if !defined(HAVE_BN_GENCB_GET_ARG) -# define BN_GENCB_get_arg(cb) (cb)->arg -#endif - -#if !defined(HAVE_EVP_MD_CTX_NEW) -# define EVP_MD_CTX_new EVP_MD_CTX_create -#endif - -#if !defined(HAVE_EVP_MD_CTX_FREE) -# define EVP_MD_CTX_free EVP_MD_CTX_destroy -#endif - -#if !defined(HAVE_HMAC_CTX_NEW) -HMAC_CTX *ossl_HMAC_CTX_new(void); -# define HMAC_CTX_new ossl_HMAC_CTX_new -#endif - -#if !defined(HAVE_HMAC_CTX_FREE) -void ossl_HMAC_CTX_free(HMAC_CTX *); -# define HMAC_CTX_free ossl_HMAC_CTX_free -#endif - -#if !defined(HAVE_X509_STORE_GET_EX_DATA) -# define X509_STORE_get_ex_data(x, idx) \ - CRYPTO_get_ex_data(&(x)->ex_data, (idx)) -#endif - -#if !defined(HAVE_X509_STORE_SET_EX_DATA) -# define X509_STORE_set_ex_data(x, idx, data) \ - CRYPTO_set_ex_data(&(x)->ex_data, (idx), (data)) -# define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \ - CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, (l), (p), \ - (newf), (dupf), (freef)) -#endif - -#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) -void ossl_X509_CRL_get0_signature(const X509_CRL *, const ASN1_BIT_STRING **, const X509_ALGOR **); -# define X509_CRL_get0_signature ossl_X509_CRL_get0_signature -#endif - -#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) -void ossl_X509_REQ_get0_signature(const X509_REQ *, const ASN1_BIT_STRING **, const X509_ALGOR **); -# define X509_REQ_get0_signature ossl_X509_REQ_get0_signature -#endif - -#if !defined(HAVE_X509_REVOKED_GET0_SERIALNUMBER) -# define X509_REVOKED_get0_serialNumber(x) ((x)->serialNumber) -#endif - -#if !defined(HAVE_X509_REVOKED_GET0_REVOCATIONDATE) -# define X509_REVOKED_get0_revocationDate(x) ((x)->revocationDate) -#endif - -#if !defined(HAVE_X509_GET0_TBS_SIGALG) -# define X509_get0_tbs_sigalg(x) ((x)->cert_info->signature) +/* added in 3.0.0 */ +#ifndef HAVE_EVP_MD_CTX_GET0_MD +# define EVP_MD_CTX_get0_md(ctx) EVP_MD_CTX_md(ctx) #endif -#if !defined(HAVE_X509_STORE_CTX_GET0_UNTRUSTED) -# define X509_STORE_CTX_get0_untrusted(x) ((x)->untrusted) -#endif - -#if !defined(HAVE_X509_STORE_CTX_GET0_CERT) -# define X509_STORE_CTX_get0_cert(x) ((x)->cert) -#endif - -#if !defined(HAVE_X509_STORE_CTX_GET0_CHAIN) -# define X509_STORE_CTX_get0_chain(ctx) X509_STORE_CTX_get_chain(ctx) -#endif - -#if !defined(HAVE_OCSP_SINGLERESP_GET0_ID) -# define OCSP_SINGLERESP_get0_id(s) ((s)->certId) -#endif - -#if !defined(HAVE_SSL_CTX_GET_CIPHERS) -# define SSL_CTX_get_ciphers(ctx) ((ctx)->cipher_list) -#endif - -#if !defined(HAVE_X509_UP_REF) -# define X509_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509) -#endif - -#if !defined(HAVE_X509_CRL_UP_REF) -# define X509_CRL_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_CRL); -#endif - -#if !defined(HAVE_X509_STORE_UP_REF) -# define X509_STORE_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_X509_STORE); -#endif - -#if !defined(HAVE_SSL_SESSION_UP_REF) -# define SSL_SESSION_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_SSL_SESSION); -#endif - -#if !defined(HAVE_EVP_PKEY_UP_REF) -# define EVP_PKEY_up_ref(x) \ - CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_EVP_PKEY); -#endif - -#if !defined(HAVE_OPAQUE_OPENSSL) -#define IMPL_PKEY_GETTER(_type, _name) \ -static inline _type *EVP_PKEY_get0_##_type(EVP_PKEY *pkey) { \ - return pkey->pkey._name; } -#define IMPL_KEY_ACCESSOR2(_type, _group, a1, a2, _fail_cond) \ -static inline void _type##_get0_##_group(const _type *obj, const BIGNUM **a1, const BIGNUM **a2) { \ - if (a1) *a1 = obj->a1; \ - if (a2) *a2 = obj->a2; } \ -static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2) { \ - if (_fail_cond) return 0; \ - BN_clear_free(obj->a1); obj->a1 = a1; \ - BN_clear_free(obj->a2); obj->a2 = a2; \ - return 1; } -#define IMPL_KEY_ACCESSOR3(_type, _group, a1, a2, a3, _fail_cond) \ -static inline void _type##_get0_##_group(const _type *obj, const BIGNUM **a1, const BIGNUM **a2, const BIGNUM **a3) { \ - if (a1) *a1 = obj->a1; \ - if (a2) *a2 = obj->a2; \ - if (a3) *a3 = obj->a3; } \ -static inline int _type##_set0_##_group(_type *obj, BIGNUM *a1, BIGNUM *a2, BIGNUM *a3) { \ - if (_fail_cond) return 0; \ - BN_clear_free(obj->a1); obj->a1 = a1; \ - BN_clear_free(obj->a2); obj->a2 = a2; \ - BN_clear_free(obj->a3); obj->a3 = a3; \ - return 1; } - -#if !defined(OPENSSL_NO_RSA) -IMPL_PKEY_GETTER(RSA, rsa) -IMPL_KEY_ACCESSOR3(RSA, key, n, e, d, (n == obj->n || e == obj->e || (obj->d && d == obj->d))) -IMPL_KEY_ACCESSOR2(RSA, factors, p, q, (p == obj->p || q == obj->q)) -IMPL_KEY_ACCESSOR3(RSA, crt_params, dmp1, dmq1, iqmp, (dmp1 == obj->dmp1 || dmq1 == obj->dmq1 || iqmp == obj->iqmp)) -#endif - -#if !defined(OPENSSL_NO_DSA) -IMPL_PKEY_GETTER(DSA, dsa) -IMPL_KEY_ACCESSOR2(DSA, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key))) -IMPL_KEY_ACCESSOR3(DSA, pqg, p, q, g, (p == obj->p || q == obj->q || g == obj->g)) -#endif - -#if !defined(OPENSSL_NO_DH) -IMPL_PKEY_GETTER(DH, dh) -IMPL_KEY_ACCESSOR2(DH, key, pub_key, priv_key, (pub_key == obj->pub_key || (obj->priv_key && priv_key == obj->priv_key))) -IMPL_KEY_ACCESSOR3(DH, pqg, p, q, g, (p == obj->p || (obj->q && q == obj->q) || g == obj->g)) -static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; } -#endif - -#if !defined(OPENSSL_NO_EC) -IMPL_PKEY_GETTER(EC_KEY, ec) -#endif - -#undef IMPL_PKEY_GETTER -#undef IMPL_KEY_ACCESSOR2 -#undef IMPL_KEY_ACCESSOR3 -#endif /* HAVE_OPAQUE_OPENSSL */ - -#if !defined(EVP_CTRL_AEAD_GET_TAG) -# define EVP_CTRL_AEAD_GET_TAG EVP_CTRL_GCM_GET_TAG -# define EVP_CTRL_AEAD_SET_TAG EVP_CTRL_GCM_SET_TAG -# define EVP_CTRL_AEAD_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN -#endif - -#if !defined(HAVE_X509_GET0_NOTBEFORE) -# define X509_get0_notBefore(x) X509_get_notBefore(x) -# define X509_get0_notAfter(x) X509_get_notAfter(x) -# define X509_CRL_get0_lastUpdate(x) X509_CRL_get_lastUpdate(x) -# define X509_CRL_get0_nextUpdate(x) X509_CRL_get_nextUpdate(x) -# define X509_set1_notBefore(x, t) X509_set_notBefore(x, t) -# define X509_set1_notAfter(x, t) X509_set_notAfter(x, t) -# define X509_CRL_set1_lastUpdate(x, t) X509_CRL_set_lastUpdate(x, t) -# define X509_CRL_set1_nextUpdate(x, t) X509_CRL_set_nextUpdate(x, t) +/* + * OpenSSL 1.1.0 added EVP_MD_CTX_pkey_ctx(), and then it was renamed to + * EVP_MD_CTX_get_pkey_ctx(x) in OpenSSL 3.0. + */ +#ifndef HAVE_EVP_MD_CTX_GET_PKEY_CTX +# define EVP_MD_CTX_get_pkey_ctx(x) EVP_MD_CTX_pkey_ctx(x) #endif -#if !defined(HAVE_SSL_SESSION_GET_PROTOCOL_VERSION) -# define SSL_SESSION_get_protocol_version(s) ((s)->ssl_version) +#ifndef HAVE_EVP_PKEY_EQ +# define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b) #endif #endif /* _OSSL_OPENSSL_MISSING_H_ */ diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 69758aed7a..98127fcba0 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -5,87 +5,79 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" #include <stdarg.h> /* for ossl_raise */ -#include <ruby/thread_native.h> /* for OpenSSL < 1.1.0 locks */ /* * Data Conversion */ -#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \ -STACK_OF(type) * \ -ossl_##name##_ary2sk0(VALUE ary) \ -{ \ - STACK_OF(type) *sk; \ - VALUE val; \ - type *x; \ - int i; \ - \ - Check_Type(ary, T_ARRAY); \ - sk = sk_##type##_new_null(); \ - if (!sk) ossl_raise(eOSSLError, NULL); \ - \ - for (i = 0; i < RARRAY_LEN(ary); i++) { \ - val = rb_ary_entry(ary, i); \ - if (!rb_obj_is_kind_of(val, expected_class)) { \ - sk_##type##_pop_free(sk, type##_free); \ - ossl_raise(eOSSLError, "object in array not" \ - " of class ##type##"); \ - } \ - x = dup(val); /* NEED TO DUP */ \ - sk_##type##_push(sk, x); \ - } \ - return sk; \ -} \ - \ -STACK_OF(type) * \ -ossl_protect_##name##_ary2sk(VALUE ary, int *status) \ -{ \ - return (STACK_OF(type)*)rb_protect( \ - (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \ - ary, \ - status); \ -} \ - \ -STACK_OF(type) * \ -ossl_##name##_ary2sk(VALUE ary) \ -{ \ - STACK_OF(type) *sk; \ - int status = 0; \ - \ - sk = ossl_protect_##name##_ary2sk(ary, &status); \ - if (status) rb_jump_tag(status); \ - \ - return sk; \ +#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \ +VALUE \ +ossl_##name##_ary2sk0(VALUE ary) \ +{ \ + STACK_OF(type) *sk; \ + VALUE val; \ + type *x; \ + int i; \ + \ + Check_Type(ary, T_ARRAY); \ + sk = sk_##type##_new_null(); \ + if (!sk) ossl_raise(eOSSLError, NULL); \ + \ + for (i = 0; i < RARRAY_LEN(ary); i++) { \ + val = rb_ary_entry(ary, i); \ + if (!rb_obj_is_kind_of(val, expected_class)) { \ + sk_##type##_pop_free(sk, type##_free); \ + ossl_raise(eOSSLError, "object in array not" \ + " of class ##type##"); \ + } \ + x = dup(val); /* NEED TO DUP */ \ + sk_##type##_push(sk, x); \ + } \ + return (VALUE)sk; \ +} \ + \ +STACK_OF(type) * \ +ossl_protect_##name##_ary2sk(VALUE ary, int *status) \ +{ \ + return (STACK_OF(type)*)rb_protect( \ + (VALUE (*)(VALUE))ossl_##name##_ary2sk0, \ + ary, \ + status); \ +} \ + \ +STACK_OF(type) * \ +ossl_##name##_ary2sk(VALUE ary) \ +{ \ + STACK_OF(type) *sk; \ + int status = 0; \ + \ + sk = ossl_protect_##name##_ary2sk(ary, &status); \ + if (status) rb_jump_tag(status); \ + \ + return sk; \ } OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr) -#define OSSL_IMPL_SK2ARY(name, type) \ -VALUE \ -ossl_##name##_sk2ary(const STACK_OF(type) *sk) \ -{ \ - type *t; \ - int i, num; \ - VALUE ary; \ - \ - if (!sk) { \ - OSSL_Debug("empty sk!"); \ - return Qnil; \ - } \ - num = sk_##type##_num(sk); \ - if (num < 0) { \ - OSSL_Debug("items in sk < -1???"); \ - return rb_ary_new(); \ - } \ - ary = rb_ary_new2(num); \ - \ - for (i=0; i<num; i++) { \ - t = sk_##type##_value(sk, i); \ - rb_ary_push(ary, ossl_##name##_new(t)); \ - } \ - return ary; \ +#define OSSL_IMPL_SK2ARY(name, type) \ +VALUE \ +ossl_##name##_sk2ary(const STACK_OF(type) *sk) \ +{ \ + type *t; \ + int i, num; \ + VALUE ary; \ + \ + RUBY_ASSERT(sk != NULL); \ + num = sk_##type##_num(sk); \ + ary = rb_ary_new_capa(num); \ + \ + for (i=0; i<num; i++) { \ + t = sk_##type##_value(sk, i); \ + rb_ary_push(ary, ossl_##name##_new(t)); \ + } \ + return ary; \ } OSSL_IMPL_SK2ARY(x509, X509) OSSL_IMPL_SK2ARY(x509crl, X509_CRL) @@ -105,14 +97,14 @@ ossl_str_new(const char *ptr, long len, int *pstate) str = rb_protect(ossl_str_new_i, len, &state); if (pstate) - *pstate = state; + *pstate = state; if (state) { - if (!pstate) - rb_set_errinfo(Qnil); - return Qnil; + if (!pstate) + rb_set_errinfo(Qnil); + return Qnil; } if (ptr) - memcpy(RSTRING_PTR(str), ptr, len); + memcpy(RSTRING_PTR(str), ptr, len); return str; } @@ -125,22 +117,22 @@ ossl_buf2str(char *buf, int len) str = ossl_str_new(buf, len, &state); OPENSSL_free(buf); if (state) - rb_jump_tag(state); + rb_jump_tag(state); return str; } void -ossl_bin2hex(unsigned char *in, char *out, size_t inlen) +ossl_bin2hex(const unsigned char *in, char *out, size_t inlen) { const char *hex = "0123456789abcdef"; size_t i; assert(inlen <= LONG_MAX / 2); for (i = 0; i < inlen; i++) { - unsigned char p = in[i]; + unsigned char p = in[i]; - out[i * 2 + 0] = hex[p >> 4]; - out[i * 2 + 1] = hex[p & 0x0f]; + out[i * 2 + 0] = hex[p >> 4]; + out[i * 2 + 1] = hex[p & 0x0f]; } } @@ -151,14 +143,14 @@ VALUE ossl_pem_passwd_value(VALUE pass) { if (NIL_P(pass)) - return Qnil; + return Qnil; StringValue(pass); /* PEM_BUFSIZE is currently used as the second argument of pem_password_cb, * that is +max_len+ of ossl_pem_passwd_cb() */ if (RSTRING_LEN(pass) > PEM_BUFSIZE) - ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE); + ossl_raise(eOSSLError, "password must not be longer than %d bytes", PEM_BUFSIZE); return pass; } @@ -168,7 +160,7 @@ ossl_pem_passwd_cb0(VALUE flag) { VALUE pass = rb_yield(flag); if (NIL_P(pass)) - return Qnil; + return Qnil; StringValue(pass); return pass; } @@ -181,46 +173,46 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_) VALUE rflag, pass = (VALUE)pwd_; if (RTEST(pass)) { - /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not - * work because it does not allow NUL characters and truncates to 1024 - * bytes silently if the input is over 1024 bytes */ - if (RB_TYPE_P(pass, T_STRING)) { - len = RSTRING_LEN(pass); - if (len <= max_len) { - memcpy(buf, RSTRING_PTR(pass), len); - return (int)len; - } - } - OSSL_Debug("passed data is not valid String???"); - return -1; + /* PEM_def_callback(buf, max_len, flag, StringValueCStr(pass)) does not + * work because it does not allow NUL characters and truncates to 1024 + * bytes silently if the input is over 1024 bytes */ + if (RB_TYPE_P(pass, T_STRING)) { + len = RSTRING_LEN(pass); + if (len <= max_len) { + memcpy(buf, RSTRING_PTR(pass), len); + return (int)len; + } + } + OSSL_Debug("passed data is not valid String???"); + return -1; } if (!rb_block_given_p()) { - return PEM_def_callback(buf, max_len, flag, NULL); + return PEM_def_callback(buf, max_len, flag, NULL); } while (1) { - /* - * when the flag is nonzero, this passphrase - * will be used to perform encryption; otherwise it will - * be used to perform decryption. - */ - rflag = flag ? Qtrue : Qfalse; - pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status); - if (status) { - /* ignore an exception raised. */ - rb_set_errinfo(Qnil); - return -1; - } - if (NIL_P(pass)) - return -1; - len = RSTRING_LEN(pass); - if (len > max_len) { - rb_warning("password must not be longer than %d bytes", max_len); - continue; - } - memcpy(buf, RSTRING_PTR(pass), len); - break; + /* + * when the flag is nonzero, this password + * will be used to perform encryption; otherwise it will + * be used to perform decryption. + */ + rflag = flag ? Qtrue : Qfalse; + pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status); + if (status) { + /* ignore an exception raised. */ + rb_set_errinfo(Qnil); + return -1; + } + if (NIL_P(pass)) + return -1; + len = RSTRING_LEN(pass); + if (len > max_len) { + rb_warning("password must not be longer than %d bytes", max_len); + continue; + } + memcpy(buf, RSTRING_PTR(pass), len); + break; } return (int)len; } @@ -255,38 +247,46 @@ VALUE ossl_to_der_if_possible(VALUE obj) { if(rb_respond_to(obj, ossl_s_to_der)) - return ossl_to_der(obj); + return ossl_to_der(obj); return obj; } /* * Errors */ -static VALUE -ossl_make_error(VALUE exc, const char *fmt, va_list args) +static ID id_i_errors; + +static void collect_errors_into(VALUE ary); + +VALUE +ossl_make_error(VALUE exc, VALUE str) { - VALUE str = Qnil; unsigned long e; + const char *data; + int flags; + VALUE errors = rb_ary_new(); - if (fmt) { - str = rb_vsprintf(fmt, args); - } - e = ERR_peek_last_error(); + if (NIL_P(str)) + str = rb_str_new(NULL, 0); + +#ifdef HAVE_ERR_GET_ERROR_ALL + e = ERR_peek_last_error_all(NULL, NULL, NULL, &data, &flags); +#else + e = ERR_peek_last_error_line_data(NULL, NULL, &data, &flags); +#endif if (e) { - const char *msg = ERR_reason_error_string(e); - - if (NIL_P(str)) { - if (msg) str = rb_str_new_cstr(msg); - } - else { - if (RSTRING_LEN(str)) rb_str_cat2(str, ": "); - rb_str_cat2(str, msg ? msg : "(null)"); - } - ossl_clear_error(); + const char *msg = ERR_reason_error_string(e); + + if (RSTRING_LEN(str)) rb_str_cat_cstr(str, ": "); + rb_str_cat_cstr(str, msg ? msg : "(null)"); + if (flags & ERR_TXT_STRING && data) + rb_str_catf(str, " (%s)", data); + collect_errors_into(errors); } - if (NIL_P(str)) str = rb_str_new(0, 0); - return rb_exc_new3(exc, str); + VALUE obj = rb_exc_new_str(exc, str); + rb_ivar_set(obj, id_i_errors, errors); + return obj; } void @@ -294,51 +294,111 @@ ossl_raise(VALUE exc, const char *fmt, ...) { va_list args; VALUE err; - va_start(args, fmt); - err = ossl_make_error(exc, fmt, args); - va_end(args); - rb_exc_raise(err); + + if (fmt) { + va_start(args, fmt); + err = rb_vsprintf(fmt, args); + va_end(args); + } + else { + err = Qnil; + } + + rb_exc_raise(ossl_make_error(exc, err)); } -void -ossl_clear_error(void) +static void +collect_errors_into(VALUE ary) { - if (dOSSL == Qtrue) { - unsigned long e; - const char *file, *data, *errstr; - int line, flags; - - while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) { - errstr = ERR_error_string(e, NULL); - if (!errstr) - errstr = "(null)"; - - if (flags & ERR_TXT_STRING) { - if (!data) - data = "(null)"; - rb_warn("error on stack: %s (%s)", errstr, data); - } - else { - rb_warn("error on stack: %s", errstr); - } - } + if (dOSSL == Qtrue || !NIL_P(ary)) { + unsigned long e; + const char *file, *data, *func, *lib, *reason; + int line, flags; + +#ifdef HAVE_ERR_GET_ERROR_ALL + while ((e = ERR_get_error_all(&file, &line, &func, &data, &flags))) { +#else + while ((e = ERR_get_error_line_data(&file, &line, &data, &flags))) { + func = ERR_func_error_string(e); +#endif + lib = ERR_lib_error_string(e); + reason = ERR_reason_error_string(e); + + VALUE str = rb_sprintf("error:%08lX:%s:%s:%s", e, lib ? lib : "", + func ? func : "", reason ? reason : ""); + if (flags & ERR_TXT_STRING) { + if (!data) + data = "(null)"; + rb_str_catf(str, " (%s)", data); + } + + if (dOSSL == Qtrue) + rb_warn("error on stack: %"PRIsVALUE, str); + if (!NIL_P(ary)) + rb_ary_push(ary, str); + } } else { - ERR_clear_error(); + ERR_clear_error(); + } +} + +void +ossl_clear_error(void) +{ + collect_errors_into(Qnil); +} + +/* + * call-seq: + * ossl_error.detailed_message(**) -> string + * + * Returns the exception message decorated with the captured \OpenSSL error + * queue entries. + */ +static VALUE +osslerror_detailed_message(int argc, VALUE *argv, VALUE self) +{ + VALUE str; +#ifdef HAVE_RB_CALL_SUPER_KW + // Ruby >= 3.2 + if (RTEST(rb_funcall(rb_eException, rb_intern("method_defined?"), 1, + ID2SYM(rb_intern("detailed_message"))))) + str = rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS); + else +#endif + str = rb_funcall(self, rb_intern("message"), 0); + VALUE errors = rb_attr_get(self, id_i_errors); + + // OpenSSLError was not created by ossl_make_error() + if (!RB_TYPE_P(errors, T_ARRAY)) + return str; + + str = rb_str_resurrect(str); + rb_str_catf(str, "\nOpenSSL error queue reported %ld errors:", + RARRAY_LEN(errors)); + for (long i = 0; i < RARRAY_LEN(errors); i++) { + VALUE err = RARRAY_AREF(errors, i); + rb_str_catf(str, "\n%"PRIsVALUE, err); } + return str; } /* * call-seq: * OpenSSL.errors -> [String...] * - * See any remaining errors held in queue. + * Returns any remaining errors held in the \OpenSSL thread-local error queue + * and clears the queue. This should normally return an empty array. + * + * This is intended for debugging Ruby/OpenSSL. If you see any errors here, + * it likely indicates a bug in the extension. Please file an issue at + * https://github.com/ruby/openssl. * - * Any errors you see here are probably due to a bug in Ruby's OpenSSL - * implementation. + * For debugging your program, OpenSSL.debug= may be useful. */ -VALUE -ossl_get_errors(void) +static VALUE +ossl_get_errors(VALUE _) { VALUE ary; long e; @@ -356,25 +416,11 @@ ossl_get_errors(void) */ VALUE dOSSL; -#if !defined(HAVE_VA_ARGS_MACRO) -void -ossl_debug(const char *fmt, ...) -{ - va_list args; - - if (dOSSL == Qtrue) { - fprintf(stderr, "OSSL_DEBUG: "); - va_start(args, fmt); - vfprintf(stderr, fmt, args); - va_end(args); - fprintf(stderr, " [CONTEXT N/A]\n"); - } -} -#endif - /* * call-seq: * OpenSSL.debug -> true | false + * + * Returns whether Ruby/OpenSSL's debug mode is currently enabled. */ static VALUE ossl_debug_get(VALUE self) @@ -384,9 +430,9 @@ ossl_debug_get(VALUE self) /* * call-seq: - * OpenSSL.debug = boolean -> boolean + * OpenSSL.debug = boolean * - * Turns on or off debug mode. With debug mode, all erros added to the OpenSSL + * Turns on or off debug mode. With debug mode, all errors added to the \OpenSSL * error queue will be printed to stderr. */ static VALUE @@ -400,12 +446,18 @@ ossl_debug_set(VALUE self, VALUE val) /* * call-seq: * OpenSSL.fips_mode -> true | false + * + * Returns whether the FIPS mode is currently enabled. */ static VALUE ossl_fips_mode_get(VALUE self) { -#ifdef OPENSSL_FIPS +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + VALUE enabled; + enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse; + return enabled; +#elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) VALUE enabled; enabled = FIPS_mode() ? Qtrue : Qfalse; return enabled; @@ -416,10 +468,10 @@ ossl_fips_mode_get(VALUE self) /* * call-seq: - * OpenSSL.fips_mode = boolean -> boolean + * OpenSSL.fips_mode = boolean * * Turns FIPS mode on or off. Turning on FIPS mode will obviously only have an - * effect for FIPS-capable installations of the OpenSSL library. Trying to do + * effect for FIPS-capable installations of the \OpenSSL library. Trying to do * so otherwise will result in an error. * * === Examples @@ -429,183 +481,65 @@ ossl_fips_mode_get(VALUE self) static VALUE ossl_fips_mode_set(VALUE self, VALUE enabled) { - -#ifdef OPENSSL_FIPS +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + if (RTEST(enabled)) { + if (!EVP_default_properties_enable_fips(NULL, 1)) { + ossl_raise(eOSSLError, "Turning on FIPS mode failed"); + } + } else { + if (!EVP_default_properties_enable_fips(NULL, 0)) { + ossl_raise(eOSSLError, "Turning off FIPS mode failed"); + } + } + return enabled; +#elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) if (RTEST(enabled)) { - int mode = FIPS_mode(); - if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */ - ossl_raise(eOSSLError, "Turning on FIPS mode failed"); + int mode = FIPS_mode(); + if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */ + ossl_raise(eOSSLError, "Turning on FIPS mode failed"); } else { - if(!FIPS_mode_set(0)) /* turning off twice is OK */ - ossl_raise(eOSSLError, "Turning off FIPS mode failed"); + if(!FIPS_mode_set(0)) /* turning off twice is OK */ + ossl_raise(eOSSLError, "Turning off FIPS mode failed"); } return enabled; #else if (RTEST(enabled)) - ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode"); + ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode"); return enabled; #endif } -#if defined(OSSL_DEBUG) -#if !defined(LIBRESSL_VERSION_NUMBER) && \ - (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \ - defined(CRYPTO_malloc_debug_init)) /* * call-seq: - * OpenSSL.mem_check_start -> nil + * OpenSSL.fixed_length_secure_compare(string, string) -> true or false * - * Calls CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON). Starts tracking memory - * allocations. See also OpenSSL.print_mem_leaks. + * Constant time memory comparison for fixed length strings, such as results + * of \HMAC calculations. * - * This is available only when built with a capable OpenSSL and --enable-debug - * configure option. + * Returns +true+ if the strings are identical, +false+ if they are of the same + * length but not identical. If the length is different, ArgumentError is + * raised. */ static VALUE -mem_check_start(VALUE self) -{ - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); - return Qnil; -} - -/* - * call-seq: - * OpenSSL.print_mem_leaks -> true | false - * - * For debugging the Ruby/OpenSSL library. Calls CRYPTO_mem_leaks_fp(stderr). - * Prints detected memory leaks to standard error. This cleans the global state - * up thus you cannot use any methods of the library after calling this. - * - * Returns +true+ if leaks detected, +false+ otherwise. - * - * This is available only when built with a capable OpenSSL and --enable-debug - * configure option. - * - * === Example - * OpenSSL.mem_check_start - * NOT_GCED = OpenSSL::PKey::RSA.new(256) - * - * END { - * GC.start - * OpenSSL.print_mem_leaks # will print the leakage - * } - */ -static VALUE -print_mem_leaks(VALUE self) -{ -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - int ret; -#endif - - BN_CTX_free(ossl_bn_ctx); - ossl_bn_ctx = NULL; - -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - ret = CRYPTO_mem_leaks_fp(stderr); - if (ret < 0) - ossl_raise(eOSSLError, "CRYPTO_mem_leaks_fp"); - return ret ? Qfalse : Qtrue; -#else - CRYPTO_mem_leaks_fp(stderr); - return Qnil; -#endif -} -#endif -#endif - -#if !defined(HAVE_OPENSSL_110_THREADING_API) -/** - * Stores locks needed for OpenSSL thread safety - */ -struct CRYPTO_dynlock_value { - rb_nativethread_lock_t lock; - rb_nativethread_id_t owner; - size_t count; -}; - -static void -ossl_lock_init(struct CRYPTO_dynlock_value *l) +ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) { - rb_nativethread_lock_initialize(&l->lock); - l->count = 0; -} + const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1); + const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2); + long len1 = RSTRING_LEN(str1); + long len2 = RSTRING_LEN(str2); -static void -ossl_lock_unlock(int mode, struct CRYPTO_dynlock_value *l) -{ - if (mode & CRYPTO_LOCK) { - /* TODO: rb_nativethread_id_t is not necessarily compared with ==. */ - rb_nativethread_id_t tid = rb_nativethread_self(); - if (l->count && l->owner == tid) { - l->count++; - return; - } - rb_nativethread_lock_lock(&l->lock); - l->owner = tid; - l->count = 1; - } else { - if (!--l->count) - rb_nativethread_lock_unlock(&l->lock); + if (len1 != len2) { + ossl_raise(rb_eArgError, "inputs must be of equal length"); } -} - -static struct CRYPTO_dynlock_value * -ossl_dyn_create_callback(const char *file, int line) -{ - /* Do not use xmalloc() here, since it may raise NoMemoryError */ - struct CRYPTO_dynlock_value *dynlock = - OPENSSL_malloc(sizeof(struct CRYPTO_dynlock_value)); - if (dynlock) - ossl_lock_init(dynlock); - return dynlock; -} -static void -ossl_dyn_lock_callback(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line) -{ - ossl_lock_unlock(mode, l); -} - -static void -ossl_dyn_destroy_callback(struct CRYPTO_dynlock_value *l, const char *file, int line) -{ - rb_nativethread_lock_destroy(&l->lock); - OPENSSL_free(l); -} - -static void ossl_threadid_func(CRYPTO_THREADID *id) -{ - /* register native thread id */ - CRYPTO_THREADID_set_pointer(id, (void *)rb_nativethread_self()); -} - -static struct CRYPTO_dynlock_value *ossl_locks; - -static void -ossl_lock_callback(int mode, int type, const char *file, int line) -{ - ossl_lock_unlock(mode, &ossl_locks[type]); -} - -static void Init_ossl_locks(void) -{ - int i; - int num_locks = CRYPTO_num_locks(); - - ossl_locks = ALLOC_N(struct CRYPTO_dynlock_value, num_locks); - for (i = 0; i < num_locks; i++) - ossl_lock_init(&ossl_locks[i]); - - CRYPTO_THREADID_set_callback(ossl_threadid_func); - CRYPTO_set_locking_callback(ossl_lock_callback); - CRYPTO_set_dynlock_create_callback(ossl_dyn_create_callback); - CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback); - CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback); + switch (CRYPTO_memcmp(p1, p2, len1)) { + case 0: return Qtrue; + default: return Qfalse; + } } -#endif /* !HAVE_OPENSSL_110_THREADING_API */ /* - * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the + * OpenSSL provides \SSL, TLS and general purpose cryptography. It wraps the * OpenSSL[https://www.openssl.org/] library. * * = Examples @@ -626,23 +560,21 @@ static void Init_ossl_locks(void) * * key = OpenSSL::PKey::RSA.new 2048 * - * open 'private_key.pem', 'w' do |io| io.write key.to_pem end - * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end + * File.write 'private_key.pem', key.private_to_pem + * File.write 'public_key.pem', key.public_to_pem * * === Exporting a Key * * Keys saved to disk without encryption are not secure as anyone who gets * ahold of the key may use it unless it is encrypted. In order to securely - * export a key you may export it with a pass phrase. + * export a key you may export it with a password. * - * cipher = OpenSSL::Cipher.new 'AES-128-CBC' - * pass_phrase = 'my secure pass phrase goes here' + * cipher = OpenSSL::Cipher.new 'aes-256-cbc' + * password = 'my secure password goes here' * - * key_secure = key.export cipher, pass_phrase + * key_secure = key.private_to_pem cipher, password * - * open 'private.secure.pem', 'w' do |io| - * io.write key_secure - * end + * File.write 'private.secure.pem', key_secure * * OpenSSL::Cipher.ciphers returns a list of available ciphers. * @@ -650,25 +582,25 @@ static void Init_ossl_locks(void) * * A key can also be loaded from a file. * - * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem' + * key2 = OpenSSL::PKey.read File.read 'private_key.pem' * key2.public? # => true * key2.private? # => true * * or * - * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem' + * key3 = OpenSSL::PKey.read File.read 'public_key.pem' * key3.public? # => true * key3.private? # => false * * === Loading an Encrypted Key * - * OpenSSL will prompt you for your pass phrase when loading an encrypted key. - * If you will not be able to type in the pass phrase you may provide it when + * \OpenSSL will prompt you for your password when loading an encrypted key. + * If you will not be able to type in the password you may provide it when * loading the key: * * key4_pem = File.read 'private.secure.pem' - * pass_phrase = 'my secure pass phrase goes here' - * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase + * password = 'my secure password goes here' + * key4 = OpenSSL::PKey.read key4_pem, password * * == RSA Encryption * @@ -710,16 +642,14 @@ static void Init_ossl_locks(void) * To sign a document, a cryptographically secure hash of the document is * computed first, which is then signed using the private key. * - * digest = OpenSSL::Digest::SHA256.new - * signature = key.sign digest, document + * signature = key.sign 'SHA256', document * * To validate the signature, again a hash of the document is computed and * the signature is decrypted using the public key. The result is then * compared to the hash just computed, if they are equal the signature was * valid. * - * digest = OpenSSL::Digest::SHA256.new - * if key.verify digest, signature, document + * if key.verify 'SHA256', signature, document * puts 'Valid' * else * puts 'Invalid' @@ -727,7 +657,7 @@ static void Init_ossl_locks(void) * * == PBKDF2 Password-based Encryption * - * If supported by the underlying OpenSSL version used, Password-based + * If supported by the underlying \OpenSSL version used, Password-based * Encryption should use the features of PKCS5. If not supported or if * required by legacy applications, the older, less secure methods specified * in RFC 2898 are also supported (see below). @@ -745,7 +675,7 @@ static void Init_ossl_locks(void) * using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt, * the number of iterations largely depends on the hardware being used. * - * cipher = OpenSSL::Cipher.new 'AES-128-CBC' + * cipher = OpenSSL::Cipher.new 'aes-256-cbc' * cipher.encrypt * iv = cipher.random_iv * @@ -753,7 +683,7 @@ static void Init_ossl_locks(void) * salt = OpenSSL::Random.random_bytes 16 * iter = 20000 * key_len = cipher.key_len - * digest = OpenSSL::Digest::SHA256.new + * digest = OpenSSL::Digest.new('SHA256') * * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest) * cipher.key = key @@ -768,7 +698,7 @@ static void Init_ossl_locks(void) * Use the same steps as before to derive the symmetric AES key, this time * setting the Cipher up for decryption. * - * cipher = OpenSSL::Cipher.new 'AES-128-CBC' + * cipher = OpenSSL::Cipher.new 'aes-256-cbc' * cipher.decrypt * cipher.iv = iv # the one generated with #random_iv * @@ -776,7 +706,7 @@ static void Init_ossl_locks(void) * salt = ... # the one generated above * iter = 20000 * key_len = cipher.key_len - * digest = OpenSSL::Digest::SHA256.new + * digest = OpenSSL::Digest.new('SHA256') * * key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest) * cipher.key = key @@ -786,46 +716,7 @@ static void Init_ossl_locks(void) * decrypted = cipher.update encrypted * decrypted << cipher.final * - * == PKCS #5 Password-based Encryption - * - * PKCS #5 is a password-based encryption standard documented at - * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or - * passphrase to be used to create a secure encryption key. If possible, PBKDF2 - * as described above should be used if the circumstances allow it. - * - * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption - * key. - * - * pass_phrase = 'my secure pass phrase goes here' - * salt = '8 octets' - * - * === Encryption - * - * First set up the cipher for encryption - * - * encryptor = OpenSSL::Cipher.new 'AES-128-CBC' - * encryptor.encrypt - * encryptor.pkcs5_keyivgen pass_phrase, salt - * - * Then pass the data you want to encrypt through - * - * encrypted = encryptor.update 'top secret document' - * encrypted << encryptor.final - * - * === Decryption - * - * Use a new Cipher instance set up for decryption - * - * decryptor = OpenSSL::Cipher.new 'AES-128-CBC' - * decryptor.decrypt - * decryptor.pkcs5_keyivgen pass_phrase, salt - * - * Then pass the data you want to decrypt through - * - * plain = decryptor.update encrypted - * plain << decryptor.final - * - * == X509 Certificates + * == \X509 Certificates * * === Creating a Certificate * @@ -833,7 +724,7 @@ static void Init_ossl_locks(void) * signature. * * key = OpenSSL::PKey::RSA.new 2048 - * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example' + * name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example' * * cert = OpenSSL::X509::Certificate.new * cert.version = 2 @@ -862,7 +753,7 @@ static void Init_ossl_locks(void) * extension_factory.create_extension('subjectKeyIdentifier', 'hash') * * The list of supported extensions (and in some cases their possible values) - * can be derived from the "objects.h" file in the OpenSSL source code. + * can be derived from the "objects.h" file in the \OpenSSL source code. * * === Signing a Certificate * @@ -872,7 +763,7 @@ static void Init_ossl_locks(void) * certificate. * * cert.issuer = name - * cert.sign key, OpenSSL::Digest::SHA1.new + * cert.sign key, OpenSSL::Digest.new('SHA1') * * open 'certificate.pem', 'w' do |io| io.write cert.to_pem end * @@ -902,12 +793,12 @@ static void Init_ossl_locks(void) * not readable by other users. * * ca_key = OpenSSL::PKey::RSA.new 2048 - * pass_phrase = 'my secure pass phrase goes here' + * password = 'my secure password goes here' * - * cipher = OpenSSL::Cipher.new 'AES-128-CBC' + * cipher = 'aes-256-cbc' * * open 'ca_key.pem', 'w', 0400 do |io| - * io.write ca_key.export(cipher, pass_phrase) + * io.write ca_key.private_to_pem(cipher, password) * end * * === CA Certificate @@ -915,7 +806,7 @@ static void Init_ossl_locks(void) * A CA certificate is created the same way we created a certificate above, but * with different extensions. * - * ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example' + * ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example' * * ca_cert = OpenSSL::X509::Certificate.new * ca_cert.serial = 0 @@ -948,7 +839,7 @@ static void Init_ossl_locks(void) * * Root CA certificates are self-signed. * - * ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new + * ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1') * * The CA certificate is saved to disk so it may be distributed to all the * users of the keys this CA will sign. @@ -966,7 +857,7 @@ static void Init_ossl_locks(void) * csr.version = 0 * csr.subject = name * csr.public_key = key.public_key - * csr.sign key, OpenSSL::Digest::SHA1.new + * csr.sign key, OpenSSL::Digest.new('SHA1') * * A CSR is saved to disk and sent to the CA for signing. * @@ -1010,29 +901,29 @@ static void Init_ossl_locks(void) * csr_cert.add_extension \ * extension_factory.create_extension('subjectKeyIdentifier', 'hash') * - * csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new + * csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1') * * open 'csr_cert.pem', 'w' do |io| * io.write csr_cert.to_pem * end * - * == SSL and TLS Connections + * == \SSL and TLS Connections * - * Using our created key and certificate we can create an SSL or TLS connection. - * An SSLContext is used to set up an SSL session. + * Using our created key and certificate we can create an \SSL or TLS + * connection. An OpenSSL::SSL::SSLContext is used to set up an \SSL session. * * context = OpenSSL::SSL::SSLContext.new * - * === SSL Server + * === \SSL Server * - * An SSL server requires the certificate and private key to communicate + * An \SSL server requires the certificate and private key to communicate * securely with its clients: * * context.cert = cert * context.key = key * - * Then create an SSLServer with a TCP server socket and the context. Use the - * SSLServer like an ordinary TCP server. + * Then create an OpenSSL::SSL::SSLServer with a TCP server socket and the + * context. Use the SSLServer like an ordinary TCP server. * * require 'socket' * @@ -1042,23 +933,24 @@ static void Init_ossl_locks(void) * loop do * ssl_connection = ssl_server.accept * - * data = connection.gets + * data = ssl_connection.gets * * response = "I got #{data.dump}" * puts response * - * connection.puts "I got #{data.dump}" - * connection.close + * ssl_connection.puts "I got #{data.dump}" + * ssl_connection.close * end * - * === SSL client + * === \SSL client * - * An SSL client is created with a TCP socket and the context. - * SSLSocket#connect must be called to initiate the SSL handshake and start - * encryption. A key and certificate are not required for the client socket. + * An \SSL client is created with a TCP socket and the context. + * OpenSSL::SSL::SSLSocket#connect must be called to initiate the \SSL handshake + * and start encryption. A key and certificate are not required for the client + * socket. * - * Note that SSLSocket#close doesn't close the underlying socket by default. Set - * SSLSocket#sync_close to true if you want. + * Note that OpenSSL::SSL::SSLSocket#close doesn't close the underlying socket + * by default. Set OpenSSL::SSL::SSLSocket#sync_close to true if you want. * * require 'socket' * @@ -1074,7 +966,7 @@ static void Init_ossl_locks(void) * * === Peer Verification * - * An unverified SSL connection does not provide much security. For enhanced + * An unverified \SSL connection does not provide much security. For enhanced * security the client or server can verify the certificate of its peer. * * The client can be modified to verify the server's certificate against the @@ -1099,6 +991,10 @@ static void Init_ossl_locks(void) void Init_openssl(void) { +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + #undef rb_intern /* * Init timezone info @@ -1110,67 +1006,109 @@ Init_openssl(void) /* * Init all digests, ciphers */ -#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 if (!OPENSSL_init_ssl(0, NULL)) rb_raise(rb_eRuntimeError, "OPENSSL_init_ssl"); -#else - OpenSSL_add_ssl_algorithms(); - OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); - SSL_load_error_strings(); -#endif /* * Init main module */ - mOSSL = rb_define_module("OpenSSL"); rb_global_variable(&mOSSL); + mOSSL = rb_define_module("OpenSSL"); + rb_define_singleton_method(mOSSL, "fixed_length_secure_compare", ossl_crypto_fixed_length_secure_compare, 2); /* - * OpenSSL ruby extension version + * \OpenSSL library version string used to compile the Ruby/OpenSSL + * extension. This may differ from the version used at runtime. */ - rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION)); + rb_define_const(mOSSL, "OPENSSL_VERSION", + rb_obj_freeze(rb_str_new_cstr(OPENSSL_VERSION_TEXT))); /* - * Version of OpenSSL the ruby OpenSSL extension was built with + * \OpenSSL library version string currently used at runtime. */ - rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT)); + rb_define_const( + mOSSL, + "OPENSSL_LIBRARY_VERSION", + rb_obj_freeze(rb_str_new_cstr(OpenSSL_version(OPENSSL_VERSION))) + ); /* - * Version of OpenSSL the ruby OpenSSL extension is running with + * \OpenSSL library version number used to compile the Ruby/OpenSSL + * extension. This may differ from the version used at runtime. + * + * The version number is encoded into a single integer value. The number + * follows the format: + * + * [\OpenSSL 3.0.0 or later] + * <tt>0xMNN00PP0</tt> (major minor 00 patch 0) + * [\OpenSSL 1.1.1 or earlier] + * <tt>0xMNNFFPPS</tt> (major minor fix patch status) + * [LibreSSL] + * <tt>0x20000000</tt> (a fixed value) + * + * See also the man page OPENSSL_VERSION_NUMBER(3). */ -#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 - rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION))); -#else - rb_define_const(mOSSL, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION))); -#endif + rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER)); +#if defined(LIBRESSL_VERSION_NUMBER) /* - * Version number of OpenSSL the ruby OpenSSL extension was built with - * (base 16) + * LibreSSL library version number used to compile the Ruby/OpenSSL + * extension. This may differ from the version used at runtime. + * + * This constant is only defined if the extension was compiled against + * LibreSSL. The number follows the format: + * <tt>0xMNNFF00f</tt> (major minor fix 00 status). + * + * See also the man page LIBRESSL_VERSION_NUMBER(3). */ - rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER)); + rb_define_const(mOSSL, "LIBRESSL_VERSION_NUMBER", INT2NUM(LIBRESSL_VERSION_NUMBER)); +#endif /* - * Boolean indicating whether OpenSSL is FIPS-capable or not + * Boolean indicating whether the \OpenSSL library is FIPS-capable or not. + * Always <tt>true</tt> for \OpenSSL 3.0 and later. + * + * This is obsolete and will be removed in the future. + * See also OpenSSL.fips_mode. */ rb_define_const(mOSSL, "OPENSSL_FIPS", -#ifdef OPENSSL_FIPS - Qtrue +/* OpenSSL 3 is FIPS-capable even when it is installed without fips option */ +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + Qtrue +#elif defined(OPENSSL_FIPS) + Qtrue +#elif defined(OPENSSL_IS_AWSLC) // AWS-LC FIPS can only be enabled during compile time. + FIPS_mode() ? Qtrue : Qfalse #else - Qfalse + Qfalse #endif - ); + ); rb_define_module_function(mOSSL, "fips_mode", ossl_fips_mode_get, 0); rb_define_module_function(mOSSL, "fips_mode=", ossl_fips_mode_set, 1); + rb_global_variable(&eOSSLError); /* - * Generic error, - * common for all classes under OpenSSL module + * Generic error class for OpenSSL. All error classes in this library + * inherit from this class. + * + * This class indicates that an error was reported by the underlying + * \OpenSSL library. */ - eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError); - rb_global_variable(&eOSSLError); + eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); + /* + * \OpenSSL error queue entries captured at the time the exception was + * raised. The same information is printed to stderr if OpenSSL.debug is + * set to +true+. + * + * This is an array of zero or more strings, ordered from the oldest to the + * newest. The format of the strings is not stable and may vary across + * versions of \OpenSSL or versions of this Ruby extension. + * + * See also the man page ERR_get_error(3). + */ + rb_attr(eOSSLError, rb_intern_const("errors"), 1, 0, 0); + rb_define_method(eOSSLError, "detailed_message", osslerror_detailed_message, -1); /* * Init debug core @@ -1186,64 +1124,27 @@ Init_openssl(void) * Get ID of to_der */ ossl_s_to_der = rb_intern("to_der"); - -#if !defined(HAVE_OPENSSL_110_THREADING_API) - Init_ossl_locks(); -#endif + id_i_errors = rb_intern("@errors"); /* * Init components */ + Init_ossl_asn1(); Init_ossl_bn(); Init_ossl_cipher(); Init_ossl_config(); Init_ossl_digest(); + Init_ossl_engine(); Init_ossl_hmac(); + Init_ossl_kdf(); Init_ossl_ns_spki(); + Init_ossl_ocsp(); Init_ossl_pkcs12(); Init_ossl_pkcs7(); Init_ossl_pkey(); + Init_ossl_provider(); Init_ossl_rand(); Init_ossl_ssl(); + Init_ossl_ts(); Init_ossl_x509(); - Init_ossl_ocsp(); - Init_ossl_engine(); - Init_ossl_asn1(); - Init_ossl_kdf(); - -#if defined(OSSL_DEBUG) - /* - * For debugging Ruby/OpenSSL. Enable only when built with --enable-debug - */ -#if !defined(LIBRESSL_VERSION_NUMBER) && \ - (OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_NO_CRYPTO_MDEBUG) || \ - defined(CRYPTO_malloc_debug_init)) - rb_define_module_function(mOSSL, "mem_check_start", mem_check_start, 0); - rb_define_module_function(mOSSL, "print_mem_leaks", print_mem_leaks, 0); - -#if defined(CRYPTO_malloc_debug_init) /* <= 1.0.2 */ - CRYPTO_malloc_debug_init(); -#endif - -#if defined(V_CRYPTO_MDEBUG_ALL) /* <= 1.0.2 */ - CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000 /* <= 1.0.2 */ - { - int i; - /* - * See crypto/ex_data.c; call def_get_class() immediately to avoid - * allocations. 15 is the maximum number that is used as the class index - * in OpenSSL 1.0.2. - */ - for (i = 0; i <= 15; i++) { - if (CRYPTO_get_ex_new_index(i, 0, (void *)"ossl-mdebug-dummy", 0, 0, 0) < 0) - rb_raise(rb_eRuntimeError, "CRYPTO_get_ex_new_index for " - "class index %d failed", i); - } - } -#endif -#endif -#endif } diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index 39699bd5e6..0b479a7200 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_H_) #define _OSSL_H_ @@ -17,21 +17,26 @@ #include <errno.h> #include <ruby/io.h> #include <ruby/thread.h> +#ifdef HAVE_RUBY_RACTOR_H +#include <ruby/ractor.h> +#else +#define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + #include <openssl/opensslv.h> + #include <openssl/err.h> #include <openssl/asn1.h> #include <openssl/x509v3.h> #include <openssl/ssl.h> #include <openssl/pkcs12.h> #include <openssl/pkcs7.h> -#include <openssl/hmac.h> #include <openssl/rand.h> #include <openssl/conf.h> -#include <openssl/conf_api.h> -#include <openssl/crypto.h> -#if !defined(OPENSSL_NO_ENGINE) -# include <openssl/engine.h> +#ifndef OPENSSL_NO_TS + #include <openssl/ts.h> #endif +#include <openssl/crypto.h> #if !defined(OPENSSL_NO_OCSP) # include <openssl/ocsp.h> #endif @@ -40,6 +45,38 @@ #include <openssl/dsa.h> #include <openssl/evp.h> #include <openssl/dh.h> +#include "openssl_missing.h" + +#ifndef LIBRESSL_VERSION_NUMBER +# define OSSL_IS_LIBRESSL 0 +# define OSSL_OPENSSL_PREREQ(maj, min, pat) \ + (OPENSSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12))) +# define OSSL_LIBRESSL_PREREQ(maj, min, pat) 0 +#else +# define OSSL_IS_LIBRESSL 1 +# define OSSL_OPENSSL_PREREQ(maj, min, pat) 0 +# define OSSL_LIBRESSL_PREREQ(maj, min, pat) \ + (LIBRESSL_VERSION_NUMBER >= ((maj << 28) | (min << 20) | (pat << 12))) +#endif + +#if OSSL_OPENSSL_PREREQ(3, 0, 0) +# define OSSL_3_const const +#else +# define OSSL_3_const /* const */ +#endif + +#if !defined(OPENSSL_NO_ENGINE) && !OSSL_OPENSSL_PREREQ(3, 0, 0) +# define OSSL_USE_ENGINE +#endif + +#if OSSL_OPENSSL_PREREQ(3, 0, 0) +# define OSSL_USE_PROVIDER +# include <openssl/provider.h> +#endif + +#if OSSL_OPENSSL_PREREQ(3, 0, 0) +# define OSSL_HAVE_IMMUTABLE_PKEY +#endif /* * Common Module @@ -55,10 +92,10 @@ extern VALUE eOSSLError; * CheckTypes */ #define OSSL_Check_Kind(obj, klass) do {\ - if (!rb_obj_is_kind_of((obj), (klass))) {\ - ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected kind of %"PRIsVALUE")",\ - rb_obj_class(obj), (klass));\ - }\ + if (!rb_obj_is_kind_of((obj), (klass))) {\ + ossl_raise(rb_eTypeError, "wrong argument (%"PRIsVALUE")! (Expected kind of %"PRIsVALUE")",\ + rb_obj_class(obj), (klass));\ + }\ } while (0) /* @@ -86,16 +123,15 @@ VALUE ossl_buf2str(char *buf, int len); VALUE ossl_str_new(const char *, long, int *); #define ossl_str_adjust(str, p) \ do{\ - long len = RSTRING_LEN(str);\ long newlen = (long)((p) - (unsigned char*)RSTRING_PTR(str));\ - assert(newlen <= len);\ + assert(newlen <= RSTRING_LEN(str));\ rb_str_set_len((str), newlen);\ }while(0) /* * Convert binary string to hex string. The caller is responsible for * ensuring out has (2 * len) bytes of capacity. */ -void ossl_bin2hex(unsigned char *in, char *out, size_t len); +void ossl_bin2hex(const unsigned char *in, char *out, size_t len); /* * Our default PEM callback @@ -120,7 +156,9 @@ int ossl_pem_passwd_cb(char *, int, int, void *); /* * ERRor messages */ -NORETURN(void ossl_raise(VALUE, const char *, ...)); +PRINTF_ARGS(NORETURN(void ossl_raise(VALUE, const char *, ...)), 2, 3); +/* Make exception instance from str and OpenSSL error reason string. */ +VALUE ossl_make_error(VALUE exc, VALUE str); /* Clear OpenSSL error queue. If dOSSL is set, rb_warn() them. */ void ossl_clear_error(void); @@ -135,43 +173,36 @@ VALUE ossl_to_der_if_possible(VALUE); */ extern VALUE dOSSL; -#if defined(HAVE_VA_ARGS_MACRO) #define OSSL_Debug(...) do { \ - if (dOSSL == Qtrue) { \ - fprintf(stderr, "OSSL_DEBUG: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \ - } \ + if (dOSSL == Qtrue) { \ + fprintf(stderr, "OSSL_DEBUG: "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, " [%s:%d]\n", __FILE__, __LINE__); \ + } \ } while (0) -#else -void ossl_debug(const char *, ...); -#define OSSL_Debug ossl_debug -#endif - /* * Include all parts */ -#include "openssl_missing.h" -#include "ruby_missing.h" #include "ossl_asn1.h" #include "ossl_bio.h" #include "ossl_bn.h" #include "ossl_cipher.h" #include "ossl_config.h" #include "ossl_digest.h" +#include "ossl_engine.h" #include "ossl_hmac.h" +#include "ossl_kdf.h" #include "ossl_ns_spki.h" #include "ossl_ocsp.h" #include "ossl_pkcs12.h" #include "ossl_pkcs7.h" #include "ossl_pkey.h" +#include "ossl_provider.h" #include "ossl_rand.h" #include "ossl_ssl.h" -#include "ossl_version.h" +#include "ossl_ts.h" #include "ossl_x509.h" -#include "ossl_engine.h" -#include "ossl_kdf.h" void Init_openssl(void); diff --git a/ext/openssl/ossl_asn1.c b/ext/openssl/ossl_asn1.c index ab45bd833c..71a87f0463 100644 --- a/ext/openssl/ossl_asn1.c +++ b/ext/openssl/ossl_asn1.c @@ -5,68 +5,91 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" -static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, - int depth, int yield, long *num_read); -static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self); +/********/ +/* + * ASN1 module + */ +#define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE) +#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG) +#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING) +#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS) +#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH) + +#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v)) +#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v)) +#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v)) +#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v)) +#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v)) + +VALUE mASN1; +static VALUE eASN1Error; + +VALUE cASN1Data; +static VALUE cASN1Primitive; +static VALUE cASN1Constructive; + +static VALUE cASN1EndOfContent; +static VALUE cASN1Boolean; /* BOOLEAN */ +static VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */ +static VALUE cASN1BitString; /* BIT STRING */ +static VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */ +static VALUE cASN1NumericString, cASN1PrintableString; +static VALUE cASN1T61String, cASN1VideotexString; +static VALUE cASN1IA5String, cASN1GraphicString; +static VALUE cASN1ISO64String, cASN1GeneralString; +static VALUE cASN1UniversalString, cASN1BMPString; +static VALUE cASN1Null; /* NULL */ +static VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ +static VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ +static VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ + +static VALUE sym_IMPLICIT, sym_EXPLICIT; +static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE; +static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS; +static ID id_each; /* * DATE conversion */ +static VALUE +time_utc_new(VALUE args) +{ + return rb_funcallv(rb_cTime, rb_intern("utc"), 6, (VALUE *)args); +} + +static VALUE +time_utc_new_rescue(VALUE args, VALUE exc) +{ + rb_raise(eASN1Error, "invalid time"); +} + VALUE asn1time_to_time(const ASN1_TIME *time) { struct tm tm; - VALUE argv[6]; - int count; - - memset(&tm, 0, sizeof(struct tm)); - - switch (time->type) { - case V_ASN1_UTCTIME: - count = sscanf((const char *)time->data, "%2d%2d%2d%2d%2d%2dZ", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, - &tm.tm_sec); - - if (count == 5) { - tm.tm_sec = 0; - } else if (count != 6) { - ossl_raise(rb_eTypeError, "bad UTCTIME format: \"%s\"", - time->data); - } - if (tm.tm_year < 69) { - tm.tm_year += 2000; - } else { - tm.tm_year += 1900; - } - break; - case V_ASN1_GENERALIZEDTIME: - count = sscanf((const char *)time->data, "%4d%2d%2d%2d%2d%2dZ", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, - &tm.tm_sec); - if (count == 5) { - tm.tm_sec = 0; - } - else if (count != 6) { - ossl_raise(rb_eTypeError, "bad GENERALIZEDTIME format: \"%s\"", - time->data); - } - break; - default: - rb_warning("unknown time format"); - return Qnil; - } - argv[0] = INT2NUM(tm.tm_year); - argv[1] = INT2NUM(tm.tm_mon); - argv[2] = INT2NUM(tm.tm_mday); - argv[3] = INT2NUM(tm.tm_hour); - argv[4] = INT2NUM(tm.tm_min); - argv[5] = INT2NUM(tm.tm_sec); - - return rb_funcall2(rb_cTime, rb_intern("utc"), 6, argv); + if (!ASN1_TIME_to_tm(time, &tm)) + ossl_raise(eASN1Error, "ASN1_TIME_to_tm"); + + VALUE args[] = { + INT2NUM(tm.tm_year + 1900), + INT2NUM(tm.tm_mon + 1), + INT2NUM(tm.tm_mday), + INT2NUM(tm.tm_hour), + INT2NUM(tm.tm_min), + INT2NUM(tm.tm_sec), + }; + return rb_rescue2(time_utc_new, (VALUE)args, time_utc_new_rescue, Qnil, + rb_eArgError, 0); +} + +static VALUE +asn1time_to_time_i(VALUE arg) +{ + return asn1time_to_time((ASN1_TIME *)arg); } void @@ -75,13 +98,13 @@ ossl_time_split(VALUE time, time_t *sec, int *days) VALUE num = rb_Integer(time); if (FIXNUM_P(num)) { - time_t t = FIX2LONG(num); - *sec = t % 86400; - *days = rb_long2int(t / 86400); + time_t t = FIX2LONG(num); + *sec = t % 86400; + *days = rb_long2int(t / 86400); } else { - *days = NUM2INT(rb_funcall(num, rb_intern("/"), 1, INT2FIX(86400))); - *sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400))); + *days = NUM2INT(rb_funcall(num, rb_intern("/"), 1, INT2FIX(86400))); + *sec = NUM2TIMET(rb_funcall(num, rb_intern("%"), 1, INT2FIX(86400))); } } @@ -91,7 +114,8 @@ ossl_time_split(VALUE time, time_t *sec, int *days) VALUE asn1str_to_str(const ASN1_STRING *str) { - return rb_str_new((const char *)str->data, str->length); + return rb_str_new((const char *)ASN1_STRING_get0_data(str), + ASN1_STRING_length(str)); } /* @@ -104,16 +128,15 @@ asn1integer_to_num(const ASN1_INTEGER *ai) VALUE num; if (!ai) { - ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); + ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); } - if (ai->type == V_ASN1_ENUMERATED) - /* const_cast: workaround for old OpenSSL */ - bn = ASN1_ENUMERATED_to_BN((ASN1_ENUMERATED *)ai, NULL); + if (ASN1_STRING_type(ai) == V_ASN1_ENUMERATED) + bn = ASN1_ENUMERATED_to_BN(ai, NULL); else - bn = ASN1_INTEGER_to_BN(ai, NULL); + bn = ASN1_INTEGER_to_BN(ai, NULL); if (!bn) - ossl_raise(eOSSLError, NULL); + ossl_raise(eOSSLError, NULL); num = ossl_bn_new(bn); BN_free(bn); @@ -126,58 +149,63 @@ num_to_asn1integer(VALUE obj, ASN1_INTEGER *ai) BIGNUM *bn; if (NIL_P(obj)) - ossl_raise(rb_eTypeError, "Can't convert nil into Integer"); + ossl_raise(rb_eTypeError, "Can't convert nil into Integer"); bn = GetBNPtr(obj); if (!(ai = BN_to_ASN1_INTEGER(bn, ai))) - ossl_raise(eOSSLError, NULL); + ossl_raise(eOSSLError, NULL); return ai; } -/********/ +static VALUE +asn1integer_to_num_i(VALUE arg) +{ + return asn1integer_to_num((ASN1_INTEGER *)arg); +} + /* - * ASN1 module + * ASN1_OBJECT conversions */ -#define ossl_asn1_get_value(o) rb_attr_get((o),sivVALUE) -#define ossl_asn1_get_tag(o) rb_attr_get((o),sivTAG) -#define ossl_asn1_get_tagging(o) rb_attr_get((o),sivTAGGING) -#define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS) -#define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH) - -#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v)) -#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v)) -#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v)) -#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v)) -#define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v)) +VALUE +ossl_asn1obj_to_string_oid(const ASN1_OBJECT *a1obj) +{ + VALUE str; + int len; -VALUE mASN1; -VALUE eASN1Error; + str = rb_usascii_str_new(NULL, 127); + len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1); + if (len <= 0 || len == INT_MAX) + ossl_raise(eOSSLError, "OBJ_obj2txt"); + if (len > RSTRING_LEN(str)) { + /* +1 is for the \0 terminator added by OBJ_obj2txt() */ + rb_str_resize(str, len + 1); + len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1); + if (len <= 0) + ossl_raise(eOSSLError, "OBJ_obj2txt"); + } + rb_str_set_len(str, len); + return str; +} -VALUE cASN1Data; -VALUE cASN1Primitive; -VALUE cASN1Constructive; - -VALUE cASN1EndOfContent; -VALUE cASN1Boolean; /* BOOLEAN */ -VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */ -VALUE cASN1BitString; /* BIT STRING */ -VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */ -VALUE cASN1NumericString, cASN1PrintableString; -VALUE cASN1T61String, cASN1VideotexString; -VALUE cASN1IA5String, cASN1GraphicString; -VALUE cASN1ISO64String, cASN1GeneralString; -VALUE cASN1UniversalString, cASN1BMPString; -VALUE cASN1Null; /* NULL */ -VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ -VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ -VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ +VALUE +ossl_asn1obj_to_string(const ASN1_OBJECT *obj) +{ + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) + return rb_str_new_cstr(OBJ_nid2sn(nid)); + return ossl_asn1obj_to_string_oid(obj); +} -static VALUE sym_IMPLICIT, sym_EXPLICIT; -static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE; -static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS; -static ID id_each; +VALUE +ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *obj) +{ + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) + return rb_str_new_cstr(OBJ_nid2ln(nid)); + return ossl_asn1obj_to_string_oid(obj); +} /* * Ruby to ASN1 converters @@ -186,9 +214,9 @@ static ASN1_BOOLEAN obj_to_asn1bool(VALUE obj) { if (NIL_P(obj)) - ossl_raise(rb_eTypeError, "Can't convert nil into Boolean"); + ossl_raise(rb_eTypeError, "Can't convert nil into Boolean"); - return RTEST(obj) ? 0xff : 0x0; + return RTEST(obj) ? 0xff : 0x0; } static ASN1_INTEGER* @@ -203,11 +231,11 @@ obj_to_asn1bstr(VALUE obj, long unused_bits) ASN1_BIT_STRING *bstr; if (unused_bits < 0 || unused_bits > 7) - ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\ - "the range 0 to 7"); + ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\ + "the range 0 to 7"); StringValue(obj); if(!(bstr = ASN1_BIT_STRING_new())) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj)); bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */ bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits; @@ -222,7 +250,7 @@ obj_to_asn1str(VALUE obj) StringValue(obj); if(!(str = ASN1_STRING_new())) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ASN1_STRING_set(str, RSTRING_PTR(obj), RSTRING_LENINT(obj)); return str; @@ -234,15 +262,15 @@ obj_to_asn1null(VALUE obj) ASN1_NULL *null; if(!NIL_P(obj)) - ossl_raise(eASN1Error, "nil expected"); + ossl_raise(eASN1Error, "nil expected"); if(!(null = ASN1_NULL_new())) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return null; } -static ASN1_OBJECT* -obj_to_asn1obj(VALUE obj) +ASN1_OBJECT * +ossl_to_asn1obj(VALUE obj) { ASN1_OBJECT *a1obj; @@ -264,7 +292,7 @@ obj_to_asn1utime(VALUE time) ossl_time_split(time, &sec, &off_days); if (!(t = ASN1_UTCTIME_adj(NULL, sec, off_days, 0))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return t; } @@ -279,7 +307,7 @@ obj_to_asn1gtime(VALUE time) ossl_time_split(time, &sec, &off_days); if (!(t = ASN1_GENERALIZEDTIME_adj(NULL, sec, off_days, 0))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return t; } @@ -292,7 +320,7 @@ obj_to_asn1derstr(VALUE obj) str = ossl_to_der(obj); if(!(a1str = ASN1_STRING_new())) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ASN1_STRING_set(a1str, RSTRING_PTR(str), RSTRING_LENINT(str)); return a1str; @@ -307,9 +335,9 @@ decode_bool(unsigned char* der, long length) const unsigned char *p = der; if (length != 3) - ossl_raise(eASN1Error, "invalid length for BOOLEAN"); + ossl_raise(eASN1Error, "invalid length for BOOLEAN"); if (p[0] != 1 || p[1] != 1) - ossl_raise(eASN1Error, "invalid BOOLEAN"); + ossl_raise(eASN1Error, "invalid BOOLEAN"); return p[2] ? Qtrue : Qfalse; } @@ -324,9 +352,9 @@ decode_int(unsigned char* der, long length) p = der; if(!(ai = d2i_ASN1_INTEGER(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE (*)(VALUE))asn1integer_to_num, - (VALUE)ai, &status); + ossl_raise(eASN1Error, NULL); + ret = rb_protect(asn1integer_to_num_i, + (VALUE)ai, &status); ASN1_INTEGER_free(ai); if(status) rb_jump_tag(status); @@ -343,11 +371,11 @@ decode_bstr(unsigned char* der, long length, long *unused_bits) p = der; if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); len = bstr->length; *unused_bits = 0; if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT) - *unused_bits = bstr->flags & 0x07; + *unused_bits = bstr->flags & 0x07; ret = rb_str_new((const char *)bstr->data, len); ASN1_BIT_STRING_free(bstr); @@ -364,9 +392,9 @@ decode_enum(unsigned char* der, long length) p = der; if(!(ai = d2i_ASN1_ENUMERATED(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE (*)(VALUE))asn1integer_to_num, - (VALUE)ai, &status); + ossl_raise(eASN1Error, NULL); + ret = rb_protect(asn1integer_to_num_i, + (VALUE)ai, &status); ASN1_ENUMERATED_free(ai); if(status) rb_jump_tag(status); @@ -381,38 +409,33 @@ decode_null(unsigned char* der, long length) p = der; if(!(null = d2i_ASN1_NULL(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); ASN1_NULL_free(null); return Qnil; } +VALUE +asn1obj_to_string_i(VALUE arg) +{ + return ossl_asn1obj_to_string((const ASN1_OBJECT *)arg); +} + static VALUE decode_obj(unsigned char* der, long length) { ASN1_OBJECT *obj; const unsigned char *p; VALUE ret; - int nid; - BIO *bio; + int state; p = der; - if(!(obj = d2i_ASN1_OBJECT(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - if((nid = OBJ_obj2nid(obj)) != NID_undef){ - ASN1_OBJECT_free(obj); - ret = rb_str_new2(OBJ_nid2sn(nid)); - } - else{ - if(!(bio = BIO_new(BIO_s_mem()))){ - ASN1_OBJECT_free(obj); - ossl_raise(eASN1Error, NULL); - } - i2a_ASN1_OBJECT(bio, obj); - ASN1_OBJECT_free(obj); - ret = ossl_membio2str(bio); - } - + if (!(obj = d2i_ASN1_OBJECT(NULL, &p, length))) + ossl_raise(eASN1Error, "d2i_ASN1_OBJECT"); + ret = rb_protect(asn1obj_to_string_i, (VALUE)obj, &state); + ASN1_OBJECT_free(obj); + if (state) + rb_jump_tag(state); return ret; } @@ -426,9 +449,9 @@ decode_time(unsigned char* der, long length) p = der; if(!(time = d2i_ASN1_TIME(NULL, &p, length))) - ossl_raise(eASN1Error, NULL); - ret = rb_protect((VALUE (*)(VALUE))asn1time_to_time, - (VALUE)time, &status); + ossl_raise(eASN1Error, NULL); + ret = rb_protect(asn1time_to_time_i, + (VALUE)time, &status); ASN1_TIME_free(time); if(status) rb_jump_tag(status); @@ -439,7 +462,7 @@ static VALUE decode_eoc(unsigned char *der, long length) { if (length != 2 || !(der[0] == 0x00 && der[1] == 0x00)) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return rb_str_new("", 0); } @@ -491,74 +514,75 @@ static VALUE class_tag_map; static int ossl_asn1_default_tag(VALUE obj); -ASN1_TYPE* +static ASN1_TYPE * ossl_asn1_get_asn1type(VALUE obj) { ASN1_TYPE *ret; VALUE value, rflag; void *ptr; - void (*free_func)(); + typedef void free_func_type(void *); + free_func_type *free_func; int tag; tag = ossl_asn1_default_tag(obj); value = ossl_asn1_get_value(obj); switch(tag){ - case V_ASN1_BOOLEAN: - ptr = (void*)(VALUE)obj_to_asn1bool(value); - free_func = NULL; - break; - case V_ASN1_INTEGER: /* FALLTHROUGH */ - case V_ASN1_ENUMERATED: - ptr = obj_to_asn1int(value); - free_func = ASN1_INTEGER_free; - break; - case V_ASN1_BIT_STRING: + case V_ASN1_BOOLEAN: + ptr = (void*)(VALUE)obj_to_asn1bool(value); + free_func = NULL; + break; + case V_ASN1_INTEGER: /* FALLTHROUGH */ + case V_ASN1_ENUMERATED: + ptr = obj_to_asn1int(value); + free_func = (free_func_type *)ASN1_INTEGER_free; + break; + case V_ASN1_BIT_STRING: rflag = rb_attr_get(obj, sivUNUSED_BITS); - ptr = obj_to_asn1bstr(value, NUM2INT(rflag)); - free_func = ASN1_BIT_STRING_free; - break; - case V_ASN1_NULL: - ptr = obj_to_asn1null(value); - free_func = ASN1_NULL_free; - break; - case V_ASN1_OCTET_STRING: /* FALLTHROUGH */ - case V_ASN1_UTF8STRING: /* FALLTHROUGH */ - case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */ - case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */ - case V_ASN1_T61STRING: /* FALLTHROUGH */ - case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */ - case V_ASN1_IA5STRING: /* FALLTHROUGH */ - case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */ - case V_ASN1_ISO64STRING: /* FALLTHROUGH */ - case V_ASN1_GENERALSTRING: /* FALLTHROUGH */ - case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */ - case V_ASN1_BMPSTRING: - ptr = obj_to_asn1str(value); - free_func = ASN1_STRING_free; - break; - case V_ASN1_OBJECT: - ptr = obj_to_asn1obj(value); - free_func = ASN1_OBJECT_free; - break; - case V_ASN1_UTCTIME: - ptr = obj_to_asn1utime(value); - free_func = ASN1_TIME_free; - break; - case V_ASN1_GENERALIZEDTIME: - ptr = obj_to_asn1gtime(value); - free_func = ASN1_TIME_free; - break; - case V_ASN1_SET: /* FALLTHROUGH */ - case V_ASN1_SEQUENCE: - ptr = obj_to_asn1derstr(obj); - free_func = ASN1_STRING_free; - break; - default: - ossl_raise(eASN1Error, "unsupported ASN.1 type"); + ptr = obj_to_asn1bstr(value, NUM2INT(rflag)); + free_func = (free_func_type *)ASN1_BIT_STRING_free; + break; + case V_ASN1_NULL: + ptr = obj_to_asn1null(value); + free_func = (free_func_type *)ASN1_NULL_free; + break; + case V_ASN1_OCTET_STRING: /* FALLTHROUGH */ + case V_ASN1_UTF8STRING: /* FALLTHROUGH */ + case V_ASN1_NUMERICSTRING: /* FALLTHROUGH */ + case V_ASN1_PRINTABLESTRING: /* FALLTHROUGH */ + case V_ASN1_T61STRING: /* FALLTHROUGH */ + case V_ASN1_VIDEOTEXSTRING: /* FALLTHROUGH */ + case V_ASN1_IA5STRING: /* FALLTHROUGH */ + case V_ASN1_GRAPHICSTRING: /* FALLTHROUGH */ + case V_ASN1_ISO64STRING: /* FALLTHROUGH */ + case V_ASN1_GENERALSTRING: /* FALLTHROUGH */ + case V_ASN1_UNIVERSALSTRING: /* FALLTHROUGH */ + case V_ASN1_BMPSTRING: + ptr = obj_to_asn1str(value); + free_func = (free_func_type *)ASN1_STRING_free; + break; + case V_ASN1_OBJECT: + ptr = ossl_to_asn1obj(value); + free_func = (free_func_type *)ASN1_OBJECT_free; + break; + case V_ASN1_UTCTIME: + ptr = obj_to_asn1utime(value); + free_func = (free_func_type *)ASN1_TIME_free; + break; + case V_ASN1_GENERALIZEDTIME: + ptr = obj_to_asn1gtime(value); + free_func = (free_func_type *)ASN1_TIME_free; + break; + case V_ASN1_SET: /* FALLTHROUGH */ + case V_ASN1_SEQUENCE: + ptr = obj_to_asn1derstr(obj); + free_func = (free_func_type *)ASN1_STRING_free; + break; + default: + ossl_raise(eASN1Error, "unsupported ASN.1 type"); } if(!(ret = OPENSSL_malloc(sizeof(ASN1_TYPE)))){ - if(free_func) free_func(ptr); - ossl_raise(eASN1Error, "ASN1_TYPE alloc failure"); + if(free_func) free_func(ptr); + ossl_raise(eASN1Error, "ASN1_TYPE alloc failure"); } memset(ret, 0, sizeof(ASN1_TYPE)); ASN1_TYPE_set(ret, tag, ptr); @@ -573,10 +597,10 @@ ossl_asn1_default_tag(VALUE obj) tmp_class = CLASS_OF(obj); while (!NIL_P(tmp_class)) { - tag = rb_hash_lookup(class_tag_map, tmp_class); - if (tag != Qnil) - return NUM2INT(tag); - tmp_class = rb_class_superclass(tmp_class); + tag = rb_hash_lookup(class_tag_map, tmp_class); + if (tag != Qnil) + return NUM2INT(tag); + tmp_class = rb_class_superclass(tmp_class); } return -1; @@ -589,7 +613,7 @@ ossl_asn1_tag(VALUE obj) tag = ossl_asn1_get_tag(obj); if(NIL_P(tag)) - ossl_raise(eASN1Error, "tag number not specified"); + ossl_raise(eASN1Error, "tag number not specified"); return NUM2INT(tag); } @@ -601,28 +625,28 @@ ossl_asn1_tag_class(VALUE obj) s = ossl_asn1_get_tag_class(obj); if (NIL_P(s) || s == sym_UNIVERSAL) - return V_ASN1_UNIVERSAL; + return V_ASN1_UNIVERSAL; else if (s == sym_APPLICATION) - return V_ASN1_APPLICATION; + return V_ASN1_APPLICATION; else if (s == sym_CONTEXT_SPECIFIC) - return V_ASN1_CONTEXT_SPECIFIC; + return V_ASN1_CONTEXT_SPECIFIC; else if (s == sym_PRIVATE) - return V_ASN1_PRIVATE; + return V_ASN1_PRIVATE; else - ossl_raise(eASN1Error, "invalid tag class"); + ossl_raise(eASN1Error, "invalid tag class"); } static VALUE ossl_asn1_class2sym(int tc) { if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - return sym_PRIVATE; + return sym_PRIVATE; else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - return sym_CONTEXT_SPECIFIC; + return sym_CONTEXT_SPECIFIC; else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - return sym_APPLICATION; + return sym_APPLICATION; else - return sym_UNIVERSAL; + return sym_UNIVERSAL; } /* @@ -645,7 +669,7 @@ static VALUE ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class) { if(!SYMBOL_P(tag_class)) - ossl_raise(eASN1Error, "invalid tag class"); + ossl_raise(eASN1Error, "invalid tag class"); ossl_asn1_set_tag(self, tag); ossl_asn1_set_value(self, value); ossl_asn1_set_tag_class(self, tag_class); @@ -667,35 +691,35 @@ to_der_internal(VALUE self, int constructed, int indef_len, VALUE body) body_length = RSTRING_LENINT(body); if (ossl_asn1_get_tagging(self) == sym_EXPLICIT) { - int inner_length, e_encoding = indef_len ? 2 : 1; - - if (default_tag_number == -1) - ossl_raise(eASN1Error, "explicit tagging of unknown tag"); - - inner_length = ASN1_object_size(encoding, body_length, default_tag_number); - total_length = ASN1_object_size(e_encoding, inner_length, tag_number); - str = rb_str_new(NULL, total_length); - p = (unsigned char *)RSTRING_PTR(str); - /* Put explicit tag */ - ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class); - /* Append inner object */ - ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL); - memcpy(p, RSTRING_PTR(body), body_length); - p += body_length; - if (indef_len) { - ASN1_put_eoc(&p); /* For inner object */ - ASN1_put_eoc(&p); /* For wrapper object */ - } + int inner_length, e_encoding = indef_len ? 2 : 1; + + if (default_tag_number == -1) + ossl_raise(eASN1Error, "explicit tagging of unknown tag"); + + inner_length = ASN1_object_size(encoding, body_length, default_tag_number); + total_length = ASN1_object_size(e_encoding, inner_length, tag_number); + str = rb_str_new(NULL, total_length); + p = (unsigned char *)RSTRING_PTR(str); + /* Put explicit tag */ + ASN1_put_object(&p, e_encoding, inner_length, tag_number, tag_class); + /* Append inner object */ + ASN1_put_object(&p, encoding, body_length, default_tag_number, V_ASN1_UNIVERSAL); + memcpy(p, RSTRING_PTR(body), body_length); + p += body_length; + if (indef_len) { + ASN1_put_eoc(&p); /* For inner object */ + ASN1_put_eoc(&p); /* For wrapper object */ + } } else { - total_length = ASN1_object_size(encoding, body_length, tag_number); - str = rb_str_new(NULL, total_length); - p = (unsigned char *)RSTRING_PTR(str); - ASN1_put_object(&p, encoding, body_length, tag_number, tag_class); - memcpy(p, RSTRING_PTR(body), body_length); - p += body_length; - if (indef_len) - ASN1_put_eoc(&p); + total_length = ASN1_object_size(encoding, body_length, tag_number); + str = rb_str_new(NULL, total_length); + p = (unsigned char *)RSTRING_PTR(str); + ASN1_put_object(&p, encoding, body_length, tag_number, tag_class); + memcpy(p, RSTRING_PTR(body), body_length); + p += body_length; + if (indef_len) + ASN1_put_eoc(&p); } assert(p - (unsigned char *)RSTRING_PTR(str) == total_length); return str; @@ -718,18 +742,22 @@ ossl_asn1data_to_der(VALUE self) VALUE value = ossl_asn1_get_value(self); if (rb_obj_is_kind_of(value, rb_cArray)) - return ossl_asn1cons_to_der(self); + return ossl_asn1cons_to_der(self); else { - if (RTEST(ossl_asn1_get_indefinite_length(self))) - ossl_raise(eASN1Error, "indefinite length form cannot be used " \ - "with primitive encoding"); - return ossl_asn1prim_to_der(self); + if (RTEST(ossl_asn1_get_indefinite_length(self))) + ossl_raise(eASN1Error, "indefinite length form cannot be used " \ + "with primitive encoding"); + return ossl_asn1prim_to_der(self); } } +static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self); +static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, + int depth, int yield, long *num_read); + static VALUE int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, - VALUE tc, long *num_read) + VALUE tc, long *num_read) { VALUE value, asn1data; unsigned char *p; @@ -738,64 +766,64 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, p = *pp; if(tc == sym_UNIVERSAL && tag < ossl_asn1_info_size) { - switch(tag){ - case V_ASN1_EOC: - value = decode_eoc(p, hlen+length); - break; - case V_ASN1_BOOLEAN: - value = decode_bool(p, hlen+length); - break; - case V_ASN1_INTEGER: - value = decode_int(p, hlen+length); - break; - case V_ASN1_BIT_STRING: - value = decode_bstr(p, hlen+length, &flag); - break; - case V_ASN1_NULL: - value = decode_null(p, hlen+length); - break; - case V_ASN1_ENUMERATED: - value = decode_enum(p, hlen+length); - break; - case V_ASN1_OBJECT: - value = decode_obj(p, hlen+length); - break; - case V_ASN1_UTCTIME: /* FALLTHROUGH */ - case V_ASN1_GENERALIZEDTIME: - value = decode_time(p, hlen+length); - break; - default: - /* use original value */ - p += hlen; - value = rb_str_new((const char *)p, length); - break; - } + switch(tag){ + case V_ASN1_EOC: + value = decode_eoc(p, hlen+length); + break; + case V_ASN1_BOOLEAN: + value = decode_bool(p, hlen+length); + break; + case V_ASN1_INTEGER: + value = decode_int(p, hlen+length); + break; + case V_ASN1_BIT_STRING: + value = decode_bstr(p, hlen+length, &flag); + break; + case V_ASN1_NULL: + value = decode_null(p, hlen+length); + break; + case V_ASN1_ENUMERATED: + value = decode_enum(p, hlen+length); + break; + case V_ASN1_OBJECT: + value = decode_obj(p, hlen+length); + break; + case V_ASN1_UTCTIME: /* FALLTHROUGH */ + case V_ASN1_GENERALIZEDTIME: + value = decode_time(p, hlen+length); + break; + default: + /* use original value */ + p += hlen; + value = rb_str_new((const char *)p, length); + break; + } } else { - p += hlen; - value = rb_str_new((const char *)p, length); + p += hlen; + value = rb_str_new((const char *)p, length); } *pp += hlen + length; *num_read = hlen + length; if (tc == sym_UNIVERSAL && - tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) { - VALUE klass = *ossl_asn1_info[tag].klass; - VALUE args[4]; - args[0] = value; - args[1] = INT2NUM(tag); - args[2] = Qnil; - args[3] = tc; - asn1data = rb_obj_alloc(klass); - ossl_asn1_initialize(4, args, asn1data); - if(tag == V_ASN1_BIT_STRING){ - rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag)); - } + tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) { + VALUE klass = *ossl_asn1_info[tag].klass; + VALUE args[4]; + args[0] = value; + args[1] = INT2NUM(tag); + args[2] = Qnil; + args[3] = tc; + asn1data = rb_obj_alloc(klass); + ossl_asn1_initialize(4, args, asn1data); + if(tag == V_ASN1_BIT_STRING){ + rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag)); + } } else { - asn1data = rb_obj_alloc(cASN1Data); - ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc); + asn1data = rb_obj_alloc(cASN1Data); + ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc); } return asn1data; @@ -803,8 +831,8 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, static VALUE int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, - long *offset, int depth, int yield, int j, - int tag, VALUE tc, long *num_read) + long *offset, int depth, int yield, int j, + int tag, VALUE tc, long *num_read) { VALUE value, asn1data, ary; int indefinite; @@ -815,40 +843,42 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, available_len = indefinite ? max_len : length; while (available_len > 0) { - long inner_read = 0; - value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read); - *num_read += inner_read; - available_len -= inner_read; - - if (indefinite && - ossl_asn1_tag(value) == V_ASN1_EOC && - ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) { - break; - } - rb_ary_push(ary, value); + long inner_read = 0; + value = ossl_asn1_decode0(pp, available_len, &off, depth + 1, yield, &inner_read); + *num_read += inner_read; + available_len -= inner_read; + + if (indefinite) { + if (ossl_asn1_tag(value) == V_ASN1_EOC && + ossl_asn1_get_tag_class(value) == sym_UNIVERSAL) + break; + if (available_len == 0) + ossl_raise(eASN1Error, "EOC missing in indefinite length encoding"); + } + rb_ary_push(ary, value); } if (tc == sym_UNIVERSAL) { - VALUE args[4]; - if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET) - asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass); - else - asn1data = rb_obj_alloc(cASN1Constructive); - args[0] = ary; - args[1] = INT2NUM(tag); - args[2] = Qnil; - args[3] = tc; - ossl_asn1_initialize(4, args, asn1data); + VALUE args[4]; + if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET) + asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass); + else + asn1data = rb_obj_alloc(cASN1Constructive); + args[0] = ary; + args[1] = INT2NUM(tag); + args[2] = Qnil; + args[3] = tc; + ossl_asn1_initialize(4, args, asn1data); } else { - asn1data = rb_obj_alloc(cASN1Data); - ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc); + asn1data = rb_obj_alloc(cASN1Data); + ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc); } if (indefinite) - ossl_asn1_set_indefinite_length(asn1data, Qtrue); + ossl_asn1_set_indefinite_length(asn1data, Qtrue); else - ossl_asn1_set_indefinite_length(asn1data, Qfalse); + ossl_asn1_set_indefinite_length(asn1data, Qfalse); *offset = off; return asn1data; @@ -856,7 +886,7 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth, - int yield, long *num_read) + int yield, long *num_read) { unsigned char *start, *p; const unsigned char *p0; @@ -872,46 +902,46 @@ ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth, if(j & 0x80) ossl_raise(eASN1Error, NULL); if(len > length) ossl_raise(eASN1Error, "value is too short"); if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - tag_class = sym_PRIVATE; + tag_class = sym_PRIVATE; else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - tag_class = sym_CONTEXT_SPECIFIC; + tag_class = sym_CONTEXT_SPECIFIC; else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - tag_class = sym_APPLICATION; + tag_class = sym_APPLICATION; else - tag_class = sym_UNIVERSAL; + tag_class = sym_UNIVERSAL; hlen = p - start; if(yield) { - VALUE arg = rb_ary_new(); - rb_ary_push(arg, LONG2NUM(depth)); - rb_ary_push(arg, LONG2NUM(*offset)); - rb_ary_push(arg, LONG2NUM(hlen)); - rb_ary_push(arg, LONG2NUM(len)); - rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse); - rb_ary_push(arg, ossl_asn1_class2sym(tc)); - rb_ary_push(arg, INT2NUM(tag)); - rb_yield(arg); + VALUE arg = rb_ary_new(); + rb_ary_push(arg, LONG2NUM(depth)); + rb_ary_push(arg, LONG2NUM(*offset)); + rb_ary_push(arg, LONG2NUM(hlen)); + rb_ary_push(arg, LONG2NUM(len)); + rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse); + rb_ary_push(arg, ossl_asn1_class2sym(tc)); + rb_ary_push(arg, INT2NUM(tag)); + rb_yield(arg); } if(j & V_ASN1_CONSTRUCTED) { - *pp += hlen; - off += hlen; - asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read); - inner_read += hlen; + *pp += hlen; + off += hlen; + asn1data = int_ossl_asn1_decode0_cons(pp, length - hlen, len, &off, depth, yield, j, tag, tag_class, &inner_read); + inner_read += hlen; } else { - if ((j & 0x01) && (len == 0)) - ossl_raise(eASN1Error, "indefinite length for primitive value"); - asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read); - off += hlen + len; + if ((j & 0x01) && (len == 0)) + ossl_raise(eASN1Error, "indefinite length for primitive value"); + asn1data = int_ossl_asn1_decode0_prim(pp, len, hlen, tag, tag_class, &inner_read); + off += hlen + len; } if (num_read) - *num_read = inner_read; + *num_read = inner_read; if (len != 0 && inner_read != hlen + len) { - ossl_raise(eASN1Error, - "Type mismatch. Bytes read: %ld Bytes available: %ld", - inner_read, hlen + len); + ossl_raise(eASN1Error, + "Type mismatch. Bytes read: %ld Bytes available: %ld", + inner_read, hlen + len); } *offset = off; @@ -922,9 +952,9 @@ static void int_ossl_decode_sanity_check(long len, long read, long offset) { if (len != 0 && (read != len || offset != len)) { - ossl_raise(eASN1Error, - "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld", - read, len, offset); + ossl_raise(eASN1Error, + "Type mismatch. Total bytes read: %ld Bytes available: %ld Offset: %ld", + read, len, offset); } } @@ -1024,11 +1054,11 @@ ossl_asn1_decode_all(VALUE self, VALUE obj) tmp_len = len; ary = rb_ary_new(); while (tmp_len > 0) { - long tmp_read = 0; - val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read); - rb_ary_push(ary, val); - read += tmp_read; - tmp_len -= tmp_read; + long tmp_read = 0; + val = ossl_asn1_decode0(&p, tmp_len, &offset, 0, 0, &tmp_read); + rb_ary_push(ary, val); + read += tmp_read; + tmp_len -= tmp_read; } RB_GC_GUARD(tmp); int_ossl_decode_sanity_check(len, read, offset); @@ -1068,23 +1098,23 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self) default_tag = ossl_asn1_default_tag(self); if (default_tag == -1 || argc > 1) { - if(NIL_P(tag)) - ossl_raise(eASN1Error, "must specify tag number"); - if(!NIL_P(tagging) && !SYMBOL_P(tagging)) - ossl_raise(eASN1Error, "invalid tagging method"); - if(NIL_P(tag_class)) { - if (NIL_P(tagging)) - tag_class = sym_UNIVERSAL; - else - tag_class = sym_CONTEXT_SPECIFIC; - } - if(!SYMBOL_P(tag_class)) - ossl_raise(eASN1Error, "invalid tag class"); + if(NIL_P(tag)) + ossl_raise(eASN1Error, "must specify tag number"); + if(!NIL_P(tagging) && !SYMBOL_P(tagging)) + ossl_raise(eASN1Error, "invalid tagging method"); + if(NIL_P(tag_class)) { + if (NIL_P(tagging)) + tag_class = sym_UNIVERSAL; + else + tag_class = sym_CONTEXT_SPECIFIC; + } + if(!SYMBOL_P(tag_class)) + ossl_raise(eASN1Error, "invalid tag class"); } else{ - tag = INT2NUM(default_tag); - tagging = Qnil; - tag_class = sym_UNIVERSAL; + tag = INT2NUM(default_tag); + tagging = Qnil; + tag_class = sym_UNIVERSAL; } ossl_asn1_set_tag(self, tag); ossl_asn1_set_value(self, value); @@ -1092,7 +1122,7 @@ ossl_asn1_initialize(int argc, VALUE *argv, VALUE self) ossl_asn1_set_tag_class(self, tag_class); ossl_asn1_set_indefinite_length(self, Qfalse); if (default_tag == V_ASN1_BIT_STRING) - rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0)); + rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0)); return self; } @@ -1134,30 +1164,33 @@ ossl_asn1prim_to_der(VALUE self) VALUE str; if (ossl_asn1_default_tag(self) == -1) { - str = ossl_asn1_get_value(self); - return to_der_internal(self, 0, 0, StringValue(str)); + str = ossl_asn1_get_value(self); + return to_der_internal(self, 0, 0, StringValue(str)); } asn1 = ossl_asn1_get_asn1type(self); alllen = i2d_ASN1_TYPE(asn1, NULL); if (alllen < 0) { - ASN1_TYPE_free(asn1); - ossl_raise(eASN1Error, "i2d_ASN1_TYPE"); + ASN1_TYPE_free(asn1); + ossl_raise(eASN1Error, "i2d_ASN1_TYPE"); } str = ossl_str_new(NULL, alllen, &state); if (state) { - ASN1_TYPE_free(asn1); - rb_jump_tag(state); + ASN1_TYPE_free(asn1); + rb_jump_tag(state); } p0 = p1 = (unsigned char *)RSTRING_PTR(str); - i2d_ASN1_TYPE(asn1, &p0); + if (i2d_ASN1_TYPE(asn1, &p0) < 0) { + ASN1_TYPE_free(asn1); + ossl_raise(eASN1Error, "i2d_ASN1_TYPE"); + } ASN1_TYPE_free(asn1); - assert(p0 - p1 == alllen); + ossl_str_adjust(str, p0); /* Strip header since to_der_internal() wants only the payload */ j = ASN1_get_object((const unsigned char **)&p1, &bodylen, &tag, &tc, alllen); if (j & 0x80) - ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */ + ossl_raise(eASN1Error, "ASN1_get_object"); /* should not happen */ return to_der_internal(self, 0, 0, rb_str_drop_bytes(str, alllen - bodylen)); } @@ -1179,22 +1212,22 @@ ossl_asn1cons_to_der(VALUE self) ary = rb_convert_type(ossl_asn1_get_value(self), T_ARRAY, "Array", "to_a"); str = rb_str_new(NULL, 0); for (i = 0; i < RARRAY_LEN(ary); i++) { - VALUE item = RARRAY_AREF(ary, i); - - if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) { - if (i != RARRAY_LEN(ary) - 1) - ossl_raise(eASN1Error, "illegal EOC octets in value"); - - /* - * EOC is not really part of the content, but we required to add one - * at the end in the past. - */ - break; - } - - item = ossl_to_der_if_possible(item); - StringValue(item); - rb_str_append(str, item); + VALUE item = RARRAY_AREF(ary, i); + + if (indef_len && rb_obj_is_kind_of(item, cASN1EndOfContent)) { + if (i != RARRAY_LEN(ary) - 1) + ossl_raise(eASN1Error, "illegal EOC octets in value"); + + /* + * EOC is not really part of the content, but we required to add one + * at the end in the past. + */ + break; + } + + item = ossl_to_der_if_possible(item); + StringValue(item); + rb_str_append(str, item); } return to_der_internal(self, 1, indef_len, str); @@ -1240,7 +1273,7 @@ ossl_asn1obj_s_register(VALUE self, VALUE oid, VALUE sn, VALUE ln) StringValueCStr(ln); if(!OBJ_create(RSTRING_PTR(oid), RSTRING_PTR(sn), RSTRING_PTR(ln))) - ossl_raise(eASN1Error, NULL); + ossl_raise(eASN1Error, NULL); return Qtrue; } @@ -1260,7 +1293,7 @@ ossl_asn1obj_get_sn(VALUE self) val = ossl_asn1_get_value(self); if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); + ret = rb_str_new2(OBJ_nid2sn(nid)); return ret; } @@ -1280,7 +1313,7 @@ ossl_asn1obj_get_ln(VALUE self) val = ossl_asn1_get_value(self); if ((nid = OBJ_txt2nid(StringValueCStr(val))) != NID_undef) - ret = rb_str_new2(OBJ_nid2ln(nid)); + ret = rb_str_new2(OBJ_nid2ln(nid)); return ret; } @@ -1288,23 +1321,7 @@ ossl_asn1obj_get_ln(VALUE self) static VALUE asn1obj_get_oid_i(VALUE vobj) { - ASN1_OBJECT *a1obj = (void *)vobj; - VALUE str; - int len; - - str = rb_usascii_str_new(NULL, 127); - len = OBJ_obj2txt(RSTRING_PTR(str), RSTRING_LENINT(str), a1obj, 1); - if (len <= 0 || len == INT_MAX) - ossl_raise(eASN1Error, "OBJ_obj2txt"); - if (len > RSTRING_LEN(str)) { - /* +1 is for the \0 terminator added by OBJ_obj2txt() */ - rb_str_resize(str, len + 1); - len = OBJ_obj2txt(RSTRING_PTR(str), len + 1, a1obj, 1); - if (len <= 0) - ossl_raise(eASN1Error, "OBJ_obj2txt"); - } - rb_str_set_len(str, len); - return str; + return ossl_asn1obj_to_string_oid((const ASN1_OBJECT *)vobj); } /* @@ -1321,14 +1338,33 @@ ossl_asn1obj_get_oid(VALUE self) ASN1_OBJECT *a1obj; int state; - a1obj = obj_to_asn1obj(ossl_asn1_get_value(self)); + a1obj = ossl_to_asn1obj(ossl_asn1_get_value(self)); str = rb_protect(asn1obj_get_oid_i, (VALUE)a1obj, &state); ASN1_OBJECT_free(a1obj); if (state) - rb_jump_tag(state); + rb_jump_tag(state); return str; } +/* + * call-seq: + * oid == other_oid => true or false + * + * Returns +true+ if _other_oid_ is the same as _oid_. + */ +static VALUE +ossl_asn1obj_eq(VALUE self, VALUE other) +{ + VALUE oid1, oid2; + + if (!rb_obj_is_kind_of(other, cASN1ObjectId)) + return Qfalse; + + oid1 = ossl_asn1obj_get_oid(self); + oid2 = ossl_asn1obj_get_oid(other); + return rb_str_equal(oid1, oid2); +} + #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \ static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\ { return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); } @@ -1361,13 +1397,6 @@ void Init_ossl_asn1(void) { #undef rb_intern - VALUE ary; - int i; - -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif sym_UNIVERSAL = ID2SYM(rb_intern_const("UNIVERSAL")); sym_CONTEXT_SPECIFIC = ID2SYM(rb_intern_const("CONTEXT_SPECIFIC")); @@ -1486,7 +1515,7 @@ Init_ossl_asn1(void) * * An Array that stores the name of a given tag number. These names are * the same as the name of the tag constant that is additionally defined, - * e.g. UNIVERSAL_TAG_NAME[2] = "INTEGER" and OpenSSL::ASN1::INTEGER = 2. + * e.g. <tt>UNIVERSAL_TAG_NAME[2] = "INTEGER"</tt> and <tt>OpenSSL::ASN1::INTEGER = 2</tt>. * * == Example usage * @@ -1517,17 +1546,20 @@ Init_ossl_asn1(void) rb_define_module_function(mASN1, "traverse", ossl_asn1_traverse, 1); rb_define_module_function(mASN1, "decode", ossl_asn1_decode, 1); rb_define_module_function(mASN1, "decode_all", ossl_asn1_decode_all, 1); - ary = rb_ary_new(); + VALUE ary = rb_ary_new_capa(ossl_asn1_info_size); + for (int i = 0; i < ossl_asn1_info_size; i++) { + const char *name = ossl_asn1_info[i].name; + if (name[0] == '[') + continue; + rb_define_const(mASN1, name, INT2NUM(i)); + rb_ary_store(ary, i, rb_obj_freeze(rb_str_new_cstr(name))); + } + rb_obj_freeze(ary); /* * Array storing tag names at the tag's index. */ rb_define_const(mASN1, "UNIVERSAL_TAG_NAME", ary); - for(i = 0; i < ossl_asn1_info_size; i++){ - if(ossl_asn1_info[i].name[0] == '[') continue; - rb_define_const(mASN1, ossl_asn1_info[i].name, INT2NUM(i)); - rb_ary_store(ary, i, rb_str_new2(ossl_asn1_info[i].name)); - } /* Document-class: OpenSSL::ASN1::ASN1Data * @@ -1818,13 +1850,14 @@ do{\ rb_define_method(cASN1ObjectId, "oid", ossl_asn1obj_get_oid, 0); rb_define_alias(cASN1ObjectId, "short_name", "sn"); rb_define_alias(cASN1ObjectId, "long_name", "ln"); + rb_define_method(cASN1ObjectId, "==", ossl_asn1obj_eq, 1); rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0); rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0); rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0); class_tag_map = rb_hash_new(); - rb_global_variable(&class_tag_map); + rb_gc_register_mark_object(class_tag_map); rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC)); rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN)); rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER)); @@ -1848,6 +1881,7 @@ do{\ rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING)); rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING)); rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING)); + rb_obj_freeze(class_tag_map); id_each = rb_intern_const("each"); } diff --git a/ext/openssl/ossl_asn1.h b/ext/openssl/ossl_asn1.h index 939a96ce74..b605df8f3f 100644 --- a/ext/openssl/ossl_asn1.h +++ b/ext/openssl/ossl_asn1.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_ASN1_H_) #define _OSSL_ASN1_H_ @@ -32,30 +32,26 @@ VALUE asn1integer_to_num(const ASN1_INTEGER *); ASN1_INTEGER *num_to_asn1integer(VALUE, ASN1_INTEGER *); /* + * ASN1_OBJECT conversions + */ +ASN1_OBJECT *ossl_to_asn1obj(VALUE obj); +/* + * Returns the short name if available, the dotted decimal notation otherwise. + * This is the most common way to return ASN1_OBJECT to Ruby. + */ +VALUE ossl_asn1obj_to_string(const ASN1_OBJECT *a1obj); +/* + * However, some places use long names instead. This is likely unintentional, + * but we keep the current behavior in existing methods. + */ +VALUE ossl_asn1obj_to_string_long_name(const ASN1_OBJECT *a1obj); + +/* * ASN1 module */ extern VALUE mASN1; -extern VALUE eASN1Error; extern VALUE cASN1Data; -extern VALUE cASN1Primitive; -extern VALUE cASN1Constructive; - -extern VALUE cASN1Boolean; /* BOOLEAN */ -extern VALUE cASN1Integer, cASN1Enumerated; /* INTEGER */ -extern VALUE cASN1BitString; /* BIT STRING */ -extern VALUE cASN1OctetString, cASN1UTF8String; /* STRINGs */ -extern VALUE cASN1NumericString, cASN1PrintableString; -extern VALUE cASN1T61String, cASN1VideotexString; -extern VALUE cASN1IA5String, cASN1GraphicString; -extern VALUE cASN1ISO64String, cASN1GeneralString; -extern VALUE cASN1UniversalString, cASN1BMPString; -extern VALUE cASN1Null; /* NULL */ -extern VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ -extern VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ -extern VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ - -ASN1_TYPE *ossl_asn1_get_asn1type(VALUE); void Init_ossl_asn1(void); diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c index 42833d901a..4edde5091d 100644 --- a/ext/openssl/ossl_bio.c +++ b/ext/openssl/ossl_bio.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -16,11 +16,11 @@ ossl_obj2bio(volatile VALUE *pobj) BIO *bio; if (RB_TYPE_P(obj, T_FILE)) - obj = rb_funcallv(obj, rb_intern("read"), 0, NULL); + obj = rb_funcallv(obj, rb_intern("read"), 0, NULL); StringValue(obj); bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj)); if (!bio) - ossl_raise(eOSSLError, "BIO_new_mem_buf"); + ossl_raise(eOSSLError, "BIO_new_mem_buf"); *pobj = obj; return bio; } @@ -36,7 +36,7 @@ ossl_membio2str(BIO *bio) ret = ossl_str_new(buf->data, buf->length, &state); BIO_free(bio); if (state) - rb_jump_tag(state); + rb_jump_tag(state); return ret; } diff --git a/ext/openssl/ossl_bio.h b/ext/openssl/ossl_bio.h index da68c5e5a2..1b871f1cd7 100644 --- a/ext/openssl/ossl_bio.h +++ b/ext/openssl/ossl_bio.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_BIO_H_) #define _OSSL_BIO_H_ diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index 6f0064e966..9014f2df2b 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -5,25 +5,25 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ /* modified by Michal Rokos <m.rokos@sh.cvut.cz> */ #include "ossl.h" #define NewBN(klass) \ - TypedData_Wrap_Struct((klass), &ossl_bn_type, 0) + TypedData_Wrap_Struct((klass), &ossl_bn_type, 0) #define SetBN(obj, bn) do { \ - if (!(bn)) { \ - ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (bn); \ + if (!(bn)) { \ + ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ + } \ + RTYPEDDATA_DATA(obj) = (bn); \ } while (0) #define GetBN(obj, bn) do { \ - TypedData_Get_Struct((obj), BIGNUM, &ossl_bn_type, (bn)); \ - if (!(bn)) { \ - ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ - } \ + TypedData_Get_Struct((obj), BIGNUM, &ossl_bn_type, (bn)); \ + if (!(bn)) { \ + ossl_raise(rb_eRuntimeError, "BN wasn't initialized!"); \ + } \ } while (0) static void @@ -35,9 +35,9 @@ ossl_bn_free(void *ptr) static const rb_data_type_t ossl_bn_type = { "OpenSSL/BN", { - 0, ossl_bn_free, + 0, ossl_bn_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE, }; /* @@ -49,7 +49,7 @@ VALUE cBN; * * Generic Error for all of OpenSSL::BN (big num) */ -VALUE eBNError; +static VALUE eBNError; /* * Public @@ -61,10 +61,9 @@ ossl_bn_new(const BIGNUM *bn) VALUE obj; obj = NewBN(cBN); - newbn = bn ? BN_dup(bn) : BN_new(); - if (!newbn) { - ossl_raise(eBNError, NULL); - } + newbn = BN_dup(bn); + if (!newbn) + ossl_raise(eBNError, "BN_dup"); SetBN(obj, newbn); return obj; @@ -76,40 +75,40 @@ integer_to_bnptr(VALUE obj, BIGNUM *orig) BIGNUM *bn; if (FIXNUM_P(obj)) { - long i; - unsigned char bin[sizeof(long)]; - long n = FIX2LONG(obj); - unsigned long un = labs(n); - - for (i = sizeof(long) - 1; 0 <= i; i--) { - bin[i] = un & 0xff; - un >>= 8; - } - - bn = BN_bin2bn(bin, sizeof(bin), orig); - if (!bn) - ossl_raise(eBNError, "BN_bin2bn"); - if (n < 0) - BN_set_negative(bn, 1); + long i; + unsigned char bin[sizeof(long)]; + long n = FIX2LONG(obj); + unsigned long un = labs(n); + + for (i = sizeof(long) - 1; 0 <= i; i--) { + bin[i] = un & 0xff; + un >>= 8; + } + + bn = BN_bin2bn(bin, sizeof(bin), orig); + if (!bn) + ossl_raise(eBNError, "BN_bin2bn"); + if (n < 0) + BN_set_negative(bn, 1); } else { /* assuming Bignum */ - size_t len = rb_absint_size(obj, NULL); - unsigned char *bin; - VALUE buf; - int sign; - - if (INT_MAX < len) { - rb_raise(eBNError, "bignum too long"); - } - bin = (unsigned char*)ALLOCV_N(unsigned char, buf, len); - sign = rb_integer_pack(obj, bin, len, 1, 0, INTEGER_PACK_BIG_ENDIAN); - - bn = BN_bin2bn(bin, (int)len, orig); - ALLOCV_END(buf); - if (!bn) - ossl_raise(eBNError, "BN_bin2bn"); - if (sign < 0) - BN_set_negative(bn, 1); + size_t len = rb_absint_size(obj, NULL); + unsigned char *bin; + VALUE buf; + int sign; + + if (INT_MAX < len) { + rb_raise(eBNError, "bignum too long"); + } + bin = (unsigned char*)ALLOCV_N(unsigned char, buf, len); + sign = rb_integer_pack(obj, bin, len, 1, 0, INTEGER_PACK_BIG_ENDIAN); + + bn = BN_bin2bn(bin, (int)len, orig); + ALLOCV_END(buf); + if (!bn) + ossl_raise(eBNError, "BN_bin2bn"); + if (sign < 0) + BN_set_negative(bn, 1); } return bn; @@ -122,11 +121,11 @@ try_convert_to_bn(VALUE obj) VALUE newobj = Qnil; if (rb_obj_is_kind_of(obj, cBN)) - return obj; + return obj; if (RB_INTEGER_TYPE_P(obj)) { - newobj = NewBN(cBN); /* Handle potential mem leaks */ - bn = integer_to_bnptr(obj, NULL); - SetBN(newobj, bn); + newobj = NewBN(cBN); /* Handle potential mem leaks */ + bn = integer_to_bnptr(obj, NULL); + SetBN(newobj, bn); } return newobj; @@ -140,7 +139,7 @@ ossl_bn_value_ptr(volatile VALUE *ptr) tmp = try_convert_to_bn(*ptr); if (NIL_P(tmp)) - ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN"); + ossl_raise(rb_eTypeError, "Cannot convert into OpenSSL::BN"); GetBN(tmp, bn); *ptr = tmp; @@ -150,12 +149,58 @@ ossl_bn_value_ptr(volatile VALUE *ptr) /* * Private */ -/* - * BN_CTX - is used in more difficult math. ops - * (Why just 1? Because Ruby itself isn't thread safe, - * we don't need to care about threads) - */ -BN_CTX *ossl_bn_ctx; + +#ifdef HAVE_RB_EXT_RACTOR_SAFE +static void +ossl_bn_ctx_free(void *ptr) +{ + BN_CTX *ctx = (BN_CTX *)ptr; + BN_CTX_free(ctx); +} + +static struct rb_ractor_local_storage_type ossl_bn_ctx_key_type = { + NULL, // mark + ossl_bn_ctx_free, +}; + +static rb_ractor_local_key_t ossl_bn_ctx_key; + +BN_CTX * +ossl_bn_ctx_get(void) +{ + // stored in ractor local storage + + BN_CTX *ctx = rb_ractor_local_storage_ptr(ossl_bn_ctx_key); + if (!ctx) { + if (!(ctx = BN_CTX_new())) { + ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX"); + } + rb_ractor_local_storage_ptr_set(ossl_bn_ctx_key, ctx); + } + return ctx; +} +#else +// for ruby 2.x +static BN_CTX *gv_ossl_bn_ctx; + +BN_CTX * +ossl_bn_ctx_get(void) +{ + if (gv_ossl_bn_ctx == NULL) { + if (!(gv_ossl_bn_ctx = BN_CTX_new())) { + ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX"); + } + } + return gv_ossl_bn_ctx; +} + +void +ossl_bn_ctx_free(void) +{ + BN_CTX_free(gv_ossl_bn_ctx); + gv_ossl_bn_ctx = NULL; +} +#endif static VALUE ossl_bn_alloc(VALUE klass) @@ -164,7 +209,7 @@ ossl_bn_alloc(VALUE klass) VALUE obj = NewBN(klass); if (!(bn = BN_new())) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } SetBN(obj, bn); @@ -173,13 +218,29 @@ ossl_bn_alloc(VALUE klass) /* * call-seq: - * OpenSSL::BN.new => aBN - * OpenSSL::BN.new(bn) => aBN - * OpenSSL::BN.new(integer) => aBN - * OpenSSL::BN.new(string) => aBN - * OpenSSL::BN.new(string, 0 | 2 | 10 | 16) => aBN + * OpenSSL::BN.new(bn) -> aBN + * OpenSSL::BN.new(integer) -> aBN + * OpenSSL::BN.new(string, base = 10) -> aBN + * + * Construct a new \OpenSSL BIGNUM object. * - * Construct a new OpenSSL BIGNUM object. + * If +bn+ is an Integer or OpenSSL::BN, a new instance of OpenSSL::BN + * representing the same value is returned. See also Integer#to_bn for the + * short-hand. + * + * If a String is given, the content will be parsed according to +base+. + * + * +string+:: + * The string to be parsed. + * +base+:: + * The format. Must be one of the following: + * - +0+ - MPI format. See the man page BN_mpi2bn(3) for details. + * - +2+ - Variable-length and big-endian binary encoding of a positive + * number. + * - +10+ - Decimal number representation, with a leading '-' for a negative + * number. + * - +16+ - Hexadecimal number representation, with a leading '-' for a + * negative number. */ static VALUE ossl_bn_initialize(int argc, VALUE *argv, VALUE self) @@ -190,69 +251,79 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self) char *ptr; if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) { - base = NUM2INT(bs); + base = NUM2INT(bs); + } + + if (NIL_P(str)) { + ossl_raise(rb_eArgError, "invalid argument"); } + rb_check_frozen(self); if (RB_INTEGER_TYPE_P(str)) { - GetBN(self, bn); - integer_to_bnptr(str, bn); + GetBN(self, bn); + integer_to_bnptr(str, bn); - return self; + return self; } if (RTEST(rb_obj_is_kind_of(str, cBN))) { - BIGNUM *other; - - GetBN(self, bn); - GetBN(str, other); /* Safe - we checked kind_of? above */ - if (!BN_copy(bn, other)) { - ossl_raise(eBNError, NULL); - } - return self; + BIGNUM *other; + + GetBN(self, bn); + GetBN(str, other); /* Safe - we checked kind_of? above */ + if (!BN_copy(bn, other)) { + ossl_raise(eBNError, NULL); + } + return self; } GetBN(self, bn); switch (base) { - case 0: + case 0: ptr = StringValuePtr(str); if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) { - ossl_raise(eBNError, NULL); - } - break; - case 2: + ossl_raise(eBNError, NULL); + } + break; + case 2: ptr = StringValuePtr(str); if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) { - ossl_raise(eBNError, NULL); - } - break; - case 10: - if (!BN_dec2bn(&bn, StringValueCStr(str))) { - ossl_raise(eBNError, NULL); - } - break; - case 16: - if (!BN_hex2bn(&bn, StringValueCStr(str))) { - ossl_raise(eBNError, NULL); - } - break; - default: - ossl_raise(rb_eArgError, "invalid radix %d", base); + ossl_raise(eBNError, NULL); + } + break; + case 10: + if (!BN_dec2bn(&bn, StringValueCStr(str))) { + ossl_raise(eBNError, NULL); + } + break; + case 16: + if (!BN_hex2bn(&bn, StringValueCStr(str))) { + ossl_raise(eBNError, NULL); + } + break; + default: + ossl_raise(rb_eArgError, "invalid radix %d", base); } return self; } /* * call-seq: - * bn.to_s => string - * bn.to_s(base) => string + * bn.to_s(base = 10) -> string * - * === Parameters - * * _base_ - Integer - * Valid values: - * * 0 - MPI - * * 2 - binary - * * 10 - the default - * * 16 - hex + * Returns the string representation of the bignum. + * + * BN.new can parse the encoded string to convert back into an OpenSSL::BN. + * + * +base+:: + * The format. Must be one of the following: + * - +0+ - MPI format. See the man page BN_bn2mpi(3) for details. + * - +2+ - Variable-length and big-endian binary encoding. The sign of + * the bignum is ignored. + * - +10+ - Decimal number representation, with a leading '-' for a negative + * bignum. + * - +16+ - Hexadecimal number representation, with a leading '-' for a + * negative bignum. */ static VALUE ossl_bn_to_s(int argc, VALUE *argv, VALUE self) @@ -263,32 +334,32 @@ ossl_bn_to_s(int argc, VALUE *argv, VALUE self) char *buf; if (rb_scan_args(argc, argv, "01", &bs) == 1) { - base = NUM2INT(bs); + base = NUM2INT(bs); } GetBN(self, bn); switch (base) { - case 0: - len = BN_bn2mpi(bn, NULL); + case 0: + len = BN_bn2mpi(bn, NULL); str = rb_str_new(0, len); - if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len) - ossl_raise(eBNError, NULL); - break; - case 2: - len = BN_num_bytes(bn); + if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len) + ossl_raise(eBNError, NULL); + break; + case 2: + len = BN_num_bytes(bn); str = rb_str_new(0, len); - if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len) - ossl_raise(eBNError, NULL); - break; - case 10: - if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL); - str = ossl_buf2str(buf, rb_long2int(strlen(buf))); - break; - case 16: - if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL); - str = ossl_buf2str(buf, rb_long2int(strlen(buf))); - break; - default: - ossl_raise(rb_eArgError, "invalid radix %d", base); + if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len) + ossl_raise(eBNError, NULL); + break; + case 10: + if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL); + str = ossl_buf2str(buf, rb_long2int(strlen(buf))); + break; + case 16: + if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL); + str = ossl_buf2str(buf, rb_long2int(strlen(buf))); + break; + default: + ossl_raise(rb_eArgError, "invalid radix %d", base); } return str; @@ -308,7 +379,7 @@ ossl_bn_to_i(VALUE self) GetBN(self, bn); if (!(txt = BN_bn2hex(bn))) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } num = rb_cstr_to_inum(txt, 16, Qtrue); OPENSSL_free(txt); @@ -326,31 +397,31 @@ static VALUE ossl_bn_coerce(VALUE self, VALUE other) { switch(TYPE(other)) { - case T_STRING: - self = ossl_bn_to_s(0, NULL, self); - break; - case T_FIXNUM: - case T_BIGNUM: - self = ossl_bn_to_i(self); - break; - default: - if (!RTEST(rb_obj_is_kind_of(other, cBN))) { - ossl_raise(rb_eTypeError, "Don't know how to coerce"); - } + case T_STRING: + self = ossl_bn_to_s(0, NULL, self); + break; + case T_FIXNUM: + case T_BIGNUM: + self = ossl_bn_to_i(self); + break; + default: + if (!RTEST(rb_obj_is_kind_of(other, cBN))) { + ossl_raise(rb_eTypeError, "Don't know how to coerce"); + } } return rb_assoc_new(other, self); } -#define BIGNUM_BOOL1(func) \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - if (BN_##func(bn)) { \ - return Qtrue; \ - } \ - return Qfalse; \ +#define BIGNUM_BOOL1(func) \ + static VALUE \ + ossl_bn_##func(VALUE self) \ + { \ + BIGNUM *bn; \ + GetBN(self, bn); \ + if (BN_##func(bn)) { \ + return Qtrue; \ + } \ + return Qfalse; \ } /* @@ -385,27 +456,27 @@ ossl_bn_is_negative(VALUE self) GetBN(self, bn); if (BN_is_zero(bn)) - return Qfalse; + return Qfalse; return BN_is_negative(bn) ? Qtrue : Qfalse; } -#define BIGNUM_1c(func) \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn, *result; \ - VALUE obj; \ - GetBN(self, bn); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn, ossl_bn_ctx)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_1c(func) \ + static VALUE \ + ossl_bn_##func(VALUE self) \ + { \ + BIGNUM *bn, *result; \ + VALUE obj; \ + GetBN(self, bn); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn, ossl_bn_ctx) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -415,23 +486,23 @@ ossl_bn_is_negative(VALUE self) */ BIGNUM_1c(sqr) -#define BIGNUM_2(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn1, bn2)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_2(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ + VALUE obj; \ + GetBN(self, bn1); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn1, bn2) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -448,23 +519,23 @@ BIGNUM_2(add) */ BIGNUM_2(sub) -#define BIGNUM_2c(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn1, bn2, ossl_bn_ctx)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_2c(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ + VALUE obj; \ + GetBN(self, bn1); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn1, bn2, ossl_bn_ctx) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -502,12 +573,33 @@ BIGNUM_2c(gcd) */ BIGNUM_2c(mod_sqr) +#define BIGNUM_2cr(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other), *result; \ + VALUE obj; \ + GetBN(self, bn1); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_##func(NULL, bn1, bn2, ossl_bn_ctx))) \ + ossl_raise(eBNError, NULL); \ + SetBN(obj, result); \ + return obj; \ + } + +/* + * Document-method: OpenSSL::BN#mod_sqrt + * call-seq: + * bn.mod_sqrt(bn2) => aBN + */ +BIGNUM_2cr(mod_sqrt) + /* * Document-method: OpenSSL::BN#mod_inverse * call-seq: - * bn.mod_inverse(bn2) => aBN + * bn.mod_inverse(bn2) => aBN */ -BIGNUM_2c(mod_inverse) +BIGNUM_2cr(mod_inverse) /* * call-seq: @@ -527,16 +619,16 @@ ossl_bn_div(VALUE self, VALUE other) obj1 = NewBN(klass); obj2 = NewBN(klass); if (!(r1 = BN_new())) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } if (!(r2 = BN_new())) { - BN_free(r1); - ossl_raise(eBNError, NULL); + BN_free(r1); + ossl_raise(eBNError, NULL); } if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) { - BN_free(r1); - BN_free(r2); - ossl_raise(eBNError, NULL); + BN_free(r1); + BN_free(r2); + ossl_raise(eBNError, NULL); } SetBN(obj1, r1); SetBN(obj2, r2); @@ -544,24 +636,24 @@ ossl_bn_div(VALUE self, VALUE other) return rb_ary_new3(2, obj1, obj2); } -#define BIGNUM_3c(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other1); \ - BIGNUM *bn3 = GetBNPtr(other2), *result; \ - VALUE obj; \ - GetBN(self, bn1); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_3c(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other1, VALUE other2) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other1); \ + BIGNUM *bn3 = GetBNPtr(other2), *result; \ + VALUE obj; \ + GetBN(self, bn1); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn1, bn2, bn3, ossl_bn_ctx) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -592,16 +684,17 @@ BIGNUM_3c(mod_mul) */ BIGNUM_3c(mod_exp) -#define BIGNUM_BIT(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE bit) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - if (!BN_##func(bn, NUM2INT(bit))) { \ - ossl_raise(eBNError, NULL); \ - } \ - return self; \ +#define BIGNUM_BIT(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE bit) \ + { \ + BIGNUM *bn; \ + rb_check_frozen(self); \ + GetBN(self, bn); \ + if (BN_##func(bn, NUM2INT(bit)) <= 0) { \ + ossl_raise(eBNError, NULL); \ + } \ + return self; \ } /* @@ -640,30 +733,30 @@ ossl_bn_is_bit_set(VALUE self, VALUE bit) b = NUM2INT(bit); GetBN(self, bn); if (BN_is_bit_set(bn, b)) { - return Qtrue; + return Qtrue; } return Qfalse; } -#define BIGNUM_SHIFT(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE bits) \ - { \ - BIGNUM *bn, *result; \ - int b; \ - VALUE obj; \ - b = NUM2INT(bits); \ - GetBN(self, bn); \ - obj = NewBN(rb_obj_class(self)); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, bn, b)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ +#define BIGNUM_SHIFT(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE bits) \ + { \ + BIGNUM *bn, *result; \ + int b; \ + VALUE obj; \ + b = NUM2INT(bits); \ + GetBN(self, bn); \ + obj = NewBN(rb_obj_class(self)); \ + if (!(result = BN_new())) { \ + ossl_raise(eBNError, NULL); \ + } \ + if (BN_##func(result, bn, b) <= 0) { \ + BN_free(result); \ + ossl_raise(eBNError, NULL); \ + } \ + SetBN(obj, result); \ + return obj; \ } /* @@ -680,17 +773,18 @@ BIGNUM_SHIFT(lshift) */ BIGNUM_SHIFT(rshift) -#define BIGNUM_SELF_SHIFT(func) \ - static VALUE \ - ossl_bn_self_##func(VALUE self, VALUE bits) \ - { \ - BIGNUM *bn; \ - int b; \ - b = NUM2INT(bits); \ - GetBN(self, bn); \ - if (!BN_##func(bn, bn, b)) \ - ossl_raise(eBNError, NULL); \ - return self; \ +#define BIGNUM_SELF_SHIFT(func) \ + static VALUE \ + ossl_bn_self_##func(VALUE self, VALUE bits) \ + { \ + BIGNUM *bn; \ + int b; \ + rb_check_frozen(self); \ + b = NUM2INT(bits); \ + GetBN(self, bn); \ + if (BN_##func(bn, bn, b) <= 0) \ + ossl_raise(eBNError, NULL); \ + return self; \ } /* @@ -707,78 +801,64 @@ BIGNUM_SELF_SHIFT(lshift) */ BIGNUM_SELF_SHIFT(rshift) -#define BIGNUM_RAND(func) \ - static VALUE \ - ossl_bn_s_##func(int argc, VALUE *argv, VALUE klass) \ - { \ - BIGNUM *result; \ - int bottom = 0, top = 0, b; \ - VALUE bits, fill, odd, obj; \ - \ - switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { \ - case 3: \ - bottom = (odd == Qtrue) ? 1 : 0; \ - /* FALLTHROUGH */ \ - case 2: \ - top = NUM2INT(fill); \ - } \ - b = NUM2INT(bits); \ - obj = NewBN(klass); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func(result, b, top, bottom)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ - } - /* - * Document-method: OpenSSL::BN.rand - * BN.rand(bits [, fill [, odd]]) -> aBN - */ -BIGNUM_RAND(rand) - -/* - * Document-method: OpenSSL::BN.pseudo_rand - * BN.pseudo_rand(bits [, fill [, odd]]) -> aBN - */ -BIGNUM_RAND(pseudo_rand) - -#define BIGNUM_RAND_RANGE(func) \ - static VALUE \ - ossl_bn_s_##func##_range(VALUE klass, VALUE range) \ - { \ - BIGNUM *bn = GetBNPtr(range), *result; \ - VALUE obj = NewBN(klass); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (!BN_##func##_range(result, bn)) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ - } - -/* - * Document-method: OpenSSL::BN.rand_range * call-seq: - * BN.rand_range(range) -> aBN + * BN.rand(bits [, fill [, odd]]) -> aBN + * + * Generates a cryptographically strong pseudo-random number of +bits+. * + * See also the man page BN_rand(3). */ -BIGNUM_RAND_RANGE(rand) +static VALUE +ossl_bn_s_rand(int argc, VALUE *argv, VALUE klass) +{ + BIGNUM *result; + int bottom = 0, top = 0, b; + VALUE bits, fill, odd, obj; + + switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) { + case 3: + bottom = (odd == Qtrue) ? 1 : 0; + /* FALLTHROUGH */ + case 2: + top = NUM2INT(fill); + } + b = NUM2INT(bits); + obj = NewBN(klass); + if (!(result = BN_new())) { + ossl_raise(eBNError, "BN_new"); + } + if (BN_rand(result, b, top, bottom) <= 0) { + BN_free(result); + ossl_raise(eBNError, "BN_rand"); + } + SetBN(obj, result); + return obj; +} /* - * Document-method: OpenSSL::BN.pseudo_rand_range * call-seq: - * BN.pseudo_rand_range(range) -> aBN + * BN.rand_range(range) -> aBN * + * Generates a cryptographically strong pseudo-random number in the range + * 0...+range+. + * + * See also the man page BN_rand_range(3). */ -BIGNUM_RAND_RANGE(pseudo_rand) +static VALUE +ossl_bn_s_rand_range(VALUE klass, VALUE range) +{ + BIGNUM *bn = GetBNPtr(range), *result; + VALUE obj = NewBN(klass); + if (!(result = BN_new())) + ossl_raise(eBNError, "BN_new"); + if (BN_rand_range(result, bn) <= 0) { + BN_free(result); + ossl_raise(eBNError, "BN_rand_range"); + } + SetBN(obj, result); + return obj; +} /* * call-seq: @@ -806,32 +886,32 @@ ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass) num = NUM2INT(vnum); if (vsafe == Qfalse) { - safe = 0; + safe = 0; } if (!NIL_P(vadd)) { - add = GetBNPtr(vadd); - rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem); + add = GetBNPtr(vadd); + rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem); } obj = NewBN(klass); if (!(result = BN_new())) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } if (!BN_generate_prime_ex(result, num, safe, add, rem, NULL)) { - BN_free(result); - ossl_raise(eBNError, NULL); + BN_free(result); + ossl_raise(eBNError, NULL); } SetBN(obj, result); return obj; } -#define BIGNUM_NUM(func) \ - static VALUE \ - ossl_bn_##func(VALUE self) \ - { \ - BIGNUM *bn; \ - GetBN(self, bn); \ - return INT2NUM(BN_##func(bn)); \ +#define BIGNUM_NUM(func) \ + static VALUE \ + ossl_bn_##func(VALUE self) \ + { \ + BIGNUM *bn; \ + GetBN(self, bn); \ + return INT2NUM(BN_##func(bn)); \ } /* @@ -848,6 +928,7 @@ BIGNUM_NUM(num_bytes) */ BIGNUM_NUM(num_bits) +/* :nodoc: */ static VALUE ossl_bn_copy(VALUE self, VALUE other) { @@ -861,7 +942,7 @@ ossl_bn_copy(VALUE self, VALUE other) bn2 = GetBNPtr(other); if (!BN_copy(bn1, bn2)) { - ossl_raise(eBNError, NULL); + ossl_raise(eBNError, NULL); } return self; } @@ -873,7 +954,17 @@ ossl_bn_copy(VALUE self, VALUE other) static VALUE ossl_bn_uplus(VALUE self) { - return self; + VALUE obj; + BIGNUM *bn1, *bn2; + + GetBN(self, bn1); + obj = NewBN(cBN); + bn2 = BN_dup(bn1); + if (!bn2) + ossl_raise(eBNError, "BN_dup"); + SetBN(obj, bn2); + + return obj; } /* @@ -890,20 +981,38 @@ ossl_bn_uminus(VALUE self) obj = NewBN(cBN); bn2 = BN_dup(bn1); if (!bn2) - ossl_raise(eBNError, "BN_dup"); + ossl_raise(eBNError, "BN_dup"); SetBN(obj, bn2); BN_set_negative(bn2, !BN_is_negative(bn2)); return obj; } -#define BIGNUM_CMP(func) \ - static VALUE \ - ossl_bn_##func(VALUE self, VALUE other) \ - { \ - BIGNUM *bn1, *bn2 = GetBNPtr(other); \ - GetBN(self, bn1); \ - return INT2NUM(BN_##func(bn1, bn2)); \ +/* + * call-seq: + * bn.abs -> aBN + */ +static VALUE +ossl_bn_abs(VALUE self) +{ + BIGNUM *bn1; + + GetBN(self, bn1); + if (BN_is_negative(bn1)) { + return ossl_bn_uminus(self); + } + else { + return ossl_bn_uplus(self); + } +} + +#define BIGNUM_CMP(func) \ + static VALUE \ + ossl_bn_##func(VALUE self, VALUE other) \ + { \ + BIGNUM *bn1, *bn2 = GetBNPtr(other); \ + GetBN(self, bn1); \ + return INT2NUM(BN_##func(bn1, bn2)); \ } /* @@ -940,11 +1049,11 @@ ossl_bn_eq(VALUE self, VALUE other) GetBN(self, bn1); other = try_convert_to_bn(other); if (NIL_P(other)) - return Qfalse; + return Qfalse; GetBN(other, bn2); if (!BN_cmp(bn1, bn2)) { - return Qtrue; + return Qtrue; } return Qfalse; } @@ -963,7 +1072,7 @@ ossl_bn_eql(VALUE self, VALUE other) BIGNUM *bn1, *bn2; if (!rb_obj_is_kind_of(other, cBN)) - return Qfalse; + return Qfalse; GetBN(self, bn1); GetBN(other, bn2); @@ -990,8 +1099,8 @@ ossl_bn_hash(VALUE self) len = BN_num_bytes(bn); buf = ALLOCV(tmp, len); if (BN_bn2bin(bn, buf) != len) { - ALLOCV_END(tmp); - ossl_raise(eBNError, "BN_bn2bin"); + ALLOCV_END(tmp); + ossl_raise(eBNError, "BN_bn2bin"); } hash = ST2FIX(rb_memhash(buf, len)); @@ -1005,34 +1114,29 @@ ossl_bn_hash(VALUE self) * bn.prime? => true | false * bn.prime?(checks) => true | false * - * Performs a Miller-Rabin probabilistic primality test with _checks_ - * iterations. If _checks_ is not specified, a number of iterations is used - * that yields a false positive rate of at most 2^-80 for random input. + * Performs a Miller-Rabin probabilistic primality test for +bn+. * - * === Parameters - * * _checks_ - integer + * <b>+checks+ parameter is deprecated in version 3.0.</b> It has no effect. */ static VALUE ossl_bn_is_prime(int argc, VALUE *argv, VALUE self) { BIGNUM *bn; - VALUE vchecks; - int checks = BN_prime_checks; + int ret; - if (rb_scan_args(argc, argv, "01", &vchecks) == 1) { - checks = NUM2INT(vchecks); - } + rb_check_arity(argc, 0, 1); GetBN(self, bn); - switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) { - case 1: - return Qtrue; - case 0: - return Qfalse; - default: - ossl_raise(eBNError, NULL); - } - /* not reachable */ - return Qnil; + +#ifdef HAVE_BN_CHECK_PRIME + ret = BN_check_prime(bn, ossl_bn_ctx, NULL); + if (ret < 0) + ossl_raise(eBNError, "BN_check_prime"); +#else + ret = BN_is_prime_fasttest_ex(bn, BN_prime_checks, ossl_bn_ctx, 1, NULL); + if (ret < 0) + ossl_raise(eBNError, "BN_is_prime_fasttest_ex"); +#endif + return ret ? Qtrue : Qfalse; } /* @@ -1041,39 +1145,53 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self) * bn.prime_fasttest?(checks) => true | false * bn.prime_fasttest?(checks, trial_div) => true | false * - * Performs a Miller-Rabin primality test. This is same as #prime? except this - * first attempts trial divisions with some small primes. + * Performs a Miller-Rabin probabilistic primality test for +bn+. * - * === Parameters - * * _checks_ - integer - * * _trial_div_ - boolean + * <b>Deprecated in version 3.0.</b> Use #prime? instead. + * + * +checks+ and +trial_div+ parameters no longer have any effect. */ static VALUE ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self) { + rb_check_arity(argc, 0, 2); + return ossl_bn_is_prime(0, argv, self); +} + +/* + * call-seq: + * bn.get_flags(flags) => flags + * + * Returns the flags on the BN object. + * The argument is used as a bit mask. + * + * === Parameters + * * _flags_ - integer + */ +static VALUE +ossl_bn_get_flags(VALUE self, VALUE arg) +{ BIGNUM *bn; - VALUE vchecks, vtrivdiv; - int checks = BN_prime_checks, do_trial_division = 1; + GetBN(self, bn); - rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv); + return INT2NUM(BN_get_flags(bn, NUM2INT(arg))); +} - if (!NIL_P(vchecks)) { - checks = NUM2INT(vchecks); - } +/* + * call-seq: + * bn.set_flags(flags) => nil + * + * Enables the flags on the BN object. + * Currently, the flags argument can contain zero of OpenSSL::BN::CONSTTIME. + */ +static VALUE +ossl_bn_set_flags(VALUE self, VALUE arg) +{ + BIGNUM *bn; GetBN(self, bn); - /* handle true/false */ - if (vtrivdiv == Qfalse) { - do_trial_division = 0; - } - switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) { - case 1: - return Qtrue; - case 0: - return Qfalse; - default: - ossl_raise(eBNError, NULL); - } - /* not reachable */ + + rb_check_frozen(self); + BN_set_flags(bn, NUM2INT(arg)); return Qnil; } @@ -1084,15 +1202,12 @@ ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self) void Init_ossl_bn(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); +#ifdef HAVE_RB_EXT_RACTOR_SAFE + ossl_bn_ctx_key = rb_ractor_local_storage_ptr_newkey(&ossl_bn_ctx_key_type); +#else + ossl_bn_ctx_get(); #endif - if (!(ossl_bn_ctx = BN_CTX_new())) { - ossl_raise(rb_eRuntimeError, "Cannot init BN_CTX"); - } - eBNError = rb_define_class_under(mOSSL, "BNError", eOSSLError); cBN = rb_define_class_under(mOSSL, "BN", rb_cObject); @@ -1111,6 +1226,7 @@ Init_ossl_bn(void) rb_define_method(cBN, "+@", ossl_bn_uplus, 0); rb_define_method(cBN, "-@", ossl_bn_uminus, 0); + rb_define_method(cBN, "abs", ossl_bn_abs, 0); rb_define_method(cBN, "+", ossl_bn_add, 1); rb_define_method(cBN, "-", ossl_bn_sub, 1); @@ -1124,6 +1240,7 @@ Init_ossl_bn(void) rb_define_method(cBN, "mod_sub", ossl_bn_mod_sub, 2); rb_define_method(cBN, "mod_mul", ossl_bn_mod_mul, 2); rb_define_method(cBN, "mod_sqr", ossl_bn_mod_sqr, 1); + rb_define_method(cBN, "mod_sqrt", ossl_bn_mod_sqrt, 1); rb_define_method(cBN, "**", ossl_bn_exp, 1); rb_define_method(cBN, "mod_exp", ossl_bn_mod_exp, 2); rb_define_method(cBN, "gcd", ossl_bn_gcd, 1); @@ -1154,9 +1271,9 @@ Init_ossl_bn(void) * get_word */ rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1); - rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1); rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1); - rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1); + rb_define_alias(rb_singleton_class(cBN), "pseudo_rand", "rand"); + rb_define_alias(rb_singleton_class(cBN), "pseudo_rand_range", "rand_range"); rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1); rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1); @@ -1173,6 +1290,23 @@ Init_ossl_bn(void) /* lshift1 - DON'T IMPL. */ /* rshift1 - DON'T IMPL. */ + rb_define_method(cBN, "get_flags", ossl_bn_get_flags, 1); + rb_define_method(cBN, "set_flags", ossl_bn_set_flags, 1); + +#ifdef BN_FLG_CONSTTIME + rb_define_const(cBN, "CONSTTIME", INT2NUM(BN_FLG_CONSTTIME)); +#endif + /* BN_FLG_MALLOCED and BN_FLG_STATIC_DATA seems for C programming. + * Allowing them leads to memory leak. + * So, for now, they are not exported +#ifdef BN_FLG_MALLOCED + rb_define_const(cBN, "MALLOCED", INT2NUM(BN_FLG_MALLOCED)); +#endif +#ifdef BN_FLG_STATIC_DATA + rb_define_const(cBN, "STATIC_DATA", INT2NUM(BN_FLG_STATIC_DATA)); +#endif + */ + /* * bn2bin * bin2bn diff --git a/ext/openssl/ossl_bn.h b/ext/openssl/ossl_bn.h index a19ba19487..0c186bd1c5 100644 --- a/ext/openssl/ossl_bn.h +++ b/ext/openssl/ossl_bn.h @@ -5,15 +5,15 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_BN_H_) #define _OSSL_BN_H_ extern VALUE cBN; -extern VALUE eBNError; -extern BN_CTX *ossl_bn_ctx; +BN_CTX *ossl_bn_ctx_get(void); +#define ossl_bn_ctx ossl_bn_ctx_get() #define GetBNPtr(obj) ossl_bn_value_ptr(&(obj)) diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index 0840c84a71..f3cd247c8f 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,7 +14,7 @@ #define AllocCipher(obj, ctx) do { \ (ctx) = EVP_CIPHER_CTX_new(); \ if (!(ctx)) \ - ossl_raise(rb_eRuntimeError, NULL); \ + ossl_raise(rb_eRuntimeError, NULL); \ RTYPEDDATA_DATA(obj) = (ctx); \ } while (0) #define GetCipherInit(obj, ctx) do { \ @@ -23,16 +23,17 @@ #define GetCipher(obj, ctx) do { \ GetCipherInit((obj), (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \ + ossl_raise(rb_eRuntimeError, "Cipher not initialized!"); \ } \ } while (0) /* * Classes */ -VALUE cCipher; -VALUE eCipherError; -static ID id_auth_tag_len, id_key_set; +static VALUE cCipher; +static VALUE eCipherError; +static VALUE eAuthTagError; +static ID id_auth_tag_len, id_key_set, id_cipher_holder; static VALUE ossl_cipher_alloc(VALUE klass); static void ossl_cipher_free(void *ptr); @@ -40,35 +41,63 @@ static void ossl_cipher_free(void *ptr); static const rb_data_type_t ossl_cipher_type = { "OpenSSL/Cipher", { - 0, ossl_cipher_free, + 0, ossl_cipher_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +#ifdef OSSL_USE_PROVIDER +static void +ossl_evp_cipher_free(void *ptr) +{ + // This is safe to call against const EVP_CIPHER * returned by + // EVP_get_cipherbyname() + EVP_CIPHER_free(ptr); +} + +static const rb_data_type_t ossl_evp_cipher_holder_type = { + "OpenSSL/EVP_CIPHER", + { + .dfree = ossl_evp_cipher_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; +#endif + /* * PUBLIC */ const EVP_CIPHER * -ossl_evp_get_cipherbyname(VALUE obj) +ossl_evp_cipher_fetch(VALUE obj, volatile VALUE *holder) { + *holder = Qnil; if (rb_obj_is_kind_of(obj, cCipher)) { - EVP_CIPHER_CTX *ctx; - - GetCipher(obj, ctx); - - return EVP_CIPHER_CTX_cipher(ctx); + EVP_CIPHER_CTX *ctx; + GetCipher(obj, ctx); + EVP_CIPHER *cipher = (EVP_CIPHER *)EVP_CIPHER_CTX_cipher(ctx); +#ifdef OSSL_USE_PROVIDER + *holder = TypedData_Wrap_Struct(0, &ossl_evp_cipher_holder_type, NULL); + if (!EVP_CIPHER_up_ref(cipher)) + ossl_raise(eCipherError, "EVP_CIPHER_up_ref"); + RTYPEDDATA_DATA(*holder) = cipher; +#endif + return cipher; } - else { - const EVP_CIPHER *cipher; - StringValueCStr(obj); - cipher = EVP_get_cipherbyname(RSTRING_PTR(obj)); - if (!cipher) - ossl_raise(rb_eArgError, - "unsupported cipher algorithm: %"PRIsVALUE, obj); - - return cipher; + const char *name = StringValueCStr(obj); + EVP_CIPHER *cipher = (EVP_CIPHER *)EVP_get_cipherbyname(name); +#ifdef OSSL_USE_PROVIDER + if (!cipher) { + ossl_clear_error(); + *holder = TypedData_Wrap_Struct(0, &ossl_evp_cipher_holder_type, NULL); + cipher = EVP_CIPHER_fetch(NULL, name, NULL); + RTYPEDDATA_DATA(*holder) = cipher; } +#endif + if (!cipher) + ossl_raise(eCipherError, "unsupported cipher algorithm: %"PRIsVALUE, + obj); + return cipher; } VALUE @@ -77,10 +106,13 @@ ossl_cipher_new(const EVP_CIPHER *cipher) VALUE ret; EVP_CIPHER_CTX *ctx; + // NOTE: This does not set id_cipher_holder because this function should + // only be called from ossl_engine.c, which will not use any + // reference-counted ciphers. ret = ossl_cipher_alloc(cCipher); AllocCipher(ret, ctx); if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return ret; } @@ -104,7 +136,7 @@ ossl_cipher_alloc(VALUE klass) * call-seq: * Cipher.new(string) -> cipher * - * The string must be a valid cipher name like "AES-128-CBC" or "3DES". + * The string must contain a valid cipher name like "aes-256-cbc". * * A list of cipher names is available by calling OpenSSL::Cipher.ciphers. */ @@ -113,23 +145,22 @@ ossl_cipher_initialize(VALUE self, VALUE str) { EVP_CIPHER_CTX *ctx; const EVP_CIPHER *cipher; - char *name; + VALUE cipher_holder; - name = StringValueCStr(str); GetCipherInit(self, ctx); if (ctx) { - ossl_raise(rb_eRuntimeError, "Cipher already initialized!"); + ossl_raise(rb_eRuntimeError, "Cipher already initialized!"); } + cipher = ossl_evp_cipher_fetch(str, &cipher_holder); AllocCipher(self, ctx); - if (!(cipher = EVP_get_cipherbyname(name))) { - ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%"PRIsVALUE")", str); - } if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, "EVP_CipherInit_ex"); + rb_ivar_set(self, id_cipher_holder, cipher_holder); return self; } +/* :nodoc: */ static VALUE ossl_cipher_copy(VALUE self, VALUE other) { @@ -140,20 +171,20 @@ ossl_cipher_copy(VALUE self, VALUE other) GetCipherInit(self, ctx1); if (!ctx1) { - AllocCipher(self, ctx1); + AllocCipher(self, ctx1); } GetCipher(other, ctx2); if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return self; } -static void* -add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary) +static void +add_cipher_name_to_ary(const OBJ_NAME *name, void *arg) { + VALUE ary = (VALUE)arg; rb_ary_push(ary, rb_str_new2(name->name)); - return NULL; } /* @@ -169,8 +200,8 @@ ossl_s_ciphers(VALUE self) ary = rb_ary_new(); OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, - (void(*)(const OBJ_NAME*,void*))add_cipher_name_to_ary, - (void*)ary); + add_cipher_name_to_ary, + (void*)ary); return ary; } @@ -191,54 +222,22 @@ ossl_cipher_reset(VALUE self) GetCipher(self, ctx); if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return self; } static VALUE -ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) +ossl_cipher_init(VALUE self, int enc) { EVP_CIPHER_CTX *ctx; - unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL; - VALUE pass, init_v; - - if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){ - /* - * oops. this code mistakes salt for IV. - * We deprecated the arguments for this method, but we decided - * keeping this behaviour for backward compatibility. - */ - VALUE cname = rb_class_path(rb_obj_class(self)); - rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; " - "use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV", - cname, cname, cname); - StringValue(pass); - GetCipher(self, ctx); - if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); - else{ - StringValue(init_v); - if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) { - memset(iv, 0, EVP_MAX_IV_LENGTH); - memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v)); - } - else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv)); - } - EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, - (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL); - p_key = key; - p_iv = iv; - } - else { - GetCipher(self, ctx); - } - if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { - ossl_raise(eCipherError, NULL); + + GetCipher(self, ctx); + if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, enc) != 1) { + ossl_raise(eCipherError, "EVP_CipherInit_ex"); } - if (p_key) - rb_ivar_set(self, id_key_set, Qtrue); + rb_ivar_set(self, id_key_set, Qfalse); return self; } @@ -249,16 +248,15 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) * * Initializes the Cipher for encryption. * - * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the - * following methods: - * * [#key=, #iv=, #random_key, #random_iv, #pkcs5_keyivgen] + * Make sure to call either #encrypt or #decrypt before using the Cipher for + * any operation or setting any parameters. * * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1). */ static VALUE -ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self) +ossl_cipher_encrypt(VALUE self) { - return ossl_cipher_init(argc, argv, self, 1); + return ossl_cipher_init(self, 1); } /* @@ -267,16 +265,15 @@ ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self) * * Initializes the Cipher for decryption. * - * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the - * following methods: - * * [#key=, #iv=, #random_key, #random_iv, #pkcs5_keyivgen] + * Make sure to call either #encrypt or #decrypt before using the Cipher for + * any operation or setting any parameters. * * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0). */ static VALUE -ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self) +ossl_cipher_decrypt(VALUE self) { - return ossl_cipher_init(argc, argv, self, 0); + return ossl_cipher_init(self, 0); } /* @@ -285,46 +282,42 @@ ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self) * * Generates and sets the key/IV based on a password. * - * *WARNING*: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40, - * or DES with MD5 or SHA1. Using anything else (like AES) will generate the - * key/iv using an OpenSSL specific method. This method is deprecated and - * should no longer be used. Use a PKCS5 v2 key generation method from - * OpenSSL::PKCS5 instead. + * *WARNING*: This method is deprecated and should not be used. This method + * corresponds to EVP_BytesToKey(), a non-standard OpenSSL extension of the + * legacy PKCS #5 v1.5 key derivation function. See OpenSSL::KDF for other + * options to derive keys from passwords. * * === Parameters * * _salt_ must be an 8 byte string if provided. * * _iterations_ is an integer with a default of 2048. * * _digest_ is a Digest object that defaults to 'MD5' - * - * A minimum of 1000 iterations is recommended. - * */ static VALUE ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) { EVP_CIPHER_CTX *ctx; const EVP_MD *digest; - VALUE vpass, vsalt, viter, vdigest; + VALUE vpass, vsalt, viter, vdigest, md_holder; unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL; int iter; rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest); StringValue(vpass); if(!NIL_P(vsalt)){ - StringValue(vsalt); - if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN) - ossl_raise(eCipherError, "salt must be an 8-octet string"); - salt = (unsigned char *)RSTRING_PTR(vsalt); + StringValue(vsalt); + if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN) + ossl_raise(eCipherError, "salt must be an 8-octet string"); + salt = (unsigned char *)RSTRING_PTR(vsalt); } iter = NIL_P(viter) ? 2048 : NUM2INT(viter); if (iter <= 0) - rb_raise(rb_eArgError, "iterations must be a positive integer"); - digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_get_digestbyname(vdigest); + rb_raise(rb_eArgError, "iterations must be a positive integer"); + digest = NIL_P(vdigest) ? EVP_md5() : ossl_evp_md_fetch(vdigest, &md_holder); GetCipher(self, ctx); EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt, - (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv); + (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv); if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); OPENSSL_cleanse(key, sizeof key); OPENSSL_cleanse(iv, sizeof iv); @@ -335,25 +328,25 @@ ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) static int ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_ptr, - const unsigned char *in, long in_len) + const unsigned char *in, long in_len) { int out_part_len; int limit = INT_MAX / 2 + 1; long out_len = 0; do { - int in_part_len = in_len > limit ? limit : (int)in_len; + int in_part_len = in_len > limit ? limit : (int)in_len; - if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0, - &out_part_len, in, in_part_len)) - return 0; + if (!EVP_CipherUpdate(ctx, out ? (out + out_len) : 0, + &out_part_len, in, in_part_len)) + return 0; - out_len += out_part_len; - in += in_part_len; + out_len += out_part_len; + in += in_part_len; } while ((in_len -= limit) > 0); if (out_len_ptr) - *out_len_ptr = out_len; + *out_len_ptr = out_len; return 1; } @@ -369,6 +362,9 @@ ossl_cipher_update_long(EVP_CIPHER_CTX *ctx, unsigned char *out, long *out_len_p * * If _buffer_ is given, the encryption/decryption result will be written to * it. _buffer_ will be resized automatically. + * + * *NOTE*: When decrypting using an AEAD cipher, the integrity of the output + * is not verified until #final has been called. */ static VALUE ossl_cipher_update(int argc, VALUE *argv, VALUE self) @@ -381,29 +377,43 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "11", &data, &str); if (!RTEST(rb_attr_get(self, id_key_set))) - ossl_raise(eCipherError, "key not set"); + ossl_raise(eCipherError, "key not set"); StringValue(data); in = (unsigned char *)RSTRING_PTR(data); - if ((in_len = RSTRING_LEN(data)) == 0) - ossl_raise(rb_eArgError, "data must not be empty"); + in_len = RSTRING_LEN(data); GetCipher(self, ctx); - out_len = in_len+EVP_CIPHER_CTX_block_size(ctx); - if (out_len <= 0) { - ossl_raise(rb_eRangeError, - "data too big to make output buffer: %ld bytes", in_len); + + /* + * As of OpenSSL 3.2, there is no reliable way to determine the required + * output buffer size for arbitrary cipher modes. + * https://github.com/openssl/openssl/issues/22628 + * + * in_len+block_size is usually sufficient, but AES key wrap with padding + * ciphers require in_len+15 even though they have a block size of 8 bytes. + * + * Using EVP_MAX_BLOCK_LENGTH (32) as a safe upper bound for ciphers + * currently implemented in OpenSSL, but this can change in the future. + */ + if (in_len > LONG_MAX - EVP_MAX_BLOCK_LENGTH) { + ossl_raise(rb_eRangeError, + "data too big to make output buffer: %ld bytes", in_len); } + out_len = in_len + EVP_MAX_BLOCK_LENGTH; - if (NIL_P(str)) { - str = rb_str_new(0, out_len); - } else { + if (NIL_P(str)) + str = rb_str_buf_new(out_len); + else { StringValue(str); - rb_str_resize(str, out_len); + if ((long)rb_str_capacity(str) >= out_len) + rb_str_modify(str); + else + rb_str_modify_expand(str, out_len - RSTRING_LEN(str)); } - if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) - ossl_raise(eCipherError, NULL); - assert(out_len < RSTRING_LEN(str)); + if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), + &out_len, in, in_len)) + ossl_raise(eCipherError, "EVP_CipherUpdate"); rb_str_set_len(str, out_len); return str; @@ -414,14 +424,17 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self) * cipher.final -> string * * Returns the remaining data held in the cipher object. Further calls to - * Cipher#update or Cipher#final will return garbage. This call should always + * Cipher#update or Cipher#final are invalid. This call should always * be made as the last call of an encryption or decryption operation, after * having fed the entire plaintext or ciphertext to the Cipher instance. * - * If an authenticated cipher was used, a CipherError is raised if the tag - * could not be authenticated successfully. Only call this method after - * setting the authentication tag and passing the entire contents of the - * ciphertext into the cipher. + * When encrypting using an AEAD cipher, the authentication tag can be + * retrieved by #auth_tag after #final has been called. + * + * When decrypting using an AEAD cipher, this method will verify the integrity + * of the ciphertext and the associated data with the authentication tag, + * which must be set by #auth_tag= prior to calling this method. + * If the verification fails, CipherError will be raised. */ static VALUE ossl_cipher_final(VALUE self) @@ -432,9 +445,17 @@ ossl_cipher_final(VALUE self) GetCipher(self, ctx); str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx)); - if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len)) - ossl_raise(eCipherError, NULL); - assert(out_len <= RSTRING_LEN(str)); + if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len)) { + /* For AEAD ciphers, this is likely an authentication failure */ + if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) { + /* For AEAD ciphers, EVP_CipherFinal_ex failures are authentication tag verification failures */ + ossl_raise(eAuthTagError, "AEAD authentication tag verification failed"); + } + else { + /* For non-AEAD ciphers */ + ossl_raise(eCipherError, "cipher final failed"); + } + } rb_str_set_len(str, out_len); return str; @@ -444,8 +465,8 @@ ossl_cipher_final(VALUE self) * call-seq: * cipher.name -> string * - * Returns the name of the cipher which may differ slightly from the original - * name provided. + * Returns the short name of the cipher which may differ slightly from the + * original name provided. */ static VALUE ossl_cipher_name(VALUE self) @@ -459,7 +480,7 @@ ossl_cipher_name(VALUE self) /* * call-seq: - * cipher.key = string -> string + * cipher.key = string * * Sets the cipher key. To generate a key, you should either use a secure * random byte string or, if the key is to be derived from a password, you @@ -467,6 +488,8 @@ ossl_cipher_name(VALUE self) * generate a secure random-based key, Cipher#random_key may be used. * * Only call this method after calling Cipher#encrypt or Cipher#decrypt. + * + * See also the man page EVP_CipherInit_ex(3). */ static VALUE ossl_cipher_set_key(VALUE self, VALUE key) @@ -479,10 +502,10 @@ ossl_cipher_set_key(VALUE self, VALUE key) key_len = EVP_CIPHER_CTX_key_length(ctx); if (RSTRING_LEN(key) != key_len) - ossl_raise(rb_eArgError, "key must be %d bytes", key_len); + ossl_raise(rb_eArgError, "key must be %d bytes", key_len); if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); rb_ivar_set(self, id_key_set, Qtrue); @@ -491,15 +514,21 @@ ossl_cipher_set_key(VALUE self, VALUE key) /* * call-seq: - * cipher.iv = string -> string + * cipher.iv = string * * Sets the cipher IV. Please note that since you should never be using ECB * mode, an IV is always explicitly required and should be set prior to - * encryption. The IV itself can be safely transmitted in public, but it - * should be unpredictable to prevent certain kinds of attacks. You may use - * Cipher#random_iv to create a secure random IV. + * encryption. The IV itself can be safely transmitted in public. * - * Only call this method after calling Cipher#encrypt or Cipher#decrypt. + * This method expects the String to have the length equal to #iv_len. To use + * a different IV length with an AEAD cipher, #iv_len= must be set prior to + * calling this method. + * + * *NOTE*: In OpenSSL API conventions, the IV value may correspond to the + * "nonce" instead in some cipher modes. Refer to the OpenSSL man pages for + * details. + * + * See also the man page EVP_CipherInit_ex(3). */ static VALUE ossl_cipher_set_iv(VALUE self, VALUE iv) @@ -511,14 +540,14 @@ ossl_cipher_set_iv(VALUE self, VALUE iv) GetCipher(self, ctx); if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) - iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); + iv_len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); if (!iv_len) - iv_len = EVP_CIPHER_CTX_iv_length(ctx); + iv_len = EVP_CIPHER_CTX_iv_length(ctx); if (RSTRING_LEN(iv) != iv_len) - ossl_raise(rb_eArgError, "iv must be %d bytes", iv_len); + ossl_raise(rb_eArgError, "iv must be %d bytes", iv_len); if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return iv; } @@ -527,8 +556,7 @@ ossl_cipher_set_iv(VALUE self, VALUE iv) * call-seq: * cipher.authenticated? -> true | false * - * Indicated whether this Cipher instance uses an Authenticated Encryption - * mode. + * Indicates whether this Cipher instance uses an AEAD mode. */ static VALUE ossl_cipher_is_authenticated(VALUE self) @@ -542,21 +570,23 @@ ossl_cipher_is_authenticated(VALUE self) /* * call-seq: - * cipher.auth_data = string -> string + * cipher.auth_data = string + * + * Sets additional authenticated data (AAD), also called associated data, for + * this Cipher. This method is available for AEAD ciphers. * - * Sets the cipher's additional authenticated data. This field must be - * set when using AEAD cipher modes such as GCM or CCM. If no associated - * data shall be used, this method must *still* be called with a value of "". * The contents of this field should be non-sensitive data which will be * added to the ciphertext to generate the authentication tag which validates * the contents of the ciphertext. * - * The AAD must be set prior to encryption or decryption. In encryption mode, - * it must be set after calling Cipher#encrypt and setting Cipher#key= and - * Cipher#iv=. When decrypting, the authenticated data must be set after key, - * iv and especially *after* the authentication tag has been set. I.e. set it - * only after calling Cipher#decrypt, Cipher#key=, Cipher#iv= and - * Cipher#auth_tag= first. + * This method must be called after #key= and #iv= have been set, but before + * starting actual encryption or decryption with #update. In some cipher modes, + * #auth_tag_len= and #ccm_data_len= may also need to be called before this + * method. + * + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CipherUpdate() with the output buffer + * set to NULL. */ static VALUE ossl_cipher_set_auth_data(VALUE self, VALUE data) @@ -572,7 +602,7 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data) GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "AEAD not supported by this cipher"); + ossl_raise(eCipherError, "AEAD not supported by this cipher"); if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len)) ossl_raise(eCipherError, "couldn't set additional authenticated data"); @@ -584,16 +614,17 @@ ossl_cipher_set_auth_data(VALUE self, VALUE data) * call-seq: * cipher.auth_tag(tag_len = 16) -> String * - * Gets the authentication tag generated by Authenticated Encryption Cipher - * modes (GCM for example). This tag may be stored along with the ciphertext, - * then set on the decryption cipher to authenticate the contents of the - * ciphertext against changes. If the optional integer parameter _tag_len_ is - * given, the returned tag will be _tag_len_ bytes long. If the parameter is - * omitted, the default length of 16 bytes or the length previously set by - * #auth_tag_len= will be used. For maximum security, the longest possible - * should be chosen. + * Gets the generated authentication tag. This method is available for AEAD + * ciphers, and should be called after encryption has been finalized by calling + * #final. + * + * The returned tag will be _tag_len_ bytes long. Some cipher modes require + * the desired length in advance using a separate call to #auth_tag_len=, + * before starting encryption. * - * The tag may only be retrieved after calling Cipher#final. + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CIPHER_CTX_ctrl() with + * EVP_CTRL_AEAD_GET_TAG. */ static VALUE ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self) @@ -604,34 +635,42 @@ ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &vtag_len); if (NIL_P(vtag_len)) - vtag_len = rb_attr_get(self, id_auth_tag_len); + vtag_len = rb_attr_get(self, id_auth_tag_len); if (!NIL_P(vtag_len)) - tag_len = NUM2INT(vtag_len); + tag_len = NUM2INT(vtag_len); GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "authentication tag not supported by this cipher"); + ossl_raise(eCipherError, "authentication tag not supported by this cipher"); ret = rb_str_new(NULL, tag_len); if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, tag_len, RSTRING_PTR(ret))) - ossl_raise(eCipherError, "retrieving the authentication tag failed"); + ossl_raise(eCipherError, "retrieving the authentication tag failed"); return ret; } /* * call-seq: - * cipher.auth_tag = string -> string + * cipher.auth_tag = string * * Sets the authentication tag to verify the integrity of the ciphertext. - * This can be called only when the cipher supports AE. The tag must be set - * after calling Cipher#decrypt, Cipher#key= and Cipher#iv=, but before - * calling Cipher#final. After all decryption is performed, the tag is - * verified automatically in the call to Cipher#final. * - * For OCB mode, the tag length must be supplied with #auth_tag_len= - * beforehand. + * The authentication tag must be set before #final is called. The tag is + * verified during the #final call. + * + * Note that, for CCM mode and OCB mode, the expected length of the tag must + * be set before starting decryption by a separate call to #auth_tag_len=. + * The content of the tag can be provided at any time before #final is called. + * + * *NOTE*: The caller must ensure that the String passed to this method has + * the desired length. Some cipher modes support variable tag lengths, and + * this method may accept a truncated tag without raising an exception. + * + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CIPHER_CTX_ctrl() with + * EVP_CTRL_AEAD_SET_TAG. */ static VALUE ossl_cipher_set_auth_tag(VALUE self, VALUE vtag) @@ -646,24 +685,27 @@ ossl_cipher_set_auth_tag(VALUE self, VALUE vtag) GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "authentication tag not supported by this cipher"); + ossl_raise(eCipherError, "authentication tag not supported by this cipher"); if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, tag)) - ossl_raise(eCipherError, "unable to set AEAD tag"); + ossl_raise(eCipherError, "unable to set AEAD tag"); return vtag; } /* * call-seq: - * cipher.auth_tag_len = Integer -> Integer + * cipher.auth_tag_len = integer + * + * Sets the length of the expected authentication tag for this Cipher. This + * method is available for some of AEAD ciphers that require the length to be + * set before starting encryption or decryption, such as CCM mode or OCB mode. * - * Sets the length of the authentication tag to be generated or to be given for - * AEAD ciphers that requires it as in input parameter. Note that not all AEAD - * ciphers support this method. + * For CCM mode and OCB mode, the tag length must be set before #iv= is set. * - * In OCB mode, the length must be supplied both when encrypting and when - * decrypting, and must be before specifying an IV. + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CIPHER_CTX_ctrl() with + * EVP_CTRL_AEAD_SET_TAG and a NULL buffer. */ static VALUE ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen) @@ -673,10 +715,10 @@ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen) GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "AEAD not supported by this cipher"); + ossl_raise(eCipherError, "AEAD not supported by this cipher"); if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len, NULL)) - ossl_raise(eCipherError, "unable to set authentication tag length"); + ossl_raise(eCipherError, "unable to set authentication tag length"); /* for #auth_tag */ rb_ivar_set(self, id_auth_tag_len, INT2NUM(tag_len)); @@ -686,11 +728,16 @@ ossl_cipher_set_auth_tag_len(VALUE self, VALUE vlen) /* * call-seq: - * cipher.iv_len = integer -> integer + * cipher.iv_len = integer + * + * Sets the IV/nonce length for this Cipher. This method is available for AEAD + * ciphers that support variable IV lengths. This method can be called if a + * different IV length than OpenSSL's default is desired, prior to calling + * #iv=. * - * Sets the IV/nonce length of the Cipher. Normally block ciphers don't allow - * changing the IV length, but some make use of IV for 'nonce'. You may need - * this for interoperability with other applications. + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + * This method internally calls EVP_CIPHER_CTX_ctrl() with + * EVP_CTRL_AEAD_SET_IVLEN. */ static VALUE ossl_cipher_set_iv_length(VALUE self, VALUE iv_length) @@ -700,10 +747,10 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length) GetCipher(self, ctx); if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER)) - ossl_raise(eCipherError, "cipher does not support AEAD"); + ossl_raise(eCipherError, "cipher does not support AEAD"); if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, len, NULL)) - ossl_raise(eCipherError, "unable to set IV length"); + ossl_raise(eCipherError, "unable to set IV length"); /* * EVP_CIPHER_CTX_iv_length() returns the default length. So we need to save @@ -716,13 +763,14 @@ ossl_cipher_set_iv_length(VALUE self, VALUE iv_length) /* * call-seq: - * cipher.key_len = integer -> integer + * cipher.key_len = integer * * Sets the key length of the cipher. If the cipher is a fixed length cipher * then attempting to set the key length to any value other than the fixed * value is an error. * - * Under normal circumstances you do not need to call this method (and probably shouldn't). + * Under normal circumstances you do not need to call this method (and + * probably shouldn't). * * See EVP_CIPHER_CTX_set_key_length for further information. */ @@ -739,13 +787,16 @@ ossl_cipher_set_key_length(VALUE self, VALUE key_length) return key_length; } +// TODO: Should #padding= take a boolean value instead? /* * call-seq: - * cipher.padding = integer -> integer + * cipher.padding = 1 or 0 * - * Enables or disables padding. By default encryption operations are padded using standard block padding and the - * padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the - * total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur. + * Enables or disables padding. By default encryption operations are padded + * using standard block padding and the padding is checked and removed when + * decrypting. If the pad parameter is zero then no padding is performed, the + * total amount of data encrypted or decrypted must then be a multiple of the + * block size or an error will occur. * * See EVP_CIPHER_CTX_set_padding for further information. */ @@ -757,7 +808,7 @@ ossl_cipher_set_padding(VALUE self, VALUE padding) GetCipher(self, ctx); if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1) - ossl_raise(eCipherError, NULL); + ossl_raise(eCipherError, NULL); return padding; } @@ -791,9 +842,9 @@ ossl_cipher_iv_length(VALUE self) GetCipher(self, ctx); if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_FLAG_AEAD_CIPHER) - len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); + len = (int)(VALUE)EVP_CIPHER_CTX_get_app_data(ctx); if (!len) - len = EVP_CIPHER_CTX_iv_length(ctx); + len = EVP_CIPHER_CTX_iv_length(ctx); return INT2NUM(len); } @@ -815,16 +866,40 @@ ossl_cipher_block_size(VALUE self) } /* + * call-seq: + * cipher.ccm_data_len = integer + * + * Sets the total length of the plaintext / ciphertext message that will be + * processed by #update in CCM mode. + * + * Make sure to call this method after #key= and #iv= have been set, and + * before #auth_data= or #update are called. + * + * This method is only available for CCM mode ciphers. + * + * See also the "AEAD Interface" section of the man page EVP_EncryptInit(3). + */ +static VALUE +ossl_cipher_set_ccm_data_len(VALUE self, VALUE data_len) +{ + int in_len, out_len; + EVP_CIPHER_CTX *ctx; + + in_len = NUM2INT(data_len); + + GetCipher(self, ctx); + if (EVP_CipherUpdate(ctx, NULL, &out_len, NULL, in_len) != 1) + ossl_raise(eCipherError, NULL); + + return data_len; +} + +/* * INIT */ void Init_ossl_cipher(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* Document-class: OpenSSL::Cipher * * Provides symmetric algorithms for encryption and decryption. The @@ -850,23 +925,7 @@ Init_ossl_cipher(void) * individual components name, key length and mode. Either all uppercase * or all lowercase strings may be used, for example: * - * cipher = OpenSSL::Cipher.new('AES-128-CBC') - * - * For each algorithm supported, there is a class defined under the - * Cipher class that goes by the name of the cipher, e.g. to obtain an - * instance of AES, you could also use - * - * # these are equivalent - * cipher = OpenSSL::Cipher::AES.new(128, :CBC) - * cipher = OpenSSL::Cipher::AES.new(128, 'CBC') - * cipher = OpenSSL::Cipher::AES.new('128-CBC') - * - * Finally, due to its wide-spread use, there are also extra classes - * defined for the different key sizes of AES - * - * cipher = OpenSSL::Cipher::AES128.new(:CBC) - * cipher = OpenSSL::Cipher::AES192.new(:CBC) - * cipher = OpenSSL::Cipher::AES256.new(:CBC) + * cipher = OpenSSL::Cipher.new('aes-128-cbc') * * === Choosing either encryption or decryption mode * @@ -896,7 +955,7 @@ Init_ossl_cipher(void) * without processing the password further. A simple and secure way to * create a key for a particular Cipher is * - * cipher = OpenSSL::AES256.new(:CFB) + * cipher = OpenSSL::Cipher.new('aes-256-cfb') * cipher.encrypt * key = cipher.random_key # also sets the generated key on the Cipher * @@ -964,14 +1023,14 @@ Init_ossl_cipher(void) * * data = "Very, very confidential data" * - * cipher = OpenSSL::Cipher::AES.new(128, :CBC) + * cipher = OpenSSL::Cipher.new('aes-128-cbc') * cipher.encrypt * key = cipher.random_key * iv = cipher.random_iv * * encrypted = cipher.update(data) + cipher.final * ... - * decipher = OpenSSL::Cipher::AES.new(128, :CBC) + * decipher = OpenSSL::Cipher.new('aes-128-cbc') * decipher.decrypt * decipher.key = key * decipher.iv = iv @@ -996,24 +1055,28 @@ Init_ossl_cipher(void) * could otherwise be exploited to modify ciphertexts in ways beneficial to * potential attackers. * - * An associated data is used where there is additional information, such as + * Associated data, also called additional authenticated data (AAD), is + * optionally used where there is additional information, such as * headers or some metadata, that must be also authenticated but not - * necessarily need to be encrypted. If no associated data is needed for - * encryption and later decryption, the OpenSSL library still requires a - * value to be set - "" may be used in case none is available. + * necessarily need to be encrypted. * * An example using the GCM (Galois/Counter Mode). You have 16 bytes _key_, * 12 bytes (96 bits) _nonce_ and the associated data _auth_data_. Be sure * not to reuse the _key_ and _nonce_ pair. Reusing an nonce ruins the * security guarantees of GCM mode. * - * cipher = OpenSSL::Cipher::AES.new(128, :GCM).encrypt + * key = OpenSSL::Random.random_bytes(16) + * nonce = OpenSSL::Random.random_bytes(12) + * auth_data = "authenticated but unencrypted data" + * data = "encrypted data" + * + * cipher = OpenSSL::Cipher.new('aes-128-gcm').encrypt * cipher.key = key * cipher.iv = nonce * cipher.auth_data = auth_data * * encrypted = cipher.update(data) + cipher.final - * tag = cipher.auth_tag # produces 16 bytes tag by default + * tag = cipher.auth_tag(16) * * Now you are the receiver. You know the _key_ and have received _nonce_, * _auth_data_, _encrypted_ and _tag_ through an untrusted network. Note @@ -1023,26 +1086,32 @@ Init_ossl_cipher(void) * ciphertext with a probability of 1/256. * * raise "tag is truncated!" unless tag.bytesize == 16 - * decipher = OpenSSL::Cipher::AES.new(128, :GCM).decrypt + * decipher = OpenSSL::Cipher.new('aes-128-gcm').decrypt * decipher.key = key * decipher.iv = nonce - * decipher.auth_tag = tag + * decipher.auth_tag = tag # could be called at any time before #final * decipher.auth_data = auth_data * * decrypted = decipher.update(encrypted) + decipher.final * * puts data == decrypted #=> true + * + * Note that other AEAD ciphers may require additional steps, such as + * setting the expected tag length (#auth_tag_len=) or the total data + * length (#ccm_data_len=) in advance. Make sure to read the relevant man + * page for details. */ cCipher = rb_define_class_under(mOSSL, "Cipher", rb_cObject); eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError); + eAuthTagError = rb_define_class_under(cCipher, "AuthTagError", eCipherError); rb_define_alloc_func(cCipher, ossl_cipher_alloc); rb_define_method(cCipher, "initialize_copy", ossl_cipher_copy, 1); rb_define_module_function(cCipher, "ciphers", ossl_s_ciphers, 0); rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1); rb_define_method(cCipher, "reset", ossl_cipher_reset, 0); - rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1); - rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1); + rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, 0); + rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, 0); rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1); rb_define_method(cCipher, "update", ossl_cipher_update, -1); rb_define_method(cCipher, "final", ossl_cipher_final, 0); @@ -1060,7 +1129,9 @@ Init_ossl_cipher(void) rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0); rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0); rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1); + rb_define_method(cCipher, "ccm_data_len=", ossl_cipher_set_ccm_data_len, 1); id_auth_tag_len = rb_intern_const("auth_tag_len"); id_key_set = rb_intern_const("key_set"); + id_cipher_holder = rb_intern_const("EVP_CIPHER_holder"); } diff --git a/ext/openssl/ossl_cipher.h b/ext/openssl/ossl_cipher.h index 2392d41c6a..fba63a140f 100644 --- a/ext/openssl/ossl_cipher.h +++ b/ext/openssl/ossl_cipher.h @@ -5,15 +5,21 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_CIPHER_H_) #define _OSSL_CIPHER_H_ -extern VALUE cCipher; -extern VALUE eCipherError; - -const EVP_CIPHER *ossl_evp_get_cipherbyname(VALUE); +/* + * Gets EVP_CIPHER from a String or an OpenSSL::Digest instance (discouraged, + * but still supported for compatibility). A holder object is created if the + * EVP_CIPHER is a "fetched" algorithm. + */ +const EVP_CIPHER *ossl_evp_cipher_fetch(VALUE obj, volatile VALUE *holder); +/* + * This is meant for OpenSSL::Engine#cipher. EVP_CIPHER must not be a fetched + * one. + */ VALUE ossl_cipher_new(const EVP_CIPHER *); void Init_ossl_cipher(void); diff --git a/ext/openssl/ossl_config.c b/ext/openssl/ossl_config.c index 28392e208c..274875a978 100644 --- a/ext/openssl/ossl_config.c +++ b/ext/openssl/ossl_config.c @@ -5,85 +5,452 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" +static VALUE cConfig, eConfigError; + +static void +nconf_free(void *conf) +{ + NCONF_free(conf); +} + +static const rb_data_type_t ossl_config_type = { + "OpenSSL/CONF", + { + 0, nconf_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE, +}; + +CONF * +GetConfig(VALUE obj) +{ + CONF *conf; + + TypedData_Get_Struct(obj, CONF, &ossl_config_type, conf); + if (!conf) + rb_raise(rb_eRuntimeError, "CONF is not initialized"); + return conf; +} + +static VALUE +config_s_alloc(VALUE klass) +{ + VALUE obj; + CONF *conf; + + obj = TypedData_Wrap_Struct(klass, &ossl_config_type, 0); + conf = NCONF_new(NULL); + if (!conf) + ossl_raise(eConfigError, "NCONF_new"); + RTYPEDDATA_DATA(obj) = conf; + return obj; +} + +static void +config_load_bio(CONF *conf, BIO *bio) +{ + long eline = -1; + + if (!NCONF_load_bio(conf, bio, &eline)) { + BIO_free(bio); + if (eline <= 0) + ossl_raise(eConfigError, "wrong config format"); + else + ossl_raise(eConfigError, "error in line %ld", eline); + } + BIO_free(bio); + + /* + * Clear the error queue even if it is parsed successfully. + * Particularly, when the .include directive refers to a non-existent file, + * it is only reported in the error queue. + */ + ossl_clear_error(); +} /* - * Classes - */ -VALUE cConfig; -/* Document-class: OpenSSL::ConfigError + * call-seq: + * Config.parse(string) -> OpenSSL::Config * - * General error for openssl library configuration files. Including formatting, - * parsing errors, etc. + * Parses a given _string_ as a blob that contains configuration for OpenSSL. */ -VALUE eConfigError; +static VALUE +config_s_parse(VALUE klass, VALUE str) +{ + VALUE obj = config_s_alloc(klass); + CONF *conf = GetConfig(obj); + BIO *bio; + + bio = ossl_obj2bio(&str); + config_load_bio(conf, bio); /* Consumes BIO */ + rb_obj_freeze(obj); + return obj; +} + +static VALUE config_get_sections(VALUE self); +static VALUE config_get_section(VALUE self, VALUE section); /* - * Public + * call-seq: + * Config.parse_config(io) -> hash + * + * Parses the configuration data read from _io_ and returns the whole content + * as a Hash. */ +static VALUE +config_s_parse_config(VALUE klass, VALUE io) +{ + VALUE obj, sections, ret; + long i; + + obj = config_s_parse(klass, io); + sections = config_get_sections(obj); + ret = rb_hash_new(); + for (i = 0; i < RARRAY_LEN(sections); i++) { + VALUE section = rb_ary_entry(sections, i); + rb_hash_aset(ret, section, config_get_section(obj, section)); + } + return ret; +} /* - * DupConfigPtr is a public C-level function for getting OpenSSL CONF struct - * from an OpenSSL::Config(eConfig) instance. We decided to implement - * OpenSSL::Config in Ruby level but we need to pass native CONF struct for - * some OpenSSL features such as X509V3_EXT_*. + * call-seq: + * Config.new(filename) -> OpenSSL::Config + * + * Creates an instance of OpenSSL::Config from the content of the file + * specified by _filename_. + * + * This can be used in contexts like OpenSSL::X509::ExtensionFactory.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. */ -CONF * -DupConfigPtr(VALUE obj) +static VALUE +config_initialize(int argc, VALUE *argv, VALUE self) { - CONF *conf; + CONF *conf = GetConfig(self); + VALUE filename; + + /* 0-arguments call has no use-case, but is kept for compatibility */ + rb_scan_args(argc, argv, "01", &filename); + rb_check_frozen(self); + if (!NIL_P(filename)) { + BIO *bio = BIO_new_file(StringValueCStr(filename), "rb"); + if (!bio) + ossl_raise(eConfigError, "BIO_new_file"); + config_load_bio(conf, bio); /* Consumes BIO */ + } + rb_obj_freeze(self); + return self; +} + +static VALUE +config_initialize_copy(VALUE self, VALUE other) +{ + CONF *conf = GetConfig(self); VALUE str; BIO *bio; - long eline = -1; - OSSL_Check_Kind(obj, cConfig); - str = rb_funcall(obj, rb_intern("to_s"), 0); + str = rb_funcall(other, rb_intern("to_s"), 0); + rb_check_frozen(self); bio = ossl_obj2bio(&str); - conf = NCONF_new(NULL); - if(!conf){ - BIO_free(bio); - ossl_raise(eConfigError, NULL); + config_load_bio(conf, bio); /* Consumes BIO */ + rb_obj_freeze(self); + return self; +} + +/* + * call-seq: + * config.get_value(section, key) -> string + * + * Gets the value of _key_ from the given _section_. + * + * Given the following configurating file being loaded: + * + * config = OpenSSL::Config.load('foo.cnf') + * #=> #<OpenSSL::Config sections=["default"]> + * 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" + */ +static VALUE +config_get_value(VALUE self, VALUE section, VALUE key) +{ + CONF *conf = GetConfig(self); + const char *str, *sectionp; + + StringValueCStr(section); + StringValueCStr(key); + /* For compatibility; NULL means "default". */ + sectionp = RSTRING_LEN(section) ? RSTRING_PTR(section) : NULL; + str = NCONF_get_string(conf, sectionp, RSTRING_PTR(key)); + if (!str) { + ossl_clear_error(); + return Qnil; } - if(!NCONF_load_bio(conf, bio, &eline)){ - BIO_free(bio); - NCONF_free(conf); - if (eline <= 0) - ossl_raise(eConfigError, "wrong config format"); - else - ossl_raise(eConfigError, "error in line %d", eline); + return rb_str_new_cstr(str); +} + +/* + * call-seq: + * config[section] -> hash + * + * Gets all key-value pairs in a specific _section_ from the current + * configuration. + * + * Given the following configurating file being loaded: + * + * config = OpenSSL::Config.load('foo.cnf') + * #=> #<OpenSSL::Config sections=["default"]> + * puts config.to_s + * #=> [ default ] + * # foo=bar + * + * You can get a hash of the specific section like so: + * + * config['default'] + * #=> {"foo"=>"bar"} + * + */ +static VALUE +config_get_section(VALUE self, VALUE section) +{ + CONF *conf = GetConfig(self); + STACK_OF(CONF_VALUE) *sk; + int i, entries; + VALUE hash; + + hash = rb_hash_new(); + StringValueCStr(section); + if (!(sk = NCONF_get_section(conf, RSTRING_PTR(section)))) { + ossl_clear_error(); + return hash; } - BIO_free(bio); + entries = sk_CONF_VALUE_num(sk); + for (i = 0; i < entries; i++) { + CONF_VALUE *entry = sk_CONF_VALUE_value(sk, i); + rb_hash_aset(hash, rb_str_new_cstr(entry->name), + rb_str_new_cstr(entry->value)); + } + return hash; +} - return conf; +static void +get_conf_section_doall_arg(CONF_VALUE *cv, VALUE *aryp) +{ + if (cv->name) + return; + rb_ary_push(*aryp, rb_str_new_cstr(cv->section)); +} + +/* IMPLEMENT_LHASH_DOALL_ARG_CONST() requires >= OpenSSL 1.1.0 */ +static IMPLEMENT_LHASH_DOALL_ARG_FN(get_conf_section, CONF_VALUE, VALUE) + +/* + * call-seq: + * config.sections -> array of string + * + * Get the names of all sections in the current configuration. + */ +static VALUE +config_get_sections(VALUE self) +{ + CONF *conf = GetConfig(self); + VALUE ary; + + ary = rb_ary_new(); + lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(get_conf_section), + &ary); + return ary; +} + +static void +dump_conf_value_doall_arg(CONF_VALUE *cv, VALUE *strp) +{ + VALUE str = *strp; + STACK_OF(CONF_VALUE) *sk; + int i, num; + + if (cv->name) + return; + sk = (STACK_OF(CONF_VALUE) *)cv->value; + num = sk_CONF_VALUE_num(sk); + rb_str_cat_cstr(str, "[ "); + rb_str_cat_cstr(str, cv->section); + rb_str_cat_cstr(str, " ]\n"); + for (i = 0; i < num; i++){ + CONF_VALUE *v = sk_CONF_VALUE_value(sk, i); + rb_str_cat_cstr(str, v->name ? v->name : "None"); + rb_str_cat_cstr(str, "="); + rb_str_cat_cstr(str, v->value ? v->value : "None"); + rb_str_cat_cstr(str, "\n"); + } + rb_str_cat_cstr(str, "\n"); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_conf_value, CONF_VALUE, VALUE) + +/* + * call-seq: + * config.to_s -> string + * + * + * Gets the parsable form of the current configuration. + * + * Given the following configuration file being loaded: + * + * config = OpenSSL::Config.load('baz.cnf') + * #=> #<OpenSSL::Config sections=["default"]> + * puts config.to_s + * #=> [ default ] + * # foo=bar + * # baz=buz + * + * You can 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) + * #=> #<OpenSSL::Config sections=["default"]> + * puts new_config + * #=> [ default ] + * foo=bar + * baz=buz + */ +static VALUE +config_to_s(VALUE self) +{ + CONF *conf = GetConfig(self); + VALUE str; + + str = rb_str_new(NULL, 0); + lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(dump_conf_value), + &str); + return str; +} + +static void +each_conf_value_doall_arg(CONF_VALUE *cv, void *unused) +{ + STACK_OF(CONF_VALUE) *sk; + VALUE section; + int i, num; + + if (cv->name) + return; + sk = (STACK_OF(CONF_VALUE) *)cv->value; + num = sk_CONF_VALUE_num(sk); + section = rb_str_new_cstr(cv->section); + for (i = 0; i < num; i++){ + CONF_VALUE *v = sk_CONF_VALUE_value(sk, i); + VALUE name = v->name ? rb_str_new_cstr(v->name) : Qnil; + VALUE value = v->value ? rb_str_new_cstr(v->value) : Qnil; + rb_yield(rb_ary_new3(3, section, name, value)); + } } -/* Document-const: DEFAULT_CONFIG_FILE +static IMPLEMENT_LHASH_DOALL_ARG_FN(each_conf_value, CONF_VALUE, void) + +/* + * call-seq: + * config.each { |section, key, value| } + * + * Retrieves the section and its pairs for the current configuration. * - * The default system configuration file for openssl + * config.each do |section, key, value| + * # ... + * end */ +static VALUE +config_each(VALUE self) +{ + CONF *conf = GetConfig(self); + + RETURN_ENUMERATOR(self, 0, 0); + + lh_doall_arg((_LHASH *)conf->data, LHASH_DOALL_ARG_FN(each_conf_value), + NULL); + return self; +} /* - * INIT + * call-seq: + * config.inspect -> string + * + * String representation of this configuration object, including the class + * name and its sections. */ +static VALUE +config_inspect(VALUE self) +{ + VALUE str, ary = config_get_sections(self); + const char *cname = rb_class2name(rb_obj_class(self)); + + str = rb_str_new_cstr("#<"); + rb_str_cat_cstr(str, cname); + rb_str_cat_cstr(str, " sections="); + rb_str_append(str, rb_inspect(ary)); + rb_str_cat_cstr(str, ">"); + + return str; +} + void Init_ossl_config(void) { - char *default_config_file; + char *path; + VALUE path_str; -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif + /* Document-class: 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 https://docs.openssl.org/master/man5/config/ + */ + cConfig = rb_define_class_under(mOSSL, "Config", rb_cObject); + /* Document-class: OpenSSL::ConfigError + * + * General error for openssl library configuration files. Including formatting, + * parsing errors, etc. + */ eConfigError = rb_define_class_under(mOSSL, "ConfigError", eOSSLError); - cConfig = rb_define_class_under(mOSSL, "Config", rb_cObject); - default_config_file = CONF_get1_default_config_file(); - rb_define_const(cConfig, "DEFAULT_CONFIG_FILE", - rb_str_new2(default_config_file)); - OPENSSL_free(default_config_file); - /* methods are defined by openssl/config.rb */ + rb_include_module(cConfig, rb_mEnumerable); + rb_define_singleton_method(cConfig, "parse", config_s_parse, 1); + rb_define_singleton_method(cConfig, "parse_config", config_s_parse_config, 1); + rb_define_alias(CLASS_OF(cConfig), "load", "new"); + rb_define_alloc_func(cConfig, config_s_alloc); + rb_define_method(cConfig, "initialize", config_initialize, -1); + rb_define_method(cConfig, "initialize_copy", config_initialize_copy, 1); + rb_define_method(cConfig, "get_value", config_get_value, 2); + rb_define_method(cConfig, "[]", config_get_section, 1); + rb_define_method(cConfig, "sections", config_get_sections, 0); + rb_define_method(cConfig, "to_s", config_to_s, 0); + rb_define_method(cConfig, "each", config_each, 0); + rb_define_method(cConfig, "inspect", config_inspect, 0); + + /* Document-const: DEFAULT_CONFIG_FILE + * + * The default system configuration file for OpenSSL. + */ + path = CONF_get1_default_config_file(); + path_str = rb_obj_freeze(ossl_buf2str(path, rb_long2int(strlen(path)))); + rb_define_const(cConfig, "DEFAULT_CONFIG_FILE", path_str); } diff --git a/ext/openssl/ossl_config.h b/ext/openssl/ossl_config.h index 627d297ba3..a254360c2c 100644 --- a/ext/openssl/ossl_config.h +++ b/ext/openssl/ossl_config.h @@ -5,15 +5,12 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ -#if !defined(_OSSL_CONFIG_H_) -#define _OSSL_CONFIG_H_ +#ifndef OSSL_CONFIG_H +#define OSSL_CONFIG_H -extern VALUE cConfig; -extern VALUE eConfigError; - -CONF* DupConfigPtr(VALUE obj); +CONF *GetConfig(VALUE obj); void Init_ossl_config(void); -#endif /* _OSSL_CONFIG_H_ */ +#endif /* OSSL_CONFIG_H */ diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c index 112ce33647..e23968b1e3 100644 --- a/ext/openssl/ossl_digest.c +++ b/ext/openssl/ossl_digest.c @@ -5,22 +5,23 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" #define GetDigest(obj, ctx) do { \ TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_digest_type, (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "Digest CTX wasn't initialized!"); \ } \ } while (0) /* * Classes */ -VALUE cDigest; -VALUE eDigestError; +static VALUE cDigest; +static VALUE eDigestError; +static ID id_md_holder; static VALUE ossl_digest_alloc(VALUE klass); @@ -33,39 +34,67 @@ ossl_digest_free(void *ctx) static const rb_data_type_t ossl_digest_type = { "OpenSSL/Digest", { - 0, ossl_digest_free, + 0, ossl_digest_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +#ifdef OSSL_USE_PROVIDER +static void +ossl_evp_md_free(void *ptr) +{ + // This is safe to call against const EVP_MD * returned by + // EVP_get_digestbyname() + EVP_MD_free(ptr); +} + +static const rb_data_type_t ossl_evp_md_holder_type = { + "OpenSSL/EVP_MD", + { + .dfree = ossl_evp_md_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; +#endif + /* * Public */ const EVP_MD * -ossl_evp_get_digestbyname(VALUE obj) +ossl_evp_md_fetch(VALUE obj, volatile VALUE *holder) { - const EVP_MD *md; - ASN1_OBJECT *oid = NULL; - - if (RB_TYPE_P(obj, T_STRING)) { - const char *name = StringValueCStr(obj); - - md = EVP_get_digestbyname(name); - if (!md) { - oid = OBJ_txt2obj(name, 0); - md = EVP_get_digestbyobj(oid); - ASN1_OBJECT_free(oid); - } - if(!md) - ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%"PRIsVALUE").", obj); - } else { + *holder = Qnil; + if (rb_obj_is_kind_of(obj, cDigest)) { EVP_MD_CTX *ctx; - GetDigest(obj, ctx); - - md = EVP_MD_CTX_md(ctx); + EVP_MD *md = (EVP_MD *)EVP_MD_CTX_get0_md(ctx); +#ifdef OSSL_USE_PROVIDER + *holder = TypedData_Wrap_Struct(0, &ossl_evp_md_holder_type, NULL); + if (!EVP_MD_up_ref(md)) + ossl_raise(eDigestError, "EVP_MD_up_ref"); + RTYPEDDATA_DATA(*holder) = md; +#endif + return md; } + const char *name = StringValueCStr(obj); + EVP_MD *md = (EVP_MD *)EVP_get_digestbyname(name); + if (!md) { + ASN1_OBJECT *oid = OBJ_txt2obj(name, 0); + md = (EVP_MD *)EVP_get_digestbyobj(oid); + ASN1_OBJECT_free(oid); + } +#ifdef OSSL_USE_PROVIDER + if (!md) { + ossl_clear_error(); + *holder = TypedData_Wrap_Struct(0, &ossl_evp_md_holder_type, NULL); + md = EVP_MD_fetch(NULL, name, NULL); + RTYPEDDATA_DATA(*holder) = md; + } +#endif + if (!md) + ossl_raise(eDigestError, "unsupported digest algorithm: %"PRIsVALUE, + obj); return md; } @@ -75,14 +104,17 @@ ossl_digest_new(const EVP_MD *md) VALUE ret; EVP_MD_CTX *ctx; + // NOTE: This does not set id_md_holder because this function should + // only be called from ossl_engine.c, which will not use any + // reference-counted digests. ret = ossl_digest_alloc(cDigest); ctx = EVP_MD_CTX_new(); if (!ctx) - ossl_raise(eDigestError, "EVP_MD_CTX_new"); + ossl_raise(eDigestError, "EVP_MD_CTX_new"); RTYPEDDATA_DATA(ret) = ctx; if (!EVP_DigestInit_ex(ctx, md, NULL)) - ossl_raise(eDigestError, "Digest initialization failed"); + ossl_raise(eDigestError, "Digest initialization failed"); return ret; } @@ -96,14 +128,15 @@ ossl_digest_alloc(VALUE klass) return TypedData_Wrap_Struct(klass, &ossl_digest_type, 0); } -VALUE ossl_digest_update(VALUE, VALUE); +static VALUE ossl_digest_update(VALUE, VALUE); /* * call-seq: * Digest.new(string [, data]) -> Digest * * Creates a Digest instance based on _string_, which is either the ln - * (long name) or sn (short name) of a supported digest algorithm. + * (long name) or sn (short name) of a supported digest algorithm. A list of + * supported algorithms can be obtained by calling OpenSSL::Digest.digests. * * If _data_ (a String) is given, it is used as the initial input to the * Digest instance, i.e. @@ -120,26 +153,28 @@ ossl_digest_initialize(int argc, VALUE *argv, VALUE self) { EVP_MD_CTX *ctx; const EVP_MD *md; - VALUE type, data; + VALUE type, data, md_holder; rb_scan_args(argc, argv, "11", &type, &data); - md = ossl_evp_get_digestbyname(type); + md = ossl_evp_md_fetch(type, &md_holder); if (!NIL_P(data)) StringValue(data); TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx); if (!ctx) { - RTYPEDDATA_DATA(self) = ctx = EVP_MD_CTX_new(); - if (!ctx) - ossl_raise(eDigestError, "EVP_MD_CTX_new"); + RTYPEDDATA_DATA(self) = ctx = EVP_MD_CTX_new(); + if (!ctx) + ossl_raise(eDigestError, "EVP_MD_CTX_new"); } if (!EVP_DigestInit_ex(ctx, md, NULL)) - ossl_raise(eDigestError, "Digest initialization failed"); + ossl_raise(eDigestError, "Digest initialization failed"); + rb_ivar_set(self, id_md_holder, md_holder); if (!NIL_P(data)) return ossl_digest_update(self, data); return self; } +/* :nodoc: */ static VALUE ossl_digest_copy(VALUE self, VALUE other) { @@ -150,18 +185,44 @@ ossl_digest_copy(VALUE self, VALUE other) TypedData_Get_Struct(self, EVP_MD_CTX, &ossl_digest_type, ctx1); if (!ctx1) { - RTYPEDDATA_DATA(self) = ctx1 = EVP_MD_CTX_new(); - if (!ctx1) - ossl_raise(eDigestError, "EVP_MD_CTX_new"); + RTYPEDDATA_DATA(self) = ctx1 = EVP_MD_CTX_new(); + if (!ctx1) + ossl_raise(eDigestError, "EVP_MD_CTX_new"); } GetDigest(other, ctx2); if (!EVP_MD_CTX_copy(ctx1, ctx2)) { - ossl_raise(eDigestError, NULL); + ossl_raise(eDigestError, NULL); } return self; } +static void +add_digest_name_to_ary(const OBJ_NAME *name, void *arg) +{ + VALUE ary = (VALUE)arg; + rb_ary_push(ary, rb_str_new2(name->name)); +} + +/* + * call-seq: + * OpenSSL::Digest.digests -> array[string...] + * + * Returns the names of all available digests in an array. + */ +static VALUE +ossl_s_digests(VALUE self) +{ + VALUE ary; + + ary = rb_ary_new(); + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, + add_digest_name_to_ary, + (void*)ary); + + return ary; +} + /* * call-seq: * digest.reset -> self @@ -176,8 +237,8 @@ ossl_digest_reset(VALUE self) EVP_MD_CTX *ctx; GetDigest(self, ctx); - if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL) != 1) { - ossl_raise(eDigestError, "Digest initialization failed."); + if (EVP_DigestInit_ex(ctx, EVP_MD_CTX_get0_md(ctx), NULL) != 1) { + ossl_raise(eDigestError, "Digest initialization failed."); } return self; @@ -192,13 +253,13 @@ ossl_digest_reset(VALUE self) * be passed individually to the Digest instance. * * === Example - * digest = OpenSSL::Digest::SHA256.new + * digest = OpenSSL::Digest.new('SHA256') * digest.update('First input') * digest << 'Second input' # equivalent to digest.update('Second input') * result = digest.digest * */ -VALUE +static VALUE ossl_digest_update(VALUE self, VALUE data) { EVP_MD_CTX *ctx; @@ -207,7 +268,7 @@ ossl_digest_update(VALUE self, VALUE data) GetDigest(self, ctx); if (!EVP_DigestUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) - ossl_raise(eDigestError, "EVP_DigestUpdate"); + ossl_raise(eDigestError, "EVP_DigestUpdate"); return self; } @@ -218,25 +279,15 @@ ossl_digest_update(VALUE self, VALUE data) * */ static VALUE -ossl_digest_finish(int argc, VALUE *argv, VALUE self) +ossl_digest_finish(VALUE self) { EVP_MD_CTX *ctx; VALUE str; - int out_len; GetDigest(self, ctx); - rb_scan_args(argc, argv, "01", &str); - out_len = EVP_MD_CTX_size(ctx); - - if (NIL_P(str)) { - str = rb_str_new(NULL, out_len); - } else { - StringValue(str); - rb_str_resize(str, out_len); - } - + str = rb_str_new(NULL, EVP_MD_CTX_size(ctx)); if (!EVP_DigestFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), NULL)) - ossl_raise(eDigestError, "EVP_DigestFinal_ex"); + ossl_raise(eDigestError, "EVP_DigestFinal_ex"); return str; } @@ -245,10 +296,11 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self) * call-seq: * digest.name -> string * - * Returns the sn of this Digest algorithm. + * Returns the short name of this Digest algorithm which may differ slightly + * from the original name provided. * * === Example - * digest = OpenSSL::Digest::SHA512.new + * digest = OpenSSL::Digest.new('SHA512') * puts digest.name # => SHA512 * */ @@ -259,7 +311,7 @@ ossl_digest_name(VALUE self) GetDigest(self, ctx); - return rb_str_new2(EVP_MD_name(EVP_MD_CTX_md(ctx))); + return rb_str_new_cstr(EVP_MD_name(EVP_MD_CTX_get0_md(ctx))); } /* @@ -270,7 +322,7 @@ ossl_digest_name(VALUE self) * final message digest result. * * === Example - * digest = OpenSSL::Digest::SHA1.new + * digest = OpenSSL::Digest.new('SHA1') * puts digest.digest_length # => 20 * */ @@ -294,7 +346,7 @@ ossl_digest_size(VALUE self) * consecutively. * * === Example - * digest = OpenSSL::Digest::SHA1.new + * digest = OpenSSL::Digest.new('SHA1') * puts digest.block_length # => 64 */ static VALUE @@ -313,13 +365,6 @@ ossl_digest_block_length(VALUE self) void Init_ossl_digest(void) { - rb_require("digest"); - -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* Document-class: OpenSSL::Digest * * OpenSSL::Digest allows you to compute message digests (sometimes @@ -348,54 +393,19 @@ Init_ossl_digest(void) * the integrity of a signed document, it suffices to re-compute the hash * and verify that it is equal to that in the signature. * - * Among the supported message digest algorithms are: - * * SHA, SHA1, SHA224, SHA256, SHA384 and SHA512 - * * MD2, MD4, MDC2 and MD5 - * * RIPEMD160 - * * DSS, DSS1 (Pseudo algorithms to be used for DSA signatures. DSS is - * equal to SHA and DSS1 is equal to SHA1) + * You can get a list of all digest algorithms supported on your system by + * running this command in your terminal: * - * For each of these algorithms, there is a sub-class of Digest that - * can be instantiated as simply as e.g. + * openssl list -digest-algorithms * - * digest = OpenSSL::Digest::SHA1.new + * Among the OpenSSL 1.1.1 supported message digest algorithms are: + * * SHA224, SHA256, SHA384, SHA512, SHA512-224 and SHA512-256 + * * SHA3-224, SHA3-256, SHA3-384 and SHA3-512 + * * BLAKE2s256 and BLAKE2b512 * - * === Mapping between Digest class and sn/ln + * Each of these algorithms can be instantiated using the name: * - * The sn (short names) and ln (long names) are defined in - * <openssl/object.h> and <openssl/obj_mac.h>. They are textual - * representations of ASN.1 OBJECT IDENTIFIERs. Each supported digest - * algorithm has an OBJECT IDENTIFIER associated to it and those again - * have short/long names assigned to them. - * E.g. the OBJECT IDENTIFIER for SHA-1 is 1.3.14.3.2.26 and its - * sn is "SHA1" and its ln is "sha1". - * ==== MD2 - * * sn: MD2 - * * ln: md2 - * ==== MD4 - * * sn: MD4 - * * ln: md4 - * ==== MD5 - * * sn: MD5 - * * ln: md5 - * ==== SHA - * * sn: SHA - * * ln: SHA - * ==== SHA-1 - * * sn: SHA1 - * * ln: sha1 - * ==== SHA-224 - * * sn: SHA224 - * * ln: sha224 - * ==== SHA-256 - * * sn: SHA256 - * * ln: sha256 - * ==== SHA-384 - * * sn: SHA384 - * * ln: sha384 - * ==== SHA-512 - * * sn: SHA512 - * * ln: sha512 + * digest = OpenSSL::Digest.new('SHA256') * * "Breaking" a message digest algorithm means defying its one-way * function characteristics, i.e. producing a collision or finding a way @@ -407,16 +417,16 @@ Init_ossl_digest(void) * * === Hashing a file * - * data = File.read('document') - * sha256 = OpenSSL::Digest::SHA256.new + * data = File.binread('document') + * sha256 = OpenSSL::Digest.new('SHA256') * digest = sha256.digest(data) * * === Hashing several pieces of data at once * - * data1 = File.read('file1') - * data2 = File.read('file2') - * data3 = File.read('file3') - * sha256 = OpenSSL::Digest::SHA256.new + * data1 = File.binread('file1') + * data2 = File.binread('file2') + * data3 = File.binread('file3') + * sha256 = OpenSSL::Digest.new('SHA256') * sha256 << data1 * sha256 << data2 * sha256 << data3 @@ -424,15 +434,21 @@ Init_ossl_digest(void) * * === Reuse a Digest instance * - * data1 = File.read('file1') - * sha256 = OpenSSL::Digest::SHA256.new + * data1 = File.binread('file1') + * sha256 = OpenSSL::Digest.new('SHA256') * digest1 = sha256.digest(data1) * - * data2 = File.read('file2') + * data2 = File.binread('file2') * sha256.reset * digest2 = sha256.digest(data2) * */ + + /* + * Digest::Class is defined by the digest library. rb_require() cannot be + * used here because it bypasses RubyGems. + */ + rb_funcall(Qnil, rb_intern_const("require"), 1, rb_str_new_cstr("digest")); cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class")); /* Document-class: OpenSSL::Digest::DigestError * @@ -443,14 +459,17 @@ Init_ossl_digest(void) rb_define_alloc_func(cDigest, ossl_digest_alloc); + rb_define_module_function(cDigest, "digests", ossl_s_digests, 0); rb_define_method(cDigest, "initialize", ossl_digest_initialize, -1); rb_define_method(cDigest, "initialize_copy", ossl_digest_copy, 1); rb_define_method(cDigest, "reset", ossl_digest_reset, 0); rb_define_method(cDigest, "update", ossl_digest_update, 1); rb_define_alias(cDigest, "<<", "update"); - rb_define_private_method(cDigest, "finish", ossl_digest_finish, -1); + rb_define_private_method(cDigest, "finish", ossl_digest_finish, 0); rb_define_method(cDigest, "digest_length", ossl_digest_size, 0); rb_define_method(cDigest, "block_length", ossl_digest_block_length, 0); rb_define_method(cDigest, "name", ossl_digest_name, 0); + + id_md_holder = rb_intern_const("EVP_MD_holder"); } diff --git a/ext/openssl/ossl_digest.h b/ext/openssl/ossl_digest.h index 50bf5666a3..9c3bb2b149 100644 --- a/ext/openssl/ossl_digest.h +++ b/ext/openssl/ossl_digest.h @@ -5,15 +5,20 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_DIGEST_H_) #define _OSSL_DIGEST_H_ -extern VALUE cDigest; -extern VALUE eDigestError; - -const EVP_MD *ossl_evp_get_digestbyname(VALUE); +/* + * Gets EVP_MD from a String or an OpenSSL::Digest instance (discouraged, but + * still supported for compatibility). A holder object is created if the EVP_MD + * is a "fetched" algorithm. + */ +const EVP_MD *ossl_evp_md_fetch(VALUE obj, volatile VALUE *holder); +/* + * This is meant for OpenSSL::Engine#digest. EVP_MD must not be a fetched one. + */ VALUE ossl_digest_new(const EVP_MD *); void Init_ossl_digest(void); diff --git a/ext/openssl/ossl_engine.c b/ext/openssl/ossl_engine.c index 5ca0d4ca3f..a2bcb07ea4 100644 --- a/ext/openssl/ossl_engine.c +++ b/ext/openssl/ossl_engine.c @@ -5,17 +5,18 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" -#if !defined(OPENSSL_NO_ENGINE) +#ifdef OSSL_USE_ENGINE +# include <openssl/engine.h> #define NewEngine(klass) \ TypedData_Wrap_Struct((klass), &ossl_engine_type, 0) #define SetEngine(obj, engine) do { \ if (!(engine)) { \ - ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (engine); \ } while(0) @@ -36,35 +37,25 @@ * * See also, https://www.openssl.org/docs/crypto/engine.html */ -VALUE cEngine; +static VALUE cEngine; /* Document-class: OpenSSL::Engine::EngineError * * This is the generic exception for OpenSSL::Engine related errors */ -VALUE eEngineError; +static VALUE eEngineError; /* * Private */ -#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 #define OSSL_ENGINE_LOAD_IF_MATCH(engine_name, x) \ do{\ - if(!strcmp(#engine_name, RSTRING_PTR(name))){\ - if (OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_##x, NULL))\ - return Qtrue;\ - else\ - ossl_raise(eEngineError, "OPENSSL_init_crypto"); \ - }\ -}while(0) -#else -#define OSSL_ENGINE_LOAD_IF_MATCH(engine_name, x) \ -do{\ - if(!strcmp(#engine_name, RSTRING_PTR(name))){\ - ENGINE_load_##engine_name();\ - return Qtrue;\ - }\ + if(!strcmp(#engine_name, RSTRING_PTR(name))){\ + if (OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_##x, NULL))\ + return Qtrue;\ + else\ + ossl_raise(eEngineError, "OPENSSL_init_crypto"); \ + }\ }while(0) -#endif static void ossl_engine_free(void *engine) @@ -75,9 +66,9 @@ ossl_engine_free(void *engine) static const rb_data_type_t ossl_engine_type = { "OpenSSL/Engine", { - 0, ossl_engine_free, + 0, ossl_engine_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -93,9 +84,6 @@ static const rb_data_type_t ossl_engine_type = { static VALUE ossl_engine_s_load(int argc, VALUE *argv, VALUE klass) { -#if !defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES) - return Qnil; -#else VALUE name; rb_scan_args(argc, argv, "01", &name); @@ -104,60 +92,13 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass) return Qtrue; } StringValueCStr(name); -#ifndef OPENSSL_NO_STATIC_ENGINE -#if HAVE_ENGINE_LOAD_DYNAMIC OSSL_ENGINE_LOAD_IF_MATCH(dynamic, DYNAMIC); -#endif -#if HAVE_ENGINE_LOAD_4758CCA - OSSL_ENGINE_LOAD_IF_MATCH(4758cca, 4758CCA); -#endif -#if HAVE_ENGINE_LOAD_AEP - OSSL_ENGINE_LOAD_IF_MATCH(aep, AEP); -#endif -#if HAVE_ENGINE_LOAD_ATALLA - OSSL_ENGINE_LOAD_IF_MATCH(atalla, ATALLA); -#endif -#if HAVE_ENGINE_LOAD_CHIL - OSSL_ENGINE_LOAD_IF_MATCH(chil, CHIL); -#endif -#if HAVE_ENGINE_LOAD_CSWIFT - OSSL_ENGINE_LOAD_IF_MATCH(cswift, CSWIFT); -#endif -#if HAVE_ENGINE_LOAD_NURON - OSSL_ENGINE_LOAD_IF_MATCH(nuron, NURON); -#endif -#if HAVE_ENGINE_LOAD_SUREWARE - OSSL_ENGINE_LOAD_IF_MATCH(sureware, SUREWARE); -#endif -#if HAVE_ENGINE_LOAD_UBSEC - OSSL_ENGINE_LOAD_IF_MATCH(ubsec, UBSEC); -#endif -#if HAVE_ENGINE_LOAD_PADLOCK OSSL_ENGINE_LOAD_IF_MATCH(padlock, PADLOCK); -#endif -#if HAVE_ENGINE_LOAD_CAPI OSSL_ENGINE_LOAD_IF_MATCH(capi, CAPI); -#endif -#if HAVE_ENGINE_LOAD_GMP - OSSL_ENGINE_LOAD_IF_MATCH(gmp, GMP); -#endif -#if HAVE_ENGINE_LOAD_GOST - OSSL_ENGINE_LOAD_IF_MATCH(gost, GOST); -#endif -#if HAVE_ENGINE_LOAD_CRYPTODEV OSSL_ENGINE_LOAD_IF_MATCH(cryptodev, CRYPTODEV); -#endif -#if HAVE_ENGINE_LOAD_AESNI - OSSL_ENGINE_LOAD_IF_MATCH(aesni, AESNI); -#endif -#endif -#ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO - OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto, OPENBSD_DEV_CRYPTO); -#endif OSSL_ENGINE_LOAD_IF_MATCH(openssl, OPENSSL); rb_warning("no such builtin loader for `%"PRIsVALUE"'", name); return Qnil; -#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */ } /* @@ -172,9 +113,6 @@ ossl_engine_s_load(int argc, VALUE *argv, VALUE klass) static VALUE ossl_engine_s_cleanup(VALUE self) { -#if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000 - ENGINE_cleanup(); -#endif return Qnil; } @@ -192,12 +130,12 @@ ossl_engine_s_engines(VALUE klass) ary = rb_ary_new(); for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)){ - obj = NewEngine(klass); - /* Need a ref count of two here because of ENGINE_free being - * called internally by OpenSSL when moving to the next ENGINE - * and by us when releasing the ENGINE reference */ - ENGINE_up_ref(e); - SetEngine(obj, e); + obj = NewEngine(klass); + /* Need a ref count of two here because of ENGINE_free being + * called internally by OpenSSL when moving to the next ENGINE + * and by us when releasing the ENGINE reference */ + ENGINE_up_ref(e); + SetEngine(obj, e); rb_ary_push(ary, obj); } @@ -225,13 +163,13 @@ ossl_engine_s_by_id(VALUE klass, VALUE id) ossl_engine_s_load(1, &id, klass); obj = NewEngine(klass); if(!(e = ENGINE_by_id(RSTRING_PTR(id)))) - ossl_raise(eEngineError, NULL); + ossl_raise(eEngineError, NULL); SetEngine(obj, e); if(rb_block_given_p()) rb_yield(obj); if(!ENGINE_init(e)) - ossl_raise(eEngineError, NULL); + ossl_raise(eEngineError, NULL); ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK, - 0, NULL, (void(*)(void))ossl_pem_passwd_cb); + 0, NULL, (void(*)(void))ossl_pem_passwd_cb); ossl_clear_error(); return obj; @@ -246,7 +184,7 @@ ossl_engine_s_by_id(VALUE klass, VALUE id) * OpenSSL::Engine.load * OpenSSL::Engine.engines #=> [#<OpenSSL::Engine#>, ...] * OpenSSL::Engine.engines.first.id - * #=> "rsax" + * #=> "rsax" */ static VALUE ossl_engine_get_id(VALUE self) @@ -265,7 +203,7 @@ ossl_engine_get_id(VALUE self) * OpenSSL::Engine.load * OpenSSL::Engine.engines #=> [#<OpenSSL::Engine#>, ...] * OpenSSL::Engine.engines.first.name - * #=> "RSAX engine support" + * #=> "RSAX engine support" * */ static VALUE @@ -336,11 +274,11 @@ ossl_engine_get_cipher(VALUE self, VALUE name) * Will raise an EngineError if the digest is unavailable. * * e = OpenSSL::Engine.by_id("openssl") - * #=> #<OpenSSL::Engine id="openssl" name="Software engine support"> + * #=> #<OpenSSL::Engine id="openssl" name="Software engine support"> * e.digest("SHA1") - * #=> #<OpenSSL::Digest: da39a3ee5e6b4b0d3255bfef95601890afd80709> + * #=> #<OpenSSL::Digest: da39a3ee5e6b4b0d3255bfef95601890afd80709> * e.digest("zomg") - * #=> OpenSSL::Engine::EngineError: no such digest `zomg' + * #=> OpenSSL::Engine::EngineError: no such digest `zomg' */ static VALUE ossl_engine_get_digest(VALUE self, VALUE name) @@ -382,7 +320,7 @@ ossl_engine_load_privkey(int argc, VALUE *argv, VALUE self) GetEngine(self, e); pkey = ENGINE_load_private_key(e, sid, NULL, sdata); if (!pkey) ossl_raise(eEngineError, NULL); - obj = ossl_pkey_new(pkey); + obj = ossl_pkey_wrap(pkey); OSSL_PKEY_SET_PRIVATE(obj); return obj; @@ -412,7 +350,7 @@ ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self) pkey = ENGINE_load_public_key(e, sid, NULL, sdata); if (!pkey) ossl_raise(eEngineError, NULL); - return ossl_pkey_new(pkey); + return ossl_pkey_wrap(pkey); } /* @@ -427,7 +365,7 @@ ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self) * your OS. * * [All flags] 0xFFFF - * [No flags] 0x0000 + * [No flags] 0x0000 * * See also <openssl/engine.h> */ @@ -461,7 +399,7 @@ ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self) GetEngine(self, e); rb_scan_args(argc, argv, "11", &cmd, &val); ret = ENGINE_ctrl_cmd_string(e, StringValueCStr(cmd), - NIL_P(val) ? NULL : StringValueCStr(val), 0); + NIL_P(val) ? NULL : StringValueCStr(val), 0); if (!ret) ossl_raise(eEngineError, NULL); return self; @@ -471,11 +409,11 @@ static VALUE ossl_engine_cmd_flag_to_name(int flag) { switch(flag){ - case ENGINE_CMD_FLAG_NUMERIC: return rb_str_new2("NUMERIC"); - case ENGINE_CMD_FLAG_STRING: return rb_str_new2("STRING"); - case ENGINE_CMD_FLAG_NO_INPUT: return rb_str_new2("NO_INPUT"); - case ENGINE_CMD_FLAG_INTERNAL: return rb_str_new2("INTERNAL"); - default: return rb_str_new2("UNKNOWN"); + case ENGINE_CMD_FLAG_NUMERIC: return rb_str_new2("NUMERIC"); + case ENGINE_CMD_FLAG_STRING: return rb_str_new2("STRING"); + case ENGINE_CMD_FLAG_NO_INPUT: return rb_str_new2("NO_INPUT"); + case ENGINE_CMD_FLAG_INTERNAL: return rb_str_new2("INTERNAL"); + default: return rb_str_new2("UNKNOWN"); } } @@ -495,13 +433,13 @@ ossl_engine_get_cmds(VALUE self) GetEngine(self, e); ary = rb_ary_new(); if ((defn = ENGINE_get_cmd_defns(e)) != NULL){ - for (p = defn; p->cmd_num > 0; p++){ - tmp = rb_ary_new(); - rb_ary_push(tmp, rb_str_new2(p->cmd_name)); - rb_ary_push(tmp, rb_str_new2(p->cmd_desc)); - rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags)); - rb_ary_push(ary, tmp); - } + for (p = defn; p->cmd_num > 0; p++){ + tmp = rb_ary_new(); + rb_ary_push(tmp, rb_str_new2(p->cmd_name)); + rb_ary_push(tmp, rb_str_new2(p->cmd_desc)); + rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags)); + rb_ary_push(ary, tmp); + } } return ary; @@ -520,7 +458,7 @@ ossl_engine_inspect(VALUE self) GetEngine(self, e); return rb_sprintf("#<%"PRIsVALUE" id=\"%s\" name=\"%s\">", - rb_obj_class(self), ENGINE_get_id(e), ENGINE_get_name(e)); + rb_obj_class(self), ENGINE_get_id(e), ENGINE_get_name(e)); } #define DefEngineConst(x) rb_define_const(cEngine, #x, INT2NUM(ENGINE_##x)) @@ -528,11 +466,6 @@ ossl_engine_inspect(VALUE self) void Init_ossl_engine(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - cEngine = rb_define_class_under(mOSSL, "Engine", rb_cObject); eEngineError = rb_define_class_under(cEngine, "EngineError", eOSSLError); @@ -558,12 +491,6 @@ Init_ossl_engine(void) DefEngineConst(METHOD_DSA); DefEngineConst(METHOD_DH); DefEngineConst(METHOD_RAND); -#ifdef ENGINE_METHOD_BN_MOD_EXP - DefEngineConst(METHOD_BN_MOD_EXP); -#endif -#ifdef ENGINE_METHOD_BN_MOD_EXP_CRT - DefEngineConst(METHOD_BN_MOD_EXP_CRT); -#endif DefEngineConst(METHOD_CIPHERS); DefEngineConst(METHOD_DIGESTS); DefEngineConst(METHOD_ALL); diff --git a/ext/openssl/ossl_engine.h b/ext/openssl/ossl_engine.h index cd548beea3..cedcebb772 100644 --- a/ext/openssl/ossl_engine.h +++ b/ext/openssl/ossl_engine.h @@ -6,14 +6,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(OSSL_ENGINE_H) #define OSSL_ENGINE_H -extern VALUE cEngine; -extern VALUE eEngineError; - void Init_ossl_engine(void); #endif /* OSSL_ENGINE_H */ diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index 564dcab522..ddcc6a5f8d 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -5,26 +5,25 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ -#if !defined(OPENSSL_NO_HMAC) - #include "ossl.h" #define NewHMAC(klass) \ TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0) #define GetHMAC(obj, ctx) do { \ - TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \ + TypedData_Get_Struct((obj), EVP_MD_CTX, &ossl_hmac_type, (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \ + ossl_raise(rb_eRuntimeError, "HMAC wasn't initialized"); \ } \ } while (0) /* * Classes */ -VALUE cHMAC; -VALUE eHMACError; +static VALUE cHMAC; +static VALUE eHMACError; +static ID id_md_holder; /* * Public @@ -36,27 +35,27 @@ VALUE eHMACError; static void ossl_hmac_free(void *ctx) { - HMAC_CTX_free(ctx); + EVP_MD_CTX_free(ctx); } static const rb_data_type_t ossl_hmac_type = { "OpenSSL/HMAC", { - 0, ossl_hmac_free, + 0, ossl_hmac_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE ossl_hmac_alloc(VALUE klass) { VALUE obj; - HMAC_CTX *ctx; + EVP_MD_CTX *ctx; obj = NewHMAC(klass); - ctx = HMAC_CTX_new(); + ctx = EVP_MD_CTX_new(); if (!ctx) - ossl_raise(eHMACError, NULL); + ossl_raise(eHMACError, "EVP_MD_CTX"); RTYPEDDATA_DATA(obj) = ctx; return obj; @@ -75,55 +74,62 @@ ossl_hmac_alloc(VALUE klass) * * === Example * - * key = 'key' - * digest = OpenSSL::Digest.new('sha1') - * instance = OpenSSL::HMAC.new(key, digest) - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance.class - * #=> OpenSSL::HMAC + * key = 'key' + * instance = OpenSSL::HMAC.new(key, 'SHA1') + * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f + * instance.class + * #=> OpenSSL::HMAC * * === A note about comparisons * - * Two instances won't be equal when they're compared, even if they have the - * same value. Use #to_s or #hexdigest to return the authentication code that - * the instance represents. For example: + * Two instances can be securely compared with #== in constant time: * - * other_instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f - * instance == other_instance - * #=> false - * instance.to_s == other_instance.to_s - * #=> true + * other_instance = OpenSSL::HMAC.new('key', 'SHA1') + * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f + * instance == other_instance + * #=> true * */ static VALUE ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) { - HMAC_CTX *ctx; + EVP_MD_CTX *ctx; + EVP_PKEY *pkey; + const EVP_MD *md; + VALUE md_holder; - StringValue(key); GetHMAC(self, ctx); - HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key), - ossl_evp_get_digestbyname(digest), NULL); + StringValue(key); + md = ossl_evp_md_fetch(digest, &md_holder); + pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, + (unsigned char *)RSTRING_PTR(key), + RSTRING_LENINT(key)); + if (!pkey) + ossl_raise(eHMACError, "EVP_PKEY_new_raw_private_key"); + if (EVP_DigestSignInit(ctx, NULL, md, NULL, pkey) != 1) { + EVP_PKEY_free(pkey); + ossl_raise(eHMACError, "EVP_DigestSignInit"); + } + rb_ivar_set(self, id_md_holder, md_holder); + /* Decrement reference counter; EVP_MD_CTX still keeps it */ + EVP_PKEY_free(pkey); return self; } +/* :nodoc: */ static VALUE ossl_hmac_copy(VALUE self, VALUE other) { - HMAC_CTX *ctx1, *ctx2; + EVP_MD_CTX *ctx1, *ctx2; rb_check_frozen(self); if (self == other) return self; GetHMAC(self, ctx1); GetHMAC(other, ctx2); - - if (!HMAC_CTX_copy(ctx1, ctx2)) - ossl_raise(eHMACError, "HMAC_CTX_copy"); + if (EVP_MD_CTX_copy(ctx1, ctx2) != 1) + ossl_raise(eHMACError, "EVP_MD_CTX_copy"); return self; } @@ -136,45 +142,28 @@ ossl_hmac_copy(VALUE self, VALUE other) * * === Example * - * first_chunk = 'The quick brown fox jumps ' - * second_chunk = 'over the lazy dog' + * first_chunk = 'The quick brown fox jumps ' + * second_chunk = 'over the lazy dog' * - * instance.update(first_chunk) - * #=> 5b9a8038a65d571076d97fe783989e52278a492a - * instance.update(second_chunk) - * #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 + * instance.update(first_chunk) + * #=> 5b9a8038a65d571076d97fe783989e52278a492a + * instance.update(second_chunk) + * #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 * */ static VALUE ossl_hmac_update(VALUE self, VALUE data) { - HMAC_CTX *ctx; + EVP_MD_CTX *ctx; StringValue(data); GetHMAC(self, ctx); - HMAC_Update(ctx, (unsigned char *)RSTRING_PTR(data), RSTRING_LEN(data)); + if (EVP_DigestSignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) + ossl_raise(eHMACError, "EVP_DigestSignUpdate"); return self; } -static void -hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) -{ - HMAC_CTX *final; - - final = HMAC_CTX_new(); - if (!final) - ossl_raise(eHMACError, "HMAC_CTX_new"); - - if (!HMAC_CTX_copy(final, ctx)) { - HMAC_CTX_free(final); - ossl_raise(eHMACError, "HMAC_CTX_copy"); - } - - HMAC_Final(final, buf, buf_len); - HMAC_CTX_free(final); -} - /* * call-seq: * hmac.digest -> string @@ -182,7 +171,7 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) * Returns the authentication code an instance represents as a binary string. * * === Example - * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) + * instance = OpenSSL::HMAC.new('key', 'SHA1') * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f * instance.digest * #=> "\xF4+\xB0\xEE\xB0\x18\xEB\xBDE\x97\xAEr\x13q\x1E\xC6\a`\x84?" @@ -190,15 +179,16 @@ hmac_final(HMAC_CTX *ctx, unsigned char *buf, unsigned int *buf_len) static VALUE ossl_hmac_digest(VALUE self) { - HMAC_CTX *ctx; - unsigned int buf_len; + EVP_MD_CTX *ctx; + size_t buf_len = EVP_MAX_MD_SIZE; VALUE ret; GetHMAC(self, ctx); ret = rb_str_new(NULL, EVP_MAX_MD_SIZE); - hmac_final(ctx, (unsigned char *)RSTRING_PTR(ret), &buf_len); - assert(buf_len <= EVP_MAX_MD_SIZE); - rb_str_set_len(ret, buf_len); + if (EVP_DigestSignFinal(ctx, (unsigned char *)RSTRING_PTR(ret), + &buf_len) != 1) + ossl_raise(eHMACError, "EVP_DigestSignFinal"); + rb_str_set_len(ret, (long)buf_len); return ret; } @@ -213,13 +203,14 @@ ossl_hmac_digest(VALUE self) static VALUE ossl_hmac_hexdigest(VALUE self) { - HMAC_CTX *ctx; + EVP_MD_CTX *ctx; unsigned char buf[EVP_MAX_MD_SIZE]; - unsigned int buf_len; + size_t buf_len = EVP_MAX_MD_SIZE; VALUE ret; GetHMAC(self, ctx); - hmac_final(ctx, buf, &buf_len); + if (EVP_DigestSignFinal(ctx, buf, &buf_len) != 1) + ossl_raise(eHMACError, "EVP_DigestSignFinal"); ret = rb_str_new(NULL, buf_len * 2); ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len); @@ -235,108 +226,36 @@ ossl_hmac_hexdigest(VALUE self) * * === Example * - * data = "The quick brown fox jumps over the lazy dog" - * instance = OpenSSL::HMAC.new('key', OpenSSL::Digest.new('sha1')) - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f + * data = "The quick brown fox jumps over the lazy dog" + * instance = OpenSSL::HMAC.new('key', 'SHA1') + * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f * - * instance.update(data) - * #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 - * instance.reset - * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f + * instance.update(data) + * #=> de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9 + * instance.reset + * #=> f42bb0eeb018ebbd4597ae7213711ec60760843f * */ static VALUE ossl_hmac_reset(VALUE self) { - HMAC_CTX *ctx; + EVP_MD_CTX *ctx; + EVP_PKEY *pkey; GetHMAC(self, ctx); - HMAC_Init_ex(ctx, NULL, 0, NULL, NULL); + pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx)); + if (EVP_DigestSignInit(ctx, NULL, EVP_MD_CTX_get0_md(ctx), NULL, pkey) != 1) + ossl_raise(eHMACError, "EVP_DigestSignInit"); return self; } /* - * call-seq: - * HMAC.digest(digest, key, data) -> aString - * - * Returns the authentication code as a binary string. The _digest_ parameter - * specifies the digest algorithm to use. This may be a String representing - * the algorithm name or an instance of OpenSSL::Digest. - * - * === Example - * - * key = 'key' - * data = 'The quick brown fox jumps over the lazy dog' - * - * hmac = OpenSSL::HMAC.digest('sha1', key, data) - * #=> "\xDE|\x9B\x85\xB8\xB7\x8A\xA6\xBC\x8Az6\xF7\n\x90p\x1C\x9D\xB4\xD9" - * - */ -static VALUE -ossl_hmac_s_digest(VALUE klass, VALUE digest, VALUE key, VALUE data) -{ - unsigned char *buf; - unsigned int buf_len; - - StringValue(key); - StringValue(data); - buf = HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key), - RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data), - RSTRING_LEN(data), NULL, &buf_len); - - return rb_str_new((const char *)buf, buf_len); -} - -/* - * call-seq: - * HMAC.hexdigest(digest, key, data) -> aString - * - * Returns the authentication code as a hex-encoded string. The _digest_ - * parameter specifies the digest algorithm to use. This may be a String - * representing the algorithm name or an instance of OpenSSL::Digest. - * - * === Example - * - * key = 'key' - * data = 'The quick brown fox jumps over the lazy dog' - * - * hmac = OpenSSL::HMAC.hexdigest('sha1', key, data) - * #=> "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9" - * - */ -static VALUE -ossl_hmac_s_hexdigest(VALUE klass, VALUE digest, VALUE key, VALUE data) -{ - unsigned char buf[EVP_MAX_MD_SIZE]; - unsigned int buf_len; - VALUE ret; - - StringValue(key); - StringValue(data); - - if (!HMAC(ossl_evp_get_digestbyname(digest), RSTRING_PTR(key), - RSTRING_LENINT(key), (unsigned char *)RSTRING_PTR(data), - RSTRING_LEN(data), buf, &buf_len)) - ossl_raise(eHMACError, "HMAC"); - - ret = rb_str_new(NULL, buf_len * 2); - ossl_bin2hex(buf, RSTRING_PTR(ret), buf_len); - - return ret; -} - -/* * INIT */ void Init_ossl_hmac(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* * Document-class: OpenSSL::HMAC * @@ -356,11 +275,10 @@ Init_ossl_hmac(void) * * === HMAC-SHA256 using incremental interface * - * data1 = File.read("file1") - * data2 = File.read("file2") + * data1 = File.binread("file1") + * data2 = File.binread("file2") * key = "key" - * digest = OpenSSL::Digest::SHA256.new - * hmac = OpenSSL::HMAC.new(key, digest) + * hmac = OpenSSL::HMAC.new(key, 'SHA256') * hmac << data1 * hmac << data2 * mac = hmac.digest @@ -370,8 +288,6 @@ Init_ossl_hmac(void) cHMAC = rb_define_class_under(mOSSL, "HMAC", rb_cObject); rb_define_alloc_func(cHMAC, ossl_hmac_alloc); - rb_define_singleton_method(cHMAC, "digest", ossl_hmac_s_digest, 3); - rb_define_singleton_method(cHMAC, "hexdigest", ossl_hmac_s_hexdigest, 3); rb_define_method(cHMAC, "initialize", ossl_hmac_initialize, 2); rb_define_method(cHMAC, "initialize_copy", ossl_hmac_copy, 1); @@ -383,13 +299,6 @@ Init_ossl_hmac(void) rb_define_method(cHMAC, "hexdigest", ossl_hmac_hexdigest, 0); rb_define_alias(cHMAC, "inspect", "hexdigest"); rb_define_alias(cHMAC, "to_s", "hexdigest"); -} -#else /* NO_HMAC */ -# warning >>> OpenSSL is compiled without HMAC support <<< -void -Init_ossl_hmac(void) -{ - rb_warning("HMAC is not available: OpenSSL is compiled without HMAC."); + id_md_holder = rb_intern_const("EVP_MD_holder"); } -#endif /* NO_HMAC */ diff --git a/ext/openssl/ossl_hmac.h b/ext/openssl/ossl_hmac.h index 7c51f4722d..e5bed37c9f 100644 --- a/ext/openssl/ossl_hmac.h +++ b/ext/openssl/ossl_hmac.h @@ -5,14 +5,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_HMAC_H_) #define _OSSL_HMAC_H_ -extern VALUE cHMAC; -extern VALUE eHMACError; - void Init_ossl_hmac(void); #endif /* _OSSL_HMAC_H_ */ diff --git a/ext/openssl/ossl_kdf.c b/ext/openssl/ossl_kdf.c index ee124718b5..1f28016440 100644 --- a/ext/openssl/ossl_kdf.c +++ b/ext/openssl/ossl_kdf.c @@ -3,9 +3,7 @@ * Copyright (C) 2007, 2017 Ruby/OpenSSL Project Authors */ #include "ossl.h" -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) -# include <openssl/kdf.h> -#endif +#include <openssl/kdf.h> static VALUE mKDF, eKDF; @@ -18,10 +16,10 @@ static VALUE mKDF, eKDF; * of _length_ bytes. * * For more information about PBKDF2, see RFC 2898 Section 5.2 - * (https://tools.ietf.org/html/rfc2898#section-5.2). + * (https://www.rfc-editor.org/rfc/rfc2898#section-5.2). * * === Parameters - * pass :: The passphrase. + * pass :: The password. * salt :: The salt. Salts prevent attacks based on dictionaries of common * passwords and attacks based on rainbow tables. It is a public * value that can be safely stored along with the password (e.g. @@ -37,16 +35,16 @@ static VALUE mKDF, eKDF; static VALUE kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self) { - VALUE pass, salt, opts, kwargs[4], str; + VALUE pass, salt, opts, kwargs[4], str, md_holder; static ID kwargs_ids[4]; int iters, len; const EVP_MD *md; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt"); - kwargs_ids[1] = rb_intern_const("iterations"); - kwargs_ids[2] = rb_intern_const("length"); - kwargs_ids[3] = rb_intern_const("hash"); + kwargs_ids[0] = rb_intern_const("salt"); + kwargs_ids[1] = rb_intern_const("iterations"); + kwargs_ids[2] = rb_intern_const("length"); + kwargs_ids[3] = rb_intern_const("hash"); } rb_scan_args(argc, argv, "1:", &pass, &opts); rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs); @@ -55,14 +53,14 @@ kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self) salt = StringValue(kwargs[0]); iters = NUM2INT(kwargs[1]); len = NUM2INT(kwargs[2]); - md = ossl_evp_get_digestbyname(kwargs[3]); + md = ossl_evp_md_fetch(kwargs[3], &md_holder); str = rb_str_new(0, len); if (!PKCS5_PBKDF2_HMAC(RSTRING_PTR(pass), RSTRING_LENINT(pass), - (unsigned char *)RSTRING_PTR(salt), - RSTRING_LENINT(salt), iters, md, len, - (unsigned char *)RSTRING_PTR(str))) - ossl_raise(eKDF, "PKCS5_PBKDF2_HMAC"); + (unsigned char *)RSTRING_PTR(salt), + RSTRING_LENINT(salt), iters, md, len, + (unsigned char *)RSTRING_PTR(str))) + ossl_raise(eKDF, "PKCS5_PBKDF2_HMAC"); return str; } @@ -81,10 +79,10 @@ kdf_pbkdf2_hmac(int argc, VALUE *argv, VALUE self) * bcrypt. * * The keyword arguments _N_, _r_ and _p_ can be used to tune scrypt. RFC 7914 - * (published on 2016-08, https://tools.ietf.org/html/rfc7914#section-2) states + * (published on 2016-08, https://www.rfc-editor.org/rfc/rfc7914#section-2) states * that using values r=8 and p=1 appears to yield good results. * - * See RFC 7914 (https://tools.ietf.org/html/rfc7914) for more information. + * See RFC 7914 (https://www.rfc-editor.org/rfc/rfc7914) for more information. * * === Parameters * pass :: Passphrase. @@ -109,11 +107,11 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) uint64_t N, r, p, maxmem; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt"); - kwargs_ids[1] = rb_intern_const("N"); - kwargs_ids[2] = rb_intern_const("r"); - kwargs_ids[3] = rb_intern_const("p"); - kwargs_ids[4] = rb_intern_const("length"); + kwargs_ids[0] = rb_intern_const("salt"); + kwargs_ids[1] = rb_intern_const("N"); + kwargs_ids[2] = rb_intern_const("r"); + kwargs_ids[3] = rb_intern_const("p"); + kwargs_ids[4] = rb_intern_const("length"); } rb_scan_args(argc, argv, "1:", &pass, &opts); rb_get_kwargs(opts, kwargs_ids, 5, 0, kwargs); @@ -133,21 +131,20 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) str = rb_str_new(0, len); if (!EVP_PBE_scrypt(RSTRING_PTR(pass), RSTRING_LEN(pass), - (unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt), - N, r, p, maxmem, (unsigned char *)RSTRING_PTR(str), len)) - ossl_raise(eKDF, "EVP_PBE_scrypt"); + (unsigned char *)RSTRING_PTR(salt), RSTRING_LEN(salt), + N, r, p, maxmem, (unsigned char *)RSTRING_PTR(str), len)) + ossl_raise(eKDF, "EVP_PBE_scrypt"); return str; } #endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) /* * call-seq: * KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String * * HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as specified in - * {RFC 5869}[https://tools.ietf.org/html/rfc5869]. + * {RFC 5869}[https://www.rfc-editor.org/rfc/rfc5869]. * * New in OpenSSL 1.1.0. * @@ -163,11 +160,19 @@ kdf_scrypt(int argc, VALUE *argv, VALUE self) * HashLen is the length of the hash function output in octets. * _hash_:: * The hash function. + * + * === Example + * # The values from https://www.rfc-editor.org/rfc/rfc5869#appendix-A.1 + * ikm = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*") + * salt = ["000102030405060708090a0b0c"].pack("H*") + * info = ["f0f1f2f3f4f5f6f7f8f9"].pack("H*") + * p OpenSSL::KDF.hkdf(ikm, salt: salt, info: info, length: 42, hash: "SHA256").unpack1("H*") + * # => "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865" */ static VALUE kdf_hkdf(int argc, VALUE *argv, VALUE self) { - VALUE ikm, salt, info, opts, kwargs[4], str; + VALUE ikm, salt, info, opts, kwargs[4], str, md_holder; static ID kwargs_ids[4]; int saltlen, ikmlen, infolen; size_t len; @@ -175,10 +180,10 @@ kdf_hkdf(int argc, VALUE *argv, VALUE self) EVP_PKEY_CTX *pctx; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt"); - kwargs_ids[1] = rb_intern_const("info"); - kwargs_ids[2] = rb_intern_const("length"); - kwargs_ids[3] = rb_intern_const("hash"); + kwargs_ids[0] = rb_intern_const("salt"); + kwargs_ids[1] = rb_intern_const("info"); + kwargs_ids[2] = rb_intern_const("length"); + kwargs_ids[3] = rb_intern_const("hash"); } rb_scan_args(argc, argv, "1:", &ikm, &opts); rb_get_kwargs(opts, kwargs_ids, 4, 0, kwargs); @@ -191,55 +196,49 @@ kdf_hkdf(int argc, VALUE *argv, VALUE self) infolen = RSTRING_LENINT(info); len = (size_t)NUM2LONG(kwargs[2]); if (len > LONG_MAX) - rb_raise(rb_eArgError, "length must be non-negative"); - md = ossl_evp_get_digestbyname(kwargs[3]); + rb_raise(rb_eArgError, "length must be non-negative"); + md = ossl_evp_md_fetch(kwargs[3], &md_holder); str = rb_str_new(NULL, (long)len); pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL); if (!pctx) - ossl_raise(eKDF, "EVP_PKEY_CTX_new_id"); + ossl_raise(eKDF, "EVP_PKEY_CTX_new_id"); if (EVP_PKEY_derive_init(pctx) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_derive_init"); + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_derive_init"); } if (EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_md"); + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_md"); } if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, (unsigned char *)RSTRING_PTR(salt), - saltlen) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_salt"); + saltlen) <= 0) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_salt"); } if (EVP_PKEY_CTX_set1_hkdf_key(pctx, (unsigned char *)RSTRING_PTR(ikm), - ikmlen) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_key"); + ikmlen) <= 0) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_key"); } if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (unsigned char *)RSTRING_PTR(info), - infolen) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_info"); + infolen) <= 0) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_CTX_set_hkdf_info"); } if (EVP_PKEY_derive(pctx, (unsigned char *)RSTRING_PTR(str), &len) <= 0) { - EVP_PKEY_CTX_free(pctx); - ossl_raise(eKDF, "EVP_PKEY_derive"); + EVP_PKEY_CTX_free(pctx); + ossl_raise(eKDF, "EVP_PKEY_derive"); } rb_str_set_len(str, (long)len); EVP_PKEY_CTX_free(pctx); return str; } -#endif void Init_ossl_kdf(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* * Document-module: OpenSSL::KDF * @@ -272,7 +271,7 @@ Init_ossl_kdf(void) * # store this with the generated value * salt = OpenSSL::Random.random_bytes(16) * iter = 20_000 - * hash = OpenSSL::Digest::SHA256.new + * hash = OpenSSL::Digest.new('SHA256') * len = hash.digest_length * # the final value to be stored * value = OpenSSL::KDF.pbkdf2_hmac(pass, salt: salt, iterations: iter, @@ -284,24 +283,8 @@ Init_ossl_kdf(void) * Typically, "==" short-circuits on evaluation, and is therefore * vulnerable to timing attacks. The proper way is to use a method that * always takes the same amount of time when comparing two values, thus - * not leaking any information to potential attackers. To compare two - * values, the following could be used: - * - * def eql_time_cmp(a, b) - * unless a.length == b.length - * return false - * end - * cmp = b.bytes - * result = 0 - * a.bytes.each_with_index {|c,i| - * result |= c ^ cmp[i] - * } - * result == 0 - * end - * - * Please note that the premature return in case of differing lengths - * typically does not leak valuable information - when using PBKDF2, the - * length of the values to be compared is of fixed size. + * not leaking any information to potential attackers. To do this, use + * +OpenSSL.fixed_length_secure_compare+. */ mKDF = rb_define_module_under(mOSSL, "KDF"); /* @@ -313,7 +296,5 @@ Init_ossl_kdf(void) #if defined(HAVE_EVP_PBE_SCRYPT) rb_define_module_function(mKDF, "scrypt", kdf_scrypt, -1); #endif -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) rb_define_module_function(mKDF, "hkdf", kdf_hkdf, -1); -#endif } diff --git a/ext/openssl/ossl_ns_spki.c b/ext/openssl/ossl_ns_spki.c index 6f61e61bf5..8440c2ee82 100644 --- a/ext/openssl/ossl_ns_spki.c +++ b/ext/openssl/ossl_ns_spki.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,23 +13,23 @@ TypedData_Wrap_Struct((klass), &ossl_netscape_spki_type, 0) #define SetSPKI(obj, spki) do { \ if (!(spki)) { \ - ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (spki); \ } while (0) #define GetSPKI(obj, spki) do { \ TypedData_Get_Struct((obj), NETSCAPE_SPKI, &ossl_netscape_spki_type, (spki)); \ if (!(spki)) { \ - ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "SPKI wasn't initialized!"); \ } \ } while (0) /* * Classes */ -VALUE mNetscape; -VALUE cSPKI; -VALUE eSPKIError; +static VALUE mNetscape; +static VALUE cSPKI; +static VALUE eSPKIError; /* * Public functions @@ -48,9 +48,9 @@ ossl_netscape_spki_free(void *spki) static const rb_data_type_t ossl_netscape_spki_type = { "OpenSSL/NETSCAPE_SPKI", { - 0, ossl_netscape_spki_free, + 0, ossl_netscape_spki_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -61,7 +61,7 @@ ossl_spki_alloc(VALUE klass) obj = NewSPKI(klass); if (!(spki = NETSCAPE_SPKI_new())) { - ossl_raise(eSPKIError, NULL); + ossl_raise(eSPKIError, NULL); } SetSPKI(obj, spki); @@ -83,15 +83,15 @@ ossl_spki_initialize(int argc, VALUE *argv, VALUE self) const unsigned char *p; if (rb_scan_args(argc, argv, "01", &buffer) == 0) { - return self; + return self; } StringValue(buffer); if (!(spki = NETSCAPE_SPKI_b64_decode(RSTRING_PTR(buffer), RSTRING_LENINT(buffer)))) { - ossl_clear_error(); - p = (unsigned char *)RSTRING_PTR(buffer); - if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) { - ossl_raise(eSPKIError, NULL); - } + ossl_clear_error(); + p = (unsigned char *)RSTRING_PTR(buffer); + if (!(spki = d2i_NETSCAPE_SPKI(NULL, &p, RSTRING_LEN(buffer)))) { + ossl_raise(eSPKIError, NULL); + } } NETSCAPE_SPKI_free(DATA_PTR(self)); SetSPKI(self, spki); @@ -115,11 +115,11 @@ ossl_spki_to_der(VALUE self) GetSPKI(self, spki); if ((len = i2d_NETSCAPE_SPKI(spki, NULL)) <= 0) - ossl_raise(eX509CertError, NULL); + ossl_raise(eSPKIError, "i2d_NETSCAPE_SPKI"); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_NETSCAPE_SPKI(spki, &p) <= 0) - ossl_raise(eX509CertError, NULL); + ossl_raise(eSPKIError, "i2d_NETSCAPE_SPKI"); ossl_str_adjust(str, p); return str; @@ -140,7 +140,7 @@ ossl_spki_to_pem(VALUE self) GetSPKI(self, spki); if (!(data = NETSCAPE_SPKI_b64_encode(spki))) { - ossl_raise(eSPKIError, NULL); + ossl_raise(eSPKIError, NULL); } str = ossl_buf2str(data, rb_long2int(strlen(data))); @@ -162,11 +162,11 @@ ossl_spki_print(VALUE self) GetSPKI(self, spki); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSPKIError, NULL); + ossl_raise(eSPKIError, NULL); } if (!NETSCAPE_SPKI_print(out, spki)) { - BIO_free(out); - ossl_raise(eSPKIError, NULL); + BIO_free(out); + ossl_raise(eSPKIError, NULL); } return ossl_membio2str(out); @@ -187,10 +187,10 @@ ossl_spki_get_public_key(VALUE self) GetSPKI(self, spki); if (!(pkey = NETSCAPE_SPKI_get_pubkey(spki))) { /* adds an reference */ - ossl_raise(eSPKIError, NULL); + ossl_raise(eSPKIError, NULL); } - return ossl_pkey_new(pkey); /* NO DUP - OK */ + return ossl_pkey_wrap(pkey); } /* @@ -214,7 +214,7 @@ ossl_spki_set_public_key(VALUE self, VALUE key) pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) - ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey"); + ossl_raise(eSPKIError, "NETSCAPE_SPKI_set_pubkey"); return key; } @@ -230,13 +230,12 @@ ossl_spki_get_challenge(VALUE self) NETSCAPE_SPKI *spki; GetSPKI(self, spki); - if (spki->spkac->challenge->length <= 0) { - OSSL_Debug("Challenge.length <= 0?"); - return rb_str_new(0, 0); + if (ASN1_STRING_length(spki->spkac->challenge) <= 0) { + OSSL_Debug("Challenge.length <= 0?"); + return rb_str_new(0, 0); } - return rb_str_new((const char *)spki->spkac->challenge->data, - spki->spkac->challenge->length); + return asn1str_to_str(spki->spkac->challenge); } /* @@ -257,8 +256,8 @@ ossl_spki_set_challenge(VALUE self, VALUE str) StringValue(str); GetSPKI(self, spki); if (!ASN1_STRING_set(spki->spkac->challenge, RSTRING_PTR(str), - RSTRING_LENINT(str))) { - ossl_raise(eSPKIError, NULL); + RSTRING_LENINT(str))) { + ossl_raise(eSPKIError, NULL); } return str; @@ -283,13 +282,13 @@ ossl_spki_sign(VALUE self, VALUE key, VALUE digest) NETSCAPE_SPKI *spki; EVP_PKEY *pkey; const EVP_MD *md; + VALUE md_holder; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); GetSPKI(self, spki); - if (!NETSCAPE_SPKI_sign(spki, pkey, md)) { - ossl_raise(eSPKIError, NULL); - } + if (!NETSCAPE_SPKI_sign(spki, pkey, md)) + ossl_raise(eSPKIError, "NETSCAPE_SPKI_sign"); return self; } @@ -315,12 +314,12 @@ ossl_spki_verify(VALUE self, VALUE key) ossl_pkey_check_public_key(pkey); switch (NETSCAPE_SPKI_verify(spki, pkey)) { case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; case 1: - return Qtrue; + return Qtrue; default: - ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify"); + ossl_raise(eSPKIError, "NETSCAPE_SPKI_verify"); } } @@ -350,7 +349,7 @@ ossl_spki_verify(VALUE self, VALUE key) * spki = OpenSSL::Netscape::SPKI.new * spki.challenge = "RandomChallenge" * spki.public_key = key.public_key - * spki.sign(key, OpenSSL::Digest::SHA256.new) + * spki.sign(key, OpenSSL::Digest.new('SHA256')) * #send a request containing this to a server generating a certificate * === Verifying an SPKI request * request = #... @@ -365,8 +364,8 @@ ossl_spki_verify(VALUE self, VALUE key) * * OpenSSL::Netscape is a namespace for SPKI (Simple Public Key * Infrastructure) which implements Signed Public Key and Challenge. - * See {RFC 2692}[http://tools.ietf.org/html/rfc2692] and {RFC - * 2693}[http://tools.ietf.org/html/rfc2692] for details. + * See {RFC 2692}[https://www.rfc-editor.org/rfc/rfc2692] and {RFC + * 2693}[https://www.rfc-editor.org/rfc/rfc2692] for details. */ /* Document-class: OpenSSL::Netscape::SPKIError @@ -378,11 +377,6 @@ ossl_spki_verify(VALUE self, VALUE key) void Init_ossl_ns_spki(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - mNetscape = rb_define_module_under(mOSSL, "Netscape"); eSPKIError = rb_define_class_under(mNetscape, "SPKIError", eOSSLError); diff --git a/ext/openssl/ossl_ns_spki.h b/ext/openssl/ossl_ns_spki.h index 62ba8cb163..043b6cdb66 100644 --- a/ext/openssl/ossl_ns_spki.h +++ b/ext/openssl/ossl_ns_spki.h @@ -5,15 +5,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_NS_SPKI_H_) #define _OSSL_NS_SPKI_H_ -extern VALUE mNetscape; -extern VALUE cSPKI; -extern VALUE eSPKIError; - void Init_ossl_ns_spki(void); #endif /* _OSSL_NS_SPKI_H_ */ diff --git a/ext/openssl/ossl_ocsp.c b/ext/openssl/ossl_ocsp.c index c0237791da..93d8bc8567 100644 --- a/ext/openssl/ossl_ocsp.c +++ b/ext/openssl/ossl_ocsp.c @@ -6,7 +6,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -67,13 +67,13 @@ if(!(cid)) ossl_raise(rb_eRuntimeError, "Cert ID wasn't initialized!"); \ } while (0) -VALUE mOCSP; -VALUE eOCSPError; -VALUE cOCSPReq; -VALUE cOCSPRes; -VALUE cOCSPBasicRes; -VALUE cOCSPSingleRes; -VALUE cOCSPCertId; +static VALUE mOCSP; +static VALUE eOCSPError; +static VALUE cOCSPReq; +static VALUE cOCSPRes; +static VALUE cOCSPBasicRes; +static VALUE cOCSPSingleRes; +static VALUE cOCSPCertId; static void ossl_ocsp_request_free(void *ptr) @@ -84,9 +84,9 @@ ossl_ocsp_request_free(void *ptr) static const rb_data_type_t ossl_ocsp_request_type = { "OpenSSL/OCSP/REQUEST", { - 0, ossl_ocsp_request_free, + 0, ossl_ocsp_request_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -98,9 +98,9 @@ ossl_ocsp_response_free(void *ptr) static const rb_data_type_t ossl_ocsp_response_type = { "OpenSSL/OCSP/RESPONSE", { - 0, ossl_ocsp_response_free, + 0, ossl_ocsp_response_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -112,9 +112,9 @@ ossl_ocsp_basicresp_free(void *ptr) static const rb_data_type_t ossl_ocsp_basicresp_type = { "OpenSSL/OCSP/BASICRESP", { - 0, ossl_ocsp_basicresp_free, + 0, ossl_ocsp_basicresp_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -126,9 +126,9 @@ ossl_ocsp_singleresp_free(void *ptr) static const rb_data_type_t ossl_ocsp_singleresp_type = { "OpenSSL/OCSP/SINGLERESP", { - 0, ossl_ocsp_singleresp_free, + 0, ossl_ocsp_singleresp_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -140,24 +140,28 @@ ossl_ocsp_certid_free(void *ptr) static const rb_data_type_t ossl_ocsp_certid_type = { "OpenSSL/OCSP/CERTID", { - 0, ossl_ocsp_certid_free, + 0, ossl_ocsp_certid_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* * Public */ static VALUE -ossl_ocspcertid_new(OCSP_CERTID *cid) +ossl_ocspcid_new(const OCSP_CERTID *cid) { VALUE obj = NewOCSPCertId(cOCSPCertId); - SetOCSPCertId(obj, cid); + /* OpenSSL 1.1.1 takes a non-const pointer */ + OCSP_CERTID *cid_new = OCSP_CERTID_dup((OCSP_CERTID *)cid); + if (!cid_new) + ossl_raise(eOCSPError, "OCSP_CERTID_dup"); + SetOCSPCertId(obj, cid_new); return obj; } /* - * OCSP::Resquest + * OCSP::Request */ static VALUE ossl_ocspreq_alloc(VALUE klass) @@ -167,12 +171,13 @@ ossl_ocspreq_alloc(VALUE klass) obj = NewOCSPReq(klass); if (!(req = OCSP_REQUEST_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPReq(obj, req); return obj; } +/* :nodoc: */ static VALUE ossl_ocspreq_initialize_copy(VALUE self, VALUE other) { @@ -184,7 +189,7 @@ ossl_ocspreq_initialize_copy(VALUE self, VALUE other) req_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_REQUEST), req); if (!req_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); + ossl_raise(eOCSPError, "ASN1_item_dup"); SetOCSPReq(self, req_new); OCSP_REQUEST_free(req_old); @@ -210,15 +215,15 @@ ossl_ocspreq_initialize(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &arg); if(!NIL_P(arg)){ - GetOCSPReq(self, req); - arg = ossl_to_der_if_possible(arg); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg)); - if (!req_new) - ossl_raise(eOCSPError, "d2i_OCSP_REQUEST"); - SetOCSPReq(self, req_new); - OCSP_REQUEST_free(req); + GetOCSPReq(self, req); + arg = ossl_to_der_if_possible(arg); + StringValue(arg); + p = (unsigned char *)RSTRING_PTR(arg); + req_new = d2i_OCSP_REQUEST(NULL, &p, RSTRING_LEN(arg)); + if (!req_new) + ossl_raise(eOCSPError, "d2i_OCSP_REQUEST"); + SetOCSPReq(self, req_new); + OCSP_REQUEST_free(req); } return self; @@ -244,13 +249,13 @@ ossl_ocspreq_add_nonce(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &val); if(NIL_P(val)) { - GetOCSPReq(self, req); - ret = OCSP_request_add1_nonce(req, NULL, -1); + GetOCSPReq(self, req); + ret = OCSP_request_add1_nonce(req, NULL, -1); } else{ - StringValue(val); - GetOCSPReq(self, req); - ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); + StringValue(val); + GetOCSPReq(self, req); + ret = OCSP_request_add1_nonce(req, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); } if(!ret) ossl_raise(eOCSPError, NULL); @@ -307,10 +312,10 @@ ossl_ocspreq_add_certid(VALUE self, VALUE certid) GetOCSPCertId(certid, id); if (!(id_new = OCSP_CERTID_dup(id))) - ossl_raise(eOCSPError, "OCSP_CERTID_dup"); + ossl_raise(eOCSPError, "OCSP_CERTID_dup"); if (!OCSP_request_add0_id(req, id_new)) { - OCSP_CERTID_free(id_new); - ossl_raise(eOCSPError, "OCSP_request_add0_id"); + OCSP_CERTID_free(id_new); + ossl_raise(eOCSPError, "OCSP_request_add0_id"); } return self; @@ -327,21 +332,19 @@ static VALUE ossl_ocspreq_get_certid(VALUE self) { OCSP_REQUEST *req; - OCSP_ONEREQ *one; - OCSP_CERTID *id; - VALUE ary, tmp; - int i, count; GetOCSPReq(self, req); - count = OCSP_request_onereq_count(req); - ary = (count > 0) ? rb_ary_new() : Qnil; - for(i = 0; i < count; i++){ - one = OCSP_request_onereq_get0(req, i); - tmp = NewOCSPCertId(cOCSPCertId); - if(!(id = OCSP_CERTID_dup(OCSP_onereq_get0_id(one)))) - ossl_raise(eOCSPError, NULL); - SetOCSPCertId(tmp, id); - rb_ary_push(ary, tmp); + int count = OCSP_request_onereq_count(req); + if (count < 0) + ossl_raise(eOCSPError, "OCSP_request_onereq_count"); + if (count == 0) + return Qnil; + + VALUE ary = rb_ary_new_capa(count); + for (int i = 0; i < count; i++) { + OCSP_ONEREQ *one = OCSP_request_onereq_get0(req, i); + OCSP_CERTID *cid = OCSP_onereq_get0_id(one); + rb_ary_push(ary, ossl_ocspcid_new(cid)); } return ary; @@ -366,7 +369,7 @@ ossl_ocspreq_get_certid(VALUE self) static VALUE ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self) { - VALUE signer_cert, signer_key, certs, flags, digest; + VALUE signer_cert, signer_key, certs, flags, digest, md_holder; OCSP_REQUEST *req; X509 *signer; EVP_PKEY *key; @@ -380,19 +383,17 @@ ossl_ocspreq_sign(int argc, VALUE *argv, VALUE self) signer = GetX509CertPtr(signer_cert); key = GetPrivPKeyPtr(signer_key); if (!NIL_P(flags)) - flg = NUM2INT(flags); - if (NIL_P(digest)) - md = EVP_sha1(); - else - md = ossl_evp_get_digestbyname(digest); + flg = NUM2INT(flags); + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); if (NIL_P(certs)) - flg |= OCSP_NOCERTS; + flg |= OCSP_NOCERTS; else - x509s = ossl_x509_ary2sk(certs); + x509s = ossl_x509_ary2sk(certs); ret = OCSP_request_sign(req, signer, key, md, x509s, flg); sk_X509_pop_free(x509s, X509_free); - if (!ret) ossl_raise(eOCSPError, NULL); + if (!ret) + ossl_raise(eOCSPError, "OCSP_request_sign"); return self; } @@ -426,7 +427,7 @@ ossl_ocspreq_verify(int argc, VALUE *argv, VALUE self) result = OCSP_request_verify(req, x509s, x509st, flg); sk_X509_pop_free(x509s, X509_free); if (result <= 0) - ossl_clear_error(); + ossl_clear_error(); return result > 0 ? Qtrue : Qfalse; } @@ -445,11 +446,11 @@ ossl_ocspreq_to_der(VALUE self) GetOCSPReq(self, req); if((len = i2d_OCSP_REQUEST(req, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_OCSP_REQUEST(req, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -493,7 +494,7 @@ ossl_ocspres_s_create(VALUE klass, VALUE status, VALUE basic_resp) else GetOCSPBasicRes(basic_resp, bs); /* NO NEED TO DUP */ obj = NewOCSPRes(klass); if(!(res = OCSP_response_create(st, bs))) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPRes(obj, res); return obj; @@ -507,12 +508,13 @@ ossl_ocspres_alloc(VALUE klass) obj = NewOCSPRes(klass); if(!(res = OCSP_RESPONSE_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPRes(obj, res); return obj; } +/* :nodoc: */ static VALUE ossl_ocspres_initialize_copy(VALUE self, VALUE other) { @@ -524,7 +526,7 @@ ossl_ocspres_initialize_copy(VALUE self, VALUE other) res_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_RESPONSE), res); if (!res_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); + ossl_raise(eOCSPError, "ASN1_item_dup"); SetOCSPRes(self, res_new); OCSP_RESPONSE_free(res_old); @@ -550,15 +552,15 @@ ossl_ocspres_initialize(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &arg); if(!NIL_P(arg)){ - GetOCSPRes(self, res); - arg = ossl_to_der_if_possible(arg); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - res_new = d2i_OCSP_RESPONSE(NULL, &p, RSTRING_LEN(arg)); - if (!res_new) - ossl_raise(eOCSPError, "d2i_OCSP_RESPONSE"); - SetOCSPRes(self, res_new); - OCSP_RESPONSE_free(res); + GetOCSPRes(self, res); + arg = ossl_to_der_if_possible(arg); + StringValue(arg); + p = (unsigned char *)RSTRING_PTR(arg); + res_new = d2i_OCSP_RESPONSE(NULL, &p, RSTRING_LEN(arg)); + if (!res_new) + ossl_raise(eOCSPError, "d2i_OCSP_RESPONSE"); + SetOCSPRes(self, res_new); + OCSP_RESPONSE_free(res); } return self; @@ -619,7 +621,7 @@ ossl_ocspres_get_basic(VALUE self) GetOCSPRes(self, res); ret = NewOCSPBasicRes(cOCSPBasicRes); if(!(bs = OCSP_response_get1_basic(res))) - return Qnil; + return Qnil; SetOCSPBasicRes(ret, bs); return ret; @@ -642,11 +644,11 @@ ossl_ocspres_to_der(VALUE self) GetOCSPRes(self, res); if((len = i2d_OCSP_RESPONSE(res, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_OCSP_RESPONSE(res, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -663,12 +665,13 @@ ossl_ocspbres_alloc(VALUE klass) obj = NewOCSPBasicRes(klass); if(!(bs = OCSP_BASICRESP_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPBasicRes(obj, bs); return obj; } +/* :nodoc: */ static VALUE ossl_ocspbres_initialize_copy(VALUE self, VALUE other) { @@ -680,7 +683,7 @@ ossl_ocspbres_initialize_copy(VALUE self, VALUE other) bs_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs); if (!bs_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); + ossl_raise(eOCSPError, "ASN1_item_dup"); SetOCSPBasicRes(self, bs_new); OCSP_BASICRESP_free(bs_old); @@ -705,15 +708,15 @@ ossl_ocspbres_initialize(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &arg); if (!NIL_P(arg)) { - GetOCSPBasicRes(self, res); - arg = ossl_to_der_if_possible(arg); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg)); - if (!res_new) - ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP"); - SetOCSPBasicRes(self, res_new); - OCSP_BASICRESP_free(res); + GetOCSPBasicRes(self, res); + arg = ossl_to_der_if_possible(arg); + StringValue(arg); + p = (unsigned char *)RSTRING_PTR(arg); + res_new = d2i_OCSP_BASICRESP(NULL, &p, RSTRING_LEN(arg)); + if (!res_new) + ossl_raise(eOCSPError, "d2i_OCSP_BASICRESP"); + SetOCSPBasicRes(self, res_new); + OCSP_BASICRESP_free(res); } return self; @@ -758,13 +761,13 @@ ossl_ocspbres_add_nonce(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "01", &val); if(NIL_P(val)) { - GetOCSPBasicRes(self, bs); - ret = OCSP_basic_add1_nonce(bs, NULL, -1); + GetOCSPBasicRes(self, bs); + ret = OCSP_basic_add1_nonce(bs, NULL, -1); } else{ - StringValue(val); - GetOCSPBasicRes(self, bs); - ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); + StringValue(val); + GetOCSPBasicRes(self, bs); + ret = OCSP_basic_add1_nonce(bs, (unsigned char *)RSTRING_PTR(val), RSTRING_LENINT(val)); } if(!ret) ossl_raise(eOCSPError, NULL); @@ -777,12 +780,12 @@ add_status_convert_time(VALUE obj) ASN1_TIME *time; if (RB_INTEGER_TYPE_P(obj)) - time = X509_gmtime_adj(NULL, NUM2INT(obj)); + time = X509_gmtime_adj(NULL, NUM2INT(obj)); else - time = ossl_x509_time_adjust(NULL, obj); + time = ossl_x509_time_adjust(NULL, obj); if (!time) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); return (VALUE)time; } @@ -803,7 +806,7 @@ add_status_convert_time(VALUE obj) * revocation, and must be one of OpenSSL::OCSP::REVOKED_STATUS_* constants. * _revocation_time_ is the time when the certificate is revoked. * - * _this_update_ and _next_update_ indicate the time at which ths status is + * _this_update_ and _next_update_ indicate the time at which the status is * verified to be correct and the time at or before which newer information * will be available, respectively. _next_update_ is optional. * @@ -816,8 +819,8 @@ add_status_convert_time(VALUE obj) */ static VALUE ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, - VALUE reason, VALUE revtime, - VALUE thisupd, VALUE nextupd, VALUE ext) + VALUE reason, VALUE revtime, + VALUE thisupd, VALUE nextupd, VALUE ext) { OCSP_BASICRESP *bs; OCSP_SINGLERESP *single; @@ -831,16 +834,16 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, GetOCSPCertId(cid, id); st = NUM2INT(status); if (!NIL_P(ext)) { /* All ext's members must be X509::Extension */ - ext = rb_check_array_type(ext); - for (i = 0; i < RARRAY_LEN(ext); i++) - OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext); + ext = rb_check_array_type(ext); + for (i = 0; i < RARRAY_LEN(ext); i++) + OSSL_Check_Kind(RARRAY_AREF(ext, i), cX509Ext); } if (st == V_OCSP_CERTSTATUS_REVOKED) { - rsn = NUM2INT(reason); - tmp = rb_protect(add_status_convert_time, revtime, &rstatus); - if (rstatus) goto err; - rev = (ASN1_TIME *)tmp; + rsn = NUM2INT(reason); + tmp = rb_protect(add_status_convert_time, revtime, &rstatus); + if (rstatus) goto err; + rev = (ASN1_TIME *)tmp; } tmp = rb_protect(add_status_convert_time, thisupd, &rstatus); @@ -848,29 +851,29 @@ ossl_ocspbres_add_status(VALUE self, VALUE cid, VALUE status, ths = (ASN1_TIME *)tmp; if (!NIL_P(nextupd)) { - tmp = rb_protect(add_status_convert_time, nextupd, &rstatus); - if (rstatus) goto err; - nxt = (ASN1_TIME *)tmp; + tmp = rb_protect(add_status_convert_time, nextupd, &rstatus); + if (rstatus) goto err; + nxt = (ASN1_TIME *)tmp; } if(!(single = OCSP_basic_add1_status(bs, id, st, rsn, rev, ths, nxt))){ - error = 1; - goto err; + error = 1; + goto err; } if(!NIL_P(ext)){ - X509_EXTENSION *x509ext; - - for(i = 0; i < RARRAY_LEN(ext); i++){ - x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i)); - if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ - error = 1; - goto err; - } - } + X509_EXTENSION *x509ext; + + for(i = 0; i < RARRAY_LEN(ext); i++){ + x509ext = GetX509ExtPtr(RARRAY_AREF(ext, i)); + if(!OCSP_SINGLERESP_add_ext(single, x509ext, -1)){ + error = 1; + goto err; + } + } } - err: + err: ASN1_TIME_free(ths); ASN1_TIME_free(nxt); ASN1_TIME_free(rev); @@ -896,48 +899,40 @@ static VALUE ossl_ocspbres_get_status(VALUE self) { OCSP_BASICRESP *bs; - OCSP_SINGLERESP *single; - OCSP_CERTID *cid; - ASN1_TIME *revtime, *thisupd, *nextupd; - int status, reason; - X509_EXTENSION *x509ext; - VALUE ret, ary, ext; - int count, ext_count, i, j; GetOCSPBasicRes(self, bs); - ret = rb_ary_new(); - count = OCSP_resp_count(bs); - for(i = 0; i < count; i++){ - single = OCSP_resp_get0(bs, i); - if(!single) continue; - - revtime = thisupd = nextupd = NULL; - status = OCSP_single_get0_status(single, &reason, &revtime, - &thisupd, &nextupd); - if(status < 0) continue; - if(!(cid = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(single)))) /* FIXME */ - ossl_raise(eOCSPError, NULL); - ary = rb_ary_new(); - rb_ary_push(ary, ossl_ocspcertid_new(cid)); - rb_ary_push(ary, INT2NUM(status)); - rb_ary_push(ary, INT2NUM(reason)); - rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil); - rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil); - rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil); - ext = rb_ary_new(); - ext_count = OCSP_SINGLERESP_get_ext_count(single); - for(j = 0; j < ext_count; j++){ - x509ext = OCSP_SINGLERESP_get_ext(single, j); - rb_ary_push(ext, ossl_x509ext_new(x509ext)); - } - rb_ary_push(ary, ext); - rb_ary_push(ret, ary); + VALUE ret = rb_ary_new(); + int count = OCSP_resp_count(bs); + for (int i = 0; i < count; i++) { + OCSP_SINGLERESP *single = OCSP_resp_get0(bs, i); + ASN1_TIME *revtime, *thisupd, *nextupd; + int reason; + + int status = OCSP_single_get0_status(single, &reason, &revtime, &thisupd, &nextupd); + if (status < 0) + ossl_raise(eOCSPError, "OCSP_single_get0_status"); + + VALUE ary = rb_ary_new(); + rb_ary_push(ary, ossl_ocspcid_new(OCSP_SINGLERESP_get0_id(single))); + rb_ary_push(ary, INT2NUM(status)); + rb_ary_push(ary, INT2NUM(reason)); + rb_ary_push(ary, revtime ? asn1time_to_time(revtime) : Qnil); + rb_ary_push(ary, thisupd ? asn1time_to_time(thisupd) : Qnil); + rb_ary_push(ary, nextupd ? asn1time_to_time(nextupd) : Qnil); + VALUE ext = rb_ary_new(); + int ext_count = OCSP_SINGLERESP_get_ext_count(single); + for (int j = 0; j < ext_count; j++) { + X509_EXTENSION *x509ext = OCSP_SINGLERESP_get_ext(single, j); + rb_ary_push(ext, ossl_x509ext_new(x509ext)); + } + rb_ary_push(ary, ext); + rb_ary_push(ret, ary); } return ret; } -static VALUE ossl_ocspsres_new(OCSP_SINGLERESP *); +static VALUE ossl_ocspsres_new(const OCSP_SINGLERESP *); /* * call-seq: @@ -955,17 +950,10 @@ ossl_ocspbres_get_responses(VALUE self) GetOCSPBasicRes(self, bs); count = OCSP_resp_count(bs); - ret = rb_ary_new2(count); + ret = rb_ary_new_capa(count); for (i = 0; i < count; i++) { - OCSP_SINGLERESP *sres, *sres_new; - - sres = OCSP_resp_get0(bs, i); - sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres); - if (!sres_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); - - rb_ary_push(ret, ossl_ocspsres_new(sres_new)); + rb_ary_push(ret, ossl_ocspsres_new(OCSP_resp_get0(bs, i))); } return ret; @@ -983,7 +971,6 @@ static VALUE ossl_ocspbres_find_response(VALUE self, VALUE target) { OCSP_BASICRESP *bs; - OCSP_SINGLERESP *sres, *sres_new; OCSP_CERTID *id; int n; @@ -991,14 +978,8 @@ ossl_ocspbres_find_response(VALUE self, VALUE target) GetOCSPBasicRes(self, bs); if ((n = OCSP_resp_find(bs, id, -1)) == -1) - return Qnil; - - sres = OCSP_resp_get0(bs, n); - sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres); - if (!sres_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); - - return ossl_ocspsres_new(sres_new); + return Qnil; + return ossl_ocspsres_new(OCSP_resp_get0(bs, n)); } /* @@ -1017,7 +998,7 @@ ossl_ocspbres_find_response(VALUE self, VALUE target) static VALUE ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self) { - VALUE signer_cert, signer_key, certs, flags, digest; + VALUE signer_cert, signer_key, certs, flags, digest, md_holder; OCSP_BASICRESP *bs; X509 *signer; EVP_PKEY *key; @@ -1031,19 +1012,17 @@ ossl_ocspbres_sign(int argc, VALUE *argv, VALUE self) signer = GetX509CertPtr(signer_cert); key = GetPrivPKeyPtr(signer_key); if (!NIL_P(flags)) - flg = NUM2INT(flags); - if (NIL_P(digest)) - md = EVP_sha1(); - else - md = ossl_evp_get_digestbyname(digest); + flg = NUM2INT(flags); + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); if (NIL_P(certs)) - flg |= OCSP_NOCERTS; + flg |= OCSP_NOCERTS; else - x509s = ossl_x509_ary2sk(certs); + x509s = ossl_x509_ary2sk(certs); ret = OCSP_basic_sign(bs, signer, key, md, x509s, flg); sk_X509_pop_free(x509s, X509_free); - if (!ret) ossl_raise(eOCSPError, NULL); + if (!ret) + ossl_raise(eOCSPError, "OCSP_basic_sign"); return self; } @@ -1069,58 +1048,10 @@ ossl_ocspbres_verify(int argc, VALUE *argv, VALUE self) x509st = GetX509StorePtr(store); flg = NIL_P(flags) ? 0 : NUM2INT(flags); x509s = ossl_x509_ary2sk(certs); -#if (OPENSSL_VERSION_NUMBER < 0x1000202fL) || defined(LIBRESSL_VERSION_NUMBER) - /* - * OpenSSL had a bug that it doesn't use the certificates in x509s for - * verifying the chain. This can be a problem when the response is signed by - * a certificate issued by an intermediate CA. - * - * root_ca - * | - * intermediate_ca - * |-------------| - * end_entity ocsp_signer - * - * When the certificate hierarchy is like this, and the response contains - * only ocsp_signer certificate, the following code wrongly fails. - * - * store = OpenSSL::X509::Store.new; store.add_cert(root_ca) - * basic_response.verify([intermediate_ca], store) - * - * So add the certificates in x509s to the embedded certificates list first. - * - * This is fixed in OpenSSL 0.9.8zg, 1.0.0s, 1.0.1n, 1.0.2b. But it still - * exists in LibreSSL 2.1.10, 2.2.9, 2.3.6, 2.4.1. - */ - if (!(flg & (OCSP_NOCHAIN | OCSP_NOVERIFY)) && - sk_X509_num(x509s) && sk_X509_num(bs->certs)) { - int i; - - bs = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_BASICRESP), bs); - if (!bs) { - sk_X509_pop_free(x509s, X509_free); - ossl_raise(eOCSPError, "ASN1_item_dup"); - } - - for (i = 0; i < sk_X509_num(x509s); i++) { - if (!OCSP_basic_add1_cert(bs, sk_X509_value(x509s, i))) { - sk_X509_pop_free(x509s, X509_free); - OCSP_BASICRESP_free(bs); - ossl_raise(eOCSPError, "OCSP_basic_add1_cert"); - } - } - result = OCSP_basic_verify(bs, x509s, x509st, flg); - OCSP_BASICRESP_free(bs); - } - else { - result = OCSP_basic_verify(bs, x509s, x509st, flg); - } -#else result = OCSP_basic_verify(bs, x509s, x509st, flg); -#endif sk_X509_pop_free(x509s, X509_free); if (result <= 0) - ossl_clear_error(); + ossl_clear_error(); return result > 0 ? Qtrue : Qfalse; } @@ -1141,11 +1072,11 @@ ossl_ocspbres_to_der(VALUE self) GetOCSPBasicRes(self, res); if ((len = i2d_OCSP_BASICRESP(res, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_OCSP_BASICRESP(res, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -1155,12 +1086,18 @@ ossl_ocspbres_to_der(VALUE self) * OCSP::SingleResponse */ static VALUE -ossl_ocspsres_new(OCSP_SINGLERESP *sres) +ossl_ocspsres_new(const OCSP_SINGLERESP *sres) { VALUE obj; + OCSP_SINGLERESP *sres_new; obj = NewOCSPSingleRes(cOCSPSingleRes); - SetOCSPSingleRes(obj, sres); + /* OpenSSL 1.1.1 takes a non-const pointer */ + sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), + (OCSP_SINGLERESP *)sres); + if (!sres_new) + ossl_raise(eOCSPError, "ASN1_item_dup"); + SetOCSPSingleRes(obj, sres_new); return obj; } @@ -1173,7 +1110,7 @@ ossl_ocspsres_alloc(VALUE klass) obj = NewOCSPSingleRes(klass); if (!(sres = OCSP_SINGLERESP_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPSingleRes(obj, sres); return obj; @@ -1198,13 +1135,14 @@ ossl_ocspsres_initialize(VALUE self, VALUE arg) p = (unsigned char*)RSTRING_PTR(arg); res_new = d2i_OCSP_SINGLERESP(NULL, &p, RSTRING_LEN(arg)); if (!res_new) - ossl_raise(eOCSPError, "d2i_OCSP_SINGLERESP"); + ossl_raise(eOCSPError, "d2i_OCSP_SINGLERESP"); SetOCSPSingleRes(self, res_new); OCSP_SINGLERESP_free(res); return self; } +/* :nodoc: */ static VALUE ossl_ocspsres_initialize_copy(VALUE self, VALUE other) { @@ -1216,7 +1154,7 @@ ossl_ocspsres_initialize_copy(VALUE self, VALUE other) sres_new = ASN1_item_dup(ASN1_ITEM_rptr(OCSP_SINGLERESP), sres); if (!sres_new) - ossl_raise(eOCSPError, "ASN1_item_dup"); + ossl_raise(eOCSPError, "ASN1_item_dup"); SetOCSPSingleRes(self, sres_new); OCSP_SINGLERESP_free(sres_old); @@ -1255,15 +1193,15 @@ ossl_ocspsres_check_validity(int argc, VALUE *argv, VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, NULL, &this_update, &next_update); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); ret = OCSP_check_validity(this_update, next_update, nsec, maxsec); if (ret) - return Qtrue; + return Qtrue; else { - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; } } @@ -1277,12 +1215,9 @@ static VALUE ossl_ocspsres_get_certid(VALUE self) { OCSP_SINGLERESP *sres; - OCSP_CERTID *id; GetOCSPSingleRes(self, sres); - id = OCSP_CERTID_dup((OCSP_CERTID *)OCSP_SINGLERESP_get0_id(sres)); /* FIXME */ - - return ossl_ocspcertid_new(id); + return ossl_ocspcid_new(OCSP_SINGLERESP_get0_id(sres)); } /* @@ -1308,7 +1243,7 @@ ossl_ocspsres_get_cert_status(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, NULL, NULL, NULL); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); return INT2NUM(status); } @@ -1327,9 +1262,9 @@ ossl_ocspsres_get_this_update(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, NULL, &time, NULL); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -1348,9 +1283,9 @@ ossl_ocspsres_get_next_update(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, NULL, NULL, &time); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -1369,11 +1304,11 @@ ossl_ocspsres_get_revocation_time(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, NULL, &time, NULL, NULL); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); if (status != V_OCSP_CERTSTATUS_REVOKED) - ossl_raise(eOCSPError, "certificate is not revoked"); + ossl_raise(eOCSPError, "certificate is not revoked"); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -1391,9 +1326,9 @@ ossl_ocspsres_get_revocation_reason(VALUE self) GetOCSPSingleRes(self, sres); status = OCSP_single_get0_status(sres, &reason, NULL, NULL, NULL); if (status < 0) - ossl_raise(eOCSPError, "OCSP_single_get0_status"); + ossl_raise(eOCSPError, "OCSP_single_get0_status"); if (status != V_OCSP_CERTSTATUS_REVOKED) - ossl_raise(eOCSPError, "certificate is not revoked"); + ossl_raise(eOCSPError, "certificate is not revoked"); return INT2NUM(reason); } @@ -1415,8 +1350,8 @@ ossl_ocspsres_get_extensions(VALUE self) count = OCSP_SINGLERESP_get_ext_count(sres); ary = rb_ary_new2(count); for (i = 0; i < count; i++) { - ext = OCSP_SINGLERESP_get_ext(sres, i); - rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */ + ext = OCSP_SINGLERESP_get_ext(sres, i); + rb_ary_push(ary, ossl_x509ext_new(ext)); /* will dup */ } return ary; @@ -1438,11 +1373,11 @@ ossl_ocspsres_to_der(VALUE self) GetOCSPSingleRes(self, sres); if ((len = i2d_OCSP_SINGLERESP(sres, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_OCSP_SINGLERESP(sres, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -1460,12 +1395,13 @@ ossl_ocspcid_alloc(VALUE klass) obj = NewOCSPCertId(klass); if(!(id = OCSP_CERTID_new())) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); SetOCSPCertId(obj, id); return obj; } +/* :nodoc: */ static VALUE ossl_ocspcid_initialize_copy(VALUE self, VALUE other) { @@ -1477,7 +1413,7 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other) cid_new = OCSP_CERTID_dup(cid); if (!cid_new) - ossl_raise(eOCSPError, "OCSP_CERTID_dup"); + ossl_raise(eOCSPError, "OCSP_CERTID_dup"); SetOCSPCertId(self, cid_new); OCSP_CERTID_free(cid_old); @@ -1489,13 +1425,15 @@ ossl_ocspcid_initialize_copy(VALUE self, VALUE other) * call-seq: * OpenSSL::OCSP::CertificateId.new(subject, issuer, digest = nil) -> certificate_id * OpenSSL::OCSP::CertificateId.new(der_string) -> certificate_id + * OpenSSL::OCSP::CertificateId.new(obj) -> certificate_id * * Creates a new OpenSSL::OCSP::CertificateId for the given _subject_ and * _issuer_ X509 certificates. The _digest_ is a digest algorithm that is used * to compute the hash values. This defaults to SHA-1. * * If only one argument is given, decodes it as DER representation of a - * certificate ID. + * certificate ID or generates certificate ID from the object that responds to + * the to_der method. */ static VALUE ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self) @@ -1505,27 +1443,28 @@ ossl_ocspcid_initialize(int argc, VALUE *argv, VALUE self) GetOCSPCertId(self, id); if (rb_scan_args(argc, argv, "12", &subject, &issuer, &digest) == 1) { - VALUE arg; - const unsigned char *p; - - arg = ossl_to_der_if_possible(subject); - StringValue(arg); - p = (unsigned char *)RSTRING_PTR(arg); - newid = d2i_OCSP_CERTID(NULL, &p, RSTRING_LEN(arg)); - if (!newid) - ossl_raise(eOCSPError, "d2i_OCSP_CERTID"); + VALUE arg; + const unsigned char *p; + + arg = ossl_to_der_if_possible(subject); + StringValue(arg); + p = (unsigned char *)RSTRING_PTR(arg); + newid = d2i_OCSP_CERTID(NULL, &p, RSTRING_LEN(arg)); + if (!newid) + ossl_raise(eOCSPError, "d2i_OCSP_CERTID"); } else { - X509 *x509s, *x509i; - const EVP_MD *md; + X509 *x509s, *x509i; + const EVP_MD *md; + VALUE md_holder; - x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */ - x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */ - md = !NIL_P(digest) ? ossl_evp_get_digestbyname(digest) : NULL; + x509s = GetX509CertPtr(subject); /* NO NEED TO DUP */ + x509i = GetX509CertPtr(issuer); /* NO NEED TO DUP */ + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); - newid = OCSP_cert_to_id(md, x509s, x509i); - if (!newid) - ossl_raise(eOCSPError, "OCSP_cert_to_id"); + newid = OCSP_cert_to_id(md, x509s, x509i); + if (!newid) + ossl_raise(eOCSPError, "OCSP_cert_to_id"); } SetOCSPCertId(self, newid); @@ -1611,8 +1550,9 @@ ossl_ocspcid_get_issuer_name_hash(VALUE self) GetOCSPCertId(self, id); OCSP_id_get0_info(&name_hash, NULL, NULL, NULL, id); - ret = rb_str_new(NULL, name_hash->length * 2); - ossl_bin2hex(name_hash->data, RSTRING_PTR(ret), name_hash->length); + ret = rb_str_new(NULL, ASN1_STRING_length(name_hash) * 2); + ossl_bin2hex(ASN1_STRING_get0_data(name_hash), RSTRING_PTR(ret), + ASN1_STRING_length(name_hash)); return ret; } @@ -1634,8 +1574,9 @@ ossl_ocspcid_get_issuer_key_hash(VALUE self) GetOCSPCertId(self, id); OCSP_id_get0_info(NULL, NULL, &key_hash, NULL, id); - ret = rb_str_new(NULL, key_hash->length * 2); - ossl_bin2hex(key_hash->data, RSTRING_PTR(ret), key_hash->length); + ret = rb_str_new(NULL, ASN1_STRING_length(key_hash) * 2); + ossl_bin2hex(ASN1_STRING_get0_data(key_hash), RSTRING_PTR(ret), + ASN1_STRING_length(key_hash)); return ret; } @@ -1652,19 +1593,10 @@ ossl_ocspcid_get_hash_algorithm(VALUE self) { OCSP_CERTID *id; ASN1_OBJECT *oid; - BIO *out; GetOCSPCertId(self, id); OCSP_id_get0_info(NULL, &oid, NULL, NULL, id); - - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eOCSPError, "BIO_new"); - - if (!i2a_ASN1_OBJECT(out, oid)) { - BIO_free(out); - ossl_raise(eOCSPError, "i2a_ASN1_OBJECT"); - } - return ossl_membio2str(out); + return ossl_asn1obj_to_string_long_name(oid); } /* @@ -1683,11 +1615,11 @@ ossl_ocspcid_to_der(VALUE self) GetOCSPCertId(self, id); if ((len = i2d_OCSP_CERTID(id, NULL)) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_OCSP_CERTID(id, &p) <= 0) - ossl_raise(eOCSPError, NULL); + ossl_raise(eOCSPError, NULL); ossl_str_adjust(str, p); return str; @@ -1696,11 +1628,6 @@ ossl_ocspcid_to_der(VALUE self) void Init_ossl_ocsp(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* * OpenSSL::OCSP implements Online Certificate Status Protocol requests * and responses. @@ -1717,7 +1644,7 @@ Init_ossl_ocsp(void) * subject certificate so the CA knows which certificate we are asking * about: * - * digest = OpenSSL::Digest::SHA1.new + * digest = OpenSSL::Digest.new('SHA1') * certificate_id = * OpenSSL::OCSP::CertificateId.new subject, issuer, digest * @@ -1734,18 +1661,11 @@ Init_ossl_ocsp(void) * To submit the request to the CA for verification we need to extract the * OCSP URI from the subject certificate: * - * authority_info_access = subject.extensions.find do |extension| - * extension.oid == 'authorityInfoAccess' - * end - * - * descriptions = authority_info_access.value.split "\n" - * ocsp = descriptions.find do |description| - * description.start_with? 'OCSP' - * end + * ocsp_uris = subject.ocsp_uris * * require 'uri' * - * ocsp_uri = URI ocsp[/URI:(.*)/, 1] + * ocsp_uri = URI ocsp_uris[0] * * To submit the request we'll POST the request to the OCSP URI (per RFC * 2560). Note that we only handle HTTP requests and don't handle any @@ -1754,7 +1674,7 @@ Init_ossl_ocsp(void) * require 'net/http' * * http_response = - * Net::HTTP.start ocsp_uri.hostname, ocsp.port do |http| + * Net::HTTP.start ocsp_uri.hostname, ocsp_uri.port do |http| * http.post ocsp_uri.path, request.to_der, * 'content-type' => 'application/ocsp-request' * end @@ -1792,7 +1712,7 @@ Init_ossl_ocsp(void) * single_response = basic_response.find_response(certificate_id) * * unless single_response - * raise 'basic_response does not have the status for the certificiate' + * raise 'basic_response does not have the status for the certificate' * end * * Then check the validity. A status issued in the future must be rejected. diff --git a/ext/openssl/ossl_ocsp.h b/ext/openssl/ossl_ocsp.h index 21e2c99a2e..becd70ffed 100644 --- a/ext/openssl/ossl_ocsp.h +++ b/ext/openssl/ossl_ocsp.h @@ -6,18 +6,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_OCSP_H_) #define _OSSL_OCSP_H_ -#if !defined(OPENSSL_NO_OCSP) -extern VALUE mOCSP; -extern VALUE cOPCSReq; -extern VALUE cOPCSRes; -extern VALUE cOPCSBasicRes; -#endif - void Init_ossl_ocsp(void); #endif /* _OSSL_OCSP_H_ */ diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c index 4566334481..32b82a881c 100644 --- a/ext/openssl/ossl_pkcs12.c +++ b/ext/openssl/ossl_pkcs12.c @@ -1,6 +1,6 @@ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -27,8 +27,8 @@ /* * Classes */ -VALUE cPKCS12; -VALUE ePKCS12Error; +static VALUE cPKCS12; +static VALUE ePKCS12Error; /* * Private @@ -42,9 +42,9 @@ ossl_pkcs12_free(void *ptr) static const rb_data_type_t ossl_pkcs12_type = { "OpenSSL/PKCS12", { - 0, ossl_pkcs12_free, + 0, ossl_pkcs12_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -60,6 +60,7 @@ ossl_pkcs12_s_allocate(VALUE klass) return obj; } +/* :nodoc: */ static VALUE ossl_pkcs12_initialize_copy(VALUE self, VALUE other) { @@ -71,7 +72,7 @@ ossl_pkcs12_initialize_copy(VALUE self, VALUE other) p12_new = ASN1_dup((i2d_of_void *)i2d_PKCS12, (d2i_of_void *)d2i_PKCS12, (char *)p12); if (!p12_new) - ossl_raise(ePKCS12Error, "ASN1_dup"); + ossl_raise(ePKCS12Error, "ASN1_dup"); SetPKCS12(self, p12_new); PKCS12_free(p12_old); @@ -121,11 +122,11 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) /* TODO: make a VALUE to nid function */ if (!NIL_P(key_nid)) { if ((nkey = OBJ_txt2nid(StringValueCStr(key_nid))) == NID_undef) - ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, key_nid); + ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, key_nid); } if (!NIL_P(cert_nid)) { if ((ncert = OBJ_txt2nid(StringValueCStr(cert_nid))) == NID_undef) - ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, cert_nid); + ossl_raise(rb_eArgError, "Unknown PBE algorithm %"PRIsVALUE, cert_nid); } if (!NIL_P(key_iter)) kiter = NUM2INT(key_iter); @@ -134,6 +135,16 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) if (!NIL_P(keytype)) ktype = NUM2INT(keytype); +#if defined(OPENSSL_IS_AWSLC) + if (ktype != 0) { + ossl_raise(rb_eArgError, "Unknown key usage type %"PRIsVALUE, INT2NUM(ktype)); + } +#else + if (ktype != 0 && ktype != KEY_SIG && ktype != KEY_EX) { + ossl_raise(rb_eArgError, "Unknown key usage type %"PRIsVALUE, INT2NUM(ktype)); + } +#endif + obj = NewPKCS12(cPKCS12); x509s = NIL_P(ca) ? NULL : ossl_x509_ary2sk(ca); p12 = PKCS12_create(passphrase, friendlyname, key, x509, x509s, @@ -149,6 +160,24 @@ ossl_pkcs12_s_create(int argc, VALUE *argv, VALUE self) return obj; } +static VALUE +ossl_pkey_wrap_i(VALUE arg) +{ + return ossl_pkey_wrap((EVP_PKEY *)arg); +} + +static VALUE +ossl_x509_new_i(VALUE arg) +{ + return ossl_x509_new((X509 *)arg); +} + +static VALUE +ossl_x509_sk2ary_i(VALUE arg) +{ + return ossl_x509_sk2ary((STACK_OF(X509) *)arg); +} + /* * call-seq: * PKCS12.new -> pkcs12 @@ -179,23 +208,19 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self) BIO_free(in); pkey = cert = ca = Qnil; - /* OpenSSL's bug; PKCS12_parse() puts errors even if it succeeds. - * Fixed in OpenSSL 1.0.0t, 1.0.1p, 1.0.2d */ - ERR_set_mark(); if(!PKCS12_parse(pkcs, passphrase, &key, &x509, &x509s)) - ossl_raise(ePKCS12Error, "PKCS12_parse"); - ERR_pop_to_mark(); + ossl_raise(ePKCS12Error, "PKCS12_parse"); if (key) { - pkey = rb_protect((VALUE (*)(VALUE))ossl_pkey_new, (VALUE)key, &st); - if (st) goto err; + pkey = rb_protect(ossl_pkey_wrap_i, (VALUE)key, &st); + if (st) goto err; } if (x509) { - cert = rb_protect((VALUE (*)(VALUE))ossl_x509_new, (VALUE)x509, &st); - if (st) goto err; + cert = rb_protect(ossl_x509_new_i, (VALUE)x509, &st); + if (st) goto err; } if (x509s) { - ca = rb_protect((VALUE (*)(VALUE))ossl_x509_sk2ary, (VALUE)x509s, &st); - if (st) goto err; + ca = rb_protect(ossl_x509_sk2ary_i, (VALUE)x509s, &st); + if (st) goto err; } err: @@ -219,25 +244,62 @@ ossl_pkcs12_to_der(VALUE self) GetPKCS12(self, p12); if((len = i2d_PKCS12(p12, NULL)) <= 0) - ossl_raise(ePKCS12Error, NULL); + ossl_raise(ePKCS12Error, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_PKCS12(p12, &p) <= 0) - ossl_raise(ePKCS12Error, NULL); + ossl_raise(ePKCS12Error, NULL); ossl_str_adjust(str, p); return str; } +/* + * call-seq: + * pkcs12.set_mac(pass, salt = nil, iter = nil, md_type = nil) + * + * Sets MAC parameters and generates MAC over the PKCS #12 structure. + * + * This method uses HMAC and the PKCS #12 specific password-based KDF as + * specified in the original PKCS #12. + * + * See also the man page PKCS12_set_mac(3). + * + * Added in version 3.3.0. + */ +static VALUE +pkcs12_set_mac(int argc, VALUE *argv, VALUE self) +{ + PKCS12 *p12; + VALUE pass, salt, iter, md_name, md_holder = Qnil; + int iter_i = 0; + const EVP_MD *md_type = NULL; + + rb_scan_args(argc, argv, "13", &pass, &salt, &iter, &md_name); + rb_check_frozen(self); + GetPKCS12(self, p12); + + StringValue(pass); + if (!NIL_P(salt)) + StringValue(salt); + if (!NIL_P(iter)) + iter_i = NUM2INT(iter); + if (!NIL_P(md_name)) + md_type = ossl_evp_md_fetch(md_name, &md_holder); + + if (!PKCS12_set_mac(p12, RSTRING_PTR(pass), RSTRING_LENINT(pass), + !NIL_P(salt) ? (unsigned char *)RSTRING_PTR(salt) : NULL, + !NIL_P(salt) ? RSTRING_LENINT(salt) : 0, + iter_i, md_type)) + ossl_raise(ePKCS12Error, "PKCS12_set_mac"); + + return Qnil; +} + void Init_ossl_pkcs12(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* * Defines a file format commonly used to store private keys with * accompanying public key certificates, protected with a password-based @@ -254,4 +316,11 @@ Init_ossl_pkcs12(void) rb_attr(cPKCS12, rb_intern("ca_certs"), 1, 0, Qfalse); rb_define_method(cPKCS12, "initialize", ossl_pkcs12_initialize, -1); rb_define_method(cPKCS12, "to_der", ossl_pkcs12_to_der, 0); + rb_define_method(cPKCS12, "set_mac", pkcs12_set_mac, -1); + +#if !defined(OPENSSL_IS_AWSLC) + /* MSIE specific PKCS12 key usage extensions */ + rb_define_const(cPKCS12, "KEY_EX", INT2NUM(KEY_EX)); + rb_define_const(cPKCS12, "KEY_SIG", INT2NUM(KEY_SIG)); +#endif } diff --git a/ext/openssl/ossl_pkcs12.h b/ext/openssl/ossl_pkcs12.h index fe4f15ef60..6d2cd901cb 100644 --- a/ext/openssl/ossl_pkcs12.h +++ b/ext/openssl/ossl_pkcs12.h @@ -1,13 +1,10 @@ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_PKCS12_H_) #define _OSSL_PKCS12_H_ -extern VALUE cPKCS12; -extern VALUE ePKCS12Error; - void Init_ossl_pkcs12(void); #endif /* _OSSL_PKCS12_H_ */ diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c index 28010c81fb..6e51fd42b9 100644 --- a/ext/openssl/ossl_pkcs7.c +++ b/ext/openssl/ossl_pkcs7.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_pkcs7_type, 0) #define SetPKCS7(obj, pkcs7) do { \ if (!(pkcs7)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (pkcs7); \ } while (0) #define GetPKCS7(obj, pkcs7) do { \ TypedData_Get_Struct((obj), PKCS7, &ossl_pkcs7_type, (pkcs7)); \ if (!(pkcs7)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7 wasn't initialized."); \ } \ } while (0) @@ -28,14 +28,14 @@ TypedData_Wrap_Struct((klass), &ossl_pkcs7_signer_info_type, 0) #define SetPKCS7si(obj, p7si) do { \ if (!(p7si)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (p7si); \ } while (0) #define GetPKCS7si(obj, p7si) do { \ TypedData_Get_Struct((obj), PKCS7_SIGNER_INFO, &ossl_pkcs7_signer_info_type, (p7si)); \ if (!(p7si)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7si wasn't initialized."); \ } \ } while (0) @@ -43,14 +43,14 @@ TypedData_Wrap_Struct((klass), &ossl_pkcs7_recip_info_type, 0) #define SetPKCS7ri(obj, p7ri) do { \ if (!(p7ri)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (p7ri); \ } while (0) #define GetPKCS7ri(obj, p7ri) do { \ TypedData_Get_Struct((obj), PKCS7_RECIP_INFO, &ossl_pkcs7_recip_info_type, (p7ri)); \ if (!(p7ri)) { \ - ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "PKCS7ri wasn't initialized."); \ } \ } while (0) @@ -64,10 +64,11 @@ /* * Classes */ -VALUE cPKCS7; -VALUE cPKCS7Signer; -VALUE cPKCS7Recipient; -VALUE ePKCS7Error; +static VALUE cPKCS7; +static VALUE cPKCS7Signer; +static VALUE cPKCS7Recipient; +static VALUE ePKCS7Error; +static ID id_md_holder, id_cipher_holder; static void ossl_pkcs7_free(void *ptr) @@ -78,11 +79,25 @@ ossl_pkcs7_free(void *ptr) static const rb_data_type_t ossl_pkcs7_type = { "OpenSSL/PKCS7", { - 0, ossl_pkcs7_free, + 0, ossl_pkcs7_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; +VALUE +ossl_pkcs7_new(PKCS7 *p7) +{ + PKCS7 *new; + VALUE obj = NewPKCS7(cPKCS7); + + new = PKCS7_dup(p7); + if (!new) + ossl_raise(ePKCS7Error, "PKCS7_dup"); + SetPKCS7(obj, new); + + return obj; +} + static void ossl_pkcs7_signer_info_free(void *ptr) { @@ -92,9 +107,9 @@ ossl_pkcs7_signer_info_free(void *ptr) static const rb_data_type_t ossl_pkcs7_signer_info_type = { "OpenSSL/PKCS7/SIGNER_INFO", { - 0, ossl_pkcs7_signer_info_free, + 0, ossl_pkcs7_signer_info_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static void @@ -106,9 +121,9 @@ ossl_pkcs7_recip_info_free(void *ptr) static const rb_data_type_t ossl_pkcs7_recip_info_type = { "OpenSSL/PKCS7/RECIP_INFO", { - 0, ossl_pkcs7_recip_info_free, + 0, ossl_pkcs7_recip_info_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -116,75 +131,64 @@ static const rb_data_type_t ossl_pkcs7_recip_info_type = { * (MADE PRIVATE UNTIL SOMEBODY WILL NEED THEM) */ static PKCS7_SIGNER_INFO * -ossl_PKCS7_SIGNER_INFO_dup(const PKCS7_SIGNER_INFO *si) +ossl_PKCS7_SIGNER_INFO_dup(PKCS7_SIGNER_INFO *si) { - return (PKCS7_SIGNER_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO, - (d2i_of_void *)d2i_PKCS7_SIGNER_INFO, - (char *)si); + PKCS7_SIGNER_INFO *si_new = ASN1_dup((i2d_of_void *)i2d_PKCS7_SIGNER_INFO, + (d2i_of_void *)d2i_PKCS7_SIGNER_INFO, + si); + if (si_new && si->pkey) { + EVP_PKEY_up_ref(si->pkey); + si_new->pkey = si->pkey; + } + return si_new; } static PKCS7_RECIP_INFO * -ossl_PKCS7_RECIP_INFO_dup(const PKCS7_RECIP_INFO *si) +ossl_PKCS7_RECIP_INFO_dup(PKCS7_RECIP_INFO *ri) { - return (PKCS7_RECIP_INFO *)ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, - (d2i_of_void *)d2i_PKCS7_RECIP_INFO, - (char *)si); + PKCS7_RECIP_INFO *ri_new = ASN1_dup((i2d_of_void *)i2d_PKCS7_RECIP_INFO, + (d2i_of_void *)d2i_PKCS7_RECIP_INFO, + ri); + if (ri_new && ri->cert) { + if (!X509_up_ref(ri->cert)) { + PKCS7_RECIP_INFO_free(ri_new); + return NULL; + } + ri_new->cert = ri->cert; + } + return ri_new; } static VALUE ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si) { - PKCS7_SIGNER_INFO *pkcs7; + PKCS7_SIGNER_INFO *p7si_new; VALUE obj; obj = NewPKCS7si(cPKCS7Signer); - pkcs7 = p7si ? ossl_PKCS7_SIGNER_INFO_dup(p7si) : PKCS7_SIGNER_INFO_new(); - if (!pkcs7) ossl_raise(ePKCS7Error, NULL); - SetPKCS7si(obj, pkcs7); + p7si_new = ossl_PKCS7_SIGNER_INFO_dup(p7si); + if (!p7si_new) + ossl_raise(ePKCS7Error, "ASN1_dup"); + SetPKCS7si(obj, p7si_new); return obj; } -static PKCS7_SIGNER_INFO * -DupPKCS7SignerPtr(VALUE obj) -{ - PKCS7_SIGNER_INFO *p7si, *pkcs7; - - GetPKCS7si(obj, p7si); - if (!(pkcs7 = ossl_PKCS7_SIGNER_INFO_dup(p7si))) { - ossl_raise(ePKCS7Error, NULL); - } - - return pkcs7; -} - static VALUE ossl_pkcs7ri_new(PKCS7_RECIP_INFO *p7ri) { - PKCS7_RECIP_INFO *pkcs7; + PKCS7_RECIP_INFO *p7ri_new; VALUE obj; obj = NewPKCS7ri(cPKCS7Recipient); - pkcs7 = p7ri ? ossl_PKCS7_RECIP_INFO_dup(p7ri) : PKCS7_RECIP_INFO_new(); - if (!pkcs7) ossl_raise(ePKCS7Error, NULL); - SetPKCS7ri(obj, pkcs7); + p7ri_new = ossl_PKCS7_RECIP_INFO_dup(p7ri); + if (!p7ri_new) + ossl_raise(ePKCS7Error,"ASN1_dup"); + SetPKCS7ri(obj, p7ri_new); return obj; } -static PKCS7_RECIP_INFO * -DupPKCS7RecipientPtr(VALUE obj) -{ - PKCS7_RECIP_INFO *p7ri, *pkcs7; - - GetPKCS7ri(obj, p7ri); - if (!(pkcs7 = ossl_PKCS7_RECIP_INFO_dup(p7ri))) { - ossl_raise(ePKCS7Error, NULL); - } - - return pkcs7; -} - /* * call-seq: * PKCS7.read_smime(string) => pkcs7 @@ -201,7 +205,13 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg) out = NULL; pkcs7 = SMIME_read_PKCS7(in, &out); BIO_free(in); - if(!pkcs7) ossl_raise(ePKCS7Error, NULL); + if (!pkcs7) + ossl_raise(ePKCS7Error, "Could not parse the PKCS7"); + if (!pkcs7->d.ptr) { + PKCS7_free(pkcs7); + ossl_raise(ePKCS7Error, "No content in PKCS7"); + } + data = out ? ossl_membio2str(out) : Qnil; SetPKCS7(ret, pkcs7); ossl_pkcs7_set_data(ret, data); @@ -228,7 +238,7 @@ ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass) if(NIL_P(data)) data = ossl_pkcs7_get_data(pkcs7); GetPKCS7(pkcs7, p7); if(!NIL_P(data) && PKCS7_is_detached(p7)) - flg |= PKCS7_DETACHED; + flg |= PKCS7_DETACHED; in = NIL_P(data) ? NULL : ossl_obj2bio(&data); if(!(out = BIO_new(BIO_s_mem()))){ BIO_free(in); @@ -269,16 +279,16 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass) in = ossl_obj2bio(&data); if(NIL_P(certs)) x509s = NULL; else{ - x509s = ossl_protect_x509_ary2sk(certs, &status); - if(status){ - BIO_free(in); - rb_jump_tag(status); - } + x509s = ossl_protect_x509_ary2sk(certs, &status); + if(status){ + BIO_free(in); + rb_jump_tag(status); + } } if(!(pkcs7 = PKCS7_sign(x509, pkey, x509s, in, flg))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); + BIO_free(in); + sk_X509_pop_free(x509s, X509_free); + ossl_raise(ePKCS7Error, NULL); } SetPKCS7(ret, pkcs7); ossl_pkcs7_set_data(ret, data); @@ -291,12 +301,19 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * PKCS7.encrypt(certs, data, [, cipher [, flags]]) => pkcs7 + * PKCS7.encrypt(certs, data, cipher, flags = 0) => pkcs7 + * + * Creates a PKCS #7 enveloped-data structure. + * + * Before version 3.3.0, +cipher+ was optional and defaulted to + * <tt>"RC2-40-CBC"</tt>. + * + * See also the man page PKCS7_encrypt(3). */ static VALUE ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass) { - VALUE certs, data, cipher, flags; + VALUE certs, data, cipher, flags, cipher_holder; STACK_OF(X509) *x509s; BIO *in; const EVP_CIPHER *ciph; @@ -305,37 +322,29 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass) PKCS7 *p7; rb_scan_args(argc, argv, "22", &certs, &data, &cipher, &flags); - if(NIL_P(cipher)){ -#if !defined(OPENSSL_NO_RC2) - ciph = EVP_rc2_40_cbc(); -#elif !defined(OPENSSL_NO_DES) - ciph = EVP_des_ede3_cbc(); -#elif !defined(OPENSSL_NO_RC2) - ciph = EVP_rc2_40_cbc(); -#elif !defined(OPENSSL_NO_AES) - ciph = EVP_EVP_aes_128_cbc(); -#else - ossl_raise(ePKCS7Error, "Must specify cipher"); -#endif - + if (NIL_P(cipher)) { + rb_raise(rb_eArgError, + "cipher must be specified. Before version 3.3, " \ + "the default cipher was RC2-40-CBC."); } - else ciph = ossl_evp_get_cipherbyname(cipher); + ciph = ossl_evp_cipher_fetch(cipher, &cipher_holder); flg = NIL_P(flags) ? 0 : NUM2INT(flags); ret = NewPKCS7(cPKCS7); in = ossl_obj2bio(&data); x509s = ossl_protect_x509_ary2sk(certs, &status); if(status){ - BIO_free(in); - rb_jump_tag(status); + BIO_free(in); + rb_jump_tag(status); } - if(!(p7 = PKCS7_encrypt(x509s, in, (EVP_CIPHER*)ciph, flg))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); + if (!(p7 = PKCS7_encrypt(x509s, in, ciph, flg))) { + BIO_free(in); + sk_X509_pop_free(x509s, X509_free); + ossl_raise(ePKCS7Error, NULL); } BIO_free(in); SetPKCS7(ret, p7); ossl_pkcs7_set_data(ret, data); + rb_ivar_set(ret, id_cipher_holder, cipher_holder); sk_X509_pop_free(x509s, X509_free); return ret; @@ -349,7 +358,7 @@ ossl_pkcs7_alloc(VALUE klass) obj = NewPKCS7(klass); if (!(pkcs7 = PKCS7_new())) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } SetPKCS7(obj, pkcs7); @@ -366,33 +375,36 @@ ossl_pkcs7_alloc(VALUE klass) static VALUE ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self) { - PKCS7 *p7, *pkcs = DATA_PTR(self); + PKCS7 *p7, *p7_orig = RTYPEDDATA_DATA(self); BIO *in; VALUE arg; if(rb_scan_args(argc, argv, "01", &arg) == 0) - return self; + return self; arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); - p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL); + p7 = d2i_PKCS7_bio(in, NULL); if (!p7) { - OSSL_BIO_reset(in); - p7 = d2i_PKCS7_bio(in, &pkcs); - if (!p7) { - BIO_free(in); - PKCS7_free(pkcs); - DATA_PTR(self) = NULL; - ossl_raise(rb_eArgError, "Could not parse the PKCS7"); - } + OSSL_BIO_reset(in); + p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); } - DATA_PTR(self) = pkcs; BIO_free(in); + if (!p7) + ossl_raise(ePKCS7Error, "Could not parse the PKCS7"); + if (!p7->d.ptr) { + PKCS7_free(p7); + ossl_raise(ePKCS7Error, "No content in PKCS7"); + } + + RTYPEDDATA_DATA(self) = p7; + PKCS7_free(p7_orig); ossl_pkcs7_set_data(self, Qnil); ossl_pkcs7_set_err_string(self, Qnil); return self; } +/* :nodoc: */ static VALUE ossl_pkcs7_copy(VALUE self, VALUE other) { @@ -406,7 +418,7 @@ ossl_pkcs7_copy(VALUE self, VALUE other) pkcs7 = PKCS7_dup(b); if (!pkcs7) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } DATA_PTR(self) = pkcs7; PKCS7_free(a); @@ -438,13 +450,13 @@ ossl_pkcs7_sym2typeid(VALUE sym) RSTRING_GETMEM(sym, s, l); for(i = 0; ; i++){ - if(i == numberof(p7_type_tab)) - ossl_raise(ePKCS7Error, "unknown type \"%"PRIsVALUE"\"", sym); - if(strlen(p7_type_tab[i].name) != l) continue; - if(strcmp(p7_type_tab[i].name, s) == 0){ - ret = p7_type_tab[i].nid; - break; - } + if(i == numberof(p7_type_tab)) + ossl_raise(ePKCS7Error, "unknown type \"%"PRIsVALUE"\"", sym); + if(strlen(p7_type_tab[i].name) != l) continue; + if(strcmp(p7_type_tab[i].name, s) == 0){ + ret = p7_type_tab[i].nid; + break; + } } return ret; @@ -461,7 +473,7 @@ ossl_pkcs7_set_type(VALUE self, VALUE type) GetPKCS7(self, p7); if(!PKCS7_set_type(p7, ossl_pkcs7_sym2typeid(type))) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); return type; } @@ -477,15 +489,15 @@ ossl_pkcs7_get_type(VALUE self) GetPKCS7(self, p7); if(PKCS7_type_is_signed(p7)) - return ID2SYM(rb_intern("signed")); + return ID2SYM(rb_intern("signed")); if(PKCS7_type_is_encrypted(p7)) - return ID2SYM(rb_intern("encrypted")); + return ID2SYM(rb_intern("encrypted")); if(PKCS7_type_is_enveloped(p7)) - return ID2SYM(rb_intern("enveloped")); + return ID2SYM(rb_intern("enveloped")); if(PKCS7_type_is_signedAndEnveloped(p7)) - return ID2SYM(rb_intern("signedAndEnveloped")); + return ID2SYM(rb_intern("signedAndEnveloped")); if(PKCS7_type_is_data(p7)) - return ID2SYM(rb_intern("data")); + return ID2SYM(rb_intern("data")); return Qnil; } @@ -496,9 +508,9 @@ ossl_pkcs7_set_detached(VALUE self, VALUE flag) GetPKCS7(self, p7); if(flag != Qtrue && flag != Qfalse) - ossl_raise(ePKCS7Error, "must specify a boolean"); + ossl_raise(ePKCS7Error, "must specify a boolean"); if(!PKCS7_set_detached(p7, flag == Qtrue ? 1 : 0)) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); return flag; } @@ -508,6 +520,8 @@ ossl_pkcs7_get_detached(VALUE self) { PKCS7 *p7; GetPKCS7(self, p7); + if (!PKCS7_type_is_signed(p7)) + return Qfalse; return PKCS7_get_detached(p7) ? Qtrue : Qfalse; } @@ -523,11 +537,14 @@ static VALUE ossl_pkcs7_set_cipher(VALUE self, VALUE cipher) { PKCS7 *pkcs7; + const EVP_CIPHER *ciph; + VALUE cipher_holder; GetPKCS7(self, pkcs7); - if (!PKCS7_set_cipher(pkcs7, ossl_evp_get_cipherbyname(cipher))) { - ossl_raise(ePKCS7Error, NULL); - } + ciph = ossl_evp_cipher_fetch(cipher, &cipher_holder); + if (!PKCS7_set_cipher(pkcs7, ciph)) + ossl_raise(ePKCS7Error, "PKCS7_set_cipher"); + rb_ivar_set(self, id_cipher_holder, cipher_holder); return cipher; } @@ -536,17 +553,18 @@ static VALUE ossl_pkcs7_add_signer(VALUE self, VALUE signer) { PKCS7 *pkcs7; - PKCS7_SIGNER_INFO *p7si; + PKCS7_SIGNER_INFO *si, *si_new; - p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */ GetPKCS7(self, pkcs7); - if (!PKCS7_add_signer(pkcs7, p7si)) { - PKCS7_SIGNER_INFO_free(p7si); - ossl_raise(ePKCS7Error, "Could not add signer."); - } - if (PKCS7_type_is_signed(pkcs7)){ - PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType, - V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)); + GetPKCS7si(signer, si); + + si_new = ossl_PKCS7_SIGNER_INFO_dup(si); + if (!si_new) + ossl_raise(ePKCS7Error, "PKCS7_SIGNER_INFO_dup"); + + if (PKCS7_add_signer(pkcs7, si_new) != 1) { + PKCS7_SIGNER_INFO_free(si_new); + ossl_raise(ePKCS7Error, "PKCS7_add_signer"); } return self; @@ -557,22 +575,17 @@ ossl_pkcs7_get_signer(VALUE self) { PKCS7 *pkcs7; STACK_OF(PKCS7_SIGNER_INFO) *sk; - PKCS7_SIGNER_INFO *si; int num, i; VALUE ary; GetPKCS7(self, pkcs7); - if (!(sk = PKCS7_get_signer_info(pkcs7))) { - OSSL_Debug("OpenSSL::PKCS7#get_signer_info == NULL!"); - return rb_ary_new(); - } - if ((num = sk_PKCS7_SIGNER_INFO_num(sk)) < 0) { - ossl_raise(ePKCS7Error, "Negative number of signers!"); - } - ary = rb_ary_new2(num); + if (!(sk = PKCS7_get_signer_info(pkcs7))) + return rb_ary_new(); + num = sk_PKCS7_SIGNER_INFO_num(sk); + ary = rb_ary_new_capa(num); for (i=0; i<num; i++) { - si = sk_PKCS7_SIGNER_INFO_value(sk, i); - rb_ary_push(ary, ossl_pkcs7si_new(si)); + PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sk, i); + rb_ary_push(ary, ossl_pkcs7si_new(si)); } return ary; @@ -582,13 +595,18 @@ static VALUE ossl_pkcs7_add_recipient(VALUE self, VALUE recip) { PKCS7 *pkcs7; - PKCS7_RECIP_INFO *ri; + PKCS7_RECIP_INFO *ri, *ri_new; - ri = DupPKCS7RecipientPtr(recip); /* NEED TO DUP */ GetPKCS7(self, pkcs7); - if (!PKCS7_add_recipient_info(pkcs7, ri)) { - PKCS7_RECIP_INFO_free(ri); - ossl_raise(ePKCS7Error, "Could not add recipient."); + GetPKCS7ri(recip, ri); + + ri_new = ossl_PKCS7_RECIP_INFO_dup(ri); + if (!ri_new) + ossl_raise(ePKCS7Error, "PKCS7_RECIP_INFO_dup"); + + if (PKCS7_add_recipient_info(pkcs7, ri_new) != 1) { + PKCS7_RECIP_INFO_free(ri_new); + ossl_raise(ePKCS7Error, "PKCS7_add_recipient_info"); } return self; @@ -599,24 +617,21 @@ ossl_pkcs7_get_recipient(VALUE self) { PKCS7 *pkcs7; STACK_OF(PKCS7_RECIP_INFO) *sk; - PKCS7_RECIP_INFO *si; int num, i; VALUE ary; GetPKCS7(self, pkcs7); if (PKCS7_type_is_enveloped(pkcs7)) - sk = pkcs7->d.enveloped->recipientinfo; + sk = pkcs7->d.enveloped->recipientinfo; else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) - sk = pkcs7->d.signed_and_enveloped->recipientinfo; + sk = pkcs7->d.signed_and_enveloped->recipientinfo; else sk = NULL; if (!sk) return rb_ary_new(); - if ((num = sk_PKCS7_RECIP_INFO_num(sk)) < 0) { - ossl_raise(ePKCS7Error, "Negative number of recipient!"); - } - ary = rb_ary_new2(num); + num = sk_PKCS7_RECIP_INFO_num(sk); + ary = rb_ary_new_capa(num); for (i=0; i<num; i++) { - si = sk_PKCS7_RECIP_INFO_value(sk, i); - rb_ary_push(ary, ossl_pkcs7ri_new(si)); + PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(sk, i); + rb_ary_push(ary, ossl_pkcs7ri_new(ri)); } return ary; @@ -631,7 +646,7 @@ ossl_pkcs7_add_certificate(VALUE self, VALUE cert) GetPKCS7(self, pkcs7); x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ if (!PKCS7_add_certificate(pkcs7, x509)){ - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } return self; @@ -647,13 +662,13 @@ pkcs7_get_certs(VALUE self) GetPKCS7(self, pkcs7); i = OBJ_obj2nid(pkcs7->type); switch(i){ - case NID_pkcs7_signed: + case NID_pkcs7_signed: certs = pkcs7->d.sign->cert; break; - case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_signedAndEnveloped: certs = pkcs7->d.signed_and_enveloped->cert; break; - default: + default: certs = NULL; } @@ -670,13 +685,13 @@ pkcs7_get_crls(VALUE self) GetPKCS7(self, pkcs7); i = OBJ_obj2nid(pkcs7->type); switch(i){ - case NID_pkcs7_signed: + case NID_pkcs7_signed: crls = pkcs7->d.sign->crl; break; - case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_signedAndEnveloped: crls = pkcs7->d.signed_and_enveloped->crl; break; - default: + default: crls = NULL; } @@ -696,7 +711,10 @@ ossl_pkcs7_set_certificates(VALUE self, VALUE ary) X509 *cert; certs = pkcs7_get_certs(self); - while((cert = sk_X509_pop(certs))) X509_free(cert); + if (certs) { + while ((cert = sk_X509_pop(certs))) + X509_free(cert); + } rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_certs_i, self); return ary; @@ -705,7 +723,10 @@ ossl_pkcs7_set_certificates(VALUE self, VALUE ary) static VALUE ossl_pkcs7_get_certificates(VALUE self) { - return ossl_x509_sk2ary(pkcs7_get_certs(self)); + STACK_OF(X509) *certs = pkcs7_get_certs(self); + if (!certs) + return Qnil; + return ossl_x509_sk2ary(certs); } static VALUE @@ -717,7 +738,7 @@ ossl_pkcs7_add_crl(VALUE self, VALUE crl) GetPKCS7(self, pkcs7); /* NO DUP needed! */ x509crl = GetX509CRLPtr(crl); if (!PKCS7_add_crl(pkcs7, x509crl)) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } return self; @@ -736,7 +757,10 @@ ossl_pkcs7_set_crls(VALUE self, VALUE ary) X509_CRL *crl; crls = pkcs7_get_crls(self); - while((crl = sk_X509_CRL_pop(crls))) X509_CRL_free(crl); + if (crls) { + while ((crl = sk_X509_CRL_pop(crls))) + X509_CRL_free(crl); + } rb_block_call(ary, rb_intern("each"), 0, 0, ossl_pkcs7_set_crls_i, self); return ary; @@ -745,7 +769,10 @@ ossl_pkcs7_set_crls(VALUE self, VALUE ary) static VALUE ossl_pkcs7_get_crls(VALUE self) { - return ossl_x509crl_sk2ary(pkcs7_get_crls(self)); + STACK_OF(X509_CRL) *crls = pkcs7_get_crls(self); + if (!crls) + return Qnil; + return ossl_x509crl_sk2ary(crls); } static VALUE @@ -758,7 +785,6 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self) BIO *in, *out; PKCS7 *p7; VALUE data; - const char *msg; GetPKCS7(self, p7); rb_scan_args(argc, argv, "22", &certs, &store, &indata, &flags); @@ -768,28 +794,30 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self) in = NIL_P(indata) ? NULL : ossl_obj2bio(&indata); if(NIL_P(certs)) x509s = NULL; else{ - x509s = ossl_protect_x509_ary2sk(certs, &status); - if(status){ - BIO_free(in); - rb_jump_tag(status); - } + x509s = ossl_protect_x509_ary2sk(certs, &status); + if(status){ + BIO_free(in); + rb_jump_tag(status); + } } if(!(out = BIO_new(BIO_s_mem()))){ - BIO_free(in); - sk_X509_pop_free(x509s, X509_free); - ossl_raise(ePKCS7Error, NULL); + BIO_free(in); + sk_X509_pop_free(x509s, X509_free); + ossl_raise(ePKCS7Error, NULL); } ok = PKCS7_verify(p7, x509s, x509st, in, out, flg); BIO_free(in); sk_X509_pop_free(x509s, X509_free); - if (ok < 0) ossl_raise(ePKCS7Error, "PKCS7_verify"); - msg = ERR_reason_error_string(ERR_peek_error()); - ossl_pkcs7_set_err_string(self, msg ? rb_str_new2(msg) : Qnil); - ossl_clear_error(); data = ossl_membio2str(out); ossl_pkcs7_set_data(self, data); - - return (ok == 1) ? Qtrue : Qfalse; + if (ok != 1) { + const char *msg = ERR_reason_error_string(ERR_peek_error()); + ossl_pkcs7_set_err_string(self, msg ? rb_str_new_cstr(msg) : Qnil); + ossl_clear_error(); + return Qfalse; + } + ossl_pkcs7_set_err_string(self, Qnil); + return Qtrue; } static VALUE @@ -809,10 +837,10 @@ ossl_pkcs7_decrypt(int argc, VALUE *argv, VALUE self) flg = NIL_P(flags) ? 0 : NUM2INT(flags); GetPKCS7(self, p7); if(!(out = BIO_new(BIO_s_mem()))) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); if(!PKCS7_decrypt(p7, key, x509, out, flg)){ - BIO_free(out); - ossl_raise(ePKCS7Error, NULL); + BIO_free(out); + ossl_raise(ePKCS7Error, NULL); } str = ossl_membio2str(out); /* out will be free */ @@ -825,30 +853,38 @@ ossl_pkcs7_add_data(VALUE self, VALUE data) PKCS7 *pkcs7; BIO *out, *in; char buf[4096]; - int len; + int len, ret; GetPKCS7(self, pkcs7); - if(PKCS7_type_is_signed(pkcs7)){ - if(!PKCS7_content_new(pkcs7, NID_pkcs7_data)) - ossl_raise(ePKCS7Error, NULL); + if (PKCS7_type_is_signed(pkcs7)) { + if (!PKCS7_content_new(pkcs7, NID_pkcs7_data)) + ossl_raise(ePKCS7Error, "PKCS7_content_new"); } in = ossl_obj2bio(&data); - if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err; - for(;;){ - if((len = BIO_read(in, buf, sizeof(buf))) <= 0) - break; - if(BIO_write(out, buf, len) != len) - goto err; + if (!(out = PKCS7_dataInit(pkcs7, NULL))) { + BIO_free(in); + ossl_raise(ePKCS7Error, "PKCS7_dataInit"); } - if(!PKCS7_dataFinal(pkcs7, out)) goto err; - ossl_pkcs7_set_data(self, Qnil); - - err: + for (;;) { + if ((len = BIO_read(in, buf, sizeof(buf))) <= 0) + break; + if (BIO_write(out, buf, len) != len) { + BIO_free_all(out); + BIO_free(in); + ossl_raise(ePKCS7Error, "BIO_write"); + } + } + if (BIO_flush(out) <= 0) { + BIO_free_all(out); + BIO_free(in); + ossl_raise(ePKCS7Error, "BIO_flush"); + } + ret = PKCS7_dataFinal(pkcs7, out); BIO_free_all(out); BIO_free(in); - if(ERR_peek_error()){ - ossl_raise(ePKCS7Error, NULL); - } + if (!ret) + ossl_raise(ePKCS7Error, "PKCS7_dataFinal"); + ossl_pkcs7_set_data(self, Qnil); return data; } @@ -863,17 +899,36 @@ ossl_pkcs7_to_der(VALUE self) GetPKCS7(self, pkcs7); if((len = i2d_PKCS7(pkcs7, NULL)) <= 0) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_PKCS7(pkcs7, &p) <= 0) - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); ossl_str_adjust(str, p); return str; } static VALUE +ossl_pkcs7_to_text(VALUE self) +{ + PKCS7 *pkcs7; + BIO *out; + VALUE str; + + GetPKCS7(self, pkcs7); + if(!(out = BIO_new(BIO_s_mem()))) + ossl_raise(ePKCS7Error, NULL); + if(!PKCS7_print_ctx(out, pkcs7, 0, NULL)) { + BIO_free(out); + ossl_raise(ePKCS7Error, NULL); + } + str = ossl_membio2str(out); + + return str; +} + +static VALUE ossl_pkcs7_to_pem(VALUE self) { PKCS7 *pkcs7; @@ -882,11 +937,11 @@ ossl_pkcs7_to_pem(VALUE self) GetPKCS7(self, pkcs7); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } if (!PEM_write_bio_PKCS7(out, pkcs7)) { - BIO_free(out); - ossl_raise(ePKCS7Error, NULL); + BIO_free(out); + ossl_raise(ePKCS7Error, NULL); } str = ossl_membio2str(out); @@ -904,7 +959,7 @@ ossl_pkcs7si_alloc(VALUE klass) obj = NewPKCS7si(klass); if (!(p7si = PKCS7_SIGNER_INFO_new())) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } SetPKCS7si(obj, p7si); @@ -918,14 +973,15 @@ ossl_pkcs7si_initialize(VALUE self, VALUE cert, VALUE key, VALUE digest) EVP_PKEY *pkey; X509 *x509; const EVP_MD *md; + VALUE md_holder; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); GetPKCS7si(self, p7si); - if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, (EVP_MD*)md))) { - ossl_raise(ePKCS7Error, NULL); - } + if (!(PKCS7_SIGNER_INFO_set(p7si, x509, pkey, md))) + ossl_raise(ePKCS7Error, "PKCS7_SIGNER_INFO_set"); + rb_ivar_set(self, id_md_holder, md_holder); return self; } @@ -959,10 +1015,10 @@ ossl_pkcs7si_get_signed_time(VALUE self) GetPKCS7si(self, p7si); if (!(asn1obj = PKCS7_get_signed_attribute(p7si, NID_pkcs9_signingTime))) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } if (asn1obj->type == V_ASN1_UTCTIME) { - return asn1time_to_time(asn1obj->value.utctime); + return asn1time_to_time(asn1obj->value.utctime); } /* * OR @@ -984,7 +1040,7 @@ ossl_pkcs7ri_alloc(VALUE klass) obj = NewPKCS7ri(klass); if (!(p7ri = PKCS7_RECIP_INFO_new())) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } SetPKCS7ri(obj, p7ri); @@ -1000,7 +1056,7 @@ ossl_pkcs7ri_initialize(VALUE self, VALUE cert) x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ GetPKCS7ri(self, p7ri); if (!PKCS7_RECIP_INFO_set(p7ri, x509)) { - ossl_raise(ePKCS7Error, NULL); + ossl_raise(ePKCS7Error, NULL); } return self; @@ -1043,11 +1099,6 @@ void Init_ossl_pkcs7(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - cPKCS7 = rb_define_class_under(mOSSL, "PKCS7", rb_cObject); ePKCS7Error = rb_define_class_under(cPKCS7, "PKCS7Error", eOSSLError); rb_define_singleton_method(cPKCS7, "read_smime", ossl_pkcs7_s_read_smime, 1); @@ -1082,13 +1133,13 @@ Init_ossl_pkcs7(void) rb_define_method(cPKCS7, "to_pem", ossl_pkcs7_to_pem, 0); rb_define_alias(cPKCS7, "to_s", "to_pem"); rb_define_method(cPKCS7, "to_der", ossl_pkcs7_to_der, 0); + rb_define_method(cPKCS7, "to_text", ossl_pkcs7_to_text, 0); cPKCS7Signer = rb_define_class_under(cPKCS7, "SignerInfo", rb_cObject); rb_define_const(cPKCS7, "Signer", cPKCS7Signer); rb_define_alloc_func(cPKCS7Signer, ossl_pkcs7si_alloc); rb_define_method(cPKCS7Signer, "initialize", ossl_pkcs7si_initialize,3); rb_define_method(cPKCS7Signer, "issuer", ossl_pkcs7si_get_issuer, 0); - rb_define_alias(cPKCS7Signer, "name", "issuer"); rb_define_method(cPKCS7Signer, "serial", ossl_pkcs7si_get_serial,0); rb_define_method(cPKCS7Signer,"signed_time",ossl_pkcs7si_get_signed_time,0); @@ -1111,4 +1162,7 @@ Init_ossl_pkcs7(void) DefPKCS7Const(BINARY); DefPKCS7Const(NOATTR); DefPKCS7Const(NOSMIMECAP); + + id_md_holder = rb_intern_const("EVP_MD_holder"); + id_cipher_holder = rb_intern_const("EVP_CIPHER_holder"); } diff --git a/ext/openssl/ossl_pkcs7.h b/ext/openssl/ossl_pkcs7.h index 139e00d640..140fda1835 100644 --- a/ext/openssl/ossl_pkcs7.h +++ b/ext/openssl/ossl_pkcs7.h @@ -5,16 +5,12 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_PKCS7_H_) #define _OSSL_PKCS7_H_ -extern VALUE cPKCS7; -extern VALUE cPKCS7Signer; -extern VALUE cPKCS7Recipient; -extern VALUE ePKCS7Error; - +VALUE ossl_pkcs7_new(PKCS7 *p7); void Init_ossl_pkcs7(void); #endif /* _OSSL_PKCS7_H_ */ diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index e1fffb2446..d2fd5b29c3 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -5,10 +5,14 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" +#ifdef OSSL_USE_ENGINE +# include <openssl/engine.h> +#endif + /* * Classes */ @@ -17,64 +21,6 @@ VALUE cPKey; VALUE ePKeyError; static ID id_private_q; -/* - * callback for generating keys - */ -static VALUE -call_check_ints0(VALUE arg) -{ - rb_thread_check_ints(); - return Qnil; -} - -static void * -call_check_ints(void *arg) -{ - int state; - rb_protect(call_check_ints0, Qnil, &state); - return (void *)(VALUE)state; -} - -int -ossl_generate_cb_2(int p, int n, BN_GENCB *cb) -{ - VALUE ary; - struct ossl_generate_cb_arg *arg; - int state; - - arg = (struct ossl_generate_cb_arg *)BN_GENCB_get_arg(cb); - if (arg->yield) { - ary = rb_ary_new2(2); - rb_ary_store(ary, 0, INT2NUM(p)); - rb_ary_store(ary, 1, INT2NUM(n)); - - /* - * can be break by raising exception or 'break' - */ - rb_protect(rb_yield, ary, &state); - if (state) { - arg->state = state; - return 0; - } - } - if (arg->interrupted) { - arg->interrupted = 0; - state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL); - if (state) { - arg->state = state; - return 0; - } - } - return 1; -} - -void -ossl_generate_cb_stop(void *ptr) -{ - struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr; - arg->interrupted = 1; -} - static void ossl_evp_pkey_free(void *ptr) { @@ -87,59 +33,184 @@ ossl_evp_pkey_free(void *ptr) const rb_data_type_t ossl_evp_pkey_type = { "OpenSSL/EVP_PKEY", { - 0, ossl_evp_pkey_free, + 0, ossl_evp_pkey_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE -pkey_new0(EVP_PKEY *pkey) +pkey_wrap0(VALUE arg) { - VALUE obj; - int type; - - if (!pkey || (type = EVP_PKEY_base_id(pkey)) == EVP_PKEY_NONE) - ossl_raise(rb_eRuntimeError, "pkey is empty"); + EVP_PKEY *pkey = (EVP_PKEY *)arg; + VALUE klass, obj; - switch (type) { + switch (EVP_PKEY_base_id(pkey)) { #if !defined(OPENSSL_NO_RSA) - case EVP_PKEY_RSA: - return ossl_rsa_new(pkey); + case EVP_PKEY_RSA: klass = cRSA; break; #endif #if !defined(OPENSSL_NO_DSA) - case EVP_PKEY_DSA: - return ossl_dsa_new(pkey); + case EVP_PKEY_DSA: klass = cDSA; break; #endif #if !defined(OPENSSL_NO_DH) - case EVP_PKEY_DH: - return ossl_dh_new(pkey); + case EVP_PKEY_DH: klass = cDH; break; #endif #if !defined(OPENSSL_NO_EC) - case EVP_PKEY_EC: - return ossl_ec_new(pkey); + case EVP_PKEY_EC: klass = cEC; break; #endif - default: - obj = NewPKey(cPKey); - SetPKey(obj, pkey); - return obj; + default: klass = cPKey; break; } + obj = rb_obj_alloc(klass); + RTYPEDDATA_DATA(obj) = pkey; + return obj; } VALUE -ossl_pkey_new(EVP_PKEY *pkey) +ossl_pkey_wrap(EVP_PKEY *pkey) { VALUE obj; int status; - obj = rb_protect((VALUE (*)(VALUE))pkey_new0, (VALUE)pkey, &status); + obj = rb_protect(pkey_wrap0, (VALUE)pkey, &status); if (status) { - EVP_PKEY_free(pkey); - rb_jump_tag(status); + EVP_PKEY_free(pkey); + rb_jump_tag(status); } return obj; } +#if OSSL_OPENSSL_PREREQ(3, 0, 0) +# include <openssl/decoder.h> + +static EVP_PKEY * +ossl_pkey_read(BIO *bio, const char *input_type, int selection, VALUE pass) +{ + void *ppass = (void *)pass; + OSSL_DECODER_CTX *dctx; + EVP_PKEY *pkey = NULL; + int pos = 0, pos2; + + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, input_type, NULL, NULL, + selection, NULL, NULL); + if (!dctx) + goto out; + if (selection == EVP_PKEY_KEYPAIR && + OSSL_DECODER_CTX_set_pem_password_cb(dctx, ossl_pem_passwd_cb, + ppass) != 1) + goto out; + while (1) { + if (OSSL_DECODER_from_bio(dctx, bio) == 1) + goto out; + if (BIO_eof(bio)) + break; + pos2 = BIO_tell(bio); + if (pos2 < 0 || pos2 <= pos) + break; + ossl_clear_error(); + pos = pos2; + } + out: + OSSL_BIO_reset(bio); + OSSL_DECODER_CTX_free(dctx); + return pkey; +} + +EVP_PKEY * +ossl_pkey_read_generic(BIO *bio, VALUE pass) +{ + EVP_PKEY *pkey = NULL; + /* First check DER, then check PEM. */ + const char *input_types[] = {"DER", "PEM"}; + int input_type_num = (int)(sizeof(input_types) / sizeof(char *)); + /* + * Non-zero selections to try to decode. + * + * See EVP_PKEY_fromdata(3) - Selections to see all the selections. + * + * This is a workaround for the decoder failing to decode or returning + * bogus keys with selection 0, if a key management provider is different + * from a decoder provider. The workaround is to avoid using selection 0. + * + * Affected OpenSSL versions: >= 3.1.0, <= 3.1.2, or >= 3.0.0, <= 3.0.10 + * Fixed OpenSSL versions: 3.2, next release of the 3.1.z and 3.0.z + * + * See https://github.com/openssl/openssl/pull/21519 for details. + * + * First check for private key formats (EVP_PKEY_KEYPAIR). This is to keep + * compatibility with ruby/openssl < 3.0 which decoded the following as a + * private key. + * + * $ openssl ecparam -name prime256v1 -genkey -outform PEM + * -----BEGIN EC PARAMETERS----- + * BggqhkjOPQMBBw== + * -----END EC PARAMETERS----- + * -----BEGIN EC PRIVATE KEY----- + * MHcCAQEEIAG8ugBbA5MHkqnZ9ujQF93OyUfL9tk8sxqM5Wv5tKg5oAoGCCqGSM49 + * AwEHoUQDQgAEVcjhJfkwqh5C7kGuhAf8XaAjVuG5ADwb5ayg/cJijCgs+GcXeedj + * 86avKpGH84DXUlB23C/kPt+6fXYlitUmXQ== + * -----END EC PRIVATE KEY----- + * + * While the first PEM block is a proper encoding of ECParameters, thus + * OSSL_DECODER_from_bio() would pick it up, ruby/openssl used to return + * the latter instead. Existing applications expect this behavior. + * + * Note that normally, the input is supposed to contain a single decodable + * PEM block only, so this special handling should not create a new problem. + * + * Note that we need to create the OSSL_DECODER_CTX variable each time when + * we use the different selection as a workaround. + * See https://github.com/openssl/openssl/issues/20657 for details. + */ + int selections[] = { + EVP_PKEY_KEYPAIR, + EVP_PKEY_KEY_PARAMETERS, + EVP_PKEY_PUBLIC_KEY + }; + int selection_num = (int)(sizeof(selections) / sizeof(int)); + int i, j; + + for (i = 0; i < input_type_num; i++) { + for (j = 0; j < selection_num; j++) { + pkey = ossl_pkey_read(bio, input_types[i], selections[j], pass); + if (pkey) { + goto out; + } + } + } + out: + return pkey; +} +#else +EVP_PKEY * +ossl_pkey_read_generic(BIO *bio, VALUE pass) +{ + void *ppass = (void *)pass; + EVP_PKEY *pkey; + + if ((pkey = d2i_PrivateKey_bio(bio, NULL))) + goto out; + OSSL_BIO_reset(bio); + if ((pkey = d2i_PKCS8PrivateKey_bio(bio, NULL, ossl_pem_passwd_cb, ppass))) + goto out; + OSSL_BIO_reset(bio); + if ((pkey = d2i_PUBKEY_bio(bio, NULL))) + goto out; + OSSL_BIO_reset(bio); + /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */ + if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, ppass))) + goto out; + OSSL_BIO_reset(bio); + if ((pkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL))) + goto out; + OSSL_BIO_reset(bio); + if ((pkey = PEM_read_bio_Parameters(bio, NULL))) + goto out; + + out: + return pkey; +} +#endif + /* * call-seq: * OpenSSL::PKey.read(string [, pwd ]) -> PKey @@ -149,7 +220,7 @@ ossl_pkey_new(EVP_PKEY *pkey) * instance of the appropriate PKey class. * * === Parameters - * * _string+ is a DER- or PEM-encoded string containing an arbitrary private + * * _string_ is a DER- or PEM-encoded string containing an arbitrary private * or public key. * * _io_ is an instance of IO containing a DER- or PEM-encoded * arbitrary private or public key. @@ -164,65 +235,318 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self) VALUE data, pass; rb_scan_args(argc, argv, "11", &data, &pass); - pass = ossl_pem_passwd_value(pass); - bio = ossl_obj2bio(&data); - if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) { - OSSL_BIO_reset(bio); - if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, (void *)pass))) { - OSSL_BIO_reset(bio); - if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) { - OSSL_BIO_reset(bio); - pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, (void *)pass); - } - } - } - + pkey = ossl_pkey_read_generic(bio, ossl_pem_passwd_value(pass)); BIO_free(bio); if (!pkey) - ossl_raise(ePKeyError, "Could not parse PKey"); + ossl_raise(ePKeyError, "Could not parse PKey"); + return ossl_pkey_wrap(pkey); +} + +static VALUE +pkey_ctx_apply_options_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, ctx_v)) +{ + VALUE key = rb_ary_entry(i, 0), value = rb_ary_entry(i, 1); + EVP_PKEY_CTX *ctx = (EVP_PKEY_CTX *)ctx_v; + + if (SYMBOL_P(key)) + key = rb_sym2str(key); + value = rb_String(value); + + if (EVP_PKEY_CTX_ctrl_str(ctx, StringValueCStr(key), StringValueCStr(value)) <= 0) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_ctrl_str(ctx, %+"PRIsVALUE", %+"PRIsVALUE")", + key, value); + return Qnil; +} + +static VALUE +pkey_ctx_apply_options0(VALUE args_v) +{ + VALUE *args = (VALUE *)args_v; + Check_Type(args[1], T_HASH); + + rb_block_call(args[1], rb_intern("each"), 0, NULL, + pkey_ctx_apply_options_i, args[0]); + return Qnil; +} + +static void +pkey_ctx_apply_options(EVP_PKEY_CTX *ctx, VALUE options, int *state) +{ + VALUE args[2]; + args[0] = (VALUE)ctx; + args[1] = options; + + rb_protect(pkey_ctx_apply_options0, (VALUE)args, state); +} + +struct pkey_blocking_generate_arg { + EVP_PKEY_CTX *ctx; + EVP_PKEY *pkey; + int state; + unsigned int yield: 1; + unsigned int genparam: 1; + unsigned int interrupted: 1; +}; + +static VALUE +pkey_gen_cb_yield(VALUE ctx_v) +{ + EVP_PKEY_CTX *ctx = (void *)ctx_v; + int i, info_num; + VALUE *argv; + + info_num = EVP_PKEY_CTX_get_keygen_info(ctx, -1); + argv = ALLOCA_N(VALUE, info_num); + for (i = 0; i < info_num; i++) + argv[i] = INT2NUM(EVP_PKEY_CTX_get_keygen_info(ctx, i)); + + return rb_yield_values2(info_num, argv); +} + +static VALUE +call_check_ints0(VALUE arg) +{ + rb_thread_check_ints(); + return Qnil; +} - return ossl_pkey_new(pkey); +static void * +call_check_ints(void *arg) +{ + int state; + rb_protect(call_check_ints0, Qnil, &state); + return (void *)(VALUE)state; } +static int +pkey_gen_cb(EVP_PKEY_CTX *ctx) +{ + struct pkey_blocking_generate_arg *arg = EVP_PKEY_CTX_get_app_data(ctx); + int state; + + if (arg->yield) { + rb_protect(pkey_gen_cb_yield, (VALUE)ctx, &state); + if (state) { + arg->state = state; + return 0; + } + } + if (arg->interrupted) { + arg->interrupted = 0; + state = (int)(VALUE)rb_thread_call_with_gvl(call_check_ints, NULL); + if (state) { + arg->state = state; + return 0; + } + } + return 1; +} + +static void +pkey_blocking_gen_stop(void *ptr) +{ + struct pkey_blocking_generate_arg *arg = ptr; + arg->interrupted = 1; +} + +static void * +pkey_blocking_gen(void *ptr) +{ + struct pkey_blocking_generate_arg *arg = ptr; + + if (arg->genparam && EVP_PKEY_paramgen(arg->ctx, &arg->pkey) <= 0) + return NULL; + if (!arg->genparam && EVP_PKEY_keygen(arg->ctx, &arg->pkey) <= 0) + return NULL; + return arg->pkey; +} + +static VALUE +pkey_generate(int argc, VALUE *argv, VALUE self, int genparam) +{ + EVP_PKEY_CTX *ctx; + VALUE alg, options; + struct pkey_blocking_generate_arg gen_arg = { 0 }; + int state; + + rb_scan_args(argc, argv, "11", &alg, &options); + if (rb_obj_is_kind_of(alg, cPKey)) { + EVP_PKEY *base_pkey; + + GetPKey(alg, base_pkey); + ctx = EVP_PKEY_CTX_new(base_pkey, NULL/* engine */); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + } + else { +#if OSSL_OPENSSL_PREREQ(3, 0, 0) + ctx = EVP_PKEY_CTX_new_from_name(NULL, StringValueCStr(alg), NULL); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_from_name"); +#else + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *tmpeng; + int pkey_id; + + StringValue(alg); + ameth = EVP_PKEY_asn1_find_str(&tmpeng, RSTRING_PTR(alg), + RSTRING_LENINT(alg)); + if (!ameth) + ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", alg); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); +#if !defined(OPENSSL_NO_ENGINE) + if (tmpeng) + ENGINE_finish(tmpeng); +#endif + + ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL/* engine */); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new_id"); +#endif + } + + if (genparam && EVP_PKEY_paramgen_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_paramgen_init"); + } + if (!genparam && EVP_PKEY_keygen_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_keygen_init"); + } + + if (!NIL_P(options)) { + pkey_ctx_apply_options(ctx, options, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + } + + gen_arg.genparam = genparam; + gen_arg.ctx = ctx; + gen_arg.yield = rb_block_given_p(); + EVP_PKEY_CTX_set_app_data(ctx, &gen_arg); + EVP_PKEY_CTX_set_cb(ctx, pkey_gen_cb); + if (gen_arg.yield) + pkey_blocking_gen(&gen_arg); + else + rb_thread_call_without_gvl(pkey_blocking_gen, &gen_arg, + pkey_blocking_gen_stop, &gen_arg); + EVP_PKEY_CTX_free(ctx); + if (!gen_arg.pkey) { + if (gen_arg.state) { + ossl_clear_error(); + rb_jump_tag(gen_arg.state); + } + else { + ossl_raise(ePKeyError, genparam ? "EVP_PKEY_paramgen" : "EVP_PKEY_keygen"); + } + } + + return ossl_pkey_wrap(gen_arg.pkey); +} + +/* + * call-seq: + * OpenSSL::PKey.generate_parameters(algo_name [, options]) -> pkey + * + * Generates new parameters for the algorithm. _algo_name_ is a String that + * represents the algorithm. The optional argument _options_ is a Hash that + * specifies the options specific to the algorithm. The order of the options + * can be important. + * + * A block can be passed optionally. The meaning of the arguments passed to + * the block varies depending on the implementation of the algorithm. The block + * may be called once or multiple times, or may not even be called. + * + * For the supported options, see the documentation for the 'openssl genpkey' + * utility command. + * + * == Example + * pkey = OpenSSL::PKey.generate_parameters("DSA", "dsa_paramgen_bits" => 2048) + * p pkey.p.num_bits #=> 2048 + */ +static VALUE +ossl_pkey_s_generate_parameters(int argc, VALUE *argv, VALUE self) +{ + return pkey_generate(argc, argv, self, 1); +} + +/* + * call-seq: + * OpenSSL::PKey.generate_key(algo_name [, options]) -> pkey + * OpenSSL::PKey.generate_key(pkey [, options]) -> pkey + * + * Generates a new key (pair). + * + * If a String is given as the first argument, it generates a new random key + * for the algorithm specified by the name just as ::generate_parameters does. + * If an OpenSSL::PKey::PKey is given instead, it generates a new random key + * for the same algorithm as the key, using the parameters the key contains. + * + * See ::generate_parameters for the details of _options_ and the given block. + * + * == Example + * pkey_params = OpenSSL::PKey.generate_parameters("DSA", "dsa_paramgen_bits" => 2048) + * pkey_params.priv_key #=> nil + * pkey = OpenSSL::PKey.generate_key(pkey_params) + * pkey.priv_key #=> #<OpenSSL::BN 6277... + */ +static VALUE +ossl_pkey_s_generate_key(int argc, VALUE *argv, VALUE self) +{ + return pkey_generate(argc, argv, self, 0); +} + +/* + * TODO: There is no convenient way to check the presence of public key + * components on OpenSSL 3.0. But since keys are immutable on 3.0, pkeys without + * these should only be created by OpenSSL::PKey.generate_parameters or by + * parsing DER-/PEM-encoded string. We would need another flag for that. + */ void ossl_pkey_check_public_key(const EVP_PKEY *pkey) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + if (EVP_PKEY_missing_parameters(pkey)) + ossl_raise(ePKeyError, "parameters missing"); +#else void *ptr; const BIGNUM *n, *e, *pubkey; if (EVP_PKEY_missing_parameters(pkey)) - ossl_raise(ePKeyError, "parameters missing"); + ossl_raise(ePKeyError, "parameters missing"); - /* OpenSSL < 1.1.0 takes non-const pointer */ - ptr = EVP_PKEY_get0((EVP_PKEY *)pkey); + ptr = EVP_PKEY_get0(pkey); switch (EVP_PKEY_base_id(pkey)) { case EVP_PKEY_RSA: - RSA_get0_key(ptr, &n, &e, NULL); - if (n && e) - return; - break; + RSA_get0_key(ptr, &n, &e, NULL); + if (n && e) + return; + break; case EVP_PKEY_DSA: - DSA_get0_key(ptr, &pubkey, NULL); - if (pubkey) - return; - break; + DSA_get0_key(ptr, &pubkey, NULL); + if (pubkey) + return; + break; case EVP_PKEY_DH: - DH_get0_key(ptr, &pubkey, NULL); - if (pubkey) - return; - break; + DH_get0_key(ptr, &pubkey, NULL); + if (pubkey) + return; + break; #if !defined(OPENSSL_NO_EC) case EVP_PKEY_EC: - if (EC_KEY_get0_public_key(ptr)) - return; - break; + if (EC_KEY_get0_public_key(ptr)) + return; + break; #endif default: - /* unsupported type; assuming ok */ - return; + /* unsupported type; assuming ok */ + return; } ossl_raise(ePKeyError, "public key missing"); +#endif } EVP_PKEY * @@ -240,12 +564,19 @@ GetPrivPKeyPtr(VALUE obj) { EVP_PKEY *pkey; - if (rb_funcallv(obj, id_private_q, 0, NULL) != Qtrue) { - ossl_raise(rb_eArgError, "Private key is needed."); - } GetPKey(obj, pkey); + if (OSSL_PKEY_IS_PRIVATE(obj)) + return pkey; + /* + * The EVP API does not provide a way to check if the EVP_PKEY has private + * components. Assuming it does... + */ + if (!rb_respond_to(obj, id_private_q)) + return pkey; + if (RTEST(rb_funcallv(obj, id_private_q, 0, NULL))) + return pkey; - return pkey; + rb_raise(rb_eArgError, "private key is needed"); } EVP_PKEY * @@ -265,16 +596,7 @@ DupPKeyPtr(VALUE obj) static VALUE ossl_pkey_alloc(VALUE klass) { - EVP_PKEY *pkey; - VALUE obj; - - obj = NewPKey(klass); - if (!(pkey = EVP_PKEY_new())) { - ossl_raise(ePKeyError, NULL); - } - SetPKey(obj, pkey); - - return obj; + return TypedData_Wrap_Struct(klass, &ossl_evp_pkey_type, NULL); } /* @@ -288,135 +610,1054 @@ static VALUE ossl_pkey_initialize(VALUE self) { if (rb_obj_is_instance_of(self, cPKey)) { - ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly"); + ossl_raise(rb_eTypeError, "OpenSSL::PKey::PKey can't be instantiated directly"); } return self; } +#ifdef HAVE_EVP_PKEY_DUP +/* :nodoc: */ +static VALUE +ossl_pkey_initialize_copy(VALUE self, VALUE other) +{ + EVP_PKEY *pkey, *pkey_other; + + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + TypedData_Get_Struct(other, EVP_PKEY, &ossl_evp_pkey_type, pkey_other); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); + if (pkey_other) { + pkey = EVP_PKEY_dup(pkey_other); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_dup"); + RTYPEDDATA_DATA(self) = pkey; + } + return self; +} +#endif + +#ifndef OSSL_USE_PROVIDER +static int +lookup_pkey_type(VALUE type) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id; + + StringValue(type); + /* + * XXX: EVP_PKEY_asn1_find_str() looks up a PEM type string. Should we use + * OBJ_txt2nid() instead (and then somehow check if the NID is an acceptable + * EVP_PKEY type)? + * It is probably fine, though, since it can handle all algorithms that + * support raw keys in 1.1.1: { X25519, X448, ED25519, ED448, HMAC }. + */ + ameth = EVP_PKEY_asn1_find_str(NULL, RSTRING_PTR(type), RSTRING_LENINT(type)); + if (!ameth) + ossl_raise(ePKeyError, "algorithm %"PRIsVALUE" not found", type); + EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth); + return pkey_id; +} +#endif + +/* + * call-seq: + * OpenSSL::PKey.new_raw_private_key(algo, string) -> PKey + * + * See the OpenSSL documentation for EVP_PKEY_new_raw_private_key() + */ + +static VALUE +ossl_pkey_new_raw_private_key(VALUE self, VALUE type, VALUE key) +{ + EVP_PKEY *pkey; + size_t keylen; + + StringValue(key); + keylen = RSTRING_LEN(key); + +#ifdef OSSL_USE_PROVIDER + pkey = EVP_PKEY_new_raw_private_key_ex(NULL, StringValueCStr(type), NULL, + (unsigned char *)RSTRING_PTR(key), + keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key_ex"); +#else + int pkey_id = lookup_pkey_type(type); + pkey = EVP_PKEY_new_raw_private_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_private_key"); +#endif + + return ossl_pkey_wrap(pkey); +} + +/* + * call-seq: + * OpenSSL::PKey.new_raw_public_key(algo, string) -> PKey + * + * See the OpenSSL documentation for EVP_PKEY_new_raw_public_key() + */ + +static VALUE +ossl_pkey_new_raw_public_key(VALUE self, VALUE type, VALUE key) +{ + EVP_PKEY *pkey; + size_t keylen; + + StringValue(key); + keylen = RSTRING_LEN(key); + +#ifdef OSSL_USE_PROVIDER + pkey = EVP_PKEY_new_raw_public_key_ex(NULL, StringValueCStr(type), NULL, + (unsigned char *)RSTRING_PTR(key), + keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key_ex"); +#else + int pkey_id = lookup_pkey_type(type); + pkey = EVP_PKEY_new_raw_public_key(pkey_id, NULL, (unsigned char *)RSTRING_PTR(key), keylen); + if (!pkey) + ossl_raise(ePKeyError, "EVP_PKEY_new_raw_public_key"); +#endif + + return ossl_pkey_wrap(pkey); +} + +/* + * call-seq: + * pkey.oid -> string + * + * Returns the short name of the OID associated with _pkey_. + */ +static VALUE +ossl_pkey_oid(VALUE self) +{ + EVP_PKEY *pkey; + int nid; + + GetPKey(self, pkey); + nid = EVP_PKEY_id(pkey); +#ifdef OSSL_USE_PROVIDER + if (nid == EVP_PKEY_KEYMGMT) + ossl_raise(ePKeyError, "EVP_PKEY_id"); +#endif + return rb_str_new_cstr(OBJ_nid2sn(nid)); +} + +/* + * call-seq: + * pkey.inspect -> string + * + * Returns a string describing the PKey object. + */ +static VALUE +ossl_pkey_inspect(VALUE self) +{ + EVP_PKEY *pkey; + + GetPKey(self, pkey); + VALUE str = rb_sprintf("#<%"PRIsVALUE":%p", + rb_obj_class(self), (void *)self); + int nid = EVP_PKEY_id(pkey); +#ifdef OSSL_USE_PROVIDER + if (nid != EVP_PKEY_KEYMGMT) +#endif + rb_str_catf(str, " oid=%s", OBJ_nid2sn(nid)); +#ifdef OSSL_USE_PROVIDER + rb_str_catf(str, " type_name=%s", EVP_PKEY_get0_type_name(pkey)); + const OSSL_PROVIDER *prov = EVP_PKEY_get0_provider(pkey); + if (prov) + rb_str_catf(str, " provider=%s", OSSL_PROVIDER_get0_name(prov)); +#endif + rb_str_catf(str, ">"); + return str; +} + +/* + * call-seq: + * pkey.to_text -> string + * + * Dumps key parameters, public key, and private key components contained in + * the key into a human-readable text. + * + * This is intended for debugging purpose. + * + * See also the man page EVP_PKEY_print_private(3). + */ +static VALUE +ossl_pkey_to_text(VALUE self) +{ + EVP_PKEY *pkey; + BIO *bio; + + GetPKey(self, pkey); + if (!(bio = BIO_new(BIO_s_mem()))) + ossl_raise(ePKeyError, "BIO_new"); + + if (EVP_PKEY_print_private(bio, pkey, 0, NULL) == 1) + goto out; + OSSL_BIO_reset(bio); + if (EVP_PKEY_print_public(bio, pkey, 0, NULL) == 1) + goto out; + OSSL_BIO_reset(bio); + if (EVP_PKEY_print_params(bio, pkey, 0, NULL) == 1) + goto out; + + BIO_free(bio); + ossl_raise(ePKeyError, "EVP_PKEY_print_params"); + + out: + return ossl_membio2str(bio); +} + +VALUE +ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, int to_der) +{ + EVP_PKEY *pkey; + VALUE cipher, pass, cipher_holder; + const EVP_CIPHER *enc = NULL; + BIO *bio; + + GetPKey(self, pkey); + rb_scan_args(argc, argv, "02", &cipher, &pass); + if (!NIL_P(cipher)) { + enc = ossl_evp_cipher_fetch(cipher, &cipher_holder); + pass = ossl_pem_passwd_value(pass); + } + + bio = BIO_new(BIO_s_mem()); + if (!bio) + ossl_raise(ePKeyError, "BIO_new"); + if (to_der) { + if (!i2d_PrivateKey_bio(bio, pkey)) { + BIO_free(bio); + ossl_raise(ePKeyError, "i2d_PrivateKey_bio"); + } + } + else { + if (!PEM_write_bio_PrivateKey_traditional(bio, pkey, enc, NULL, 0, + ossl_pem_passwd_cb, + (void *)pass)) { + BIO_free(bio); + ossl_raise(ePKeyError, "PEM_write_bio_PrivateKey_traditional"); + } + } + return ossl_membio2str(bio); +} + +static VALUE +do_pkcs8_export(int argc, VALUE *argv, VALUE self, int to_der) +{ + EVP_PKEY *pkey; + VALUE cipher, pass, cipher_holder; + const EVP_CIPHER *enc = NULL; + BIO *bio; + + GetPKey(self, pkey); + rb_scan_args(argc, argv, "02", &cipher, &pass); + if (argc > 0) { + /* + * TODO: EncryptedPrivateKeyInfo actually has more options. + * Should they be exposed? + */ + enc = ossl_evp_cipher_fetch(cipher, &cipher_holder); + pass = ossl_pem_passwd_value(pass); + } + + bio = BIO_new(BIO_s_mem()); + if (!bio) + ossl_raise(ePKeyError, "BIO_new"); + if (to_der) { + if (!i2d_PKCS8PrivateKey_bio(bio, pkey, enc, NULL, 0, + ossl_pem_passwd_cb, (void *)pass)) { + BIO_free(bio); + ossl_raise(ePKeyError, "i2d_PKCS8PrivateKey_bio"); + } + } + else { + if (!PEM_write_bio_PKCS8PrivateKey(bio, pkey, enc, NULL, 0, + ossl_pem_passwd_cb, (void *)pass)) { + BIO_free(bio); + ossl_raise(ePKeyError, "PEM_write_bio_PKCS8PrivateKey"); + } + } + return ossl_membio2str(bio); +} + +/* + * call-seq: + * pkey.private_to_der -> string + * pkey.private_to_der(cipher, password) -> string + * + * Serializes the private key to DER-encoded PKCS #8 format. If called without + * arguments, unencrypted PKCS #8 PrivateKeyInfo format is used. If called with + * a cipher name and a password, PKCS #8 EncryptedPrivateKeyInfo format with + * PBES2 encryption scheme is used. + */ +static VALUE +ossl_pkey_private_to_der(int argc, VALUE *argv, VALUE self) +{ + return do_pkcs8_export(argc, argv, self, 1); +} + +/* + * call-seq: + * pkey.private_to_pem -> string + * pkey.private_to_pem(cipher, password) -> string + * + * Serializes the private key to PEM-encoded PKCS #8 format. See #private_to_der + * for more details. + * + * An unencrypted PEM-encoded key will look like: + * + * -----BEGIN PRIVATE KEY----- + * [...] + * -----END PRIVATE KEY----- + * + * An encrypted PEM-encoded key will look like: + * + * -----BEGIN ENCRYPTED PRIVATE KEY----- + * [...] + * -----END ENCRYPTED PRIVATE KEY----- + */ +static VALUE +ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self) +{ + return do_pkcs8_export(argc, argv, self, 0); +} + /* * call-seq: - * pkey.sign(digest, data) -> String + * pkey.raw_private_key => string * - * To sign the String _data_, _digest_, an instance of OpenSSL::Digest, must - * be provided. The return value is again a String containing the signature. - * A PKeyError is raised should errors occur. - * Any previous state of the Digest instance is irrelevant to the signature - * outcome, the digest instance is reset to its initial state during the - * operation. + * See the OpenSSL documentation for EVP_PKEY_get_raw_private_key() + */ + +static VALUE +ossl_pkey_raw_private_key(VALUE self) +{ + EVP_PKEY *pkey; + VALUE str; + size_t len; + + GetPKey(self, pkey); + if (EVP_PKEY_get_raw_private_key(pkey, NULL, &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key"); + str = rb_str_new(NULL, len); + + if (EVP_PKEY_get_raw_private_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_private_key"); + + rb_str_set_len(str, len); + + return str; +} + +VALUE +ossl_pkey_export_spki(VALUE self, int to_der) +{ + EVP_PKEY *pkey; + BIO *bio; + + GetPKey(self, pkey); + ossl_pkey_check_public_key(pkey); + bio = BIO_new(BIO_s_mem()); + if (!bio) + ossl_raise(ePKeyError, "BIO_new"); + if (to_der) { + if (!i2d_PUBKEY_bio(bio, pkey)) { + BIO_free(bio); + ossl_raise(ePKeyError, "i2d_PUBKEY_bio"); + } + } + else { + if (!PEM_write_bio_PUBKEY(bio, pkey)) { + BIO_free(bio); + ossl_raise(ePKeyError, "PEM_write_bio_PUBKEY"); + } + } + return ossl_membio2str(bio); +} + +/* + * call-seq: + * pkey.public_to_der -> string + * + * Serializes the public key to DER-encoded X.509 SubjectPublicKeyInfo format. + */ +static VALUE +ossl_pkey_public_to_der(VALUE self) +{ + return ossl_pkey_export_spki(self, 1); +} + +/* + * call-seq: + * pkey.public_to_pem -> string + * + * Serializes the public key to PEM-encoded X.509 SubjectPublicKeyInfo format. + * + * A PEM-encoded key will look like: + * + * -----BEGIN PUBLIC KEY----- + * [...] + * -----END PUBLIC KEY----- + */ +static VALUE +ossl_pkey_public_to_pem(VALUE self) +{ + return ossl_pkey_export_spki(self, 0); +} + +/* + * call-seq: + * pkey.raw_public_key => string + * + * See the OpenSSL documentation for EVP_PKEY_get_raw_public_key() + */ + +static VALUE +ossl_pkey_raw_public_key(VALUE self) +{ + EVP_PKEY *pkey; + VALUE str; + size_t len; + + GetPKey(self, pkey); + if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key"); + str = rb_str_new(NULL, len); + + if (EVP_PKEY_get_raw_public_key(pkey, (unsigned char *)RSTRING_PTR(str), &len) != 1) + ossl_raise(ePKeyError, "EVP_PKEY_get_raw_public_key"); + + rb_str_set_len(str, len); + + return str; +} + +/* + * call-seq: + * pkey.compare?(another_pkey) -> true | false + * + * Used primarily to check if an OpenSSL::X509::Certificate#public_key compares to its private key. * * == Example - * data = 'Sign me!' - * digest = OpenSSL::Digest::SHA256.new - * pkey = OpenSSL::PKey::RSA.new(2048) - * signature = pkey.sign(digest, data) + * x509 = OpenSSL::X509::Certificate.new(pem_encoded_certificate) + * rsa_key = OpenSSL::PKey::RSA.new(pem_encoded_private_key) + * + * rsa_key.compare?(x509.public_key) => true | false + */ +static VALUE +ossl_pkey_compare(VALUE self, VALUE other) +{ + int ret; + EVP_PKEY *selfPKey; + EVP_PKEY *otherPKey; + + GetPKey(self, selfPKey); + GetPKey(other, otherPKey); + + /* Explicitly check the key type given EVP_PKEY_ASN1_METHOD(3) + * docs param_cmp could return any negative number. + */ + if (EVP_PKEY_id(selfPKey) != EVP_PKEY_id(otherPKey)) + ossl_raise(rb_eTypeError, "cannot match different PKey types"); + + ret = EVP_PKEY_eq(selfPKey, otherPKey); + + if (ret == 0) + return Qfalse; + else if (ret == 1) + return Qtrue; + else + ossl_raise(ePKeyError, "EVP_PKEY_eq"); +} + +/* + * call-seq: + * pkey.sign(digest, data [, options]) -> string + * + * Hashes and signs the +data+ using a message digest algorithm +digest+ and + * a private key +pkey+. + * + * See #verify for the verification operation. + * + * See also the man page EVP_DigestSign(3). + * + * +digest+:: + * A String that represents the message digest algorithm name, or +nil+ + * if the PKey type requires no digest algorithm. + * For backwards compatibility, this can be an instance of OpenSSL::Digest. + * Its state will not affect the signature. + * +data+:: + * A String. The data to be hashed and signed. + * +options+:: + * A Hash that contains algorithm specific control operations to \OpenSSL. + * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details. + * +options+ parameter was added in version 3.0. + * + * Example: + * data = "Sign me!" + * pkey = OpenSSL::PKey.generate_key("RSA", rsa_keygen_bits: 2048) + * signopts = { rsa_padding_mode: "pss" } + * signature = pkey.sign("SHA256", data, signopts) + * + * # Creates a copy of the RSA key pkey, but without the private components + * pub_key = pkey.public_key + * puts pub_key.verify("SHA256", signature, data, signopts) # => true */ static VALUE -ossl_pkey_sign(VALUE self, VALUE digest, VALUE data) +ossl_pkey_sign(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; - const EVP_MD *md; + VALUE digest, data, options, sig, md_holder; + const EVP_MD *md = NULL; EVP_MD_CTX *ctx; - unsigned int buf_len; - VALUE str; - int result; + EVP_PKEY_CTX *pctx; + size_t siglen; + int state; pkey = GetPrivPKeyPtr(self); - md = ossl_evp_get_digestbyname(digest); + rb_scan_args(argc, argv, "21", &digest, &data, &options); + if (!NIL_P(digest)) + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(data); - str = rb_str_new(0, EVP_PKEY_size(pkey)); ctx = EVP_MD_CTX_new(); if (!ctx) - ossl_raise(ePKeyError, "EVP_MD_CTX_new"); - if (!EVP_SignInit_ex(ctx, md, NULL)) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_SignInit_ex"); + ossl_raise(ePKeyError, "EVP_MD_CTX_new"); + if (EVP_DigestSignInit(ctx, &pctx, md, /* engine */NULL, pkey) < 1) { + EVP_MD_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_DigestSignInit"); } - if (!EVP_SignUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_SignUpdate"); + if (!NIL_P(options)) { + pkey_ctx_apply_options(pctx, options, &state); + if (state) { + EVP_MD_CTX_free(ctx); + rb_jump_tag(state); + } + } + if (EVP_DigestSign(ctx, NULL, &siglen, (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) < 1) { + EVP_MD_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_DigestSign"); + } + if (siglen > LONG_MAX) { + EVP_MD_CTX_free(ctx); + rb_raise(ePKeyError, "signature would be too large"); + } + sig = ossl_str_new(NULL, (long)siglen, &state); + if (state) { + EVP_MD_CTX_free(ctx); + rb_jump_tag(state); + } + if (EVP_DigestSign(ctx, (unsigned char *)RSTRING_PTR(sig), &siglen, + (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) < 1) { + EVP_MD_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_DigestSign"); } - result = EVP_SignFinal(ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey); EVP_MD_CTX_free(ctx); - if (!result) - ossl_raise(ePKeyError, "EVP_SignFinal"); - rb_str_set_len(str, buf_len); - - return str; + rb_str_set_len(sig, siglen); + return sig; } /* - * call-seq: - * pkey.verify(digest, signature, data) -> String + * call-seq: + * pkey.verify(digest, signature, data [, options]) -> true or false * - * To verify the String _signature_, _digest_, an instance of - * OpenSSL::Digest, must be provided to re-compute the message digest of the - * original _data_, also a String. The return value is +true+ if the - * signature is valid, +false+ otherwise. A PKeyError is raised should errors - * occur. - * Any previous state of the Digest instance is irrelevant to the validation - * outcome, the digest instance is reset to its initial state during the - * operation. + * Verifies the +signature+ for the +data+ using a message digest algorithm + * +digest+ and a public key +pkey+. * - * == Example - * data = 'Sign me!' - * digest = OpenSSL::Digest::SHA256.new - * pkey = OpenSSL::PKey::RSA.new(2048) - * signature = pkey.sign(digest, data) - * pub_key = pkey.public_key - * puts pub_key.verify(digest, signature, data) # => true + * Returns +true+ if the signature is successfully verified, +false+ otherwise. + * The caller must check the return value. + * + * See #sign for the signing operation and an example. + * + * See also the man page EVP_DigestVerify(3). + * + * +digest+:: + * See #sign. + * +signature+:: + * A String containing the signature to be verified. + * +data+:: + * See #sign. + * +options+:: + * See #sign. +options+ parameter was added in version 3.0. */ static VALUE -ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data) +ossl_pkey_verify(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; - const EVP_MD *md; + VALUE digest, sig, data, options, md_holder; + const EVP_MD *md = NULL; EVP_MD_CTX *ctx; - int siglen, result; + EVP_PKEY_CTX *pctx; + int state, ret; GetPKey(self, pkey); + rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options); ossl_pkey_check_public_key(pkey); - md = ossl_evp_get_digestbyname(digest); + if (!NIL_P(digest)) + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(sig); - siglen = RSTRING_LENINT(sig); StringValue(data); ctx = EVP_MD_CTX_new(); if (!ctx) - ossl_raise(ePKeyError, "EVP_MD_CTX_new"); - if (!EVP_VerifyInit_ex(ctx, md, NULL)) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_VerifyInit_ex"); + ossl_raise(ePKeyError, "EVP_MD_CTX_new"); + if (EVP_DigestVerifyInit(ctx, &pctx, md, /* engine */NULL, pkey) < 1) { + EVP_MD_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_DigestVerifyInit"); } - if (!EVP_VerifyUpdate(ctx, RSTRING_PTR(data), RSTRING_LEN(data))) { - EVP_MD_CTX_free(ctx); - ossl_raise(ePKeyError, "EVP_VerifyUpdate"); + if (!NIL_P(options)) { + pkey_ctx_apply_options(pctx, options, &state); + if (state) { + EVP_MD_CTX_free(ctx); + rb_jump_tag(state); + } } - result = EVP_VerifyFinal(ctx, (unsigned char *)RSTRING_PTR(sig), siglen, pkey); + ret = EVP_DigestVerify(ctx, (unsigned char *)RSTRING_PTR(sig), + RSTRING_LEN(sig), (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)); EVP_MD_CTX_free(ctx); - switch (result) { - case 0: - ossl_clear_error(); - return Qfalse; - case 1: - return Qtrue; - default: - ossl_raise(ePKeyError, "EVP_VerifyFinal"); + if (ret < 0) + ossl_raise(ePKeyError, "EVP_DigestVerify"); + if (ret) + return Qtrue; + else { + ossl_clear_error(); + return Qfalse; } } /* + * call-seq: + * pkey.sign_raw(digest, data [, options]) -> string + * + * Signs +data+ using a private key +pkey+. Unlike #sign, +data+ will not be + * hashed by +digest+ automatically. + * + * See #verify_raw for the verification operation. + * + * Added in version 3.0. See also the man page EVP_PKEY_sign(3). + * + * +digest+:: + * A String that represents the message digest algorithm name, or +nil+ + * if the PKey type requires no digest algorithm. + * Although this method will not hash +data+ with it, this parameter may still + * be required depending on the signature algorithm. + * +data+:: + * A String. The data to be signed. + * +options+:: + * A Hash that contains algorithm specific control operations to \OpenSSL. + * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details. + * + * Example: + * data = "Sign me!" + * hash = OpenSSL::Digest.digest("SHA256", data) + * pkey = OpenSSL::PKey.generate_key("RSA", rsa_keygen_bits: 2048) + * signopts = { rsa_padding_mode: "pss" } + * signature = pkey.sign_raw("SHA256", hash, signopts) + * + * # Creates a copy of the RSA key pkey, but without the private components + * pub_key = pkey.public_key + * puts pub_key.verify_raw("SHA256", signature, hash, signopts) # => true + */ +static VALUE +ossl_pkey_sign_raw(int argc, VALUE *argv, VALUE self) +{ + EVP_PKEY *pkey; + VALUE digest, data, options, sig, md_holder; + const EVP_MD *md = NULL; + EVP_PKEY_CTX *ctx; + size_t outlen; + int state; + + GetPKey(self, pkey); + rb_scan_args(argc, argv, "21", &digest, &data, &options); + if (!NIL_P(digest)) + md = ossl_evp_md_fetch(digest, &md_holder); + StringValue(data); + + ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + if (EVP_PKEY_sign_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_sign_init"); + } + if (md && EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_CTX_set_signature_md"); + } + if (!NIL_P(options)) { + pkey_ctx_apply_options(ctx, options, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + } + if (EVP_PKEY_sign(ctx, NULL, &outlen, (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_sign"); + } + if (outlen > LONG_MAX) { + EVP_PKEY_CTX_free(ctx); + rb_raise(ePKeyError, "signature would be too large"); + } + sig = ossl_str_new(NULL, (long)outlen, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + if (EVP_PKEY_sign(ctx, (unsigned char *)RSTRING_PTR(sig), &outlen, + (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_sign"); + } + EVP_PKEY_CTX_free(ctx); + rb_str_set_len(sig, outlen); + return sig; +} + +/* + * call-seq: + * pkey.verify_raw(digest, signature, data [, options]) -> true or false + * + * Verifies the +signature+ for the +data+ using a public key +pkey+. Unlike + * #verify, this method will not hash +data+ with +digest+ automatically. + * + * Returns +true+ if the signature is successfully verified, +false+ otherwise. + * The caller must check the return value. + * + * See #sign_raw for the signing operation and an example code. + * + * Added in version 3.0. See also the man page EVP_PKEY_verify(3). + * + * +signature+:: + * A String containing the signature to be verified. + */ +static VALUE +ossl_pkey_verify_raw(int argc, VALUE *argv, VALUE self) +{ + EVP_PKEY *pkey; + VALUE digest, sig, data, options, md_holder; + const EVP_MD *md = NULL; + EVP_PKEY_CTX *ctx; + int state, ret; + + GetPKey(self, pkey); + rb_scan_args(argc, argv, "31", &digest, &sig, &data, &options); + ossl_pkey_check_public_key(pkey); + if (!NIL_P(digest)) + md = ossl_evp_md_fetch(digest, &md_holder); + StringValue(sig); + StringValue(data); + + ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + if (EVP_PKEY_verify_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_verify_init"); + } + if (md && EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_CTX_set_signature_md"); + } + if (!NIL_P(options)) { + pkey_ctx_apply_options(ctx, options, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + } + ret = EVP_PKEY_verify(ctx, (unsigned char *)RSTRING_PTR(sig), + RSTRING_LEN(sig), + (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)); + EVP_PKEY_CTX_free(ctx); + if (ret < 0) + ossl_raise(ePKeyError, "EVP_PKEY_verify"); + + if (ret) + return Qtrue; + else { + ossl_clear_error(); + return Qfalse; + } +} + +/* + * call-seq: + * pkey.verify_recover(digest, signature [, options]) -> string + * + * Recovers the signed data from +signature+ using a public key +pkey+. Not all + * signature algorithms support this operation. + * + * Added in version 3.0. See also the man page EVP_PKEY_verify_recover(3). + * + * +signature+:: + * A String containing the signature to be verified. + */ +static VALUE +ossl_pkey_verify_recover(int argc, VALUE *argv, VALUE self) +{ + EVP_PKEY *pkey; + VALUE digest, sig, options, out, md_holder; + const EVP_MD *md = NULL; + EVP_PKEY_CTX *ctx; + int state; + size_t outlen; + + GetPKey(self, pkey); + rb_scan_args(argc, argv, "21", &digest, &sig, &options); + ossl_pkey_check_public_key(pkey); + if (!NIL_P(digest)) + md = ossl_evp_md_fetch(digest, &md_holder); + StringValue(sig); + + ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + if (EVP_PKEY_verify_recover_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_verify_recover_init"); + } + if (md && EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_CTX_set_signature_md"); + } + if (!NIL_P(options)) { + pkey_ctx_apply_options(ctx, options, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + } + if (EVP_PKEY_verify_recover(ctx, NULL, &outlen, + (unsigned char *)RSTRING_PTR(sig), + RSTRING_LEN(sig)) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_verify_recover"); + } + out = ossl_str_new(NULL, (long)outlen, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + if (EVP_PKEY_verify_recover(ctx, (unsigned char *)RSTRING_PTR(out), &outlen, + (unsigned char *)RSTRING_PTR(sig), + RSTRING_LEN(sig)) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_verify_recover"); + } + EVP_PKEY_CTX_free(ctx); + rb_str_set_len(out, outlen); + return out; +} + +/* + * call-seq: + * pkey.derive(peer_pkey) -> string + * + * Derives a shared secret from _pkey_ and _peer_pkey_. _pkey_ must contain + * the private components, _peer_pkey_ must contain the public components. + */ +static VALUE +ossl_pkey_derive(int argc, VALUE *argv, VALUE self) +{ + EVP_PKEY *pkey, *peer_pkey; + EVP_PKEY_CTX *ctx; + VALUE peer_pkey_obj, str; + size_t keylen; + int state; + + GetPKey(self, pkey); + rb_scan_args(argc, argv, "1", &peer_pkey_obj); + GetPKey(peer_pkey_obj, peer_pkey); + + ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + if (EVP_PKEY_derive_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_derive_init"); + } + if (EVP_PKEY_derive_set_peer(ctx, peer_pkey) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_derive_set_peer"); + } + if (EVP_PKEY_derive(ctx, NULL, &keylen) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_derive"); + } + if (keylen > LONG_MAX) + rb_raise(ePKeyError, "derived key would be too large"); + str = ossl_str_new(NULL, (long)keylen, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + if (EVP_PKEY_derive(ctx, (unsigned char *)RSTRING_PTR(str), &keylen) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_derive"); + } + EVP_PKEY_CTX_free(ctx); + rb_str_set_len(str, keylen); + return str; +} + +/* + * call-seq: + * pkey.encrypt(data [, options]) -> string + * + * Performs a public key encryption operation using +pkey+. + * + * See #decrypt for the reverse operation. + * + * Added in version 3.0. See also the man page EVP_PKEY_encrypt(3). + * + * +data+:: + * A String to be encrypted. + * +options+:: + * A Hash that contains algorithm specific control operations to \OpenSSL. + * See OpenSSL's man page EVP_PKEY_CTX_ctrl_str(3) for details. + * + * Example: + * pkey = OpenSSL::PKey.generate_key("RSA", rsa_keygen_bits: 2048) + * data = "secret data" + * encrypted = pkey.encrypt(data, rsa_padding_mode: "oaep") + * decrypted = pkey.decrypt(data, rsa_padding_mode: "oaep") + * p decrypted #=> "secret data" + */ +static VALUE +ossl_pkey_encrypt(int argc, VALUE *argv, VALUE self) +{ + EVP_PKEY *pkey; + EVP_PKEY_CTX *ctx; + VALUE data, options, str; + size_t outlen; + int state; + + GetPKey(self, pkey); + rb_scan_args(argc, argv, "11", &data, &options); + StringValue(data); + + ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + if (EVP_PKEY_encrypt_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_encrypt_init"); + } + if (!NIL_P(options)) { + pkey_ctx_apply_options(ctx, options, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + } + if (EVP_PKEY_encrypt(ctx, NULL, &outlen, + (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_encrypt"); + } + if (outlen > LONG_MAX) { + EVP_PKEY_CTX_free(ctx); + rb_raise(ePKeyError, "encrypted data would be too large"); + } + str = ossl_str_new(NULL, (long)outlen, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + if (EVP_PKEY_encrypt(ctx, (unsigned char *)RSTRING_PTR(str), &outlen, + (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_encrypt"); + } + EVP_PKEY_CTX_free(ctx); + rb_str_set_len(str, outlen); + return str; +} + +/* + * call-seq: + * pkey.decrypt(data [, options]) -> string + * + * Performs a public key decryption operation using +pkey+. + * + * See #encrypt for a description of the parameters and an example. + * + * Added in version 3.0. See also the man page EVP_PKEY_decrypt(3). + */ +static VALUE +ossl_pkey_decrypt(int argc, VALUE *argv, VALUE self) +{ + EVP_PKEY *pkey; + EVP_PKEY_CTX *ctx; + VALUE data, options, str; + size_t outlen; + int state; + + GetPKey(self, pkey); + rb_scan_args(argc, argv, "11", &data, &options); + StringValue(data); + + ctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); + if (!ctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + if (EVP_PKEY_decrypt_init(ctx) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_decrypt_init"); + } + if (!NIL_P(options)) { + pkey_ctx_apply_options(ctx, options, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + } + if (EVP_PKEY_decrypt(ctx, NULL, &outlen, + (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_decrypt"); + } + if (outlen > LONG_MAX) { + EVP_PKEY_CTX_free(ctx); + rb_raise(ePKeyError, "decrypted data would be too large"); + } + str = ossl_str_new(NULL, (long)outlen, &state); + if (state) { + EVP_PKEY_CTX_free(ctx); + rb_jump_tag(state); + } + if (EVP_PKEY_decrypt(ctx, (unsigned char *)RSTRING_PTR(str), &outlen, + (unsigned char *)RSTRING_PTR(data), + RSTRING_LEN(data)) <= 0) { + EVP_PKEY_CTX_free(ctx); + ossl_raise(ePKeyError, "EVP_PKEY_decrypt"); + } + EVP_PKEY_CTX_free(ctx); + rb_str_set_len(str, outlen); + return str; +} + +/* * INIT */ void Init_ossl_pkey(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - /* Document-module: OpenSSL::PKey * * == Asymmetric Public Key Algorithms @@ -472,7 +1713,16 @@ Init_ossl_pkey(void) /* Document-class: OpenSSL::PKey::PKeyError * - *Raised when errors occur during PKey#sign or PKey#verify. + * Raised when errors occur during PKey#sign or PKey#verify. + * + * Before version 4.0.0, OpenSSL::PKey::PKeyError had the following + * subclasses. These subclasses have been removed and the constants are + * now defined as aliases of OpenSSL::PKey::PKeyError. + * + * * OpenSSL::PKey::DHError + * * OpenSSL::PKey::DSAError + * * OpenSSL::PKey::ECError + * * OpenSSL::PKey::RSAError */ ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); @@ -488,12 +1738,37 @@ Init_ossl_pkey(void) cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1); + rb_define_module_function(mPKey, "generate_parameters", ossl_pkey_s_generate_parameters, -1); + rb_define_module_function(mPKey, "generate_key", ossl_pkey_s_generate_key, -1); + rb_define_module_function(mPKey, "new_raw_private_key", ossl_pkey_new_raw_private_key, 2); + rb_define_module_function(mPKey, "new_raw_public_key", ossl_pkey_new_raw_public_key, 2); rb_define_alloc_func(cPKey, ossl_pkey_alloc); rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0); +#ifdef HAVE_EVP_PKEY_DUP + rb_define_method(cPKey, "initialize_copy", ossl_pkey_initialize_copy, 1); +#else + rb_undef_method(cPKey, "initialize_copy"); +#endif + rb_define_method(cPKey, "oid", ossl_pkey_oid, 0); + rb_define_method(cPKey, "inspect", ossl_pkey_inspect, 0); + rb_define_method(cPKey, "to_text", ossl_pkey_to_text, 0); + rb_define_method(cPKey, "private_to_der", ossl_pkey_private_to_der, -1); + rb_define_method(cPKey, "private_to_pem", ossl_pkey_private_to_pem, -1); + rb_define_method(cPKey, "public_to_der", ossl_pkey_public_to_der, 0); + rb_define_method(cPKey, "public_to_pem", ossl_pkey_public_to_pem, 0); + rb_define_method(cPKey, "raw_private_key", ossl_pkey_raw_private_key, 0); + rb_define_method(cPKey, "raw_public_key", ossl_pkey_raw_public_key, 0); + rb_define_method(cPKey, "compare?", ossl_pkey_compare, 1); - rb_define_method(cPKey, "sign", ossl_pkey_sign, 2); - rb_define_method(cPKey, "verify", ossl_pkey_verify, 3); + rb_define_method(cPKey, "sign", ossl_pkey_sign, -1); + rb_define_method(cPKey, "verify", ossl_pkey_verify, -1); + rb_define_method(cPKey, "sign_raw", ossl_pkey_sign_raw, -1); + rb_define_method(cPKey, "verify_raw", ossl_pkey_verify_raw, -1); + rb_define_method(cPKey, "verify_recover", ossl_pkey_verify_recover, -1); + rb_define_method(cPKey, "derive", ossl_pkey_derive, -1); + rb_define_method(cPKey, "encrypt", ossl_pkey_encrypt, -1); + rb_define_method(cPKey, "decrypt", ossl_pkey_decrypt, -1); id_private_q = rb_intern("private?"); diff --git a/ext/openssl/ossl_pkey.h b/ext/openssl/ossl_pkey.h index 0db59305f7..023361b90f 100644 --- a/ext/openssl/ossl_pkey.h +++ b/ext/openssl/ossl_pkey.h @@ -5,237 +5,189 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ -#if !defined(_OSSL_PKEY_H_) -#define _OSSL_PKEY_H_ +#if !defined(OSSL_PKEY_H) +#define OSSL_PKEY_H extern VALUE mPKey; extern VALUE cPKey; extern VALUE ePKeyError; extern const rb_data_type_t ossl_evp_pkey_type; -#define OSSL_PKEY_SET_PRIVATE(obj) rb_iv_set((obj), "private", Qtrue) -#define OSSL_PKEY_SET_PUBLIC(obj) rb_iv_set((obj), "private", Qfalse) -#define OSSL_PKEY_IS_PRIVATE(obj) (rb_iv_get((obj), "private") == Qtrue) +/* For ENGINE */ +#define OSSL_PKEY_SET_PRIVATE(obj) rb_ivar_set((obj), rb_intern("private"), Qtrue) +#define OSSL_PKEY_IS_PRIVATE(obj) (rb_attr_get((obj), rb_intern("private")) == Qtrue) -#define NewPKey(klass) \ - TypedData_Wrap_Struct((klass), &ossl_evp_pkey_type, 0) -#define SetPKey(obj, pkey) do { \ - if (!(pkey)) { \ - rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!"); \ - } \ - RTYPEDDATA_DATA(obj) = (pkey); \ - OSSL_PKEY_SET_PUBLIC(obj); \ -} while (0) #define GetPKey(obj, pkey) do {\ TypedData_Get_Struct((obj), EVP_PKEY, &ossl_evp_pkey_type, (pkey)); \ if (!(pkey)) { \ - rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!");\ + rb_raise(rb_eRuntimeError, "PKEY wasn't initialized!");\ } \ } while (0) -struct ossl_generate_cb_arg { - int yield; - int interrupted; - int state; -}; -int ossl_generate_cb_2(int p, int n, BN_GENCB *cb); -void ossl_generate_cb_stop(void *ptr); - -VALUE ossl_pkey_new(EVP_PKEY *); +/* Takes ownership of the EVP_PKEY */ +VALUE ossl_pkey_wrap(EVP_PKEY *); void ossl_pkey_check_public_key(const EVP_PKEY *); +EVP_PKEY *ossl_pkey_read_generic(BIO *, VALUE); EVP_PKEY *GetPKeyPtr(VALUE); EVP_PKEY *DupPKeyPtr(VALUE); EVP_PKEY *GetPrivPKeyPtr(VALUE); + +/* + * Serializes _self_ in X.509 SubjectPublicKeyInfo format and returns the + * resulting String. Sub-classes use this when overriding #to_der. + */ +VALUE ossl_pkey_export_spki(VALUE self, int to_der); +/* + * Serializes the private key _self_ in the traditional private key format + * and returns the resulting String. Sub-classes use this when overriding + * #to_der. + */ +VALUE ossl_pkey_export_traditional(int argc, VALUE *argv, VALUE self, + int to_der); + void Init_ossl_pkey(void); /* * RSA */ extern VALUE cRSA; -extern VALUE eRSAError; - -VALUE ossl_rsa_new(EVP_PKEY *); void Init_ossl_rsa(void); /* * DSA */ extern VALUE cDSA; -extern VALUE eDSAError; - -VALUE ossl_dsa_new(EVP_PKEY *); void Init_ossl_dsa(void); /* * DH */ extern VALUE cDH; -extern VALUE eDHError; - -VALUE ossl_dh_new(EVP_PKEY *); void Init_ossl_dh(void); /* * EC */ extern VALUE cEC; -extern VALUE eECError; -extern VALUE cEC_GROUP; -extern VALUE eEC_GROUP; -extern VALUE cEC_POINT; -extern VALUE eEC_POINT; VALUE ossl_ec_new(EVP_PKEY *); void Init_ossl_ec(void); -#define OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, _name, _get) \ -/* \ - * call-seq: \ - * _keytype##.##_name -> aBN \ - */ \ -static VALUE ossl_##_keytype##_get_##_name(VALUE self) \ -{ \ - _type *obj; \ - const BIGNUM *bn; \ - \ - Get##_type(self, obj); \ - _get; \ - if (bn == NULL) \ - return Qnil; \ - return ossl_bn_new(bn); \ +#define OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, _name, _get) \ +/* \ + * call-seq: \ + * _keytype##.##_name -> aBN \ + */ \ +static VALUE ossl_##_keytype##_get_##_name(VALUE self) \ +{ \ + const _type *obj; \ + const BIGNUM *bn; \ + \ + Get##_type(self, obj); \ + _get; \ + if (bn == NULL) \ + return Qnil; \ + return ossl_bn_new(bn); \ } -#define OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \ - _type##_get0_##_group(obj, &bn, NULL, NULL)) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ - _type##_get0_##_group(obj, NULL, &bn, NULL)) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a3, \ - _type##_get0_##_group(obj, NULL, NULL, &bn)) - -#define OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \ - _type##_get0_##_group(obj, &bn, NULL)) \ - OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ - _type##_get0_##_group(obj, NULL, &bn)) - -#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ -/* \ - * call-seq: \ - * _keytype##.set_##_group(a1, a2, a3) -> self \ - */ \ +#define OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \ + _type##_get0_##_group(obj, &bn, NULL, NULL)) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ + _type##_get0_##_group(obj, NULL, &bn, NULL)) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a3, \ + _type##_get0_##_group(obj, NULL, NULL, &bn)) + +#define OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a1, \ + _type##_get0_##_group(obj, &bn, NULL)) \ + OSSL_PKEY_BN_DEF_GETTER0(_keytype, _type, a2, \ + _type##_get0_##_group(obj, NULL, &bn)) + +#ifndef OSSL_HAVE_IMMUTABLE_PKEY +#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ +/* \ + * call-seq: \ + * _keytype##.set_##_group(a1, a2, a3) -> self \ + */ \ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \ -{ \ - _type *obj; \ - BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\ - BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\ - BIGNUM *bn3 = NULL, *orig_bn3 = NIL_P(v3) ? NULL : GetBNPtr(v3);\ - \ - Get##_type(self, obj); \ - if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \ - (orig_bn2 && !(bn2 = BN_dup(orig_bn2))) || \ - (orig_bn3 && !(bn3 = BN_dup(orig_bn3)))) { \ - BN_clear_free(bn1); \ - BN_clear_free(bn2); \ - BN_clear_free(bn3); \ - ossl_raise(eBNError, NULL); \ - } \ - \ - if (!_type##_set0_##_group(obj, bn1, bn2, bn3)) { \ - BN_clear_free(bn1); \ - BN_clear_free(bn2); \ - BN_clear_free(bn3); \ - ossl_raise(ePKeyError, #_type"_set0_"#_group); \ - } \ - return self; \ +{ \ + _type *obj; \ + BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\ + BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\ + BIGNUM *bn3 = NULL, *orig_bn3 = NIL_P(v3) ? NULL : GetBNPtr(v3);\ + \ + Get##_type(self, obj); \ + if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \ + (orig_bn2 && !(bn2 = BN_dup(orig_bn2))) || \ + (orig_bn3 && !(bn3 = BN_dup(orig_bn3)))) { \ + BN_clear_free(bn1); \ + BN_clear_free(bn2); \ + BN_clear_free(bn3); \ + ossl_raise(ePKeyError, "BN_dup"); \ + } \ + \ + if (!_type##_set0_##_group(obj, bn1, bn2, bn3)) { \ + BN_clear_free(bn1); \ + BN_clear_free(bn2); \ + BN_clear_free(bn3); \ + ossl_raise(ePKeyError, #_type"_set0_"#_group); \ + } \ + return self; \ } -#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ -/* \ - * call-seq: \ - * _keytype##.set_##_group(a1, a2) -> self \ - */ \ +#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ +/* \ + * call-seq: \ + * _keytype##.set_##_group(a1, a2) -> self \ + */ \ static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \ -{ \ - _type *obj; \ - BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\ - BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\ - \ - Get##_type(self, obj); \ - if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \ - (orig_bn2 && !(bn2 = BN_dup(orig_bn2)))) { \ - BN_clear_free(bn1); \ - BN_clear_free(bn2); \ - ossl_raise(eBNError, NULL); \ - } \ - \ - if (!_type##_set0_##_group(obj, bn1, bn2)) { \ - BN_clear_free(bn1); \ - BN_clear_free(bn2); \ - ossl_raise(ePKeyError, #_type"_set0_"#_group); \ - } \ - return self; \ +{ \ + _type *obj; \ + BIGNUM *bn1 = NULL, *orig_bn1 = NIL_P(v1) ? NULL : GetBNPtr(v1);\ + BIGNUM *bn2 = NULL, *orig_bn2 = NIL_P(v2) ? NULL : GetBNPtr(v2);\ + \ + Get##_type(self, obj); \ + if ((orig_bn1 && !(bn1 = BN_dup(orig_bn1))) || \ + (orig_bn2 && !(bn2 = BN_dup(orig_bn2)))) { \ + BN_clear_free(bn1); \ + BN_clear_free(bn2); \ + ossl_raise(ePKeyError, "BN_dup"); \ + } \ + \ + if (!_type##_set0_##_group(obj, bn1, bn2)) { \ + BN_clear_free(bn1); \ + BN_clear_free(bn2); \ + ossl_raise(ePKeyError, #_type"_set0_"#_group); \ + } \ + return self; \ } - -#define OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, _name) \ -/* \ - * call-seq: \ - * _keytype##.##_name = bn -> bn \ - */ \ -static VALUE ossl_##_keytype##_set_##_name(VALUE self, VALUE bignum) \ -{ \ - _type *obj; \ - BIGNUM *bn; \ - \ - rb_warning("#"#_name"= is deprecated; use #set_"#_group); \ - Get##_type(self, obj); \ - if (NIL_P(bignum)) { \ - BN_clear_free(obj->_name); \ - obj->_name = NULL; \ - return Qnil; \ - } \ - \ - bn = GetBNPtr(bignum); \ - if (obj->_name == NULL) \ - obj->_name = BN_new(); \ - if (obj->_name == NULL) \ - ossl_raise(eBNError, NULL); \ - if (BN_copy(obj->_name, bn) == NULL) \ - ossl_raise(eBNError, NULL); \ - return bignum; \ +#else +#define OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ +static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2, VALUE v3) \ +{ \ + rb_raise(ePKeyError, \ + #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \ } -#if defined(HAVE_OPAQUE_OPENSSL) /* OpenSSL 1.1.0 */ -#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) +#define OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ +static VALUE ossl_##_keytype##_set_##_group(VALUE self, VALUE v1, VALUE v2) \ +{ \ + rb_raise(ePKeyError, \ + #_keytype"#set_"#_group"= is incompatible with OpenSSL 3.0"); \ +} +#endif -#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) +#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \ + OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ + OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) -#define DEF_OSSL_PKEY_BN(class, keytype, name) \ - rb_define_method((class), #name, ossl_##keytype##_get_##name, 0) +#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \ + OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ + OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) -#else -#define OSSL_PKEY_BN_DEF3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_GETTER3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_SETTER3(_keytype, _type, _group, a1, a2, a3) \ - OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a1) \ - OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a2) \ - OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a3) - -#define OSSL_PKEY_BN_DEF2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_GETTER2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_SETTER2(_keytype, _type, _group, a1, a2) \ - OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a1) \ - OSSL_PKEY_BN_DEF_SETTER_OLD(_keytype, _type, _group, a2) - -#define DEF_OSSL_PKEY_BN(class, keytype, name) do { \ - rb_define_method((class), #name, ossl_##keytype##_get_##name, 0);\ - rb_define_method((class), #name "=", ossl_##keytype##_set_##name, 1);\ -} while (0) -#endif /* HAVE_OPAQUE_OPENSSL */ +#define DEF_OSSL_PKEY_BN(class, keytype, name) \ + rb_define_method((class), #name, ossl_##keytype##_get_##name, 0) -#endif /* _OSSL_PKEY_H_ */ +#endif /* OSSL_PKEY_H */ diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index bf4e3f9322..3f2975c5a3 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,232 +14,129 @@ #define GetPKeyDH(obj, pkey) do { \ GetPKey((obj), (pkey)); \ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \ + ossl_raise(rb_eRuntimeError, "THIS IS NOT A DH!") ; \ } \ } while (0) #define GetDH(obj, dh) do { \ EVP_PKEY *_pkey; \ GetPKeyDH((obj), _pkey); \ (dh) = EVP_PKEY_get0_DH(_pkey); \ + if ((dh) == NULL) \ + ossl_raise(ePKeyError, "failed to get DH from EVP_PKEY"); \ } while (0) /* * Classes */ VALUE cDH; -VALUE eDHError; - -/* - * Public - */ -static VALUE -dh_instance(VALUE klass, DH *dh) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!dh) { - return Qfalse; - } - obj = NewPKey(klass); - if (!(pkey = EVP_PKEY_new())) { - return Qfalse; - } - if (!EVP_PKEY_assign_DH(pkey, dh)) { - EVP_PKEY_free(pkey); - return Qfalse; - } - SetPKey(obj, pkey); - - return obj; -} - -VALUE -ossl_dh_new(EVP_PKEY *pkey) -{ - VALUE obj; - - if (!pkey) { - obj = dh_instance(cDH, DH_new()); - } else { - obj = NewPKey(cDH); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) { - ossl_raise(rb_eTypeError, "Not a DH key!"); - } - SetPKey(obj, pkey); - } - if (obj == Qfalse) { - ossl_raise(eDHError, NULL); - } - - return obj; -} /* * Private */ -struct dh_blocking_gen_arg { - DH *dh; - int size; - int gen; - BN_GENCB *cb; - int result; -}; - -static void * -dh_blocking_gen(void *arg) -{ - struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg; - gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb); - return 0; -} - -static DH * -dh_generate(int size, int gen) -{ - struct ossl_generate_cb_arg cb_arg = { 0 }; - struct dh_blocking_gen_arg gen_arg; - DH *dh = DH_new(); - BN_GENCB *cb = BN_GENCB_new(); - - if (!dh || !cb) { - DH_free(dh); - BN_GENCB_free(cb); - return NULL; - } - - if (rb_block_given_p()) - cb_arg.yield = 1; - BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg); - gen_arg.dh = dh; - gen_arg.size = size; - gen_arg.gen = gen; - gen_arg.cb = cb; - if (cb_arg.yield == 1) { - /* we cannot release GVL when callback proc is supplied */ - dh_blocking_gen(&gen_arg); - } else { - /* there's a chance to unblock */ - rb_thread_call_without_gvl(dh_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); - } - - BN_GENCB_free(cb); - if (!gen_arg.result) { - DH_free(dh); - if (cb_arg.state) { - /* Clear OpenSSL error queue before re-raising. */ - ossl_clear_error(); - rb_jump_tag(cb_arg.state); - } - return NULL; - } - - if (!DH_generate_key(dh)) { - DH_free(dh); - return NULL; - } - - return dh; -} - -/* - * call-seq: - * DH.generate(size [, generator]) -> dh - * - * Creates a new DH instance from scratch by generating the private and public - * components alike. - * - * === Parameters - * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. - * * _generator_ is a small number > 1, typically 2 or 5. - * - */ -static VALUE -ossl_dh_s_generate(int argc, VALUE *argv, VALUE klass) -{ - DH *dh ; - int g = 2; - VALUE size, gen, obj; - - if (rb_scan_args(argc, argv, "11", &size, &gen) == 2) { - g = NUM2INT(gen); - } - dh = dh_generate(NUM2INT(size), g); - obj = dh_instance(klass, dh); - if (obj == Qfalse) { - DH_free(dh); - ossl_raise(eDHError, NULL); - } - - return obj; -} - /* * call-seq: * DH.new -> dh * DH.new(string) -> dh * DH.new(size [, generator]) -> dh * - * Either generates a DH instance from scratch or by reading already existing - * DH parameters from _string_. Note that when reading a DH instance from - * data that was encoded from a DH instance by using DH#to_pem or DH#to_der - * the result will *not* contain a public/private key pair yet. This needs to - * be generated using DH#generate_key! first. + * Creates a new instance of OpenSSL::PKey::DH. + * + * If called without arguments, an empty instance without any parameter or key + * components is created. Use #set_pqg to manually set the parameters afterwards + * (and optionally #set_key to set private and public key components). + * This form is not compatible with OpenSSL 3.0 or later. + * + * If a String is given, tries to parse it as a DER- or PEM- encoded parameters. + * See also OpenSSL::PKey.read which can parse keys of any kinds. + * + * The DH.new(size [, generator]) form is an alias of DH.generate. + * + * +string+:: + * A String that contains the DER or PEM encoded key. + * +size+:: + * See DH.generate. + * +generator+:: + * See DH.generate. + * + * Examples: + * # Creating an instance from scratch + * # Note that this is deprecated and will result in ArgumentError when + * # using OpenSSL 3.0 or later. + * dh = OpenSSL::PKey::DH.new + * dh.set_pqg(bn_p, nil, bn_g) * - * === Parameters - * * _size_ is an integer representing the desired key size. Keys smaller than 1024 bits should be considered insecure. - * * _generator_ is a small number > 1, typically 2 or 5. - * * _string_ contains the DER or PEM encoded key. + * # Generating a parameters and a key pair + * dh = OpenSSL::PKey::DH.new(2048) # An alias of OpenSSL::PKey::DH.generate(2048) * - * === Examples - * DH.new # -> dh - * DH.new(1024) # -> dh - * DH.new(1024, 5) # -> dh - * #Reading DH parameters - * dh = DH.new(File.read('parameters.pem')) # -> dh, but no public/private key yet - * dh.generate_key! # -> dh with public and private key + * # Reading DH parameters from a PEM-encoded string + * dh_params = OpenSSL::PKey::DH.new(File.read('parameters.pem')) # loads parameters only + * dh = OpenSSL::PKey.generate_key(dh_params) # generates a key pair */ static VALUE ossl_dh_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; + int type; DH *dh; - int g = 2; - BIO *in; - VALUE arg, gen; - - GetPKey(self, pkey); - if(rb_scan_args(argc, argv, "02", &arg, &gen) == 0) { - dh = DH_new(); - } - else if (RB_INTEGER_TYPE_P(arg)) { - if (!NIL_P(gen)) { - g = NUM2INT(gen); - } - if (!(dh = dh_generate(NUM2INT(arg), g))) { - ossl_raise(eDHError, NULL); - } + BIO *in = NULL; + VALUE arg; + + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); + + /* The DH.new(size, generator) form is handled by lib/openssl/pkey.rb */ + if (rb_scan_args(argc, argv, "01", &arg) == 0) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(rb_eArgError, "OpenSSL::PKey::DH.new cannot be called " \ + "without arguments; pkeys are immutable with OpenSSL 3.0"); +#else + dh = DH_new(); + if (!dh) + ossl_raise(ePKeyError, "DH_new"); + goto legacy; +#endif } - else { - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(&arg); - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); - if (!dh){ - OSSL_BIO_reset(in); - dh = d2i_DHparams_bio(in, NULL); - } - BIO_free(in); - if (!dh) { - ossl_raise(eDHError, NULL); - } + + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); + + /* + * On OpenSSL <= 1.1.1 and current versions of LibreSSL, the generic + * routine does not support DER-encoded parameters + */ + dh = d2i_DHparams_bio(in, NULL); + if (dh) + goto legacy; + OSSL_BIO_reset(in); + + pkey = ossl_pkey_read_generic(in, Qnil); + BIO_free(in); + if (!pkey) + ossl_raise(ePKeyError, "could not parse pkey"); + + type = EVP_PKEY_base_id(pkey); + if (type != EVP_PKEY_DH) { + EVP_PKEY_free(pkey); + rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type)); } - if (!EVP_PKEY_assign_DH(pkey, dh)) { - DH_free(dh); - ossl_raise(eDHError, NULL); + RTYPEDDATA_DATA(self) = pkey; + return self; + + legacy: + BIO_free(in); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) { + EVP_PKEY_free(pkey); + DH_free(dh); + ossl_raise(ePKeyError, "EVP_PKEY_assign_DH"); } + RTYPEDDATA_DATA(self) = pkey; return self; } +#ifndef HAVE_EVP_PKEY_DUP +/* :nodoc: */ static VALUE ossl_dh_initialize_copy(VALUE self, VALUE other) { @@ -247,31 +144,38 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) DH *dh, *dh_other; const BIGNUM *pub, *priv; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eDHError, "DH already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); GetDH(other, dh_other); dh = DHparams_dup(dh_other); if (!dh) - ossl_raise(eDHError, "DHparams_dup"); - EVP_PKEY_assign_DH(pkey, dh); + ossl_raise(ePKeyError, "DHparams_dup"); DH_get0_key(dh_other, &pub, &priv); if (pub) { - BIGNUM *pub2 = BN_dup(pub); - BIGNUM *priv2 = BN_dup(priv); + BIGNUM *pub2 = BN_dup(pub); + BIGNUM *priv2 = BN_dup(priv); if (!pub2 || (priv && !priv2)) { - BN_clear_free(pub2); - BN_clear_free(priv2); - ossl_raise(eDHError, "BN_dup"); - } - DH_set0_key(dh, pub2, priv2); + BN_clear_free(pub2); + BN_clear_free(priv2); + ossl_raise(ePKeyError, "BN_dup"); + } + DH_set0_key(dh, pub2, priv2); } + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_DH(pkey, dh) != 1) { + EVP_PKEY_free(pkey); + DH_free(dh); + ossl_raise(ePKeyError, "EVP_PKEY_assign_DH"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#endif /* * call-seq: @@ -283,7 +187,7 @@ ossl_dh_initialize_copy(VALUE self, VALUE other) static VALUE ossl_dh_is_public(VALUE self) { - DH *dh; + OSSL_3_const DH *dh; const BIGNUM *bn; GetDH(self, dh); @@ -302,14 +206,14 @@ ossl_dh_is_public(VALUE self) static VALUE ossl_dh_is_private(VALUE self) { - DH *dh; + OSSL_3_const DH *dh; const BIGNUM *bn; GetDH(self, dh); DH_get0_key(dh, NULL, &bn); #if !defined(OPENSSL_NO_ENGINE) - return (bn || DH_get0_engine(dh)) ? Qtrue : Qfalse; + return (bn || DH_get0_engine((DH *)dh)) ? Qtrue : Qfalse; #else return bn ? Qtrue : Qfalse; #endif @@ -321,24 +225,35 @@ ossl_dh_is_private(VALUE self) * dh.to_pem -> aString * dh.to_s -> aString * - * Encodes this DH to its PEM encoding. Note that any existing per-session - * public/private keys will *not* get encoded, just the Diffie-Hellman - * parameters will be encoded. + * Serializes the DH parameters to a PEM-encoding. + * + * Note that any existing per-session public/private keys will *not* get + * encoded, just the Diffie-Hellman parameters will be encoded. + * + * PEM-encoded parameters will look like: + * + * -----BEGIN DH PARAMETERS----- + * [...] + * -----END DH PARAMETERS----- + * + * See also #public_to_pem (X.509 SubjectPublicKeyInfo) and + * #private_to_pem (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for + * serialization with the private or public key components. */ static VALUE ossl_dh_export(VALUE self) { - DH *dh; + OSSL_3_const DH *dh; BIO *out; VALUE str; GetDH(self, dh); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDHError, NULL); + ossl_raise(ePKeyError, NULL); } if (!PEM_write_bio_DHparams(out, dh)) { - BIO_free(out); - ossl_raise(eDHError, NULL); + BIO_free(out); + ossl_raise(ePKeyError, NULL); } str = ossl_membio2str(out); @@ -349,26 +264,30 @@ ossl_dh_export(VALUE self) * call-seq: * dh.to_der -> aString * - * Encodes this DH to its DER encoding. Note that any existing per-session - * public/private keys will *not* get encoded, just the Diffie-Hellman - * parameters will be encoded. - + * Serializes the DH parameters to a DER-encoding + * + * Note that any existing per-session public/private keys will *not* get + * encoded, just the Diffie-Hellman parameters will be encoded. + * + * See also #public_to_der (X.509 SubjectPublicKeyInfo) and + * #private_to_der (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) for + * serialization with the private or public key components. */ static VALUE ossl_dh_to_der(VALUE self) { - DH *dh; + OSSL_3_const DH *dh; unsigned char *p; long len; VALUE str; GetDH(self, dh); if((len = i2d_DHparams(dh, NULL)) <= 0) - ossl_raise(eDHError, NULL); + ossl_raise(ePKeyError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_DHparams(dh, &p) < 0) - ossl_raise(eDHError, NULL); + ossl_raise(ePKeyError, NULL); ossl_str_adjust(str, p); return str; @@ -376,180 +295,43 @@ ossl_dh_to_der(VALUE self) /* * call-seq: - * dh.params -> hash - * - * Stores all parameters of key to the hash - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dh_get_params(VALUE self) -{ - DH *dh; - VALUE hash; - const BIGNUM *p, *q, *g, *pub_key, *priv_key; - - GetDH(self, dh); - DH_get0_pqg(dh, &p, &q, &g); - DH_get0_key(dh, &pub_key, &priv_key); - - hash = rb_hash_new(); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key)); - - return hash; -} - -/* - * call-seq: - * dh.to_text -> aString - * - * Prints all parameters of key to buffer - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dh_to_text(VALUE self) -{ - DH *dh; - BIO *out; - VALUE str; - - GetDH(self, dh); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDHError, NULL); - } - if (!DHparams_print(out, dh)) { - BIO_free(out); - ossl_raise(eDHError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * dh.public_key -> aDH - * - * Returns a new DH instance that carries just the public information, i.e. - * the prime _p_ and the generator _g_, but no public/private key yet. Such - * a pair may be generated using DH#generate_key!. The "public key" needed - * for a key exchange with DH#compute_key is considered as per-session - * information and may be retrieved with DH#pub_key once a key pair has - * been generated. - * If the current instance already contains private information (and thus a - * valid public/private key pair), this information will no longer be present - * in the new instance generated by DH#public_key. This feature is helpful for - * publishing the Diffie-Hellman parameters without leaking any of the private - * per-session information. - * - * === Example - * dh = OpenSSL::PKey::DH.new(2048) # has public and private key set - * public_key = dh.public_key # contains only prime and generator - * parameters = public_key.to_der # it's safe to publish this - */ -static VALUE -ossl_dh_to_public_key(VALUE self) -{ - DH *orig_dh, *dh; - VALUE obj; - - GetDH(self, orig_dh); - dh = DHparams_dup(orig_dh); /* err check perfomed by dh_instance */ - obj = dh_instance(rb_obj_class(self), dh); - if (obj == Qfalse) { - DH_free(dh); - ossl_raise(eDHError, NULL); - } - - return obj; -} - -/* - * call-seq: * dh.params_ok? -> true | false * * Validates the Diffie-Hellman parameters associated with this instance. * It checks whether a safe prime and a suitable generator are used. If this * is not the case, +false+ is returned. + * + * See also the man page EVP_PKEY_param_check(3). */ static VALUE ossl_dh_check_params(VALUE self) { - DH *dh; - int codes; - - GetDH(self, dh); - if (!DH_check(dh, &codes)) { - return Qfalse; - } - - return codes == 0 ? Qtrue : Qfalse; -} + int ret; +#ifdef HAVE_EVP_PKEY_CHECK + EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx; -/* - * call-seq: - * dh.generate_key! -> self - * - * Generates a private and public key unless a private key already exists. - * If this DH instance was generated from public DH parameters (e.g. by - * encoding the result of DH#public_key), then this method needs to be - * called first in order to generate the per-session keys before performing - * the actual key exchange. - * - * === Example - * dh = OpenSSL::PKey::DH.new(2048) - * public_key = dh.public_key #contains no private/public key yet - * public_key.generate_key! - * puts public_key.private? # => true - */ -static VALUE -ossl_dh_generate_key(VALUE self) -{ + GetPKey(self, pkey); + pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); + if (!pctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + ret = EVP_PKEY_param_check(pctx); + EVP_PKEY_CTX_free(pctx); +#else DH *dh; + int codes; GetDH(self, dh); - if (!DH_generate_key(dh)) - ossl_raise(eDHError, "Failed to generate key"); - return self; -} - -/* - * call-seq: - * dh.compute_key(pub_bn) -> aString - * - * Returns a String containing a shared secret computed from the other party's public value. - * See DH_compute_key() for further information. - * - * === Parameters - * * _pub_bn_ is a OpenSSL::BN, *not* the DH instance returned by - * DH#public_key as that contains the DH parameters only. - */ -static VALUE -ossl_dh_compute_key(VALUE self, VALUE pub) -{ - DH *dh; - const BIGNUM *pub_key, *dh_p; - VALUE str; - int len; + ret = DH_check(dh, &codes) == 1 && codes == 0; +#endif - GetDH(self, dh); - DH_get0_pqg(dh, &dh_p, NULL, NULL); - if (!dh_p) - ossl_raise(eDHError, "incomplete DH"); - pub_key = GetBNPtr(pub); - len = DH_size(dh); - str = rb_str_new(0, len); - if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) { - ossl_raise(eDHError, NULL); + if (ret == 1) + return Qtrue; + else { + /* DH_check_ex() will put error entry on failure */ + ossl_clear_error(); + return Qfalse; } - rb_str_set_len(str, len); - - return str; } /* @@ -575,19 +357,6 @@ OSSL_PKEY_BN_DEF2(dh, DH, key, pub_key, priv_key) void Init_ossl_dh(void) { -#if 0 - mPKey = rb_define_module_under(mOSSL, "PKey"); - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); -#endif - - /* Document-class: OpenSSL::PKey::DHError - * - * Generic exception that is raised if an operation on a DH PKey - * fails unexpectedly or in case an instantiation of an instance of DH - * fails due to non-conformant input data. - */ - eDHError = rb_define_class_under(mPKey, "DHError", ePKeyError); /* Document-class: OpenSSL::PKey::DH * * An implementation of the Diffie-Hellman key exchange protocol based on @@ -606,30 +375,33 @@ Init_ossl_dh(void) * The per-session private key, an OpenSSL::BN. * * === Example of a key exchange - * dh1 = OpenSSL::PKey::DH.new(2048) - * der = dh1.public_key.to_der #you may send this publicly to the participating party - * dh2 = OpenSSL::PKey::DH.new(der) - * dh2.generate_key! #generate the per-session key pair - * symm_key1 = dh1.compute_key(dh2.pub_key) - * symm_key2 = dh2.compute_key(dh1.pub_key) + * # you may send the parameters (der) and own public key (pub1) publicly + * # to the participating party + * dh1 = OpenSSL::PKey::DH.new(2048) + * der = dh1.to_der + * pub1 = dh1.pub_key + * + * # the other party generates its per-session key pair + * dhparams = OpenSSL::PKey::DH.new(der) + * dh2 = OpenSSL::PKey.generate_key(dhparams) + * pub2 = dh2.pub_key * - * puts symm_key1 == symm_key2 # => true + * symm_key1 = dh1.compute_key(pub2) + * symm_key2 = dh2.compute_key(pub1) + * puts symm_key1 == symm_key2 # => true */ cDH = rb_define_class_under(mPKey, "DH", cPKey); - rb_define_singleton_method(cDH, "generate", ossl_dh_s_generate, -1); rb_define_method(cDH, "initialize", ossl_dh_initialize, -1); +#ifndef HAVE_EVP_PKEY_DUP rb_define_method(cDH, "initialize_copy", ossl_dh_initialize_copy, 1); +#endif rb_define_method(cDH, "public?", ossl_dh_is_public, 0); rb_define_method(cDH, "private?", ossl_dh_is_private, 0); - rb_define_method(cDH, "to_text", ossl_dh_to_text, 0); rb_define_method(cDH, "export", ossl_dh_export, 0); rb_define_alias(cDH, "to_pem", "export"); rb_define_alias(cDH, "to_s", "export"); rb_define_method(cDH, "to_der", ossl_dh_to_der, 0); - rb_define_method(cDH, "public_key", ossl_dh_to_public_key, 0); rb_define_method(cDH, "params_ok?", ossl_dh_check_params, 0); - rb_define_method(cDH, "generate_key!", ossl_dh_generate_key, 0); - rb_define_method(cDH, "compute_key", ossl_dh_compute_key, 1); DEF_OSSL_PKEY_BN(cDH, dh, p); DEF_OSSL_PKEY_BN(cDH, dh, q); @@ -638,8 +410,6 @@ Init_ossl_dh(void) DEF_OSSL_PKEY_BN(cDH, dh, priv_key); rb_define_method(cDH, "set_pqg", ossl_dh_set_pqg, 3); rb_define_method(cDH, "set_key", ossl_dh_set_key, 2); - - rb_define_method(cDH, "params", ossl_dh_get_params, 0); } #else /* defined NO_DH */ diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index 56cc9dd4f1..041646a058 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,17 +14,19 @@ #define GetPKeyDSA(obj, pkey) do { \ GetPKey((obj), (pkey)); \ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A DSA!"); \ + ossl_raise(rb_eRuntimeError, "THIS IS NOT A DSA!"); \ } \ } while (0) #define GetDSA(obj, dsa) do { \ EVP_PKEY *_pkey; \ GetPKeyDSA((obj), _pkey); \ (dsa) = EVP_PKEY_get0_DSA(_pkey); \ + if ((dsa) == NULL) \ + ossl_raise(ePKeyError, "failed to get DSA from EVP_PKEY"); \ } while (0) static inline int -DSA_HAS_PRIVATE(DSA *dsa) +DSA_HAS_PRIVATE(OSSL_3_const DSA *dsa) { const BIGNUM *bn; DSA_get0_key(dsa, NULL, &bn); @@ -32,7 +34,7 @@ DSA_HAS_PRIVATE(DSA *dsa) } static inline int -DSA_PRIVATE(VALUE obj, DSA *dsa) +DSA_PRIVATE(VALUE obj, OSSL_3_const DSA *dsa) { return DSA_HAS_PRIVATE(dsa) || OSSL_PKEY_IS_PRIVATE(obj); } @@ -41,248 +43,139 @@ DSA_PRIVATE(VALUE obj, DSA *dsa) * Classes */ VALUE cDSA; -VALUE eDSAError; - -/* - * Public - */ -static VALUE -dsa_instance(VALUE klass, DSA *dsa) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!dsa) { - return Qfalse; - } - obj = NewPKey(klass); - if (!(pkey = EVP_PKEY_new())) { - return Qfalse; - } - if (!EVP_PKEY_assign_DSA(pkey, dsa)) { - EVP_PKEY_free(pkey); - return Qfalse; - } - SetPKey(obj, pkey); - - return obj; -} - -VALUE -ossl_dsa_new(EVP_PKEY *pkey) -{ - VALUE obj; - - if (!pkey) { - obj = dsa_instance(cDSA, DSA_new()); - } else { - obj = NewPKey(cDSA); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DSA) { - ossl_raise(rb_eTypeError, "Not a DSA key!"); - } - SetPKey(obj, pkey); - } - if (obj == Qfalse) { - ossl_raise(eDSAError, NULL); - } - - return obj; -} /* * Private */ -struct dsa_blocking_gen_arg { - DSA *dsa; - int size; - int *counter; - unsigned long *h; - BN_GENCB *cb; - int result; -}; - -static void * -dsa_blocking_gen(void *arg) -{ - struct dsa_blocking_gen_arg *gen = (struct dsa_blocking_gen_arg *)arg; - gen->result = DSA_generate_parameters_ex(gen->dsa, gen->size, NULL, 0, - gen->counter, gen->h, gen->cb); - return 0; -} - -static DSA * -dsa_generate(int size) -{ - struct ossl_generate_cb_arg cb_arg = { 0 }; - struct dsa_blocking_gen_arg gen_arg; - DSA *dsa = DSA_new(); - BN_GENCB *cb = BN_GENCB_new(); - int counter; - unsigned long h; - - if (!dsa || !cb) { - DSA_free(dsa); - BN_GENCB_free(cb); - return NULL; - } - - if (rb_block_given_p()) - cb_arg.yield = 1; - BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg); - gen_arg.dsa = dsa; - gen_arg.size = size; - gen_arg.counter = &counter; - gen_arg.h = &h; - gen_arg.cb = cb; - if (cb_arg.yield == 1) { - /* we cannot release GVL when callback proc is supplied */ - dsa_blocking_gen(&gen_arg); - } else { - /* there's a chance to unblock */ - rb_thread_call_without_gvl(dsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); - } - - BN_GENCB_free(cb); - if (!gen_arg.result) { - DSA_free(dsa); - if (cb_arg.state) { - /* Clear OpenSSL error queue before re-raising. By the way, the - * documentation of DSA_generate_parameters_ex() says the error code - * can be obtained by ERR_get_error(), but the default - * implementation, dsa_builtin_paramgen() doesn't put any error... */ - ossl_clear_error(); - rb_jump_tag(cb_arg.state); - } - return NULL; - } - - if (!DSA_generate_key(dsa)) { - DSA_free(dsa); - return NULL; - } - - return dsa; -} - -/* - * call-seq: - * DSA.generate(size) -> dsa - * - * Creates a new DSA instance by generating a private/public key pair - * from scratch. - * - * === Parameters - * * _size_ is an integer representing the desired key size. - * - */ -static VALUE -ossl_dsa_s_generate(VALUE klass, VALUE size) -{ - DSA *dsa = dsa_generate(NUM2INT(size)); /* err handled by dsa_instance */ - VALUE obj = dsa_instance(klass, dsa); - - if (obj == Qfalse) { - DSA_free(dsa); - ossl_raise(eDSAError, NULL); - } - - return obj; -} - /* * call-seq: * DSA.new -> dsa - * DSA.new(size) -> dsa * DSA.new(string [, pass]) -> dsa + * DSA.new(size) -> dsa * * Creates a new DSA instance by reading an existing key from _string_. * - * === Parameters - * * _size_ is an integer representing the desired key size. - * * _string_ contains a DER or PEM encoded key. - * * _pass_ is a string that contains an optional password. + * If called without arguments, creates a new instance with no key components + * set. They can be set individually by #set_pqg and #set_key. + * This form is not compatible with OpenSSL 3.0 or later. + * + * If called with a String, tries to parse as DER or PEM encoding of a \DSA key. + * See also OpenSSL::PKey.read which can parse keys of any kinds. + * + * If called with a number, generates random parameters and a key pair. This + * form works as an alias of DSA.generate. + * + * +string+:: + * A String that contains a DER or PEM encoded key. + * +pass+:: + * A String that contains an optional password. + * +size+:: + * See DSA.generate. + * + * Examples: + * p OpenSSL::PKey::DSA.new(1024) + * #=> #<OpenSSL::PKey::DSA:0x000055a8d6025bf0 oid=DSA> * - * === Examples - * DSA.new -> dsa - * DSA.new(1024) -> dsa - * DSA.new(File.read('dsa.pem')) -> dsa - * DSA.new(File.read('dsa.pem'), 'mypassword') -> dsa + * p OpenSSL::PKey::DSA.new(File.read('dsa.pem')) + * #=> #<OpenSSL::PKey::DSA:0x000055555d6b8110 oid=DSA> * + * p OpenSSL::PKey::DSA.new(File.read('dsa.pem'), 'mypassword') + * #=> #<OpenSSL::PKey::DSA:0x0000556f973c40b8 oid=DSA> */ static VALUE ossl_dsa_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; DSA *dsa; - BIO *in; + BIO *in = NULL; VALUE arg, pass; - - GetPKey(self, pkey); - if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) { + int type; + + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); + + /* The DSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ + rb_scan_args(argc, argv, "02", &arg, &pass); + if (argc == 0) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(rb_eArgError, "OpenSSL::PKey::DSA.new cannot be called " \ + "without arguments; pkeys are immutable with OpenSSL 3.0"); +#else dsa = DSA_new(); + if (!dsa) + ossl_raise(ePKeyError, "DSA_new"); + goto legacy; +#endif } - else if (RB_INTEGER_TYPE_P(arg)) { - if (!(dsa = dsa_generate(NUM2INT(arg)))) { - ossl_raise(eDSAError, NULL); - } - } - else { - pass = ossl_pem_passwd_value(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(&arg); - dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass); - if (!dsa) { - OSSL_BIO_reset(in); - dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL); - } - if (!dsa) { - OSSL_BIO_reset(in); - dsa = d2i_DSAPrivateKey_bio(in, NULL); - } - if (!dsa) { - OSSL_BIO_reset(in); - dsa = d2i_DSA_PUBKEY_bio(in, NULL); - } - if (!dsa) { - OSSL_BIO_reset(in); -#define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ - (d2i_of_void *)d2i_DSAPublicKey, PEM_STRING_DSA_PUBLIC, (bp), (void **)(x), (cb), (u)) - dsa = PEM_read_bio_DSAPublicKey(in, NULL, NULL, NULL); -#undef PEM_read_bio_DSAPublicKey - } - BIO_free(in); - if (!dsa) { - ossl_clear_error(); - ossl_raise(eDSAError, "Neither PUB key nor PRIV key"); - } - } - if (!EVP_PKEY_assign_DSA(pkey, dsa)) { - DSA_free(dsa); - ossl_raise(eDSAError, NULL); + + pass = ossl_pem_passwd_value(pass); + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); + + /* DER-encoded DSAPublicKey format isn't supported by the generic routine */ + dsa = (DSA *)PEM_ASN1_read_bio((d2i_of_void *)d2i_DSAPublicKey, + PEM_STRING_DSA_PUBLIC, + in, NULL, NULL, NULL); + if (dsa) + goto legacy; + OSSL_BIO_reset(in); + + pkey = ossl_pkey_read_generic(in, pass); + BIO_free(in); + if (!pkey) + ossl_raise(ePKeyError, "Neither PUB key nor PRIV key"); + + type = EVP_PKEY_base_id(pkey); + if (type != EVP_PKEY_DSA) { + EVP_PKEY_free(pkey); + rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type)); } + RTYPEDDATA_DATA(self) = pkey; + return self; + legacy: + BIO_free(in); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa) != 1) { + EVP_PKEY_free(pkey); + DSA_free(dsa); + ossl_raise(ePKeyError, "EVP_PKEY_assign_DSA"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#ifndef HAVE_EVP_PKEY_DUP +/* :nodoc: */ static VALUE ossl_dsa_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; DSA *dsa, *dsa_new; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eDSAError, "DSA already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); GetDSA(other, dsa); - dsa_new = ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, (d2i_of_void *)d2i_DSAPrivateKey, (char *)dsa); + dsa_new = (DSA *)ASN1_dup((i2d_of_void *)i2d_DSAPrivateKey, + (d2i_of_void *)d2i_DSAPrivateKey, + (char *)dsa); if (!dsa_new) - ossl_raise(eDSAError, "ASN1_dup"); + ossl_raise(ePKeyError, "ASN1_dup"); - EVP_PKEY_assign_DSA(pkey, dsa_new); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_DSA(pkey, dsa_new) != 1) { + EVP_PKEY_free(pkey); + DSA_free(dsa_new); + ossl_raise(ePKeyError, "EVP_PKEY_assign_DSA"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#endif /* * call-seq: @@ -294,7 +187,7 @@ ossl_dsa_initialize_copy(VALUE self, VALUE other) static VALUE ossl_dsa_is_public(VALUE self) { - DSA *dsa; + const DSA *dsa; const BIGNUM *bn; GetDSA(self, dsa); @@ -313,7 +206,7 @@ ossl_dsa_is_public(VALUE self) static VALUE ossl_dsa_is_private(VALUE self) { - DSA *dsa; + OSSL_3_const DSA *dsa; GetDSA(self, dsa); @@ -326,265 +219,98 @@ ossl_dsa_is_private(VALUE self) * dsa.to_pem([cipher, password]) -> aString * dsa.to_s([cipher, password]) -> aString * - * Encodes this DSA to its PEM encoding. + * Serializes a private or public key to a PEM-encoding. * - * === Parameters - * * _cipher_ is an OpenSSL::Cipher. - * * _password_ is a string containing your password. + * [When the key contains public components only] * - * === Examples - * DSA.to_pem -> aString - * DSA.to_pem(cipher, 'mypassword') -> aString + * Serializes it into an X.509 SubjectPublicKeyInfo. + * The parameters _cipher_ and _password_ are ignored. * - */ -static VALUE -ossl_dsa_export(int argc, VALUE *argv, VALUE self) -{ - DSA *dsa; - BIO *out; - const EVP_CIPHER *ciph = NULL; - VALUE cipher, pass, str; - - GetDSA(self, dsa); - rb_scan_args(argc, argv, "02", &cipher, &pass); - if (!NIL_P(cipher)) { - ciph = ossl_evp_get_cipherbyname(cipher); - pass = ossl_pem_passwd_value(pass); - } - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDSAError, NULL); - } - if (DSA_HAS_PRIVATE(dsa)) { - if (!PEM_write_bio_DSAPrivateKey(out, dsa, ciph, NULL, 0, - ossl_pem_passwd_cb, (void *)pass)){ - BIO_free(out); - ossl_raise(eDSAError, NULL); - } - } else { - if (!PEM_write_bio_DSA_PUBKEY(out, dsa)) { - BIO_free(out); - ossl_raise(eDSAError, NULL); - } - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * dsa.to_der -> aString + * A PEM-encoded key will look like: * - * Encodes this DSA to its DER encoding. + * -----BEGIN PUBLIC KEY----- + * [...] + * -----END PUBLIC KEY----- * - */ -static VALUE -ossl_dsa_to_der(VALUE self) -{ - DSA *dsa; - int (*i2d_func)(DSA *, unsigned char **); - unsigned char *p; - long len; - VALUE str; - - GetDSA(self, dsa); - if(DSA_HAS_PRIVATE(dsa)) - i2d_func = (int (*)(DSA *,unsigned char **))i2d_DSAPrivateKey; - else - i2d_func = i2d_DSA_PUBKEY; - if((len = i2d_func(dsa, NULL)) <= 0) - ossl_raise(eDSAError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_func(dsa, &p) < 0) - ossl_raise(eDSAError, NULL); - ossl_str_adjust(str, p); - - return str; -} - - -/* - * call-seq: - * dsa.params -> hash + * Consider using #public_to_pem instead. This serializes the key into an + * X.509 SubjectPublicKeyInfo regardless of whether it is a public key + * or a private key. * - * Stores all parameters of key to the hash - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dsa_get_params(VALUE self) -{ - DSA *dsa; - VALUE hash; - const BIGNUM *p, *q, *g, *pub_key, *priv_key; - - GetDSA(self, dsa); - DSA_get0_pqg(dsa, &p, &q, &g); - DSA_get0_key(dsa, &pub_key, &priv_key); - - hash = rb_hash_new(); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); - rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g)); - rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key)); - rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key)); - - return hash; -} - -/* - * call-seq: - * dsa.to_text -> aString + * [When the key contains private components, and no parameters are given] * - * Prints all parameters of key to buffer - * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!! - * Don't use :-)) (I's up to you) - */ -static VALUE -ossl_dsa_to_text(VALUE self) -{ - DSA *dsa; - BIO *out; - VALUE str; - - GetDSA(self, dsa); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eDSAError, NULL); - } - if (!DSA_print(out, dsa, 0)) { /* offset = 0 */ - BIO_free(out); - ossl_raise(eDSAError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * dsa.public_key -> aDSA + * Serializes it into a traditional \OpenSSL DSAPrivateKey. * - * Returns a new DSA instance that carries just the public key information. - * If the current instance has also private key information, this will no - * longer be present in the new instance. This feature is helpful for - * publishing the public key information without leaking any of the private - * information. + * A PEM-encoded key will look like: * - * === Example - * dsa = OpenSSL::PKey::DSA.new(2048) # has public and private information - * pub_key = dsa.public_key # has only the public part available - * pub_key_der = pub_key.to_der # it's safe to publish this + * -----BEGIN DSA PRIVATE KEY----- + * [...] + * -----END DSA PRIVATE KEY----- * + * [When the key contains private components, and _cipher_ and _password_ are given] * - */ -static VALUE -ossl_dsa_to_public_key(VALUE self) -{ - EVP_PKEY *pkey; - DSA *dsa; - VALUE obj; - - GetPKeyDSA(self, pkey); - /* err check performed by dsa_instance */ -#define DSAPublicKey_dup(dsa) (DSA *)ASN1_dup( \ - (i2d_of_void *)i2d_DSAPublicKey, (d2i_of_void *)d2i_DSAPublicKey, (char *)(dsa)) - dsa = DSAPublicKey_dup(EVP_PKEY_get0_DSA(pkey)); -#undef DSAPublicKey_dup - obj = dsa_instance(rb_obj_class(self), dsa); - if (obj == Qfalse) { - DSA_free(dsa); - ossl_raise(eDSAError, NULL); - } - return obj; -} - -/* - * call-seq: - * dsa.syssign(string) -> aString + * Serializes it into a traditional \OpenSSL DSAPrivateKey and encrypts it in + * OpenSSL's traditional PEM encryption format. + * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an + * instance of OpenSSL::Cipher. + * + * An encrypted PEM-encoded key will look like: * - * Computes and returns the DSA signature of _string_, where _string_ is - * expected to be an already-computed message digest of the original input - * data. The signature is issued using the private key of this DSA instance. + * -----BEGIN DSA PRIVATE KEY----- + * Proc-Type: 4,ENCRYPTED + * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 * - * === Parameters - * * _string_ is a message digest of the original input data to be signed. + * [...] + * -----END DSA PRIVATE KEY----- * - * === Example - * dsa = OpenSSL::PKey::DSA.new(2048) - * doc = "Sign me" - * digest = OpenSSL::Digest::SHA1.digest(doc) - * sig = dsa.syssign(digest) + * Note that this format uses MD5 to derive the encryption key, and hence + * will not be available on FIPS-compliant systems. * + * <b>This method is kept for compatibility.</b> + * This should only be used when the traditional, non-standard \OpenSSL format + * is required. * + * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem + * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead. */ static VALUE -ossl_dsa_sign(VALUE self, VALUE data) +ossl_dsa_export(int argc, VALUE *argv, VALUE self) { - DSA *dsa; - const BIGNUM *dsa_q; - unsigned int buf_len; - VALUE str; + OSSL_3_const DSA *dsa; GetDSA(self, dsa); - DSA_get0_pqg(dsa, NULL, &dsa_q, NULL); - if (!dsa_q) - ossl_raise(eDSAError, "incomplete DSA"); - if (!DSA_PRIVATE(self, dsa)) - ossl_raise(eDSAError, "Private DSA key needed!"); - StringValue(data); - str = rb_str_new(0, DSA_size(dsa)); - if (!DSA_sign(0, (unsigned char *)RSTRING_PTR(data), RSTRING_LENINT(data), - (unsigned char *)RSTRING_PTR(str), - &buf_len, dsa)) { /* type is ignored (0) */ - ossl_raise(eDSAError, NULL); - } - rb_str_set_len(str, buf_len); - - return str; + if (DSA_HAS_PRIVATE(dsa)) + return ossl_pkey_export_traditional(argc, argv, self, 0); + else + return ossl_pkey_export_spki(self, 0); } /* * call-seq: - * dsa.sysverify(digest, sig) -> true | false + * dsa.to_der -> aString * - * Verifies whether the signature is valid given the message digest input. It - * does so by validating _sig_ using the public key of this DSA instance. + * Serializes a private or public key to a DER-encoding. * - * === Parameters - * * _digest_ is a message digest of the original input data to be signed - * * _sig_ is a DSA signature value + * See #to_pem for details. * - * === Example - * dsa = OpenSSL::PKey::DSA.new(2048) - * doc = "Sign me" - * digest = OpenSSL::Digest::SHA1.digest(doc) - * sig = dsa.syssign(digest) - * puts dsa.sysverify(digest, sig) # => true + * <b>This method is kept for compatibility.</b> + * This should only be used when the traditional, non-standard \OpenSSL format + * is required. * + * Consider using #public_to_der or #private_to_der instead. */ static VALUE -ossl_dsa_verify(VALUE self, VALUE digest, VALUE sig) +ossl_dsa_to_der(VALUE self) { - DSA *dsa; - int ret; + OSSL_3_const DSA *dsa; GetDSA(self, dsa); - StringValue(digest); - StringValue(sig); - /* type is ignored (0) */ - ret = DSA_verify(0, (unsigned char *)RSTRING_PTR(digest), RSTRING_LENINT(digest), - (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), dsa); - if (ret < 0) { - ossl_raise(eDSAError, NULL); - } - else if (ret == 1) { - return Qtrue; - } - - return Qfalse; + if (DSA_HAS_PRIVATE(dsa)) + return ossl_pkey_export_traditional(0, NULL, self, 1); + else + return ossl_pkey_export_spki(self, 1); } + /* * Document-method: OpenSSL::PKey::DSA#set_pqg * call-seq: @@ -608,20 +334,6 @@ OSSL_PKEY_BN_DEF2(dsa, DSA, key, pub_key, priv_key) void Init_ossl_dsa(void) { -#if 0 - mPKey = rb_define_module_under(mOSSL, "PKey"); - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); -#endif - - /* Document-class: OpenSSL::PKey::DSAError - * - * Generic exception that is raised if an operation on a DSA PKey - * fails unexpectedly or in case an instantiation of an instance of DSA - * fails due to non-conformant input data. - */ - eDSAError = rb_define_class_under(mPKey, "DSAError", ePKeyError); - /* Document-class: OpenSSL::PKey::DSA * * DSA, the Digital Signature Algorithm, is specified in NIST's @@ -630,20 +342,17 @@ Init_ossl_dsa(void) */ cDSA = rb_define_class_under(mPKey, "DSA", cPKey); - rb_define_singleton_method(cDSA, "generate", ossl_dsa_s_generate, 1); rb_define_method(cDSA, "initialize", ossl_dsa_initialize, -1); +#ifndef HAVE_EVP_PKEY_DUP rb_define_method(cDSA, "initialize_copy", ossl_dsa_initialize_copy, 1); +#endif rb_define_method(cDSA, "public?", ossl_dsa_is_public, 0); rb_define_method(cDSA, "private?", ossl_dsa_is_private, 0); - rb_define_method(cDSA, "to_text", ossl_dsa_to_text, 0); rb_define_method(cDSA, "export", ossl_dsa_export, -1); rb_define_alias(cDSA, "to_pem", "export"); rb_define_alias(cDSA, "to_s", "export"); rb_define_method(cDSA, "to_der", ossl_dsa_to_der, 0); - rb_define_method(cDSA, "public_key", ossl_dsa_to_public_key, 0); - rb_define_method(cDSA, "syssign", ossl_dsa_sign, 1); - rb_define_method(cDSA, "sysverify", ossl_dsa_verify, 2); DEF_OSSL_PKEY_BN(cDSA, dsa, p); DEF_OSSL_PKEY_BN(cDSA, dsa, q); @@ -652,8 +361,6 @@ Init_ossl_dsa(void) DEF_OSSL_PKEY_BN(cDSA, dsa, priv_key); rb_define_method(cDSA, "set_pqg", ossl_dsa_set_pqg, 3); rb_define_method(cDSA, "set_key", ossl_dsa_set_key, 2); - - rb_define_method(cDSA, "params", ossl_dsa_get_params, 0); } #else /* defined NO_DSA */ diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index 8bb611248b..35f031819d 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -15,25 +15,27 @@ static const rb_data_type_t ossl_ec_point_type; #define GetPKeyEC(obj, pkey) do { \ GetPKey((obj), (pkey)); \ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \ + ossl_raise(rb_eRuntimeError, "THIS IS NOT A EC PKEY!"); \ } \ } while (0) #define GetEC(obj, key) do { \ EVP_PKEY *_pkey; \ GetPKeyEC(obj, _pkey); \ (key) = EVP_PKEY_get0_EC_KEY(_pkey); \ + if ((key) == NULL) \ + ossl_raise(ePKeyError, "failed to get EC_KEY from EVP_PKEY"); \ } while (0) #define GetECGroup(obj, group) do { \ TypedData_Get_Struct(obj, EC_GROUP, &ossl_ec_group_type, group); \ if ((group) == NULL) \ - ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \ + ossl_raise(eEC_GROUP, "EC_GROUP is not initialized"); \ } while (0) #define GetECPoint(obj, point) do { \ TypedData_Get_Struct(obj, EC_POINT, &ossl_ec_point_type, point); \ if ((point) == NULL) \ - ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \ + ossl_raise(eEC_POINT, "EC_POINT is not initialized"); \ } while (0) #define GetECPointGroup(obj, group) do { \ VALUE _group = rb_attr_get(obj, id_i_group); \ @@ -41,69 +43,19 @@ static const rb_data_type_t ossl_ec_point_type; } while (0) VALUE cEC; -VALUE eECError; -VALUE cEC_GROUP; -VALUE eEC_GROUP; -VALUE cEC_POINT; -VALUE eEC_POINT; - -static ID s_GFp; -static ID s_GFp_simple; -static ID s_GFp_mont; -static ID s_GFp_nist; -static ID s_GF2m; -static ID s_GF2m_simple; - -static ID ID_uncompressed; -static ID ID_compressed; -static ID ID_hybrid; +static VALUE cEC_GROUP; +static VALUE eEC_GROUP; +static VALUE cEC_POINT; +static VALUE eEC_POINT; + +static VALUE sym_GFp, sym_GF2m; +static VALUE sym_uncompressed, sym_compressed, sym_hybrid; static ID id_i_group; static VALUE ec_group_new(const EC_GROUP *group); static VALUE ec_point_new(const EC_POINT *point, const EC_GROUP *group); -static VALUE ec_instance(VALUE klass, EC_KEY *ec) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!ec) { - return Qfalse; - } - obj = NewPKey(klass); - if (!(pkey = EVP_PKEY_new())) { - return Qfalse; - } - if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { - EVP_PKEY_free(pkey); - return Qfalse; - } - SetPKey(obj, pkey); - - return obj; -} - -VALUE ossl_ec_new(EVP_PKEY *pkey) -{ - VALUE obj; - - if (!pkey) { - obj = ec_instance(cEC, EC_KEY_new()); - } else { - obj = NewPKey(cEC); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) { - ossl_raise(rb_eTypeError, "Not a EC key!"); - } - SetPKey(obj, pkey); - } - if (obj == Qfalse) { - ossl_raise(eECError, NULL); - } - - return obj; -} - /* * Creates a new EC_KEY on the EC group obj. arg can be an EC::Group or a String * representing an OID. @@ -114,27 +66,27 @@ ec_key_new_from_group(VALUE arg) EC_KEY *ec; if (rb_obj_is_kind_of(arg, cEC_GROUP)) { - EC_GROUP *group; + EC_GROUP *group; - GetECGroup(arg, group); - if (!(ec = EC_KEY_new())) - ossl_raise(eECError, NULL); + GetECGroup(arg, group); + if (!(ec = EC_KEY_new())) + ossl_raise(ePKeyError, NULL); - if (!EC_KEY_set_group(ec, group)) { - EC_KEY_free(ec); - ossl_raise(eECError, NULL); - } + if (!EC_KEY_set_group(ec, group)) { + EC_KEY_free(ec); + ossl_raise(ePKeyError, NULL); + } } else { - int nid = OBJ_sn2nid(StringValueCStr(arg)); + int nid = OBJ_sn2nid(StringValueCStr(arg)); - if (nid == NID_undef) - ossl_raise(eECError, "invalid curve name"); + if (nid == NID_undef) + ossl_raise(ePKeyError, "invalid curve name"); - if (!(ec = EC_KEY_new_by_curve_name(nid))) - ossl_raise(eECError, NULL); + if (!(ec = EC_KEY_new_by_curve_name(nid))) + ossl_raise(ePKeyError, NULL); - EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); - EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); + EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); + EC_KEY_set_conv_form(ec, POINT_CONVERSION_UNCOMPRESSED); } return ec; @@ -150,19 +102,23 @@ ec_key_new_from_group(VALUE arg) static VALUE ossl_ec_key_s_generate(VALUE klass, VALUE arg) { + EVP_PKEY *pkey; EC_KEY *ec; VALUE obj; - ec = ec_key_new_from_group(arg); + obj = rb_obj_alloc(klass); - obj = ec_instance(klass, ec); - if (obj == Qfalse) { - EC_KEY_free(ec); - ossl_raise(eECError, NULL); + ec = ec_key_new_from_group(arg); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) { + EVP_PKEY_free(pkey); + EC_KEY_free(ec); + ossl_raise(ePKeyError, "EVP_PKEY_assign_EC_KEY"); } + RTYPEDDATA_DATA(obj) = pkey; if (!EC_KEY_generate_key(ec)) - ossl_raise(eECError, "EC_KEY_generate_key"); + ossl_raise(ePKeyError, "EC_KEY_generate_key"); return obj; } @@ -182,81 +138,88 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; EC_KEY *ec; + BIO *in; VALUE arg, pass; + int type; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eECError, "EC_KEY already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); rb_scan_args(argc, argv, "02", &arg, &pass); - if (NIL_P(arg)) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(rb_eArgError, "OpenSSL::PKey::EC.new cannot be called " \ + "without arguments; pkeys are immutable with OpenSSL 3.0"); +#else if (!(ec = EC_KEY_new())) - ossl_raise(eECError, NULL); - } else if (rb_obj_is_kind_of(arg, cEC)) { - EC_KEY *other_ec = NULL; - - GetEC(arg, other_ec); - if (!(ec = EC_KEY_dup(other_ec))) - ossl_raise(eECError, NULL); - } else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { - ec = ec_key_new_from_group(arg); - } else { - BIO *in; - - pass = ossl_pem_passwd_value(pass); - in = ossl_obj2bio(&arg); - - ec = PEM_read_bio_ECPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass); - if (!ec) { - OSSL_BIO_reset(in); - ec = PEM_read_bio_EC_PUBKEY(in, NULL, ossl_pem_passwd_cb, (void *)pass); - } - if (!ec) { - OSSL_BIO_reset(in); - ec = d2i_ECPrivateKey_bio(in, NULL); - } - if (!ec) { - OSSL_BIO_reset(in); - ec = d2i_EC_PUBKEY_bio(in, NULL); - } - BIO_free(in); - - if (!ec) { - ossl_clear_error(); - ec = ec_key_new_from_group(arg); - } + ossl_raise(ePKeyError, "EC_KEY_new"); + goto legacy; +#endif } + else if (rb_obj_is_kind_of(arg, cEC_GROUP)) { + ec = ec_key_new_from_group(arg); + goto legacy; + } + + pass = ossl_pem_passwd_value(pass); + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); - if (!EVP_PKEY_assign_EC_KEY(pkey, ec)) { - EC_KEY_free(ec); - ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); + pkey = ossl_pkey_read_generic(in, pass); + BIO_free(in); + if (!pkey) { + ossl_clear_error(); + ec = ec_key_new_from_group(arg); + goto legacy; } + type = EVP_PKEY_base_id(pkey); + if (type != EVP_PKEY_EC) { + EVP_PKEY_free(pkey); + rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type)); + } + RTYPEDDATA_DATA(self) = pkey; + return self; + + legacy: + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec) != 1) { + EVP_PKEY_free(pkey); + EC_KEY_free(ec); + ossl_raise(ePKeyError, "EVP_PKEY_assign_EC_KEY"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#ifndef HAVE_EVP_PKEY_DUP +/* :nodoc: */ static VALUE ossl_ec_key_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; EC_KEY *ec, *ec_new; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eECError, "EC already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); GetEC(other, ec); ec_new = EC_KEY_dup(ec); if (!ec_new) - ossl_raise(eECError, "EC_KEY_dup"); - if (!EVP_PKEY_assign_EC_KEY(pkey, ec_new)) { - EC_KEY_free(ec_new); - ossl_raise(eECError, "EVP_PKEY_assign_EC_KEY"); + ossl_raise(ePKeyError, "EC_KEY_dup"); + + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_EC_KEY(pkey, ec_new) != 1) { + EC_KEY_free(ec_new); + ossl_raise(ePKeyError, "EVP_PKEY_assign_EC_KEY"); } + RTYPEDDATA_DATA(self) = pkey; return self; } +#endif /* * call-seq: @@ -268,13 +231,13 @@ ossl_ec_key_initialize_copy(VALUE self, VALUE other) static VALUE ossl_ec_key_get_group(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; const EC_GROUP *group; GetEC(self, ec); group = EC_KEY_get0_group(ec); if (!group) - return Qnil; + return Qnil; return ec_group_new(group); } @@ -289,6 +252,9 @@ ossl_ec_key_get_group(VALUE self) static VALUE ossl_ec_key_set_group(VALUE self, VALUE group_v) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); +#else EC_KEY *ec; EC_GROUP *group; @@ -296,9 +262,10 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v) GetECGroup(group_v, group); if (EC_KEY_set_group(ec, group) != 1) - ossl_raise(eECError, "EC_KEY_set_group"); + ossl_raise(ePKeyError, "EC_KEY_set_group"); return group_v; +#endif } /* @@ -309,7 +276,7 @@ ossl_ec_key_set_group(VALUE self, VALUE group_v) */ static VALUE ossl_ec_key_get_private_key(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; const BIGNUM *bn; GetEC(self, ec); @@ -327,6 +294,9 @@ static VALUE ossl_ec_key_get_private_key(VALUE self) */ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); +#else EC_KEY *ec; BIGNUM *bn = NULL; @@ -335,16 +305,18 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) bn = GetBNPtr(private_key); switch (EC_KEY_set_private_key(ec, bn)) { - case 1: + case 1: break; - case 0: + case 0: if (bn == NULL) break; - default: - ossl_raise(eECError, "EC_KEY_set_private_key"); + /* fallthrough */ + default: + ossl_raise(ePKeyError, "EC_KEY_set_private_key"); } return private_key; +#endif } /* @@ -355,7 +327,7 @@ static VALUE ossl_ec_key_set_private_key(VALUE self, VALUE private_key) */ static VALUE ossl_ec_key_get_public_key(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; const EC_POINT *point; GetEC(self, ec); @@ -373,6 +345,9 @@ static VALUE ossl_ec_key_get_public_key(VALUE self) */ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); +#else EC_KEY *ec; EC_POINT *point = NULL; @@ -381,16 +356,18 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) GetECPoint(public_key, point); switch (EC_KEY_set_public_key(ec, point)) { - case 1: + case 1: break; - case 0: + case 0: if (point == NULL) break; - default: - ossl_raise(eECError, "EC_KEY_set_public_key"); + /* fallthrough */ + default: + ossl_raise(ePKeyError, "EC_KEY_set_public_key"); } return public_key; +#endif } /* @@ -402,7 +379,7 @@ static VALUE ossl_ec_key_set_public_key(VALUE self, VALUE public_key) */ static VALUE ossl_ec_key_is_public(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; GetEC(self, ec); @@ -418,126 +395,112 @@ static VALUE ossl_ec_key_is_public(VALUE self) */ static VALUE ossl_ec_key_is_private(VALUE self) { - EC_KEY *ec; + OSSL_3_const EC_KEY *ec; GetEC(self, ec); return EC_KEY_get0_private_key(ec) ? Qtrue : Qfalse; } -static VALUE ossl_ec_key_to_string(VALUE self, VALUE ciph, VALUE pass, int format) -{ - EC_KEY *ec; - BIO *out; - int i = -1; - int private = 0; - VALUE str; - const EVP_CIPHER *cipher = NULL; - - GetEC(self, ec); - - if (EC_KEY_get0_public_key(ec) == NULL) - ossl_raise(eECError, "can't export - no public key set"); - - if (EC_KEY_check_key(ec) != 1) - ossl_raise(eECError, "can't export - EC_KEY_check_key failed"); - - if (EC_KEY_get0_private_key(ec)) - private = 1; - - if (!NIL_P(ciph)) { - cipher = ossl_evp_get_cipherbyname(ciph); - pass = ossl_pem_passwd_value(pass); - } - - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eECError, "BIO_new(BIO_s_mem())"); - - switch(format) { - case EXPORT_PEM: - if (private) { - i = PEM_write_bio_ECPrivateKey(out, ec, cipher, NULL, 0, ossl_pem_passwd_cb, (void *)pass); - } else { - i = PEM_write_bio_EC_PUBKEY(out, ec); - } - - break; - case EXPORT_DER: - if (private) { - i = i2d_ECPrivateKey_bio(out, ec); - } else { - i = i2d_EC_PUBKEY_bio(out, ec); - } - - break; - default: - BIO_free(out); - ossl_raise(rb_eRuntimeError, "unknown format (internal error)"); - } - - if (i != 1) { - BIO_free(out); - ossl_raise(eECError, "outlen=%d", i); - } - - str = ossl_membio2str(out); - - return str; -} - /* * call-seq: - * key.export([cipher, pass_phrase]) => String - * key.to_pem([cipher, pass_phrase]) => String + * key.export([cipher, password]) => String + * key.to_pem([cipher, password]) => String + * + * Serializes a private or public key to a PEM-encoding. + * + * [When the key contains public components only] + * + * Serializes it into an X.509 SubjectPublicKeyInfo. + * The parameters _cipher_ and _password_ are ignored. + * + * A PEM-encoded key will look like: + * + * -----BEGIN PUBLIC KEY----- + * [...] + * -----END PUBLIC KEY----- + * + * Consider using #public_to_pem instead. This serializes the key into an + * X.509 SubjectPublicKeyInfo regardless of whether it is a public key + * or a private key. + * + * [When the key contains private components, and no parameters are given] + * + * Serializes it into a SEC 1/RFC 5915 ECPrivateKey. + * + * A PEM-encoded key will look like: + * + * -----BEGIN EC PRIVATE KEY----- + * [...] + * -----END EC PRIVATE KEY----- + * + * [When the key contains private components, and _cipher_ and _password_ are given] + * + * Serializes it into a SEC 1/RFC 5915 ECPrivateKey + * and encrypts it in OpenSSL's traditional PEM encryption format. + * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an + * instance of OpenSSL::Cipher. + * + * An encrypted PEM-encoded key will look like: + * + * -----BEGIN EC PRIVATE KEY----- + * Proc-Type: 4,ENCRYPTED + * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 * - * Outputs the EC key in PEM encoding. If _cipher_ and _pass_phrase_ are given - * they will be used to encrypt the key. _cipher_ must be an OpenSSL::Cipher - * instance. Note that encryption will only be effective for a private key, - * public keys will always be encoded in plain text. + * [...] + * -----END EC PRIVATE KEY----- + * + * Note that this format uses MD5 to derive the encryption key, and hence + * will not be available on FIPS-compliant systems. + * + * <b>This method is kept for compatibility.</b> + * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is + * required. + * + * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem + * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead. */ -static VALUE ossl_ec_key_export(int argc, VALUE *argv, VALUE self) +static VALUE +ossl_ec_key_export(int argc, VALUE *argv, VALUE self) { - VALUE cipher, passwd; - rb_scan_args(argc, argv, "02", &cipher, &passwd); - return ossl_ec_key_to_string(self, cipher, passwd, EXPORT_PEM); + OSSL_3_const EC_KEY *ec; + + GetEC(self, ec); + if (EC_KEY_get0_public_key(ec) == NULL) + ossl_raise(ePKeyError, "can't export - no public key set"); + if (EC_KEY_get0_private_key(ec)) + return ossl_pkey_export_traditional(argc, argv, self, 0); + else + return ossl_pkey_export_spki(self, 0); } /* * call-seq: * key.to_der => String * - * See the OpenSSL documentation for i2d_ECPrivateKey_bio() - */ -static VALUE ossl_ec_key_to_der(VALUE self) -{ - return ossl_ec_key_to_string(self, Qnil, Qnil, EXPORT_DER); -} - -/* - * call-seq: - * key.to_text => String + * Serializes a private or public key to a DER-encoding. + * + * See #to_pem for details. + * + * <b>This method is kept for compatibility.</b> + * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is + * required. * - * See the OpenSSL documentation for EC_KEY_print() + * Consider using #public_to_der or #private_to_der instead. */ -static VALUE ossl_ec_key_to_text(VALUE self) +static VALUE +ossl_ec_key_to_der(VALUE self) { - EC_KEY *ec; - BIO *out; - VALUE str; + OSSL_3_const EC_KEY *ec; GetEC(self, ec); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eECError, "BIO_new(BIO_s_mem())"); - } - if (!EC_KEY_print(out, ec, 0)) { - BIO_free(out); - ossl_raise(eECError, "EC_KEY_print"); - } - str = ossl_membio2str(out); - - return str; + if (EC_KEY_get0_public_key(ec) == NULL) + ossl_raise(ePKeyError, "can't export - no public key set"); + if (EC_KEY_get0_private_key(ec)) + return ossl_pkey_export_traditional(0, NULL, self, 1); + else + return ossl_pkey_export_spki(self, 1); } - /* * call-seq: * key.generate_key! => self @@ -554,114 +517,63 @@ static VALUE ossl_ec_key_to_text(VALUE self) */ static VALUE ossl_ec_key_generate_key(VALUE self) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(ePKeyError, "pkeys are immutable on OpenSSL 3.0"); +#else EC_KEY *ec; GetEC(self, ec); if (EC_KEY_generate_key(ec) != 1) - ossl_raise(eECError, "EC_KEY_generate_key"); + ossl_raise(ePKeyError, "EC_KEY_generate_key"); return self; +#endif } /* - * call-seq: - * key.check_key => true + * call-seq: + * key.check_key => true * - * Raises an exception if the key is invalid. + * Raises an exception if the key is invalid. * - * See the OpenSSL documentation for EC_KEY_check_key() + * See also the man page EVP_PKEY_public_check(3). */ static VALUE ossl_ec_key_check_key(VALUE self) { - EC_KEY *ec; - - GetEC(self, ec); - if (EC_KEY_check_key(ec) != 1) - ossl_raise(eECError, "EC_KEY_check_key"); - - return Qtrue; -} - -/* - * call-seq: - * key.dh_compute_key(pubkey) => String - * - * See the OpenSSL documentation for ECDH_compute_key() - */ -static VALUE ossl_ec_key_dh_compute_key(VALUE self, VALUE pubkey) -{ - EC_KEY *ec; - EC_POINT *point; - int buf_len; - VALUE str; - - GetEC(self, ec); - GetECPoint(pubkey, point); - -/* BUG: need a way to figure out the maximum string size */ - buf_len = 1024; - str = rb_str_new(0, buf_len); -/* BUG: take KDF as a block */ - buf_len = ECDH_compute_key(RSTRING_PTR(str), buf_len, point, ec, NULL); - if (buf_len < 0) - ossl_raise(eECError, "ECDH_compute_key"); - - rb_str_resize(str, buf_len); - - return str; -} - -/* sign_setup */ - -/* - * call-seq: - * key.dsa_sign_asn1(data) => String - * - * See the OpenSSL documentation for ECDSA_sign() - */ -static VALUE ossl_ec_key_dsa_sign_asn1(VALUE self, VALUE data) -{ - EC_KEY *ec; - unsigned int buf_len; - VALUE str; +#ifdef HAVE_EVP_PKEY_CHECK + EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx; + const EC_KEY *ec; + GetPKey(self, pkey); GetEC(self, ec); - StringValue(data); - - if (EC_KEY_get0_private_key(ec) == NULL) - ossl_raise(eECError, "Private EC key needed!"); - - str = rb_str_new(0, ECDSA_size(ec)); - if (ECDSA_sign(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(str), &buf_len, ec) != 1) - ossl_raise(eECError, "ECDSA_sign"); - rb_str_set_len(str, buf_len); - - return str; -} + pctx = EVP_PKEY_CTX_new(pkey, /* engine */NULL); + if (!pctx) + ossl_raise(ePKeyError, "EVP_PKEY_CTX_new"); + + if (EC_KEY_get0_private_key(ec) != NULL) { + if (EVP_PKEY_check(pctx) != 1) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(ePKeyError, "EVP_PKEY_check"); + } + } + else { + if (EVP_PKEY_public_check(pctx) != 1) { + EVP_PKEY_CTX_free(pctx); + ossl_raise(ePKeyError, "EVP_PKEY_public_check"); + } + } -/* - * call-seq: - * key.dsa_verify_asn1(data, sig) => true or false - * - * See the OpenSSL documentation for ECDSA_verify() - */ -static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig) -{ + EVP_PKEY_CTX_free(pctx); +#else EC_KEY *ec; GetEC(self, ec); - StringValue(data); - StringValue(sig); - - switch (ECDSA_verify(0, (unsigned char *) RSTRING_PTR(data), RSTRING_LENINT(data), (unsigned char *) RSTRING_PTR(sig), (int)RSTRING_LEN(sig), ec)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: break; - } - - ossl_raise(eECError, "ECDSA_verify"); + if (EC_KEY_check_key(ec) != 1) + ossl_raise(ePKeyError, "EC_KEY_check_key"); +#endif - UNREACHABLE; + return Qtrue; } /* @@ -670,15 +582,15 @@ static VALUE ossl_ec_key_dsa_verify_asn1(VALUE self, VALUE data, VALUE sig) static void ossl_ec_group_free(void *ptr) { - EC_GROUP_clear_free(ptr); + EC_GROUP_free(ptr); } static const rb_data_type_t ossl_ec_group_type = { "OpenSSL/ec_group", { - 0, ossl_ec_group_free, + 0, ossl_ec_group_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -696,7 +608,7 @@ ec_group_new(const EC_GROUP *group) obj = ossl_ec_group_alloc(cEC_GROUP); group_new = EC_GROUP_dup(group); if (!group_new) - ossl_raise(eEC_GROUP, "EC_GROUP_dup"); + ossl_raise(eEC_GROUP, "EC_GROUP_dup"); RTYPEDDATA_DATA(obj) = group_new; return obj; @@ -706,20 +618,11 @@ ec_group_new(const EC_GROUP *group) * call-seq: * OpenSSL::PKey::EC::Group.new(ec_group) * OpenSSL::PKey::EC::Group.new(pem_or_der_encoded) - * OpenSSL::PKey::EC::Group.new(ec_method) * OpenSSL::PKey::EC::Group.new(:GFp, bignum_p, bignum_a, bignum_b) * OpenSSL::PKey::EC::Group.new(:GF2m, bignum_p, bignum_a, bignum_b) * * Creates a new EC::Group object. * - * _ec_method_ is a symbol that represents an EC_METHOD. Currently the following - * are supported: - * - * * :GFp_simple - * * :GFp_mont - * * :GFp_nist - * * :GF2m_simple - * * If the first argument is :GFp or :GF2m, creates a new curve with given * parameters. */ @@ -733,30 +636,8 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) ossl_raise(rb_eRuntimeError, "EC_GROUP is already initialized"); switch (rb_scan_args(argc, argv, "13", &arg1, &arg2, &arg3, &arg4)) { - case 1: - if (SYMBOL_P(arg1)) { - const EC_METHOD *method = NULL; - ID id = SYM2ID(arg1); - - if (id == s_GFp_simple) { - method = EC_GFp_simple_method(); - } else if (id == s_GFp_mont) { - method = EC_GFp_mont_method(); - } else if (id == s_GFp_nist) { - method = EC_GFp_nist_method(); -#if !defined(OPENSSL_NO_EC2M) - } else if (id == s_GF2m_simple) { - method = EC_GF2m_simple_method(); -#endif - } - - if (method) { - if ((group = EC_GROUP_new(method)) == NULL) - ossl_raise(eEC_GROUP, "EC_GROUP_new"); - } else { - ossl_raise(rb_eArgError, "unknown symbol, must be :GFp_simple, :GFp_mont, :GFp_nist or :GF2m_simple"); - } - } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) { + case 1: + if (rb_obj_is_kind_of(arg1, cEC_GROUP)) { const EC_GROUP *arg1_group; GetECGroup(arg1, arg1_group); @@ -767,7 +648,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); if (!group) { - OSSL_BIO_reset(in); + OSSL_BIO_reset(in); group = d2i_ECPKParameters_bio(in, NULL); } @@ -777,11 +658,14 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) const char *name = StringValueCStr(arg1); int nid = OBJ_sn2nid(name); - ossl_clear_error(); /* ignore errors in d2i_ECPKParameters_bio() */ + ossl_clear_error(); /* ignore errors in d2i_ECPKParameters_bio() */ if (nid == NID_undef) ossl_raise(eEC_GROUP, "unknown curve name (%"PRIsVALUE")", arg1); - +#if !defined(OPENSSL_IS_AWSLC) group = EC_GROUP_new_by_curve_name(nid); +#else /* EC_GROUPs are static and immutable by default in AWS-LC. */ + group = EC_GROUP_new_by_curve_name_mutable(nid); +#endif if (group == NULL) ossl_raise(eEC_GROUP, "unable to create curve (%"PRIsVALUE")", arg1); @@ -791,42 +675,43 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self) } break; - case 4: + case 4: if (SYMBOL_P(arg1)) { - ID id = SYM2ID(arg1); EC_GROUP *(*new_curve)(const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *) = NULL; const BIGNUM *p = GetBNPtr(arg2); const BIGNUM *a = GetBNPtr(arg3); const BIGNUM *b = GetBNPtr(arg4); - if (id == s_GFp) { + if (arg1 == sym_GFp) { new_curve = EC_GROUP_new_curve_GFp; + } #if !defined(OPENSSL_NO_EC2M) - } else if (id == s_GF2m) { + else if (arg1 == sym_GF2m) { new_curve = EC_GROUP_new_curve_GF2m; + } #endif - } else { + else { ossl_raise(rb_eArgError, "unknown symbol, must be :GFp or :GF2m"); } if ((group = new_curve(p, a, b, ossl_bn_ctx)) == NULL) ossl_raise(eEC_GROUP, "EC_GROUP_new_by_GF*"); } else { - ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m"); + ossl_raise(rb_eArgError, "unknown argument, must be :GFp or :GF2m"); } break; - default: - ossl_raise(rb_eArgError, "wrong number of arguments"); + default: + ossl_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1 or 4)", argc); } - if (group == NULL) - ossl_raise(eEC_GROUP, ""); + ASSUME(group); RTYPEDDATA_DATA(self) = group; return self; } +/* :nodoc: */ static VALUE ossl_ec_group_initialize_copy(VALUE self, VALUE other) { @@ -834,12 +719,12 @@ ossl_ec_group_initialize_copy(VALUE self, VALUE other) TypedData_Get_Struct(self, EC_GROUP, &ossl_ec_group_type, group_new); if (group_new) - ossl_raise(eEC_GROUP, "EC::Group already initialized"); + ossl_raise(eEC_GROUP, "EC::Group already initialized"); GetECGroup(other, group); group_new = EC_GROUP_dup(group); if (!group_new) - ossl_raise(eEC_GROUP, "EC_GROUP_dup"); + ossl_raise(eEC_GROUP, "EC_GROUP_dup"); RTYPEDDATA_DATA(self) = group_new; return self; @@ -860,10 +745,11 @@ static VALUE ossl_ec_group_eql(VALUE a, VALUE b) GetECGroup(a, group1); GetECGroup(b, group2); - if (EC_GROUP_cmp(group1, group2, ossl_bn_ctx) == 1) - return Qfalse; - - return Qtrue; + switch (EC_GROUP_cmp(group1, group2, ossl_bn_ctx)) { + case 0: return Qtrue; + case 1: return Qfalse; + default: ossl_raise(eEC_GROUP, "EC_GROUP_cmp"); + } } /* @@ -882,7 +768,7 @@ static VALUE ossl_ec_group_get_generator(VALUE self) GetECGroup(self, group); generator = EC_GROUP_get0_generator(group); if (!generator) - return Qnil; + return Qnil; return ec_point_new(generator, group); } @@ -925,11 +811,10 @@ static VALUE ossl_ec_group_get_order(VALUE self) { VALUE bn_obj; BIGNUM *bn; - EC_GROUP *group = NULL; + EC_GROUP *group; GetECGroup(self, group); - - bn_obj = ossl_bn_new(NULL); + bn_obj = ossl_bn_new(BN_value_one()); bn = GetBNPtr(bn_obj); if (EC_GROUP_get_order(group, bn, ossl_bn_ctx) != 1) @@ -950,11 +835,10 @@ static VALUE ossl_ec_group_get_cofactor(VALUE self) { VALUE bn_obj; BIGNUM *bn; - EC_GROUP *group = NULL; + EC_GROUP *group; GetECGroup(self, group); - - bn_obj = ossl_bn_new(NULL); + bn_obj = ossl_bn_new(BN_value_one()); bn = GetBNPtr(bn_obj); if (EC_GROUP_get_cofactor(group, bn, ossl_bn_ctx) != 1) @@ -965,25 +849,23 @@ static VALUE ossl_ec_group_get_cofactor(VALUE self) /* * call-seq: - * group.curve_name => String + * group.curve_name -> string or nil * - * Returns the curve name (sn). + * Returns the curve name (short name) corresponding to this group, or +nil+ + * if \OpenSSL does not have an OID associated with the group. * * See the OpenSSL documentation for EC_GROUP_get_curve_name() */ static VALUE ossl_ec_group_get_curve_name(VALUE self) { - EC_GROUP *group = NULL; + EC_GROUP *group; int nid; GetECGroup(self, group); - if (group == NULL) - return Qnil; - nid = EC_GROUP_get_curve_name(group); - -/* BUG: an nid or asn1 object should be returned, maybe. */ - return rb_str_new2(OBJ_nid2sn(nid)); + if (nid == NID_undef) + return Qnil; + return rb_str_new_cstr(OBJ_nid2sn(nid)); } /* @@ -1076,37 +958,36 @@ static VALUE ossl_ec_group_set_asn1_flag(VALUE self, VALUE flag_v) */ static VALUE ossl_ec_group_get_point_conversion_form(VALUE self) { - EC_GROUP *group = NULL; + EC_GROUP *group; point_conversion_form_t form; - VALUE ret; GetECGroup(self, group); form = EC_GROUP_get_point_conversion_form(group); switch (form) { - case POINT_CONVERSION_UNCOMPRESSED: ret = ID_uncompressed; break; - case POINT_CONVERSION_COMPRESSED: ret = ID_compressed; break; - case POINT_CONVERSION_HYBRID: ret = ID_hybrid; break; - default: ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, this module should be updated", form); + case POINT_CONVERSION_UNCOMPRESSED: + return sym_uncompressed; + case POINT_CONVERSION_COMPRESSED: + return sym_compressed; + case POINT_CONVERSION_HYBRID: + return sym_hybrid; + default: + ossl_raise(eEC_GROUP, "unsupported point conversion form: %d, " \ + "this module should be updated", form); } - - return ID2SYM(ret); } static point_conversion_form_t parse_point_conversion_form_symbol(VALUE sym) { - ID id = SYM2ID(sym); - - if (id == ID_uncompressed) - return POINT_CONVERSION_UNCOMPRESSED; - else if (id == ID_compressed) - return POINT_CONVERSION_COMPRESSED; - else if (id == ID_hybrid) - return POINT_CONVERSION_HYBRID; - else - ossl_raise(rb_eArgError, "unsupported point conversion form %+"PRIsVALUE - " (expected :compressed, :uncompressed, or :hybrid)", sym); + if (sym == sym_uncompressed) + return POINT_CONVERSION_UNCOMPRESSED; + if (sym == sym_compressed) + return POINT_CONVERSION_COMPRESSED; + if (sym == sym_hybrid) + return POINT_CONVERSION_HYBRID; + ossl_raise(rb_eArgError, "unsupported point conversion form %+"PRIsVALUE + " (expected :compressed, :uncompressed, or :hybrid)", sym); } /* @@ -1211,20 +1092,20 @@ static VALUE ossl_ec_group_to_string(VALUE self, int format) ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())"); switch(format) { - case EXPORT_PEM: + case EXPORT_PEM: i = PEM_write_bio_ECPKParameters(out, group); - break; - case EXPORT_DER: + break; + case EXPORT_DER: i = i2d_ECPKParameters_bio(out, group); - break; - default: + break; + default: BIO_free(out); - ossl_raise(rb_eRuntimeError, "unknown format (internal error)"); + ossl_raise(rb_eRuntimeError, "unknown format (internal error)"); } if (i != 1) { BIO_free(out); - ossl_raise(eECError, NULL); + ossl_raise(ePKeyError, NULL); } str = ossl_membio2str(out); @@ -1268,11 +1149,11 @@ static VALUE ossl_ec_group_to_text(VALUE self) GetECGroup(self, group); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())"); + ossl_raise(eEC_GROUP, "BIO_new(BIO_s_mem())"); } if (!ECPKParameters_print(out, group, 0)) { - BIO_free(out); - ossl_raise(eEC_GROUP, NULL); + BIO_free(out); + ossl_raise(eEC_GROUP, NULL); } str = ossl_membio2str(out); @@ -1292,9 +1173,9 @@ ossl_ec_point_free(void *ptr) static const rb_data_type_t ossl_ec_point_type = { "OpenSSL/EC_POINT", { - 0, ossl_ec_point_free, + 0, ossl_ec_point_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -1312,7 +1193,7 @@ ec_point_new(const EC_POINT *point, const EC_GROUP *group) obj = ossl_ec_point_alloc(cEC_POINT); point_new = EC_POINT_dup(point, group); if (!point_new) - ossl_raise(eEC_POINT, "EC_POINT_dup"); + ossl_raise(eEC_POINT, "EC_POINT_dup"); RTYPEDDATA_DATA(obj) = point_new; rb_ivar_set(obj, id_i_group, ec_group_new(group)); @@ -1340,39 +1221,39 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point); if (point) - rb_raise(eEC_POINT, "EC_POINT already initialized"); + rb_raise(eEC_POINT, "EC_POINT already initialized"); rb_scan_args(argc, argv, "11", &group_v, &arg2); if (rb_obj_is_kind_of(group_v, cEC_POINT)) { - if (argc != 1) - rb_raise(rb_eArgError, "invalid second argument"); - return ossl_ec_point_initialize_copy(self, group_v); + if (argc != 1) + rb_raise(rb_eArgError, "invalid second argument"); + return ossl_ec_point_initialize_copy(self, group_v); } GetECGroup(group_v, group); if (argc == 1) { - point = EC_POINT_new(group); - if (!point) - ossl_raise(eEC_POINT, "EC_POINT_new"); + point = EC_POINT_new(group); + if (!point) + ossl_raise(eEC_POINT, "EC_POINT_new"); } else { - if (rb_obj_is_kind_of(arg2, cBN)) { - point = EC_POINT_bn2point(group, GetBNPtr(arg2), NULL, ossl_bn_ctx); - if (!point) - ossl_raise(eEC_POINT, "EC_POINT_bn2point"); - } - else { - StringValue(arg2); - point = EC_POINT_new(group); - if (!point) - ossl_raise(eEC_POINT, "EC_POINT_new"); - if (!EC_POINT_oct2point(group, point, - (unsigned char *)RSTRING_PTR(arg2), - RSTRING_LEN(arg2), ossl_bn_ctx)) { - EC_POINT_free(point); - ossl_raise(eEC_POINT, "EC_POINT_oct2point"); - } - } + if (rb_obj_is_kind_of(arg2, cBN)) { + point = EC_POINT_bn2point(group, GetBNPtr(arg2), NULL, ossl_bn_ctx); + if (!point) + ossl_raise(eEC_POINT, "EC_POINT_bn2point"); + } + else { + StringValue(arg2); + point = EC_POINT_new(group); + if (!point) + ossl_raise(eEC_POINT, "EC_POINT_new"); + if (!EC_POINT_oct2point(group, point, + (unsigned char *)RSTRING_PTR(arg2), + RSTRING_LEN(arg2), ossl_bn_ctx)) { + EC_POINT_free(point); + ossl_raise(eEC_POINT, "EC_POINT_oct2point"); + } + } } RTYPEDDATA_DATA(self) = point; @@ -1381,6 +1262,7 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_ec_point_initialize_copy(VALUE self, VALUE other) { @@ -1390,7 +1272,7 @@ ossl_ec_point_initialize_copy(VALUE self, VALUE other) TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point_new); if (point_new) - ossl_raise(eEC_POINT, "EC::Point already initialized"); + ossl_raise(eEC_POINT, "EC::Point already initialized"); GetECPoint(other, point); group_v = rb_obj_dup(rb_attr_get(other, id_i_group)); @@ -1398,7 +1280,7 @@ ossl_ec_point_initialize_copy(VALUE self, VALUE other) point_new = EC_POINT_dup(point, group); if (!point_new) - ossl_raise(eEC_POINT, "EC_POINT_dup"); + ossl_raise(eEC_POINT, "EC_POINT_dup"); RTYPEDDATA_DATA(self) = point_new; rb_ivar_set(self, id_i_group, group_v); @@ -1424,10 +1306,13 @@ static VALUE ossl_ec_point_eql(VALUE a, VALUE b) GetECPoint(b, point2); GetECGroup(group_v1, group); - if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1) - return Qfalse; + switch (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx)) { + case 0: return Qtrue; + case 1: return Qfalse; + default: ossl_raise(eEC_POINT, "EC_POINT_cmp"); + } - return Qtrue; + UNREACHABLE; } /* @@ -1443,9 +1328,9 @@ static VALUE ossl_ec_point_is_at_infinity(VALUE self) GetECPointGroup(self, group); switch (EC_POINT_is_at_infinity(group, point)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: ossl_raise(cEC_POINT, "EC_POINT_is_at_infinity"); + case 1: return Qtrue; + case 0: return Qfalse; + default: ossl_raise(eEC_POINT, "EC_POINT_is_at_infinity"); } UNREACHABLE; @@ -1464,9 +1349,9 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self) GetECPointGroup(self, group); switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) { - case 1: return Qtrue; - case 0: return Qfalse; - default: ossl_raise(cEC_POINT, "EC_POINT_is_on_curve"); + case 1: return Qtrue; + case 0: return Qfalse; + default: ossl_raise(eEC_POINT, "EC_POINT_is_on_curve"); } UNREACHABLE; @@ -1475,6 +1360,8 @@ static VALUE ossl_ec_point_is_on_curve(VALUE self) /* * call-seq: * point.make_affine! => self + * + * This method is deprecated and should not be used. This is a no-op. */ static VALUE ossl_ec_point_make_affine(VALUE self) { @@ -1484,8 +1371,11 @@ static VALUE ossl_ec_point_make_affine(VALUE self) GetECPoint(self, point); GetECPointGroup(self, group); + rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated"); +#if !defined(OSSL_HAVE_IMMUTABLE_PKEY) && !defined(OPENSSL_IS_AWSLC) if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1) - ossl_raise(cEC_POINT, "EC_POINT_make_affine"); + ossl_raise(eEC_POINT, "EC_POINT_make_affine"); +#endif return self; } @@ -1503,7 +1393,7 @@ static VALUE ossl_ec_point_invert(VALUE self) GetECPointGroup(self, group); if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1) - ossl_raise(cEC_POINT, "EC_POINT_invert"); + ossl_raise(eEC_POINT, "EC_POINT_invert"); return self; } @@ -1521,7 +1411,7 @@ static VALUE ossl_ec_point_set_to_infinity(VALUE self) GetECPointGroup(self, group); if (EC_POINT_set_to_infinity(group, point) != 1) - ossl_raise(cEC_POINT, "EC_POINT_set_to_infinity"); + ossl_raise(eEC_POINT, "EC_POINT_set_to_infinity"); return self; } @@ -1553,19 +1443,46 @@ ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form) len = EC_POINT_point2oct(group, point, form, NULL, 0, ossl_bn_ctx); if (!len) - ossl_raise(eEC_POINT, "EC_POINT_point2oct"); + ossl_raise(eEC_POINT, "EC_POINT_point2oct"); str = rb_str_new(NULL, (long)len); if (!EC_POINT_point2oct(group, point, form, - (unsigned char *)RSTRING_PTR(str), len, - ossl_bn_ctx)) - ossl_raise(eEC_POINT, "EC_POINT_point2oct"); + (unsigned char *)RSTRING_PTR(str), len, + ossl_bn_ctx)) + ossl_raise(eEC_POINT, "EC_POINT_point2oct"); return str; } /* * call-seq: + * point.add(point) => point + * + * Performs elliptic curve point addition. + */ +static VALUE ossl_ec_point_add(VALUE self, VALUE other) +{ + EC_POINT *point_self, *point_other, *point_result; + const EC_GROUP *group; + VALUE group_v = rb_attr_get(self, id_i_group); + VALUE result; + + GetECPoint(self, point_self); + GetECPoint(other, point_other); + GetECGroup(group_v, group); + + result = rb_obj_alloc(cEC_POINT); + ossl_ec_point_initialize(1, &group_v, result); + GetECPoint(result, point_result); + + if (EC_POINT_add(group, point_result, point_self, point_other, ossl_bn_ctx) != 1) { + ossl_raise(eEC_POINT, "EC_POINT_add"); + } + + return result; +} + +/* + * call-seq: * point.mul(bn1 [, bn2]) => point - * point.mul(bns, points [, bn2]) => point * * Performs elliptic curve point multiplication. * @@ -1573,11 +1490,9 @@ ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form) * generator of the group of _point_. _bn2_ may be omitted, and in that case, * the result is just <tt>bn1 * point</tt>. * - * The second form calculates <tt>bns[0] * point + bns[1] * points[0] + ... - * + bns[-1] * points[-1] + bn2 * G</tt>. _bn2_ may be omitted. _bns_ must be - * an array of OpenSSL::BN. _points_ must be an array of - * OpenSSL::PKey::EC::Point. Please note that <tt>points[0]</tt> is not - * multiplied by <tt>bns[0]</tt>, but <tt>bns[1]</tt>. + * Before version 4.0.0, and when compiled with OpenSSL 1.1.1 or older, this + * method allowed another form: + * point.mul(bns, points [, bn2]) => point */ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) { @@ -1595,54 +1510,15 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) GetECPoint(result, point_result); rb_scan_args(argc, argv, "12", &arg1, &arg2, &arg3); - if (!RB_TYPE_P(arg1, T_ARRAY)) { - BIGNUM *bn = GetBNPtr(arg1); + if (RB_TYPE_P(arg1, T_ARRAY) || argc > 2) + rb_raise(rb_eNotImpError, "OpenSSL::PKey::EC::Point#mul with arrays " \ + "is no longer supported"); - if (!NIL_P(arg2)) - bn_g = GetBNPtr(arg2); - if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1) - ossl_raise(eEC_POINT, NULL); - } else { - /* - * bignums | arg1[0] | arg1[1] | arg1[2] | ... - * points | self | arg2[0] | arg2[1] | ... - */ - long i, num; - VALUE bns_tmp, tmp_p, tmp_b; - const EC_POINT **points; - const BIGNUM **bignums; - - Check_Type(arg1, T_ARRAY); - Check_Type(arg2, T_ARRAY); - if (RARRAY_LEN(arg1) != RARRAY_LEN(arg2) + 1) /* arg2 must be 1 larger */ - ossl_raise(rb_eArgError, "bns must be 1 longer than points; see the documentation"); - - num = RARRAY_LEN(arg1); - bns_tmp = rb_ary_tmp_new(num); - bignums = ALLOCV_N(const BIGNUM *, tmp_b, num); - for (i = 0; i < num; i++) { - VALUE item = RARRAY_AREF(arg1, i); - bignums[i] = GetBNPtr(item); - rb_ary_push(bns_tmp, item); - } - - points = ALLOCV_N(const EC_POINT *, tmp_p, num); - points[0] = point_self; /* self */ - for (i = 0; i < num - 1; i++) - GetECPoint(RARRAY_AREF(arg2, i), points[i + 1]); - - if (!NIL_P(arg3)) - bn_g = GetBNPtr(arg3); - - if (EC_POINTs_mul(group, point_result, bn_g, num, points, bignums, ossl_bn_ctx) != 1) { - ALLOCV_END(tmp_b); - ALLOCV_END(tmp_p); - ossl_raise(eEC_POINT, NULL); - } - - ALLOCV_END(tmp_b); - ALLOCV_END(tmp_p); - } + BIGNUM *bn = GetBNPtr(arg1); + if (!NIL_P(arg2)) + bn_g = GetBNPtr(arg2); + if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1) + ossl_raise(eEC_POINT, NULL); return result; } @@ -1650,15 +1526,6 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) void Init_ossl_ec(void) { #undef rb_intern -#if 0 - mPKey = rb_define_module_under(mOSSL, "PKey"); - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); -#endif - - eECError = rb_define_class_under(mPKey, "ECError", ePKeyError); - /* * Document-class: OpenSSL::PKey::EC * @@ -1680,28 +1547,23 @@ void Init_ossl_ec(void) eEC_GROUP = rb_define_class_under(cEC_GROUP, "Error", eOSSLError); eEC_POINT = rb_define_class_under(cEC_POINT, "Error", eOSSLError); - s_GFp = rb_intern("GFp"); - s_GF2m = rb_intern("GF2m"); - s_GFp_simple = rb_intern("GFp_simple"); - s_GFp_mont = rb_intern("GFp_mont"); - s_GFp_nist = rb_intern("GFp_nist"); - s_GF2m_simple = rb_intern("GF2m_simple"); + sym_GFp = ID2SYM(rb_intern_const("GFp")); + sym_GF2m = ID2SYM(rb_intern_const("GF2m")); - ID_uncompressed = rb_intern("uncompressed"); - ID_compressed = rb_intern("compressed"); - ID_hybrid = rb_intern("hybrid"); + sym_uncompressed = ID2SYM(rb_intern_const("uncompressed")); + sym_compressed = ID2SYM(rb_intern_const("compressed")); + sym_hybrid = ID2SYM(rb_intern_const("hybrid")); rb_define_const(cEC, "NAMED_CURVE", INT2NUM(OPENSSL_EC_NAMED_CURVE)); -#if defined(OPENSSL_EC_EXPLICIT_CURVE) rb_define_const(cEC, "EXPLICIT_CURVE", INT2NUM(OPENSSL_EC_EXPLICIT_CURVE)); -#endif rb_define_singleton_method(cEC, "builtin_curves", ossl_s_builtin_curves, 0); rb_define_singleton_method(cEC, "generate", ossl_ec_key_s_generate, 1); rb_define_method(cEC, "initialize", ossl_ec_key_initialize, -1); +#ifndef HAVE_EVP_PKEY_DUP rb_define_method(cEC, "initialize_copy", ossl_ec_key_initialize_copy, 1); -/* copy/dup/cmp */ +#endif rb_define_method(cEC, "group", ossl_ec_key_get_group, 0); rb_define_method(cEC, "group=", ossl_ec_key_set_group, 1); @@ -1724,15 +1586,9 @@ void Init_ossl_ec(void) rb_define_alias(cEC, "generate_key", "generate_key!"); rb_define_method(cEC, "check_key", ossl_ec_key_check_key, 0); - rb_define_method(cEC, "dh_compute_key", ossl_ec_key_dh_compute_key, 1); - rb_define_method(cEC, "dsa_sign_asn1", ossl_ec_key_dsa_sign_asn1, 1); - rb_define_method(cEC, "dsa_verify_asn1", ossl_ec_key_dsa_verify_asn1, 2); -/* do_sign/do_verify */ - rb_define_method(cEC, "export", ossl_ec_key_export, -1); rb_define_alias(cEC, "to_pem", "export"); rb_define_method(cEC, "to_der", ossl_ec_key_to_der, 0); - rb_define_method(cEC, "to_text", ossl_ec_key_to_text, 0); rb_define_alloc_func(cEC_GROUP, ossl_ec_group_alloc); @@ -1786,6 +1642,7 @@ void Init_ossl_ec(void) /* all the other methods */ rb_define_method(cEC_POINT, "to_octet_string", ossl_ec_point_to_octet_string, 1); + rb_define_method(cEC_POINT, "add", ossl_ec_point_add, 1); rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1); id_i_group = rb_intern("@group"); diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index 4800fb2710..039b2c6a34 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -14,26 +14,28 @@ #define GetPKeyRSA(obj, pkey) do { \ GetPKey((obj), (pkey)); \ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { /* PARANOIA? */ \ - ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \ + ossl_raise(rb_eRuntimeError, "THIS IS NOT A RSA!") ; \ } \ } while (0) #define GetRSA(obj, rsa) do { \ EVP_PKEY *_pkey; \ GetPKeyRSA((obj), _pkey); \ (rsa) = EVP_PKEY_get0_RSA(_pkey); \ + if ((rsa) == NULL) \ + ossl_raise(ePKeyError, "failed to get RSA from EVP_PKEY"); \ } while (0) static inline int -RSA_HAS_PRIVATE(RSA *rsa) +RSA_HAS_PRIVATE(OSSL_3_const RSA *rsa) { - const BIGNUM *p, *q; + const BIGNUM *e, *d; - RSA_get0_factors(rsa, &p, &q); - return p && q; /* d? why? */ + RSA_get0_key(rsa, NULL, &e, &d); + return e && d; } static inline int -RSA_PRIVATE(VALUE obj, RSA *rsa) +RSA_PRIVATE(VALUE obj, OSSL_3_const RSA *rsa) { return RSA_HAS_PRIVATE(rsa) || OSSL_PKEY_IS_PRIVATE(obj); } @@ -42,254 +44,133 @@ RSA_PRIVATE(VALUE obj, RSA *rsa) * Classes */ VALUE cRSA; -VALUE eRSAError; - -/* - * Public - */ -static VALUE -rsa_instance(VALUE klass, RSA *rsa) -{ - EVP_PKEY *pkey; - VALUE obj; - - if (!rsa) { - return Qfalse; - } - obj = NewPKey(klass); - if (!(pkey = EVP_PKEY_new())) { - return Qfalse; - } - if (!EVP_PKEY_assign_RSA(pkey, rsa)) { - EVP_PKEY_free(pkey); - return Qfalse; - } - SetPKey(obj, pkey); - - return obj; -} - -VALUE -ossl_rsa_new(EVP_PKEY *pkey) -{ - VALUE obj; - - if (!pkey) { - obj = rsa_instance(cRSA, RSA_new()); - } - else { - obj = NewPKey(cRSA); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA) { - ossl_raise(rb_eTypeError, "Not a RSA key!"); - } - SetPKey(obj, pkey); - } - if (obj == Qfalse) { - ossl_raise(eRSAError, NULL); - } - - return obj; -} /* * Private */ -struct rsa_blocking_gen_arg { - RSA *rsa; - BIGNUM *e; - int size; - BN_GENCB *cb; - int result; -}; - -static void * -rsa_blocking_gen(void *arg) -{ - struct rsa_blocking_gen_arg *gen = (struct rsa_blocking_gen_arg *)arg; - gen->result = RSA_generate_key_ex(gen->rsa, gen->size, gen->e, gen->cb); - return 0; -} - -static RSA * -rsa_generate(int size, unsigned long exp) -{ - int i; - struct ossl_generate_cb_arg cb_arg = { 0 }; - struct rsa_blocking_gen_arg gen_arg; - RSA *rsa = RSA_new(); - BIGNUM *e = BN_new(); - BN_GENCB *cb = BN_GENCB_new(); - - if (!rsa || !e || !cb) { - RSA_free(rsa); - BN_free(e); - BN_GENCB_free(cb); - return NULL; - } - for (i = 0; i < (int)sizeof(exp) * 8; ++i) { - if (exp & (1UL << i)) { - if (BN_set_bit(e, i) == 0) { - BN_free(e); - RSA_free(rsa); - BN_GENCB_free(cb); - return NULL; - } - } - } - - if (rb_block_given_p()) - cb_arg.yield = 1; - BN_GENCB_set(cb, ossl_generate_cb_2, &cb_arg); - gen_arg.rsa = rsa; - gen_arg.e = e; - gen_arg.size = size; - gen_arg.cb = cb; - if (cb_arg.yield == 1) { - /* we cannot release GVL when callback proc is supplied */ - rsa_blocking_gen(&gen_arg); - } else { - /* there's a chance to unblock */ - rb_thread_call_without_gvl(rsa_blocking_gen, &gen_arg, ossl_generate_cb_stop, &cb_arg); - } - - BN_GENCB_free(cb); - BN_free(e); - if (!gen_arg.result) { - RSA_free(rsa); - if (cb_arg.state) { - /* must clear OpenSSL error stack */ - ossl_clear_error(); - rb_jump_tag(cb_arg.state); - } - return NULL; - } - - return rsa; -} - /* * call-seq: - * RSA.generate(size) => RSA instance - * RSA.generate(size, exponent) => RSA instance + * RSA.new -> rsa + * RSA.new(encoded_key [, password ]) -> rsa + * RSA.new(encoded_key) { password } -> rsa + * RSA.new(size [, exponent]) -> rsa * - * Generates an RSA keypair. _size_ is an integer representing the desired key - * size. Keys smaller than 1024 should be considered insecure. _exponent_ is - * an odd number normally 3, 17, or 65537. - */ -static VALUE -ossl_rsa_s_generate(int argc, VALUE *argv, VALUE klass) -{ -/* why does this method exist? why can't initialize take an optional exponent? */ - RSA *rsa; - VALUE size, exp; - VALUE obj; - - rb_scan_args(argc, argv, "11", &size, &exp); - - rsa = rsa_generate(NUM2INT(size), NIL_P(exp) ? RSA_F4 : NUM2ULONG(exp)); /* err handled by rsa_instance */ - obj = rsa_instance(klass, rsa); - - if (obj == Qfalse) { - RSA_free(rsa); - ossl_raise(eRSAError, NULL); - } - - return obj; -} - -/* - * call-seq: - * RSA.new(key_size) => RSA instance - * RSA.new(encoded_key) => RSA instance - * RSA.new(encoded_key, pass_phrase) => RSA instance + * Generates or loads an \RSA keypair. * - * Generates or loads an RSA keypair. If an integer _key_size_ is given it - * represents the desired key size. Keys less than 1024 bits should be - * considered insecure. + * If called without arguments, creates a new instance with no key components + * set. They can be set individually by #set_key, #set_factors, and + * #set_crt_params. + * This form is not compatible with OpenSSL 3.0 or later. * - * A key can instead be loaded from an _encoded_key_ which must be PEM or DER - * encoded. A _pass_phrase_ can be used to decrypt the key. If none is given - * OpenSSL will prompt for the pass phrase. + * If called with a String, tries to parse as DER or PEM encoding of an \RSA key. + * Note that if _password_ is not specified, but the key is encrypted with a + * password, \OpenSSL will prompt for it. + * See also OpenSSL::PKey.read which can parse keys of any kind. * - * = Examples + * If called with a number, generates a new key pair. This form works as an + * alias of RSA.generate. * + * Examples: * OpenSSL::PKey::RSA.new 2048 * OpenSSL::PKey::RSA.new File.read 'rsa.pem' - * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my pass phrase' + * OpenSSL::PKey::RSA.new File.read('rsa.pem'), 'my password' */ static VALUE ossl_rsa_initialize(int argc, VALUE *argv, VALUE self) { EVP_PKEY *pkey; RSA *rsa; - BIO *in; + BIO *in = NULL; VALUE arg, pass; - - GetPKey(self, pkey); - if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) { - rsa = RSA_new(); - } - else if (RB_INTEGER_TYPE_P(arg)) { - rsa = rsa_generate(NUM2INT(arg), NIL_P(pass) ? RSA_F4 : NUM2ULONG(pass)); - if (!rsa) ossl_raise(eRSAError, NULL); - } - else { - pass = ossl_pem_passwd_value(pass); - arg = ossl_to_der_if_possible(arg); - in = ossl_obj2bio(&arg); - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, (void *)pass); - if (!rsa) { - OSSL_BIO_reset(in); - rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = d2i_RSA_PUBKEY_bio(in, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); - } - if (!rsa) { - OSSL_BIO_reset(in); - rsa = d2i_RSAPublicKey_bio(in, NULL); - } - BIO_free(in); - if (!rsa) { - ossl_raise(eRSAError, "Neither PUB key nor PRIV key"); - } + int type; + + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); + + /* The RSA.new(size, generator) form is handled by lib/openssl/pkey.rb */ + rb_scan_args(argc, argv, "02", &arg, &pass); + if (argc == 0) { +#ifdef OSSL_HAVE_IMMUTABLE_PKEY + rb_raise(rb_eArgError, "OpenSSL::PKey::RSA.new cannot be called " \ + "without arguments; pkeys are immutable with OpenSSL 3.0"); +#else + rsa = RSA_new(); + if (!rsa) + ossl_raise(ePKeyError, "RSA_new"); + goto legacy; +#endif } - if (!EVP_PKEY_assign_RSA(pkey, rsa)) { - RSA_free(rsa); - ossl_raise(eRSAError, NULL); + + pass = ossl_pem_passwd_value(pass); + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); + + /* First try RSAPublicKey format */ + rsa = d2i_RSAPublicKey_bio(in, NULL); + if (rsa) + goto legacy; + OSSL_BIO_reset(in); + rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL); + if (rsa) + goto legacy; + OSSL_BIO_reset(in); + + /* Use the generic routine */ + pkey = ossl_pkey_read_generic(in, pass); + BIO_free(in); + if (!pkey) + ossl_raise(ePKeyError, "Neither PUB key nor PRIV key"); + + type = EVP_PKEY_base_id(pkey); + if (type != EVP_PKEY_RSA) { + EVP_PKEY_free(pkey); + rb_raise(ePKeyError, "incorrect pkey type: %s", OBJ_nid2sn(type)); } + RTYPEDDATA_DATA(self) = pkey; + return self; + legacy: + BIO_free(in); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa) != 1) { + EVP_PKEY_free(pkey); + RSA_free(rsa); + ossl_raise(ePKeyError, "EVP_PKEY_assign_RSA"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#ifndef HAVE_EVP_PKEY_DUP +/* :nodoc: */ static VALUE ossl_rsa_initialize_copy(VALUE self, VALUE other) { EVP_PKEY *pkey; RSA *rsa, *rsa_new; - GetPKey(self, pkey); - if (EVP_PKEY_base_id(pkey) != EVP_PKEY_NONE) - ossl_raise(eRSAError, "RSA already initialized"); + TypedData_Get_Struct(self, EVP_PKEY, &ossl_evp_pkey_type, pkey); + if (pkey) + rb_raise(rb_eTypeError, "pkey already initialized"); GetRSA(other, rsa); - rsa_new = ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, (d2i_of_void *)d2i_RSAPrivateKey, (char *)rsa); + rsa_new = (RSA *)ASN1_dup((i2d_of_void *)i2d_RSAPrivateKey, + (d2i_of_void *)d2i_RSAPrivateKey, + (char *)rsa); if (!rsa_new) - ossl_raise(eRSAError, "ASN1_dup"); + ossl_raise(ePKeyError, "ASN1_dup"); - EVP_PKEY_assign_RSA(pkey, rsa_new); + pkey = EVP_PKEY_new(); + if (!pkey || EVP_PKEY_assign_RSA(pkey, rsa_new) != 1) { + RSA_free(rsa_new); + ossl_raise(ePKeyError, "EVP_PKEY_assign_RSA"); + } + RTYPEDDATA_DATA(self) = pkey; return self; } +#endif /* * call-seq: @@ -301,7 +182,7 @@ ossl_rsa_initialize_copy(VALUE self, VALUE other) static VALUE ossl_rsa_is_public(VALUE self) { - RSA *rsa; + OSSL_3_const RSA *rsa; GetRSA(self, rsa); /* @@ -320,220 +201,115 @@ ossl_rsa_is_public(VALUE self) static VALUE ossl_rsa_is_private(VALUE self) { - RSA *rsa; + OSSL_3_const RSA *rsa; GetRSA(self, rsa); return RSA_PRIVATE(self, rsa) ? Qtrue : Qfalse; } -/* - * call-seq: - * rsa.export([cipher, pass_phrase]) => PEM-format String - * rsa.to_pem([cipher, pass_phrase]) => PEM-format String - * rsa.to_s([cipher, pass_phrase]) => PEM-format String - * - * Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are - * given they will be used to encrypt the key. _cipher_ must be an - * OpenSSL::Cipher instance. - */ -static VALUE -ossl_rsa_export(int argc, VALUE *argv, VALUE self) +static int +can_export_rsaprivatekey(VALUE self) { - RSA *rsa; - BIO *out; - const EVP_CIPHER *ciph = NULL; - VALUE cipher, pass, str; + OSSL_3_const RSA *rsa; + const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; GetRSA(self, rsa); - rb_scan_args(argc, argv, "02", &cipher, &pass); - - if (!NIL_P(cipher)) { - ciph = ossl_evp_get_cipherbyname(cipher); - pass = ossl_pem_passwd_value(pass); - } - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eRSAError, NULL); - } - if (RSA_HAS_PRIVATE(rsa)) { - if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0, - ossl_pem_passwd_cb, (void *)pass)) { - BIO_free(out); - ossl_raise(eRSAError, NULL); - } - } else { - if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) { - BIO_free(out); - ossl_raise(eRSAError, NULL); - } - } - str = ossl_membio2str(out); + RSA_get0_key(rsa, &n, &e, &d); + RSA_get0_factors(rsa, &p, &q); + RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); - return str; + return n && e && d && p && q && dmp1 && dmq1 && iqmp; } /* * call-seq: - * rsa.to_der => DER-format String + * rsa.export([cipher, password]) => PEM-format String + * rsa.to_pem([cipher, password]) => PEM-format String + * rsa.to_s([cipher, password]) => PEM-format String + * + * Serializes a private or public key to a PEM-encoding. + * + * [When the key contains public components only] + * + * Serializes it into an X.509 SubjectPublicKeyInfo. + * The parameters _cipher_ and _password_ are ignored. * - * Outputs this keypair in DER encoding. + * A PEM-encoded key will look like: + * + * -----BEGIN PUBLIC KEY----- + * [...] + * -----END PUBLIC KEY----- + * + * Consider using #public_to_pem instead. This serializes the key into an + * X.509 SubjectPublicKeyInfo regardless of whether the key is a public key + * or a private key. + * + * [When the key contains private components, and no parameters are given] + * + * Serializes it into a PKCS #1 RSAPrivateKey. + * + * A PEM-encoded key will look like: + * + * -----BEGIN RSA PRIVATE KEY----- + * [...] + * -----END RSA PRIVATE KEY----- + * + * [When the key contains private components, and _cipher_ and _password_ are given] + * + * Serializes it into a PKCS #1 RSAPrivateKey + * and encrypts it in OpenSSL's traditional PEM encryption format. + * _cipher_ must be a cipher name understood by OpenSSL::Cipher.new or an + * instance of OpenSSL::Cipher. + * + * An encrypted PEM-encoded key will look like: + * + * -----BEGIN RSA PRIVATE KEY----- + * Proc-Type: 4,ENCRYPTED + * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 + * + * [...] + * -----END RSA PRIVATE KEY----- + * + * Note that this format uses MD5 to derive the encryption key, and hence + * will not be available on FIPS-compliant systems. + * + * <b>This method is kept for compatibility.</b> + * This should only be used when the PKCS #1 RSAPrivateKey format is required. + * + * Consider using #public_to_pem (X.509 SubjectPublicKeyInfo) or #private_to_pem + * (PKCS #8 PrivateKeyInfo or EncryptedPrivateKeyInfo) instead. */ static VALUE -ossl_rsa_to_der(VALUE self) +ossl_rsa_export(int argc, VALUE *argv, VALUE self) { - RSA *rsa; - int (*i2d_func)(const RSA *, unsigned char **); - unsigned char *p; - long len; - VALUE str; - - GetRSA(self, rsa); - if (RSA_HAS_PRIVATE(rsa)) - i2d_func = i2d_RSAPrivateKey; + if (can_export_rsaprivatekey(self)) + return ossl_pkey_export_traditional(argc, argv, self, 0); else - i2d_func = (int (*)(const RSA *, unsigned char **))i2d_RSA_PUBKEY; - if((len = i2d_func(rsa, NULL)) <= 0) - ossl_raise(eRSAError, NULL); - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - if(i2d_func(rsa, &p) < 0) - ossl_raise(eRSAError, NULL); - ossl_str_adjust(str, p); - - return str; + return ossl_pkey_export_spki(self, 0); } /* * call-seq: - * rsa.public_encrypt(string) => String - * rsa.public_encrypt(string, padding) => String + * rsa.to_der => DER-format String * - * Encrypt _string_ with the public key. _padding_ defaults to PKCS1_PADDING. - * The encrypted string output can be decrypted using #private_decrypt. - */ -static VALUE -ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self) -{ - RSA *rsa; - const BIGNUM *rsa_n; - int buf_len, pad; - VALUE str, buffer, padding; - - GetRSA(self, rsa); - RSA_get0_key(rsa, &rsa_n, NULL, NULL); - if (!rsa_n) - ossl_raise(eRSAError, "incomplete RSA"); - rb_scan_args(argc, argv, "11", &buffer, &padding); - pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); - StringValue(buffer); - str = rb_str_new(0, RSA_size(rsa)); - buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), - (unsigned char *)RSTRING_PTR(str), rsa, pad); - if (buf_len < 0) ossl_raise(eRSAError, NULL); - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * rsa.public_decrypt(string) => String - * rsa.public_decrypt(string, padding) => String + * Serializes a private or public key to a DER-encoding. * - * Decrypt _string_, which has been encrypted with the private key, with the - * public key. _padding_ defaults to PKCS1_PADDING. - */ -static VALUE -ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self) -{ - RSA *rsa; - const BIGNUM *rsa_n; - int buf_len, pad; - VALUE str, buffer, padding; - - GetRSA(self, rsa); - RSA_get0_key(rsa, &rsa_n, NULL, NULL); - if (!rsa_n) - ossl_raise(eRSAError, "incomplete RSA"); - rb_scan_args(argc, argv, "11", &buffer, &padding); - pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); - StringValue(buffer); - str = rb_str_new(0, RSA_size(rsa)); - buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), - (unsigned char *)RSTRING_PTR(str), rsa, pad); - if (buf_len < 0) ossl_raise(eRSAError, NULL); - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * rsa.private_encrypt(string) => String - * rsa.private_encrypt(string, padding) => String + * See #to_pem for details. * - * Encrypt _string_ with the private key. _padding_ defaults to PKCS1_PADDING. - * The encrypted string output can be decrypted using #public_decrypt. - */ -static VALUE -ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self) -{ - RSA *rsa; - const BIGNUM *rsa_n; - int buf_len, pad; - VALUE str, buffer, padding; - - GetRSA(self, rsa); - RSA_get0_key(rsa, &rsa_n, NULL, NULL); - if (!rsa_n) - ossl_raise(eRSAError, "incomplete RSA"); - if (!RSA_PRIVATE(self, rsa)) - ossl_raise(eRSAError, "private key needed."); - rb_scan_args(argc, argv, "11", &buffer, &padding); - pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); - StringValue(buffer); - str = rb_str_new(0, RSA_size(rsa)); - buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), - (unsigned char *)RSTRING_PTR(str), rsa, pad); - if (buf_len < 0) ossl_raise(eRSAError, NULL); - rb_str_set_len(str, buf_len); - - return str; -} - -/* - * call-seq: - * rsa.private_decrypt(string) => String - * rsa.private_decrypt(string, padding) => String + * <b>This method is kept for compatibility.</b> + * This should only be used when the PKCS #1 RSAPrivateKey format is required. * - * Decrypt _string_, which has been encrypted with the public key, with the - * private key. _padding_ defaults to PKCS1_PADDING. + * Consider using #public_to_der or #private_to_der instead. */ static VALUE -ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self) +ossl_rsa_to_der(VALUE self) { - RSA *rsa; - const BIGNUM *rsa_n; - int buf_len, pad; - VALUE str, buffer, padding; - - GetRSA(self, rsa); - RSA_get0_key(rsa, &rsa_n, NULL, NULL); - if (!rsa_n) - ossl_raise(eRSAError, "incomplete RSA"); - if (!RSA_PRIVATE(self, rsa)) - ossl_raise(eRSAError, "private key needed."); - rb_scan_args(argc, argv, "11", &buffer, &padding); - pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding); - StringValue(buffer); - str = rb_str_new(0, RSA_size(rsa)); - buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer), - (unsigned char *)RSTRING_PTR(str), rsa, pad); - if (buf_len < 0) ossl_raise(eRSAError, NULL); - rb_str_set_len(str, buf_len); - - return str; + if (can_export_rsaprivatekey(self)) + return ossl_pkey_export_traditional(0, NULL, self, 1); + else + return ossl_pkey_export_spki(self, 1); } /* @@ -543,7 +319,7 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self) * Signs _data_ using the Probabilistic Signature Scheme (RSA-PSS) and returns * the calculated signature. * - * RSAError will be raised if an error occurs. + * PKeyError will be raised if an error occurs. * * See #verify_pss for the verification operation. * @@ -565,14 +341,14 @@ ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self) * data = "Sign me!" * pkey = OpenSSL::PKey::RSA.new(2048) * signature = pkey.sign_pss("SHA256", data, salt_length: :max, mgf1_hash: "SHA256") - * pub_key = pkey.public_key + * pub_key = OpenSSL::PKey.read(pkey.public_to_der) * puts pub_key.verify_pss("SHA256", signature, data, * salt_length: :auto, mgf1_hash: "SHA256") # => true */ static VALUE ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) { - VALUE digest, data, options, kwargs[2], signature; + VALUE digest, data, options, kwargs[2], signature, mgf1md_holder, md_holder; static ID kwargs_ids[2]; EVP_PKEY *pkey; EVP_PKEY_CTX *pkey_ctx; @@ -582,46 +358,46 @@ ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) int salt_len; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt_length"); - kwargs_ids[1] = rb_intern_const("mgf1_hash"); + kwargs_ids[0] = rb_intern_const("salt_length"); + kwargs_ids[1] = rb_intern_const("mgf1_hash"); } rb_scan_args(argc, argv, "2:", &digest, &data, &options); rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs); if (kwargs[0] == ID2SYM(rb_intern("max"))) - salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */ + salt_len = -2; /* RSA_PSS_SALTLEN_MAX_SIGN */ else if (kwargs[0] == ID2SYM(rb_intern("digest"))) - salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ + salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ else - salt_len = NUM2INT(kwargs[0]); - mgf1md = ossl_evp_get_digestbyname(kwargs[1]); + salt_len = NUM2INT(kwargs[0]); + mgf1md = ossl_evp_md_fetch(kwargs[1], &mgf1md_holder); pkey = GetPrivPKeyPtr(self); buf_len = EVP_PKEY_size(pkey); - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(data); signature = rb_str_new(NULL, (long)buf_len); md_ctx = EVP_MD_CTX_new(); if (!md_ctx) - goto err; + goto err; if (EVP_DigestSignInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1) - goto err; + goto err; if (EVP_DigestSignUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) - goto err; + goto err; if (EVP_DigestSignFinal(md_ctx, (unsigned char *)RSTRING_PTR(signature), &buf_len) != 1) - goto err; + goto err; rb_str_set_len(signature, (long)buf_len); @@ -630,7 +406,7 @@ ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) err: EVP_MD_CTX_free(md_ctx); - ossl_raise(eRSAError, NULL); + ossl_raise(ePKeyError, NULL); } /* @@ -640,7 +416,7 @@ ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) * Verifies _data_ using the Probabilistic Signature Scheme (RSA-PSS). * * The return value is +true+ if the signature is valid, +false+ otherwise. - * RSAError will be raised if an error occurs. + * PKeyError will be raised if an error occurs. * * See #sign_pss for the signing operation and an example code. * @@ -659,7 +435,7 @@ ossl_rsa_sign_pss(int argc, VALUE *argv, VALUE self) static VALUE ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self) { - VALUE digest, signature, data, options, kwargs[2]; + VALUE digest, signature, data, options, kwargs[2], mgf1md_holder, md_holder; static ID kwargs_ids[2]; EVP_PKEY *pkey; EVP_PKEY_CTX *pkey_ctx; @@ -668,183 +444,64 @@ ossl_rsa_verify_pss(int argc, VALUE *argv, VALUE self) int result, salt_len; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("salt_length"); - kwargs_ids[1] = rb_intern_const("mgf1_hash"); + kwargs_ids[0] = rb_intern_const("salt_length"); + kwargs_ids[1] = rb_intern_const("mgf1_hash"); } rb_scan_args(argc, argv, "3:", &digest, &signature, &data, &options); rb_get_kwargs(options, kwargs_ids, 2, 0, kwargs); if (kwargs[0] == ID2SYM(rb_intern("auto"))) - salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */ + salt_len = -2; /* RSA_PSS_SALTLEN_AUTO */ else if (kwargs[0] == ID2SYM(rb_intern("digest"))) - salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ + salt_len = -1; /* RSA_PSS_SALTLEN_DIGEST */ else - salt_len = NUM2INT(kwargs[0]); - mgf1md = ossl_evp_get_digestbyname(kwargs[1]); + salt_len = NUM2INT(kwargs[0]); + mgf1md = ossl_evp_md_fetch(kwargs[1], &mgf1md_holder); GetPKey(self, pkey); - md = ossl_evp_get_digestbyname(digest); + md = ossl_evp_md_fetch(digest, &md_holder); StringValue(signature); StringValue(data); md_ctx = EVP_MD_CTX_new(); if (!md_ctx) - goto err; + goto err; if (EVP_DigestVerifyInit(md_ctx, &pkey_ctx, md, NULL, pkey) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len) != 1) - goto err; + goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1md) != 1) - goto err; + goto err; if (EVP_DigestVerifyUpdate(md_ctx, RSTRING_PTR(data), RSTRING_LEN(data)) != 1) - goto err; + goto err; result = EVP_DigestVerifyFinal(md_ctx, - (unsigned char *)RSTRING_PTR(signature), - RSTRING_LEN(signature)); + (unsigned char *)RSTRING_PTR(signature), + RSTRING_LEN(signature)); + EVP_MD_CTX_free(md_ctx); switch (result) { case 0: - ossl_clear_error(); - EVP_MD_CTX_free(md_ctx); - return Qfalse; + ossl_clear_error(); + return Qfalse; case 1: - EVP_MD_CTX_free(md_ctx); - return Qtrue; + return Qtrue; default: - goto err; + ossl_raise(ePKeyError, "EVP_DigestVerifyFinal"); } err: EVP_MD_CTX_free(md_ctx); - ossl_raise(eRSAError, NULL); -} - -/* - * call-seq: - * rsa.params => hash - * - * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!! - * - * Stores all parameters of key to the hash. The hash has keys 'n', 'e', 'd', - * 'p', 'q', 'dmp1', 'dmq1', 'iqmp'. - * - * Don't use :-)) (It's up to you) - */ -static VALUE -ossl_rsa_get_params(VALUE self) -{ - RSA *rsa; - VALUE hash; - const BIGNUM *n, *e, *d, *p, *q, *dmp1, *dmq1, *iqmp; - - GetRSA(self, rsa); - RSA_get0_key(rsa, &n, &e, &d); - RSA_get0_factors(rsa, &p, &q); - RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); - - hash = rb_hash_new(); - rb_hash_aset(hash, rb_str_new2("n"), ossl_bn_new(n)); - rb_hash_aset(hash, rb_str_new2("e"), ossl_bn_new(e)); - rb_hash_aset(hash, rb_str_new2("d"), ossl_bn_new(d)); - rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p)); - rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q)); - rb_hash_aset(hash, rb_str_new2("dmp1"), ossl_bn_new(dmp1)); - rb_hash_aset(hash, rb_str_new2("dmq1"), ossl_bn_new(dmq1)); - rb_hash_aset(hash, rb_str_new2("iqmp"), ossl_bn_new(iqmp)); - - return hash; + ossl_raise(ePKeyError, NULL); } /* - * call-seq: - * rsa.to_text => String - * - * THIS METHOD IS INSECURE, PRIVATE INFORMATION CAN LEAK OUT!!! - * - * Dumps all parameters of a keypair to a String - * - * Don't use :-)) (It's up to you) - */ -static VALUE -ossl_rsa_to_text(VALUE self) -{ - RSA *rsa; - BIO *out; - VALUE str; - - GetRSA(self, rsa); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eRSAError, NULL); - } - if (!RSA_print(out, rsa, 0)) { /* offset = 0 */ - BIO_free(out); - ossl_raise(eRSAError, NULL); - } - str = ossl_membio2str(out); - - return str; -} - -/* - * call-seq: - * rsa.public_key -> RSA - * - * Makes new RSA instance containing the public key from the private key. - */ -static VALUE -ossl_rsa_to_public_key(VALUE self) -{ - EVP_PKEY *pkey; - RSA *rsa; - VALUE obj; - - GetPKeyRSA(self, pkey); - /* err check performed by rsa_instance */ - rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(pkey)); - obj = rsa_instance(rb_obj_class(self), rsa); - if (obj == Qfalse) { - RSA_free(rsa); - ossl_raise(eRSAError, NULL); - } - return obj; -} - -/* - * TODO: Test me - -static VALUE -ossl_rsa_blinding_on(VALUE self) -{ - RSA *rsa; - - GetRSA(self, rsa); - - if (RSA_blinding_on(rsa, ossl_bn_ctx) != 1) { - ossl_raise(eRSAError, NULL); - } - return self; -} - -static VALUE -ossl_rsa_blinding_off(VALUE self) -{ - RSA *rsa; - - GetRSA(self, rsa); - RSA_blinding_off(rsa); - - return self; -} - */ - -/* * Document-method: OpenSSL::PKey::RSA#set_key * call-seq: * rsa.set_key(n, e, d) -> self @@ -879,20 +536,6 @@ OSSL_PKEY_BN_DEF3(rsa, RSA, crt_params, dmp1, dmq1, iqmp) void Init_ossl_rsa(void) { -#if 0 - mPKey = rb_define_module_under(mOSSL, "PKey"); - cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject); - ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError); -#endif - - /* Document-class: OpenSSL::PKey::RSAError - * - * Generic exception that is raised if an operation on an RSA PKey - * fails unexpectedly or in case an instantiation of an instance of RSA - * fails due to non-conformant input data. - */ - eRSAError = rb_define_class_under(mPKey, "RSAError", ePKeyError); - /* Document-class: OpenSSL::PKey::RSA * * RSA is an asymmetric public key algorithm that has been formalized in @@ -905,22 +548,17 @@ Init_ossl_rsa(void) */ cRSA = rb_define_class_under(mPKey, "RSA", cPKey); - rb_define_singleton_method(cRSA, "generate", ossl_rsa_s_generate, -1); rb_define_method(cRSA, "initialize", ossl_rsa_initialize, -1); +#ifndef HAVE_EVP_PKEY_DUP rb_define_method(cRSA, "initialize_copy", ossl_rsa_initialize_copy, 1); +#endif rb_define_method(cRSA, "public?", ossl_rsa_is_public, 0); rb_define_method(cRSA, "private?", ossl_rsa_is_private, 0); - rb_define_method(cRSA, "to_text", ossl_rsa_to_text, 0); rb_define_method(cRSA, "export", ossl_rsa_export, -1); rb_define_alias(cRSA, "to_pem", "export"); rb_define_alias(cRSA, "to_s", "export"); rb_define_method(cRSA, "to_der", ossl_rsa_to_der, 0); - rb_define_method(cRSA, "public_key", ossl_rsa_to_public_key, 0); - rb_define_method(cRSA, "public_encrypt", ossl_rsa_public_encrypt, -1); - rb_define_method(cRSA, "public_decrypt", ossl_rsa_public_decrypt, -1); - rb_define_method(cRSA, "private_encrypt", ossl_rsa_private_encrypt, -1); - rb_define_method(cRSA, "private_decrypt", ossl_rsa_private_decrypt, -1); rb_define_method(cRSA, "sign_pss", ossl_rsa_sign_pss, -1); rb_define_method(cRSA, "verify_pss", ossl_rsa_verify_pss, -1); @@ -936,13 +574,6 @@ Init_ossl_rsa(void) rb_define_method(cRSA, "set_factors", ossl_rsa_set_factors, 2); rb_define_method(cRSA, "set_crt_params", ossl_rsa_set_crt_params, 3); - rb_define_method(cRSA, "params", ossl_rsa_get_params, 0); - - DefRSAConst(PKCS1_PADDING); - DefRSAConst(SSLV23_PADDING); - DefRSAConst(NO_PADDING); - DefRSAConst(PKCS1_OAEP_PADDING); - /* * TODO: Test it rb_define_method(cRSA, "blinding_on!", ossl_rsa_blinding_on, 0); diff --git a/ext/openssl/ossl_provider.c b/ext/openssl/ossl_provider.c new file mode 100644 index 0000000000..ea5abb8e48 --- /dev/null +++ b/ext/openssl/ossl_provider.c @@ -0,0 +1,204 @@ +/* + * This program is licensed under the same licence as Ruby. + * (See the file 'COPYING'.) + */ +#include "ossl.h" + +#ifdef OSSL_USE_PROVIDER +#define NewProvider(klass) \ + TypedData_Wrap_Struct((klass), &ossl_provider_type, 0) +#define SetProvider(obj, provider) do { \ + if (!(provider)) { \ + ossl_raise(rb_eRuntimeError, "Provider wasn't initialized."); \ + } \ + RTYPEDDATA_DATA(obj) = (provider); \ +} while(0) +#define GetProvider(obj, provider) do { \ + TypedData_Get_Struct((obj), OSSL_PROVIDER, &ossl_provider_type, (provider)); \ + if (!(provider)) { \ + ossl_raise(rb_eRuntimeError, "PROVIDER wasn't initialized."); \ + } \ +} while (0) + +static const rb_data_type_t ossl_provider_type = { + "OpenSSL/Provider", + { + 0, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +/* + * Classes + */ +/* Document-class: OpenSSL::Provider + * + * This class is the access to openssl's Provider + * See also, https://www.openssl.org/docs/manmaster/man7/provider.html + */ +static VALUE cProvider; +/* Document-class: OpenSSL::Provider::ProviderError + * + * This is the generic exception for OpenSSL::Provider related errors + */ +static VALUE eProviderError; + +/* + * call-seq: + * OpenSSL::Provider.load(name) -> provider + * + * This method loads and initializes a provider + */ +static VALUE +ossl_provider_s_load(VALUE klass, VALUE name) +{ + OSSL_PROVIDER *provider = NULL; + VALUE obj; + + const char *provider_name_ptr = StringValueCStr(name); + + provider = OSSL_PROVIDER_load(NULL, provider_name_ptr); + if (provider == NULL) { + ossl_raise(eProviderError, "Failed to load %s provider", provider_name_ptr); + } + obj = NewProvider(klass); + SetProvider(obj, provider); + + return obj; +} + +struct ary_with_state { VALUE ary; int state; }; +struct rb_push_provider_name_args { OSSL_PROVIDER *prov; VALUE ary; }; + +static VALUE +rb_push_provider_name(VALUE rb_push_provider_name_args) +{ + struct rb_push_provider_name_args *args = (struct rb_push_provider_name_args *)rb_push_provider_name_args; + + VALUE name = rb_str_new2(OSSL_PROVIDER_get0_name(args->prov)); + return rb_ary_push(args->ary, name); +} + +static int +push_provider(OSSL_PROVIDER *prov, void *cbdata) +{ + struct ary_with_state *ary_with_state = (struct ary_with_state *)cbdata; + struct rb_push_provider_name_args args = { prov, ary_with_state->ary }; + + rb_protect(rb_push_provider_name, (VALUE)&args, &ary_with_state->state); + if (ary_with_state->state) { + return 0; + } else { + return 1; + } +} + +/* + * call-seq: + * OpenSSL::Provider.provider_names -> [provider_name, ...] + * + * Returns an array of currently loaded provider names. + */ +static VALUE +ossl_provider_s_provider_names(VALUE klass) +{ + VALUE ary = rb_ary_new(); + struct ary_with_state cbdata = { ary, 0 }; + + int result = OSSL_PROVIDER_do_all(NULL, &push_provider, (void*)&cbdata); + if (result != 1 ) { + if (cbdata.state) { + rb_jump_tag(cbdata.state); + } else { + ossl_raise(eProviderError, "Failed to load provider names"); + } + } + + return ary; +} + +/* + * call-seq: + * provider.unload -> true + * + * This method unloads this provider. + * + * if provider unload fails or already unloaded, it raises OpenSSL::Provider::ProviderError + */ +static VALUE +ossl_provider_unload(VALUE self) +{ + OSSL_PROVIDER *prov; + if (RTYPEDDATA_DATA(self) == NULL) { + ossl_raise(eProviderError, "Provider already unloaded."); + } + GetProvider(self, prov); + + int result = OSSL_PROVIDER_unload(prov); + + if (result != 1) { + ossl_raise(eProviderError, "Failed to unload provider"); + } + RTYPEDDATA_DATA(self) = NULL; + return Qtrue; +} + +/* + * call-seq: + * provider.name -> string + * + * Get the name of this provider. + * + * if this provider is already unloaded, it raises OpenSSL::Provider::ProviderError + */ +static VALUE +ossl_provider_get_name(VALUE self) +{ + OSSL_PROVIDER *prov; + if (RTYPEDDATA_DATA(self) == NULL) { + ossl_raise(eProviderError, "Provider already unloaded."); + } + GetProvider(self, prov); + + return rb_str_new2(OSSL_PROVIDER_get0_name(prov)); +} + +/* + * call-seq: + * provider.inspect -> string + * + * Pretty prints this provider. + */ +static VALUE +ossl_provider_inspect(VALUE self) +{ + OSSL_PROVIDER *prov; + if (RTYPEDDATA_DATA(self) == NULL ) { + return rb_sprintf("#<%"PRIsVALUE" unloaded provider>", rb_obj_class(self)); + } + GetProvider(self, prov); + + return rb_sprintf("#<%"PRIsVALUE" name=\"%s\">", + rb_obj_class(self), OSSL_PROVIDER_get0_name(prov)); +} + +void +Init_ossl_provider(void) +{ + cProvider = rb_define_class_under(mOSSL, "Provider", rb_cObject); + eProviderError = rb_define_class_under(cProvider, "ProviderError", eOSSLError); + + rb_undef_alloc_func(cProvider); + rb_define_singleton_method(cProvider, "load", ossl_provider_s_load, 1); + rb_define_singleton_method(cProvider, "provider_names", ossl_provider_s_provider_names, 0); + + rb_define_method(cProvider, "unload", ossl_provider_unload, 0); + rb_define_method(cProvider, "name", ossl_provider_get_name, 0); + rb_define_method(cProvider, "inspect", ossl_provider_inspect, 0); +} +#else +void +Init_ossl_provider(void) +{ +} +#endif diff --git a/ext/openssl/ossl_provider.h b/ext/openssl/ossl_provider.h new file mode 100644 index 0000000000..1d69cb1e44 --- /dev/null +++ b/ext/openssl/ossl_provider.h @@ -0,0 +1,5 @@ +#if !defined(OSSL_PROVIDER_H) +#define OSSL_PROVIDER_H + +void Init_ossl_provider(void); +#endif diff --git a/ext/openssl/ossl_rand.c b/ext/openssl/ossl_rand.c index c95857060a..753f8b25f7 100644 --- a/ext/openssl/ossl_rand.c +++ b/ext/openssl/ossl_rand.c @@ -5,12 +5,12 @@ * All rights reserved. * * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" -VALUE mRandom; -VALUE eRandomError; +static VALUE mRandom; +static VALUE eRandomError; /* * call-seq: @@ -67,10 +67,8 @@ ossl_rand_add(VALUE self, VALUE str, VALUE entropy) static VALUE ossl_rand_load_file(VALUE self, VALUE filename) { - rb_check_safe_obj(filename); - if(!RAND_load_file(StringValueCStr(filename), -1)) { - ossl_raise(eRandomError, NULL); + ossl_raise(eRandomError, NULL); } return Qtrue; } @@ -86,17 +84,15 @@ ossl_rand_load_file(VALUE self, VALUE filename) static VALUE ossl_rand_write_file(VALUE self, VALUE filename) { - rb_check_safe_obj(filename); - if (RAND_write_file(StringValueCStr(filename)) == -1) { - ossl_raise(eRandomError, NULL); + ossl_raise(eRandomError, NULL); } return Qtrue; } /* * call-seq: - * random_bytes(length) -> string + * random_bytes(length) -> string * * Generates a String with _length_ number of cryptographically strong * pseudo-random bytes. @@ -116,44 +112,14 @@ ossl_rand_bytes(VALUE self, VALUE len) str = rb_str_new(0, n); ret = RAND_bytes((unsigned char *)RSTRING_PTR(str), n); if (ret == 0) { - ossl_raise(eRandomError, "RAND_bytes"); + ossl_raise(eRandomError, "RAND_bytes"); } else if (ret == -1) { - ossl_raise(eRandomError, "RAND_bytes is not supported"); + ossl_raise(eRandomError, "RAND_bytes is not supported"); } return str; } -#if defined(HAVE_RAND_PSEUDO_BYTES) -/* - * call-seq: - * pseudo_bytes(length) -> string - * - * Generates a String with _length_ number of pseudo-random bytes. - * - * Pseudo-random byte sequences generated by ::pseudo_bytes will be unique if - * they are of sufficient length, but are not necessarily unpredictable. - * - * === Example - * - * OpenSSL::Random.pseudo_bytes(12) - * #=> "..." - */ -static VALUE -ossl_rand_pseudo_bytes(VALUE self, VALUE len) -{ - VALUE str; - int n = NUM2INT(len); - - str = rb_str_new(0, n); - if (RAND_pseudo_bytes((unsigned char *)RSTRING_PTR(str), n) < 1) { - ossl_raise(eRandomError, NULL); - } - - return str; -} -#endif - #ifdef HAVE_RAND_EGD /* * call-seq: @@ -164,10 +130,8 @@ ossl_rand_pseudo_bytes(VALUE self, VALUE len) static VALUE ossl_rand_egd(VALUE self, VALUE filename) { - rb_check_safe_obj(filename); - if (RAND_egd(StringValueCStr(filename)) == -1) { - ossl_raise(eRandomError, NULL); + ossl_raise(eRandomError, NULL); } return Qtrue; } @@ -186,10 +150,8 @@ ossl_rand_egd_bytes(VALUE self, VALUE filename, VALUE len) { int n = NUM2INT(len); - rb_check_safe_obj(filename); - if (RAND_egd_bytes(StringValueCStr(filename), n) == -1) { - ossl_raise(eRandomError, NULL); + ossl_raise(eRandomError, NULL); } return Qtrue; } @@ -213,11 +175,6 @@ ossl_rand_status(VALUE self) void Init_ossl_rand(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - mRandom = rb_define_module_under(mOSSL, "Random"); eRandomError = rb_define_class_under(mRandom, "RandomError", eOSSLError); @@ -227,9 +184,7 @@ Init_ossl_rand(void) rb_define_module_function(mRandom, "load_random_file", ossl_rand_load_file, 1); rb_define_module_function(mRandom, "write_random_file", ossl_rand_write_file, 1); rb_define_module_function(mRandom, "random_bytes", ossl_rand_bytes, 1); -#if defined(HAVE_RAND_PSEUDO_BYTES) - rb_define_module_function(mRandom, "pseudo_bytes", ossl_rand_pseudo_bytes, 1); -#endif + rb_define_alias(rb_singleton_class(mRandom), "pseudo_bytes", "random_bytes"); #ifdef HAVE_RAND_EGD rb_define_module_function(mRandom, "egd", ossl_rand_egd, 1); rb_define_module_function(mRandom, "egd_bytes", ossl_rand_egd_bytes, 2); diff --git a/ext/openssl/ossl_rand.h b/ext/openssl/ossl_rand.h index 8f77a3b239..294986d017 100644 --- a/ext/openssl/ossl_rand.h +++ b/ext/openssl/ossl_rand.h @@ -5,14 +5,11 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_RAND_H_) #define _OSSL_RAND_H_ -extern VALUE mRandom; -extern VALUE eRandomError; - void Init_ossl_rand(void); #endif /* _OSSL_RAND_H_ */ diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index f25dc959b1..630d46e43f 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -7,12 +7,17 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" +#ifndef OPENSSL_NO_SOCK #define numberof(ary) (int)(sizeof(ary)/sizeof((ary)[0])) +#if !defined(OPENSSL_NO_NEXTPROTONEG) && !OSSL_IS_LIBRESSL +# define OSSL_USE_NEXTPROTONEG +#endif + #ifdef _WIN32 # define TO_SOCKET(s) _get_osfhandle(s) #else @@ -20,56 +25,52 @@ #endif #define GetSSLCTX(obj, ctx) do { \ - TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \ + TypedData_Get_Struct((obj), SSL_CTX, &ossl_sslctx_type, (ctx)); \ } while (0) VALUE mSSL; -static VALUE mSSLExtConfig; static VALUE eSSLError; -VALUE cSSLContext; +static VALUE cSSLContext; VALUE cSSLSocket; static VALUE eSSLErrorWaitReadable; static VALUE eSSLErrorWaitWritable; -static ID id_call, ID_callback_state, id_tmp_dh_callback, id_tmp_ecdh_callback, - id_npn_protocols_encoded; +static ID id_call, ID_callback_state, id_npn_protocols_encoded, id_each; static VALUE sym_exception, sym_wait_readable, sym_wait_writable; static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode, - id_i_verify_depth, id_i_verify_callback, id_i_client_ca, - id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert, - id_i_client_cert_cb, id_i_tmp_ecdh_callback, id_i_timeout, - id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb, - id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols, - id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb, - id_i_verify_hostname; + id_i_verify_depth, id_i_verify_callback, id_i_client_ca, + id_i_renegotiation_cb, id_i_cert, id_i_key, id_i_extra_chain_cert, + id_i_client_cert_cb, id_i_timeout, + id_i_session_id_context, id_i_session_get_cb, id_i_session_new_cb, + id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols, + id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb, + id_i_verify_hostname, id_i_keylog_cb, id_i_tmp_dh_callback; static ID id_i_io, id_i_context, id_i_hostname; -static int ossl_ssl_ex_vcb_idx; static int ossl_ssl_ex_ptr_idx; static int ossl_sslctx_ex_ptr_idx; -#if !defined(HAVE_X509_STORE_UP_REF) -static int ossl_sslctx_ex_store_p; -#endif static void -ossl_sslctx_free(void *ptr) +ossl_sslctx_mark(void *ptr) { SSL_CTX *ctx = ptr; -#if !defined(HAVE_X509_STORE_UP_REF) - if (ctx && SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_store_p)) - ctx->cert_store = NULL; -#endif - SSL_CTX_free(ctx); + rb_gc_mark((VALUE)SSL_CTX_get_ex_data(ctx, ossl_sslctx_ex_ptr_idx)); +} + +static void +ossl_sslctx_free(void *ptr) +{ + SSL_CTX_free(ptr); } static const rb_data_type_t ossl_sslctx_type = { "OpenSSL/SSL/CTX", { - 0, ossl_sslctx_free, + ossl_sslctx_mark, ossl_sslctx_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -77,126 +78,24 @@ ossl_sslctx_s_alloc(VALUE klass) { SSL_CTX *ctx; long mode = 0 | - SSL_MODE_ENABLE_PARTIAL_WRITE | - SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | - SSL_MODE_RELEASE_BUFFERS; + SSL_MODE_ENABLE_PARTIAL_WRITE | + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | + SSL_MODE_RELEASE_BUFFERS; VALUE obj; obj = TypedData_Wrap_Struct(klass, &ossl_sslctx_type, 0); -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) ctx = SSL_CTX_new(TLS_method()); -#else - ctx = SSL_CTX_new(SSLv23_method()); -#endif if (!ctx) { ossl_raise(eSSLError, "SSL_CTX_new"); } SSL_CTX_set_mode(ctx, mode); + SSL_CTX_set_dh_auto(ctx, 1); RTYPEDDATA_DATA(obj) = ctx; SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_ptr_idx, (void *)obj); -#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_ECDH_AUTO) - /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It - * allows to specify multiple curve names and OpenSSL will select - * automatically from them. In OpenSSL 1.0.2, the automatic selection has to - * be enabled explicitly. But OpenSSL 1.1.0 removed the knob and it is - * always enabled. To uniform the behavior, we enable the automatic - * selection also in 1.0.2. Users can still disable ECDH by removing ECDH - * cipher suites by SSLContext#ciphers=. */ - if (!SSL_CTX_set_ecdh_auto(ctx, 1)) - ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto"); -#endif - return obj; } -static int -parse_proto_version(VALUE str) -{ - int i; - static const struct { - const char *name; - int version; - } map[] = { - { "SSL2", SSL2_VERSION }, - { "SSL3", SSL3_VERSION }, - { "TLS1", TLS1_VERSION }, - { "TLS1_1", TLS1_1_VERSION }, - { "TLS1_2", TLS1_2_VERSION }, -#ifdef TLS1_3_VERSION - { "TLS1_3", TLS1_3_VERSION }, -#endif - }; - - if (NIL_P(str)) - return 0; - if (RB_INTEGER_TYPE_P(str)) - return NUM2INT(str); - - if (SYMBOL_P(str)) - str = rb_sym2str(str); - StringValue(str); - for (i = 0; i < numberof(map); i++) - if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str))) - return map[i].version; - rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str); -} - -/* - * call-seq: - * ctx.set_minmax_proto_version(min, max) -> nil - * - * Sets the minimum and maximum supported protocol versions. See #min_version= - * and #max_version=. - */ -static VALUE -ossl_sslctx_set_minmax_proto_version(VALUE self, VALUE min_v, VALUE max_v) -{ - SSL_CTX *ctx; - int min, max; - - GetSSLCTX(self, ctx); - min = parse_proto_version(min_v); - max = parse_proto_version(max_v); - -#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION - if (!SSL_CTX_set_min_proto_version(ctx, min)) - ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version"); - if (!SSL_CTX_set_max_proto_version(ctx, max)) - ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version"); -#else - { - unsigned long sum = 0, opts = 0; - int i; - static const struct { - int ver; - unsigned long opts; - } options_map[] = { - { SSL2_VERSION, SSL_OP_NO_SSLv2 }, - { SSL3_VERSION, SSL_OP_NO_SSLv3 }, - { TLS1_VERSION, SSL_OP_NO_TLSv1 }, - { TLS1_1_VERSION, SSL_OP_NO_TLSv1_1 }, - { TLS1_2_VERSION, SSL_OP_NO_TLSv1_2 }, -# if defined(TLS1_3_VERSION) - { TLS1_3_VERSION, SSL_OP_NO_TLSv1_3 }, -# endif - }; - - for (i = 0; i < numberof(options_map); i++) { - sum |= options_map[i].opts; - if ((min && min > options_map[i].ver) || - (max && max < options_map[i].ver)) { - opts |= options_map[i].opts; - } - } - SSL_CTX_clear_options(ctx, sum); - SSL_CTX_set_options(ctx, opts); - } -#endif - - return Qnil; -} - static VALUE ossl_call_client_cert_cb(VALUE obj) { @@ -205,7 +104,7 @@ ossl_call_client_cert_cb(VALUE obj) ctx_obj = rb_attr_get(obj, id_i_context); cb = rb_attr_get(ctx_obj, id_i_client_cert_cb); if (NIL_P(cb)) - return Qnil; + return Qnil; ary = rb_funcallv(cb, id_call, 1, &obj); Check_Type(ary, T_ARRAY); @@ -223,7 +122,7 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); ret = rb_protect(ossl_call_client_cert_cb, obj, NULL); if (NIL_P(ret)) - return 0; + return 0; *x509 = DupX509CertPtr(RARRAY_AREF(ret, 0)); *pkey = DupPKeyPtr(RARRAY_AREF(ret, 1)); @@ -231,93 +130,50 @@ ossl_client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey) return 1; } -#if !defined(OPENSSL_NO_DH) || \ - !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) +#if !defined(OPENSSL_NO_DH) struct tmp_dh_callback_args { VALUE ssl_obj; - ID id; - int type; int is_export; int keylength; }; -static EVP_PKEY * -ossl_call_tmp_dh_callback(struct tmp_dh_callback_args *args) +static VALUE +ossl_call_tmp_dh_callback(VALUE arg) { - VALUE cb, dh; - EVP_PKEY *pkey; + struct tmp_dh_callback_args *args = (struct tmp_dh_callback_args *)arg; + VALUE ctx_obj, cb, obj; + const DH *dh; - cb = rb_funcall(args->ssl_obj, args->id, 0); + ctx_obj = rb_attr_get(args->ssl_obj, id_i_context); + cb = rb_attr_get(ctx_obj, id_i_tmp_dh_callback); if (NIL_P(cb)) - return NULL; - dh = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export), - INT2NUM(args->keylength)); - pkey = GetPKeyPtr(dh); - if (EVP_PKEY_base_id(pkey) != args->type) - return NULL; + return (VALUE)NULL; + + obj = rb_funcall(cb, id_call, 3, args->ssl_obj, INT2NUM(args->is_export), + INT2NUM(args->keylength)); + // TODO: We should riase if obj is not DH + dh = EVP_PKEY_get0_DH(GetPKeyPtr(obj)); + if (!dh) + ossl_clear_error(); - return pkey; + return (VALUE)dh; } -#endif -#if !defined(OPENSSL_NO_DH) static DH * ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength) { - VALUE rb_ssl; - EVP_PKEY *pkey; - struct tmp_dh_callback_args args; int state; - - rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - args.ssl_obj = rb_ssl; - args.id = id_tmp_dh_callback; - args.is_export = is_export; - args.keylength = keylength; - args.type = EVP_PKEY_DH; - - pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback, - (VALUE)&args, &state); + VALUE rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + struct tmp_dh_callback_args args = {rb_ssl, is_export, keylength}; + VALUE ret = rb_protect(ossl_call_tmp_dh_callback, (VALUE)&args, &state); if (state) { - rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state)); - return NULL; + rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state)); + return NULL; } - if (!pkey) - return NULL; - - return EVP_PKEY_get0_DH(pkey); + return (DH *)ret; } #endif /* OPENSSL_NO_DH */ -#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) -static EC_KEY * -ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength) -{ - VALUE rb_ssl; - EVP_PKEY *pkey; - struct tmp_dh_callback_args args; - int state; - - rb_ssl = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - args.ssl_obj = rb_ssl; - args.id = id_tmp_ecdh_callback; - args.is_export = is_export; - args.keylength = keylength; - args.type = EVP_PKEY_EC; - - pkey = (EVP_PKEY *)rb_protect((VALUE (*)(VALUE))ossl_call_tmp_dh_callback, - (VALUE)&args, &state); - if (state) { - rb_ivar_set(rb_ssl, ID_callback_state, INT2NUM(state)); - return NULL; - } - if (!pkey) - return NULL; - - return EVP_PKEY_get0_EC_KEY(pkey); -} -#endif - static VALUE call_verify_certificate_identity(VALUE ctx_v) { @@ -330,13 +186,13 @@ call_verify_certificate_identity(VALUE ctx_v) hostname = rb_attr_get(ssl_obj, id_i_hostname); if (!RTEST(hostname)) { - rb_warning("verify_hostname requires hostname to be set"); - return Qtrue; + rb_warning("verify_hostname requires hostname to be set"); + return Qtrue; } cert_obj = ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx)); return rb_funcall(mSSL, rb_intern("verify_certificate_identity"), 2, - cert_obj, hostname); + cert_obj, hostname); } static int @@ -347,19 +203,22 @@ ossl_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) int status; ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); - cb = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_vcb_idx); ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); sslctx_obj = rb_attr_get(ssl_obj, id_i_context); + cb = rb_attr_get(sslctx_obj, id_i_verify_callback); verify_hostname = rb_attr_get(sslctx_obj, id_i_verify_hostname); if (preverify_ok && RTEST(verify_hostname) && !SSL_is_server(ssl) && - !X509_STORE_CTX_get_error_depth(ctx)) { - ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status); - if (status) { - rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); - return 0; - } - preverify_ok = ret == Qtrue; + !X509_STORE_CTX_get_error_depth(ctx)) { + ret = rb_protect(call_verify_certificate_identity, (VALUE)ctx, &status); + if (status) { + rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); + return 0; + } + if (ret != Qtrue) { + preverify_ok = 0; + X509_STORE_CTX_set_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH); + } } return ossl_verify_cb_call(cb, preverify_ok, ctx); @@ -380,11 +239,7 @@ ossl_call_session_get_cb(VALUE ary) } static SSL_SESSION * -#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER) ossl_sslctx_session_get_cb(SSL *ssl, const unsigned char *buf, int len, int *copy) -#else -ossl_sslctx_session_get_cb(SSL *ssl, unsigned char *buf, int len, int *copy) -#endif { VALUE ary, ssl_obj, ret_obj; SSL_SESSION *sess; @@ -457,6 +312,54 @@ ossl_sslctx_session_new_cb(SSL *ssl, SSL_SESSION *sess) return 0; } +#if !OSSL_IS_LIBRESSL +/* + * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements + * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see + * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6). + */ + +struct ossl_call_keylog_cb_args { + VALUE ssl_obj; + const char * line; +}; + +static VALUE +ossl_call_keylog_cb(VALUE args_v) +{ + VALUE sslctx_obj, cb, line_v; + struct ossl_call_keylog_cb_args *args = (struct ossl_call_keylog_cb_args *) args_v; + + sslctx_obj = rb_attr_get(args->ssl_obj, id_i_context); + + cb = rb_attr_get(sslctx_obj, id_i_keylog_cb); + if (NIL_P(cb)) return Qnil; + + line_v = rb_str_new_cstr(args->line); + + return rb_funcall(cb, id_call, 2, args->ssl_obj, line_v); +} + +static void +ossl_sslctx_keylog_cb(const SSL *ssl, const char *line) +{ + VALUE ssl_obj; + struct ossl_call_keylog_cb_args args; + int state = 0; + + OSSL_Debug("SSL keylog callback entered"); + + ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + args.ssl_obj = ssl_obj; + args.line = line; + + rb_protect(ossl_call_keylog_cb, (VALUE)&args, &state); + if (state) { + rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); + } +} +#endif + static VALUE ossl_call_session_remove_cb(VALUE ary) { @@ -482,7 +385,7 @@ ossl_sslctx_session_remove_cb(SSL_CTX *ctx, SSL_SESSION *sess) * when SSL_CTX_free() is called. */ if (rb_during_gc()) - return; + return; OSSL_Debug("SSL SESSION remove callback entered"); @@ -513,8 +416,9 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg)) GetSSLCTX(arg, ctx); x509 = DupX509CertPtr(i); - if(!SSL_CTX_add_extra_chain_cert(ctx, x509)){ - ossl_raise(eSSLError, NULL); + if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) { + X509_free(x509); + ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert"); } return i; @@ -523,52 +427,42 @@ ossl_sslctx_add_extra_chain_cert_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, arg)) static VALUE ossl_sslctx_setup(VALUE self); static VALUE -ossl_call_servername_cb(VALUE ary) +ossl_call_servername_cb(VALUE arg) { - VALUE ssl_obj, sslctx_obj, cb, ret_obj; - - Check_Type(ary, T_ARRAY); - ssl_obj = rb_ary_entry(ary, 0); + SSL *ssl = (void *)arg; + const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); + if (!servername) + return Qnil; - sslctx_obj = rb_attr_get(ssl_obj, id_i_context); - cb = rb_attr_get(sslctx_obj, id_i_servername_cb); - if (NIL_P(cb)) return Qnil; + VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + VALUE sslctx_obj = rb_attr_get(ssl_obj, id_i_context); + VALUE cb = rb_attr_get(sslctx_obj, id_i_servername_cb); + VALUE ary = rb_assoc_new(ssl_obj, rb_str_new_cstr(servername)); - ret_obj = rb_funcallv(cb, id_call, 1, &ary); + VALUE ret_obj = rb_funcallv(cb, id_call, 1, &ary); if (rb_obj_is_kind_of(ret_obj, cSSLContext)) { - SSL *ssl; SSL_CTX *ctx2; - ossl_sslctx_setup(ret_obj); - GetSSL(ssl_obj, ssl); GetSSLCTX(ret_obj, ctx2); - SSL_set_SSL_CTX(ssl, ctx2); + if (!SSL_set_SSL_CTX(ssl, ctx2)) + ossl_raise(eSSLError, "SSL_set_SSL_CTX"); rb_ivar_set(ssl_obj, id_i_context, ret_obj); } else if (!NIL_P(ret_obj)) { - ossl_raise(rb_eArgError, "servername_cb must return an " - "OpenSSL::SSL::SSLContext object or nil"); + ossl_raise(rb_eArgError, "servername_cb must return an " + "OpenSSL::SSL::SSLContext object or nil"); } - return ret_obj; + return Qnil; } static int ssl_servername_cb(SSL *ssl, int *ad, void *arg) { - VALUE ary, ssl_obj; - int state = 0; - const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); - - if (!servername) - return SSL_TLSEXT_ERR_OK; - - ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - ary = rb_ary_new2(2); - rb_ary_push(ary, ssl_obj); - rb_ary_push(ary, rb_str_new2(servername)); + int state; - rb_protect(ossl_call_servername_cb, ary, &state); + rb_protect(ossl_call_servername_cb, (VALUE)ssl, &state); if (state) { + VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(state)); return SSL_TLSEXT_ERR_ALERT_FATAL; } @@ -589,15 +483,13 @@ ssl_renegotiation_cb(const SSL *ssl) rb_funcallv(cb, id_call, 1, &ssl_obj); } -#if !defined(OPENSSL_NO_NEXTPROTONEG) || \ - defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) static VALUE -ssl_npn_encode_protocol_i(VALUE cur, VALUE encoded) +ssl_npn_encode_protocol_i(RB_BLOCK_CALL_FUNC_ARGLIST(cur, encoded)) { int len = RSTRING_LENINT(cur); char len_byte; if (len < 1 || len > 255) - ossl_raise(eSSLError, "Advertised protocol must have length 1..255"); + ossl_raise(eSSLError, "Advertised protocol must have length 1..255"); /* Encode the length byte */ len_byte = len; rb_str_buf_cat(encoded, &len_byte, 1); @@ -609,7 +501,7 @@ static VALUE ssl_encode_npn_protocols(VALUE protocols) { VALUE encoded = rb_str_new(NULL, 0); - rb_iterate(rb_each, protocols, ssl_npn_encode_protocol_i, encoded); + rb_block_call(protocols, id_each, 0, 0, ssl_npn_encode_protocol_i, encoded); return encoded; } @@ -631,16 +523,16 @@ npn_select_cb_common_i(VALUE tmp) /* assume OpenSSL verifies this format */ /* The format is len_1|proto_1|...|len_n|proto_n */ while (in < in_end) { - l = *in++; - rb_ary_push(protocols, rb_str_new((const char *)in, l)); - in += l; + l = *in++; + rb_ary_push(protocols, rb_str_new((const char *)in, l)); + in += l; } selected = rb_funcallv(args->cb, id_call, 1, &protocols); StringValue(selected); len = RSTRING_LEN(selected); if (len < 1 || len >= 256) { - ossl_raise(eSSLError, "Selected protocol name must have length 1..255"); + ossl_raise(eSSLError, "Selected protocol name must have length 1..255"); } return selected; @@ -648,8 +540,8 @@ npn_select_cb_common_i(VALUE tmp) static int ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out, - unsigned char *outlen, const unsigned char *in, - unsigned int inlen) + unsigned char *outlen, const unsigned char *in, + unsigned int inlen) { VALUE selected; int status; @@ -661,10 +553,10 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out, selected = rb_protect(npn_select_cb_common_i, (VALUE)&args, &status); if (status) { - VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); + VALUE ssl_obj = (VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx); - rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); - return SSL_TLSEXT_ERR_ALERT_FATAL; + rb_ivar_set(ssl_obj, ID_callback_state, INT2NUM(status)); + return SSL_TLSEXT_ERR_ALERT_FATAL; } *out = (unsigned char *)RSTRING_PTR(selected); @@ -672,14 +564,13 @@ ssl_npn_select_cb_common(SSL *ssl, VALUE cb, const unsigned char **out, return SSL_TLSEXT_ERR_OK; } -#endif -#ifndef OPENSSL_NO_NEXTPROTONEG +#ifdef OSSL_USE_NEXTPROTONEG static int ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, - void *arg) + void *arg) { - VALUE protocols = (VALUE)arg; + VALUE protocols = rb_attr_get((VALUE)arg, id_npn_protocols_encoded); *out = (const unsigned char *) RSTRING_PTR(protocols); *outlen = RSTRING_LENINT(protocols); @@ -689,7 +580,7 @@ ssl_npn_advertise_cb(SSL *ssl, const unsigned char **out, unsigned int *outlen, static int ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, void *arg) + const unsigned char *in, unsigned int inlen, void *arg) { VALUE sslctx_obj, cb; @@ -697,14 +588,13 @@ ssl_npn_select_cb(SSL *ssl, unsigned char **out, unsigned char *outlen, cb = rb_attr_get(sslctx_obj, id_i_npn_select_cb); return ssl_npn_select_cb_common(ssl, cb, (const unsigned char **)out, - outlen, in, inlen); + outlen, in, inlen); } #endif -#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB static int ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, void *arg) + const unsigned char *in, unsigned int inlen, void *arg) { VALUE sslctx_obj, cb; @@ -713,7 +603,6 @@ ssl_alpn_select_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, return ssl_npn_select_cb_common(ssl, cb, out, outlen, in, inlen); } -#endif /* This function may serve as the entry point to support further callbacks. */ static void @@ -722,12 +611,15 @@ ssl_info_cb(const SSL *ssl, int where, int val) int is_server = SSL_is_server((SSL *)ssl); if (is_server && where & SSL_CB_HANDSHAKE_START) { - ssl_renegotiation_cb(ssl); + ssl_renegotiation_cb(ssl); } } /* - * Gets various OpenSSL options. + * call-seq: + * ctx.options -> integer + * + * Gets various \OpenSSL options. */ static VALUE ossl_sslctx_get_options(VALUE self) @@ -742,7 +634,17 @@ ossl_sslctx_get_options(VALUE self) } /* - * Sets various OpenSSL options. + * call-seq: + * ctx.options = integer + * + * Sets various \OpenSSL options. The options are a bit field and can be + * combined with the bitwise OR operator (<tt>|</tt>). Available options are + * defined as constants in OpenSSL::SSL that begin with +OP_+. + * + * For backwards compatibility, passing +nil+ has the same effect as passing + * OpenSSL::SSL::OP_ALL. + * + * See also man page SSL_CTX_set_options(3). */ static VALUE ossl_sslctx_set_options(VALUE self, VALUE options) @@ -755,9 +657,9 @@ ossl_sslctx_set_options(VALUE self, VALUE options) SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx)); if (NIL_P(options)) { - SSL_CTX_set_options(ctx, SSL_OP_ALL); + SSL_CTX_set_options(ctx, SSL_OP_ALL); } else { - SSL_CTX_set_options(ctx, NUM2ULONG(options)); + SSL_CTX_set_options(ctx, NUM2ULONG(options)); } return self; @@ -787,49 +689,26 @@ ossl_sslctx_setup(VALUE self) GetSSLCTX(self, ctx); #if !defined(OPENSSL_NO_DH) - SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); + if (!NIL_P(rb_attr_get(self, id_i_tmp_dh_callback))) { + SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); + SSL_CTX_set_dh_auto(ctx, 0); + } #endif -#if !defined(OPENSSL_NO_EC) - /* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0, - * but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */ - if (RTEST(rb_attr_get(self, id_i_tmp_ecdh_callback))) { -# if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) - rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead"); - SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback); -# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO) - /* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores - * tmp_ecdh_callback. So disable ecdh_auto. */ - if (!SSL_CTX_set_ecdh_auto(ctx, 0)) - ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto"); -# endif -# else - ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; " - "use #ecdh_curves= instead"); -# endif - } -#endif /* OPENSSL_NO_EC */ +#if !defined(OPENSSL_IS_AWSLC) /* AWS-LC has no support for TLS 1.3 PHA. */ + SSL_CTX_set_post_handshake_auth(ctx, 1); +#endif val = rb_attr_get(self, id_i_cert_store); if (!NIL_P(val)) { - X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */ - SSL_CTX_set_cert_store(ctx, store); -#if !defined(HAVE_X509_STORE_UP_REF) - /* - * WORKAROUND: - * X509_STORE can count references, but - * X509_STORE_free() doesn't care it. - * So we won't increment it but mark it by ex_data. - */ - SSL_CTX_set_ex_data(ctx, ossl_sslctx_ex_store_p, ctx); -#else /* Fixed in OpenSSL 1.0.2; bff9ce4db38b (master), 5b4b9ce976fc (1.0.2) */ - X509_STORE_up_ref(store); -#endif + X509_STORE *store = GetX509StorePtr(val); /* NO NEED TO DUP */ + SSL_CTX_set_cert_store(ctx, store); + X509_STORE_up_ref(store); } val = rb_attr_get(self, id_i_extra_chain_cert); if(!NIL_P(val)){ - rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); + rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self); } /* private key may be bundled in certificate file. */ @@ -853,38 +732,45 @@ ossl_sslctx_setup(VALUE self) val = rb_attr_get(self, id_i_client_ca); if(!NIL_P(val)){ - if (RB_TYPE_P(val, T_ARRAY)) { - for(i = 0; i < RARRAY_LEN(val); i++){ - client_ca = GetX509CertPtr(RARRAY_AREF(val, i)); - if (!SSL_CTX_add_client_CA(ctx, client_ca)){ - /* Copies X509_NAME => FREE it. */ - ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); - } - } + if (RB_TYPE_P(val, T_ARRAY)) { + for(i = 0; i < RARRAY_LEN(val); i++){ + client_ca = GetX509CertPtr(RARRAY_AREF(val, i)); + if (!SSL_CTX_add_client_CA(ctx, client_ca)){ + /* Copies X509_NAME => FREE it. */ + ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); + } + } } - else{ - client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ + else{ + client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */ if (!SSL_CTX_add_client_CA(ctx, client_ca)){ - /* Copies X509_NAME => FREE it. */ - ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); + /* Copies X509_NAME => FREE it. */ + ossl_raise(eSSLError, "SSL_CTX_add_client_CA"); } - } + } } val = rb_attr_get(self, id_i_ca_file); ca_file = NIL_P(val) ? NULL : StringValueCStr(val); val = rb_attr_get(self, id_i_ca_path); ca_path = NIL_P(val) ? NULL : StringValueCStr(val); - if(ca_file || ca_path){ - if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) - rb_warning("can't set verify locations"); +#ifdef HAVE_SSL_CTX_LOAD_VERIFY_FILE + if (ca_file && !SSL_CTX_load_verify_file(ctx, ca_file)) + ossl_raise(eSSLError, "SSL_CTX_load_verify_file"); + if (ca_path && !SSL_CTX_load_verify_dir(ctx, ca_path)) + ossl_raise(eSSLError, "SSL_CTX_load_verify_dir"); +#else + if (ca_file || ca_path) { + if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) + ossl_raise(eSSLError, "SSL_CTX_load_verify_locations"); } +#endif val = rb_attr_get(self, id_i_verify_mode); verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val); SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback); if (RTEST(rb_attr_get(self, id_i_client_cert_cb))) - SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); + SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb); val = rb_attr_get(self, id_i_timeout); if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val)); @@ -892,70 +778,167 @@ ossl_sslctx_setup(VALUE self) val = rb_attr_get(self, id_i_verify_depth); if(!NIL_P(val)) SSL_CTX_set_verify_depth(ctx, NUM2INT(val)); -#ifndef OPENSSL_NO_NEXTPROTONEG +#ifdef OSSL_USE_NEXTPROTONEG val = rb_attr_get(self, id_i_npn_protocols); if (!NIL_P(val)) { - VALUE encoded = ssl_encode_npn_protocols(val); - rb_ivar_set(self, id_npn_protocols_encoded, encoded); - SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)encoded); - OSSL_Debug("SSL NPN advertise callback added"); + VALUE encoded = ssl_encode_npn_protocols(val); + rb_ivar_set(self, id_npn_protocols_encoded, encoded); + SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *)self); + OSSL_Debug("SSL NPN advertise callback added"); } if (RTEST(rb_attr_get(self, id_i_npn_select_cb))) { - SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self); - OSSL_Debug("SSL NPN select callback added"); + SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self); + OSSL_Debug("SSL NPN select callback added"); } #endif -#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB val = rb_attr_get(self, id_i_alpn_protocols); if (!NIL_P(val)) { - VALUE rprotos = ssl_encode_npn_protocols(val); + VALUE rprotos = ssl_encode_npn_protocols(val); - /* returns 0 on success */ - if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos), - RSTRING_LENINT(rprotos))) - ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos"); - OSSL_Debug("SSL ALPN values added"); + /* returns 0 on success */ + if (SSL_CTX_set_alpn_protos(ctx, (unsigned char *)RSTRING_PTR(rprotos), + RSTRING_LENINT(rprotos))) + ossl_raise(eSSLError, "SSL_CTX_set_alpn_protos"); + OSSL_Debug("SSL ALPN values added"); } if (RTEST(rb_attr_get(self, id_i_alpn_select_cb))) { - SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self); - OSSL_Debug("SSL ALPN select callback added"); + SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self); + OSSL_Debug("SSL ALPN select callback added"); } -#endif rb_obj_freeze(self); val = rb_attr_get(self, id_i_session_id_context); if (!NIL_P(val)){ - StringValue(val); - if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), - RSTRING_LENINT(val))){ - ossl_raise(eSSLError, "SSL_CTX_set_session_id_context"); - } + StringValue(val); + if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val), + RSTRING_LENINT(val))){ + ossl_raise(eSSLError, "SSL_CTX_set_session_id_context"); + } } if (RTEST(rb_attr_get(self, id_i_session_get_cb))) { - SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); - OSSL_Debug("SSL SESSION get callback added"); + SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb); + OSSL_Debug("SSL SESSION get callback added"); } if (RTEST(rb_attr_get(self, id_i_session_new_cb))) { - SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); - OSSL_Debug("SSL SESSION new callback added"); + SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb); + OSSL_Debug("SSL SESSION new callback added"); } if (RTEST(rb_attr_get(self, id_i_session_remove_cb))) { - SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); - OSSL_Debug("SSL SESSION remove callback added"); + SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb); + OSSL_Debug("SSL SESSION remove callback added"); } val = rb_attr_get(self, id_i_servername_cb); if (!NIL_P(val)) { SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); - OSSL_Debug("SSL TLSEXT servername callback added"); + OSSL_Debug("SSL TLSEXT servername callback added"); + } + +#if !OSSL_IS_LIBRESSL + /* + * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements + * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see + * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6). + */ + if (RTEST(rb_attr_get(self, id_i_keylog_cb))) { + SSL_CTX_set_keylog_callback(ctx, ossl_sslctx_keylog_cb); + OSSL_Debug("SSL keylog callback added"); } +#endif return Qtrue; } +static int +parse_proto_version(VALUE str) +{ + int i; + static const struct { + const char *name; + int version; + } map[] = { + { "SSL2", SSL2_VERSION }, + { "SSL3", SSL3_VERSION }, + { "TLS1", TLS1_VERSION }, + { "TLS1_1", TLS1_1_VERSION }, + { "TLS1_2", TLS1_2_VERSION }, + { "TLS1_3", TLS1_3_VERSION }, + }; + + if (NIL_P(str)) + return 0; + if (RB_INTEGER_TYPE_P(str)) + return NUM2INT(str); + + if (SYMBOL_P(str)) + str = rb_sym2str(str); + StringValue(str); + for (i = 0; i < numberof(map); i++) + if (!strncmp(map[i].name, RSTRING_PTR(str), RSTRING_LEN(str))) + return map[i].version; + rb_raise(rb_eArgError, "unrecognized version %+"PRIsVALUE, str); +} + +/* + * call-seq: + * ctx.min_version = OpenSSL::SSL::TLS1_2_VERSION + * ctx.min_version = :TLS1_2 + * ctx.min_version = nil + * + * Sets the lower bound on the supported SSL/TLS protocol version. The + * version may be specified by an integer constant named + * OpenSSL::SSL::*_VERSION, a Symbol, or +nil+ which means "any version". + * + * === Example + * ctx = OpenSSL::SSL::SSLContext.new + * ctx.min_version = OpenSSL::SSL::TLS1_1_VERSION + * ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION + * + * sock = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx) + * sock.connect # Initiates a connection using either TLS 1.1 or TLS 1.2 + */ +static VALUE +ossl_sslctx_set_min_version(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + int version; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + version = parse_proto_version(v); + + if (!SSL_CTX_set_min_proto_version(ctx, version)) + ossl_raise(eSSLError, "SSL_CTX_set_min_proto_version"); + return v; +} + +/* + * call-seq: + * ctx.max_version = OpenSSL::SSL::TLS1_2_VERSION + * ctx.max_version = :TLS1_2 + * ctx.max_version = nil + * + * Sets the upper bound of the supported SSL/TLS protocol version. See + * #min_version= for the possible values. + */ +static VALUE +ossl_sslctx_set_max_version(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + int version; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + version = parse_proto_version(v); + + if (!SSL_CTX_set_max_proto_version(ctx, version)) + ossl_raise(eSSLError, "SSL_CTX_set_max_proto_version"); + return v; +} + static VALUE ossl_ssl_cipher_to_ary(const SSL_CIPHER *cipher) { @@ -1001,29 +984,14 @@ ossl_sslctx_get_ciphers(VALUE self) return ary; } -/* - * call-seq: - * ctx.ciphers = "cipher1:cipher2:..." - * ctx.ciphers = [name, ...] - * ctx.ciphers = [[name, version, bits, alg_bits], ...] - * - * Sets the list of available cipher suites for this context. Note in a server - * context some ciphers require the appropriate certificates. For example, an - * RSA cipher suite can only be chosen when an RSA certificate is available. - */ static VALUE -ossl_sslctx_set_ciphers(VALUE self, VALUE v) +build_cipher_string(VALUE v) { - SSL_CTX *ctx; VALUE str, elem; - int i; - rb_check_frozen(self); - if (NIL_P(v)) - return v; - else if (RB_TYPE_P(v, T_ARRAY)) { + if (RB_TYPE_P(v, T_ARRAY)) { str = rb_str_new(0, 0); - for (i = 0; i < RARRAY_LEN(v); i++) { + for (long i = 0; i < RARRAY_LEN(v); i++) { elem = rb_ary_entry(v, i); if (RB_TYPE_P(elem, T_ARRAY)) elem = rb_ary_entry(elem, 0); elem = rb_String(elem); @@ -1035,36 +1003,200 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) StringValue(str); } + return str; +} + +/* + * call-seq: + * ctx.ciphers = "cipher1:cipher2:..." + * ctx.ciphers = [name, ...] + * ctx.ciphers = [[name, version, bits, alg_bits], ...] + * + * Sets the list of available cipher suites for TLS 1.2 and below for this + * context. + * + * Note in a server context some ciphers require the appropriate certificates. + * For example, an RSA cipher suite can only be chosen when an RSA certificate + * is available. + * + * This method does not affect TLS 1.3 connections. See also #ciphersuites=. + */ +static VALUE +ossl_sslctx_set_ciphers(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + VALUE str; + + rb_check_frozen(self); + // Assigning nil is a no-op for compatibility + if (NIL_P(v)) + return v; + + str = build_cipher_string(v); + GetSSLCTX(self, ctx); - if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) { + if (!SSL_CTX_set_cipher_list(ctx, StringValueCStr(str))) ossl_raise(eSSLError, "SSL_CTX_set_cipher_list"); - } return v; } -#if !defined(OPENSSL_NO_EC) /* * call-seq: - * ctx.ecdh_curves = curve_list -> curve_list + * ctx.ciphersuites = "cipher1:cipher2:..." + * ctx.ciphersuites = [name, ...] + * + * Sets the list of available TLS 1.3 cipher suites for this context. + */ +static VALUE +ossl_sslctx_set_ciphersuites(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + VALUE str; + + rb_check_frozen(self); + // Assigning nil is a no-op for compatibility + if (NIL_P(v)) + return v; + + str = build_cipher_string(v); + + GetSSLCTX(self, ctx); + if (!SSL_CTX_set_ciphersuites(ctx, StringValueCStr(str))) + ossl_raise(eSSLError, "SSL_CTX_set_ciphersuites"); + + return v; +} + +#ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST +/* + * call-seq: + * ctx.sigalgs = "sigalg1:sigalg2:..." + * + * Sets the list of "supported signature algorithms" for this context. + * + * For a TLS client, the list is used in the "signature_algorithms" extension + * in the ClientHello message. For a server, the list is used by OpenSSL to + * determine the set of shared signature algorithms. OpenSSL will pick the most + * appropriate one from it. + * + * See also #client_sigalgs= for the client authentication equivalent. + */ +static VALUE +ossl_sslctx_set_sigalgs(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + + if (!SSL_CTX_set1_sigalgs_list(ctx, StringValueCStr(v))) + ossl_raise(eSSLError, "SSL_CTX_set1_sigalgs_list"); + + return v; +} +#endif + +#ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST +/* + * call-seq: + * ctx.client_sigalgs = "sigalg1:sigalg2:..." + * + * Sets the list of "supported signature algorithms" for client authentication + * for this context. + * + * For a TLS server, the list is sent to the client as part of the + * CertificateRequest message. + * + * See also #sigalgs= for the server authentication equivalent. + */ +static VALUE +ossl_sslctx_set_client_sigalgs(VALUE self, VALUE v) +{ + SSL_CTX *ctx; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + + if (!SSL_CTX_set1_client_sigalgs_list(ctx, StringValueCStr(v))) + ossl_raise(eSSLError, "SSL_CTX_set1_client_sigalgs_list"); + + return v; +} +#endif + +#ifndef OPENSSL_NO_DH +/* + * call-seq: + * ctx.tmp_dh = pkey + * + * Sets DH parameters used for ephemeral DH key exchange. This is relevant for + * servers only. + * + * +pkey+ is an instance of OpenSSL::PKey::DH. Note that key components + * contained in the key object, if any, are ignored. The server will always + * generate a new key pair for each handshake. + * + * Added in version 3.0. See also the man page SSL_CTX_set0_tmp_dh_pkey(3). + * + * Example: + * ctx = OpenSSL::SSL::SSLContext.new + * ctx.tmp_dh = OpenSSL::DH.generate(2048) + * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx) + * Thread.new { svr.accept } + */ +static VALUE +ossl_sslctx_set_tmp_dh(VALUE self, VALUE arg) +{ + SSL_CTX *ctx; + EVP_PKEY *pkey; + + rb_check_frozen(self); + GetSSLCTX(self, ctx); + pkey = GetPKeyPtr(arg); + + if (EVP_PKEY_base_id(pkey) != EVP_PKEY_DH) + rb_raise(eSSLError, "invalid pkey type %s (expected DH)", + OBJ_nid2sn(EVP_PKEY_base_id(pkey))); +#ifdef HAVE_SSL_CTX_SET0_TMP_DH_PKEY + if (!SSL_CTX_set0_tmp_dh_pkey(ctx, pkey)) + ossl_raise(eSSLError, "SSL_CTX_set0_tmp_dh_pkey"); + EVP_PKEY_up_ref(pkey); +#else + if (!SSL_CTX_set_tmp_dh(ctx, EVP_PKEY_get0_DH(pkey))) + ossl_raise(eSSLError, "SSL_CTX_set_tmp_dh"); +#endif + + // Turn off the "auto" DH parameters set by ossl_sslctx_s_alloc() + SSL_CTX_set_dh_auto(ctx, 0); + + return arg; +} +#endif + +/* + * call-seq: + * ctx.groups = groups_list + * ctx.ecdh_curves = groups_list * - * Sets the list of "supported elliptic curves" for this context. + * Sets the list of supported groups for key agreement for this context. * - * For a TLS client, the list is directly used in the Supported Elliptic Curves - * Extension. For a server, the list is used by OpenSSL to determine the set of - * shared curves. OpenSSL will pick the most appropriate one from it. + * For a TLS client, the list is directly used in the "supported_groups" + * extension. For a server, the list is used by OpenSSL to determine the set of + * shared supported groups. OpenSSL will pick the most appropriate one from it. * - * Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve - * can be set, and this has no effect for TLS clients. + * #ecdh_curves= is a deprecated alias for #groups=. + * + * See also the man page SSL_CTX_set1_groups_list(3). * * === Example * ctx1 = OpenSSL::SSL::SSLContext.new - * ctx1.ecdh_curves = "X25519:P-256:P-224" + * ctx1.groups = "X25519:P-256:P-224" * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1) * Thread.new { svr.accept } * * ctx2 = OpenSSL::SSL::SSLContext.new - * ctx2.ecdh_curves = "P-256" + * ctx2.groups = "P-256" * cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2) * cli.connect * @@ -1072,7 +1204,7 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v) * # => "prime256v1" (is an alias for NIST P-256) */ static VALUE -ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg) +ossl_sslctx_set_groups(VALUE self, VALUE arg) { SSL_CTX *ctx; @@ -1080,53 +1212,10 @@ ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg) GetSSLCTX(self, ctx); StringValueCStr(arg); -#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST) - if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg))) - ossl_raise(eSSLError, NULL); -#else - /* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to - * SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */ - { - VALUE curve, splitted; - EC_KEY *ec; - int nid; - - splitted = rb_str_split(arg, ":"); - if (!RARRAY_LEN(splitted)) - ossl_raise(eSSLError, "invalid input format"); - curve = RARRAY_AREF(splitted, 0); - StringValueCStr(curve); - - /* SSL_CTX_set1_curves_list() accepts NIST names */ - nid = EC_curve_nist2nid(RSTRING_PTR(curve)); - if (nid == NID_undef) - nid = OBJ_txt2nid(RSTRING_PTR(curve)); - if (nid == NID_undef) - ossl_raise(eSSLError, "unknown curve name"); - - ec = EC_KEY_new_by_curve_name(nid); - if (!ec) - ossl_raise(eSSLError, NULL); - EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); - if (!SSL_CTX_set_tmp_ecdh(ctx, ec)) { - EC_KEY_free(ec); - ossl_raise(eSSLError, "SSL_CTX_set_tmp_ecdh"); - } - EC_KEY_free(ec); -# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO) - /* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto - * is enabled. So disable ecdh_auto. */ - if (!SSL_CTX_set_ecdh_auto(ctx, 0)) - ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto"); -# endif - } -#endif - + if (!SSL_CTX_set1_groups_list(ctx, RSTRING_PTR(arg))) + ossl_raise(eSSLError, "SSL_CTX_set1_groups_list"); return arg; } -#else -#define ossl_sslctx_set_ecdh_curves rb_f_notimplement -#endif /* * call-seq: @@ -1143,12 +1232,7 @@ ossl_sslctx_get_security_level(VALUE self) GetSSLCTX(self, ctx); -#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) return INT2NUM(SSL_CTX_get_security_level(ctx)); -#else - (void)ctx; - return INT2FIX(0); -#endif } /* @@ -1178,14 +1262,7 @@ ossl_sslctx_set_security_level(VALUE self, VALUE value) rb_check_frozen(self); GetSSLCTX(self, ctx); -#if defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) SSL_CTX_set_security_level(ctx, NUM2INT(value)); -#else - (void)ctx; - if (NUM2INT(value) != 0) - ossl_raise(rb_eNotImpError, "setting security level to other than 0 is " - "not supported in this version of OpenSSL"); -#endif return value; } @@ -1212,7 +1289,7 @@ ossl_sslctx_enable_fallback_scsv(VALUE self) /* * call-seq: - * ctx.add_certificate(certiticate, pkey [, extra_certs]) -> self + * ctx.add_certificate(certificate, pkey [, extra_certs]) -> self * * Adds a certificate to the context. _pkey_ must be a corresponding private * key with _certificate_. @@ -1244,10 +1321,6 @@ ossl_sslctx_enable_fallback_scsv(VALUE self) * ecdsa_pkey = ... * another_ca_cert = ... * ctx.add_certificate(ecdsa_cert, ecdsa_pkey, [another_ca_cert]) - * - * === Note - * OpenSSL before the version 1.0.2 could handle only one extra chain across - * all key types. Calling this method discards the chain set previously. */ static VALUE ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self) @@ -1271,49 +1344,24 @@ ossl_sslctx_add_certificate(int argc, VALUE *argv, VALUE self) pub_pkey = X509_get_pubkey(x509); EVP_PKEY_free(pub_pkey); if (!pub_pkey) - rb_raise(rb_eArgError, "certificate does not contain public key"); - if (EVP_PKEY_cmp(pub_pkey, pkey) != 1) - rb_raise(rb_eArgError, "public key mismatch"); + rb_raise(rb_eArgError, "certificate does not contain public key"); + if (EVP_PKEY_eq(pub_pkey, pkey) != 1) + rb_raise(rb_eArgError, "public key mismatch"); if (argc >= 3) - extra_chain = ossl_x509_ary2sk(extra_chain_ary); + extra_chain = ossl_x509_ary2sk(extra_chain_ary); if (!SSL_CTX_use_certificate(ctx, x509)) { - sk_X509_pop_free(extra_chain, X509_free); - ossl_raise(eSSLError, "SSL_CTX_use_certificate"); + sk_X509_pop_free(extra_chain, X509_free); + ossl_raise(eSSLError, "SSL_CTX_use_certificate"); } if (!SSL_CTX_use_PrivateKey(ctx, pkey)) { - sk_X509_pop_free(extra_chain, X509_free); - ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey"); + sk_X509_pop_free(extra_chain, X509_free); + ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey"); } - - if (extra_chain) { -#if OPENSSL_VERSION_NUMBER >= 0x10002000 && !defined(LIBRESSL_VERSION_NUMBER) - if (!SSL_CTX_set0_chain(ctx, extra_chain)) { - sk_X509_pop_free(extra_chain, X509_free); - ossl_raise(eSSLError, "SSL_CTX_set0_chain"); - } -#else - STACK_OF(X509) *orig_extra_chain; - X509 *x509_tmp; - - /* First, clear the existing chain */ - SSL_CTX_get_extra_chain_certs(ctx, &orig_extra_chain); - if (orig_extra_chain && sk_X509_num(orig_extra_chain)) { - rb_warning("SSL_CTX_set0_chain() is not available; " \ - "clearing previously set certificate chain"); - SSL_CTX_clear_extra_chain_certs(ctx); - } - while ((x509_tmp = sk_X509_shift(extra_chain))) { - /* Transfers ownership */ - if (!SSL_CTX_add_extra_chain_cert(ctx, x509_tmp)) { - X509_free(x509_tmp); - sk_X509_pop_free(extra_chain, X509_free); - ossl_raise(eSSLError, "SSL_CTX_add_extra_chain_cert"); - } - } - sk_X509_free(extra_chain); -#endif + if (extra_chain && !SSL_CTX_set0_chain(ctx, extra_chain)) { + sk_X509_pop_free(extra_chain, X509_free); + ossl_raise(eSSLError, "SSL_CTX_set0_chain"); } return self; } @@ -1507,12 +1555,18 @@ ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self) /* * SSLSocket class */ -#ifndef OPENSSL_NO_SOCK static inline int ssl_started(SSL *ssl) { - /* the FD is set in ossl_ssl_setup(), called by #connect or #accept */ - return SSL_get_fd(ssl) >= 0; + /* BIO is created through ossl_ssl_setup(), called by #connect or #accept */ + return SSL_get_rbio(ssl) != NULL; +} + +static void +ossl_ssl_mark(void *ptr) +{ + SSL *ssl = ptr; + rb_gc_mark((VALUE)SSL_get_ex_data(ssl, ossl_ssl_ex_ptr_idx)); } static void @@ -1524,9 +1578,9 @@ ossl_ssl_free(void *ssl) const rb_data_type_t ossl_ssl_type = { "OpenSSL/SSL", { - 0, ossl_ssl_free, + ossl_ssl_mark, ossl_ssl_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -1535,6 +1589,29 @@ ossl_ssl_s_alloc(VALUE klass) return TypedData_Wrap_Struct(klass, &ossl_ssl_type, NULL); } +static VALUE +peer_ip_address(VALUE self) +{ + VALUE remote_address = rb_funcall(rb_attr_get(self, id_i_io), rb_intern("remote_address"), 0); + + return rb_funcall(remote_address, rb_intern("inspect_sockaddr"), 0); +} + +static VALUE +fallback_peer_ip_address(VALUE self, VALUE args) +{ + return rb_str_new_cstr("(null)"); +} + +static VALUE +peeraddr_ip_str(VALUE self) +{ + VALUE rb_mErrno = rb_const_get(rb_cObject, rb_intern("Errno")); + VALUE rb_eSystemCallError = rb_const_get(rb_mErrno, rb_intern("SystemCallError")); + + return rb_rescue2(peer_ip_address, self, fallback_peer_ip_address, (VALUE)0, rb_eSystemCallError, NULL); +} + /* * call-seq: * SSLSocket.new(io) => aSSLSocket @@ -1554,40 +1631,50 @@ ossl_ssl_s_alloc(VALUE klass) static VALUE ossl_ssl_initialize(int argc, VALUE *argv, VALUE self) { - VALUE io, v_ctx, verify_cb; + VALUE io, v_ctx; SSL *ssl; SSL_CTX *ctx; TypedData_Get_Struct(self, SSL, &ossl_ssl_type, ssl); if (ssl) - ossl_raise(eSSLError, "SSL already initialized"); + ossl_raise(eSSLError, "SSL already initialized"); if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1) - v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); + v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0); GetSSLCTX(v_ctx, ctx); rb_ivar_set(self, id_i_context, v_ctx); ossl_sslctx_setup(v_ctx); if (rb_respond_to(io, rb_intern("nonblock="))) - rb_funcall(io, rb_intern("nonblock="), 1, Qtrue); + rb_funcall(io, rb_intern("nonblock="), 1, Qtrue); + Check_Type(io, T_FILE); rb_ivar_set(self, id_i_io, io); ssl = SSL_new(ctx); if (!ssl) - ossl_raise(eSSLError, NULL); + ossl_raise(eSSLError, NULL); RTYPEDDATA_DATA(self) = ssl; SSL_set_ex_data(ssl, ossl_ssl_ex_ptr_idx, (void *)self); SSL_set_info_callback(ssl, ssl_info_cb); - verify_cb = rb_attr_get(v_ctx, id_i_verify_callback); - SSL_set_ex_data(ssl, ossl_ssl_ex_vcb_idx, (void *)verify_cb); rb_call_super(0, NULL); return self; } +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + static VALUE ossl_ssl_setup(VALUE self) { @@ -1597,14 +1684,14 @@ ossl_ssl_setup(VALUE self) GetSSL(self, ssl); if (ssl_started(ssl)) - return Qtrue; + return Qtrue; io = rb_attr_get(self, id_i_io); GetOpenFile(io, fptr); rb_io_check_readable(fptr); rb_io_check_writable(fptr); - if (!SSL_set_fd(ssl, TO_SOCKET(fptr->fd))) - ossl_raise(eSSLError, "SSL_set_fd"); + if (!SSL_set_fd(ssl, TO_SOCKET(rb_io_descriptor(io)))) + ossl_raise(eSSLError, "SSL_set_fd"); return Qtrue; } @@ -1619,14 +1706,14 @@ static void write_would_block(int nonblock) { if (nonblock) - ossl_raise(eSSLErrorWaitWritable, "write would block"); + ossl_raise(eSSLErrorWaitWritable, "write would block"); } static void read_would_block(int nonblock) { if (nonblock) - ossl_raise(eSSLErrorWaitReadable, "read would block"); + ossl_raise(eSSLErrorWaitReadable, "read would block"); } static int @@ -1634,74 +1721,122 @@ no_exception_p(VALUE opts) { if (RB_TYPE_P(opts, T_HASH) && rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse) - return 1; + return 1; return 0; } +// Provided by Ruby 3.2.0 and later in order to support the default IO#timeout. +#ifndef RUBY_IO_TIMEOUT_DEFAULT +#define RUBY_IO_TIMEOUT_DEFAULT Qnil +#endif + +#ifdef HAVE_RB_IO_TIMEOUT +#define IO_TIMEOUT_ERROR rb_eIOTimeoutError +#else +#define IO_TIMEOUT_ERROR rb_eIOError +#endif + + +static void +io_wait_writable(VALUE io) +{ +#ifdef HAVE_RB_IO_MAYBE_WAIT + if (!rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) { + rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become writable!"); + } +#else + rb_io_t *fptr; + GetOpenFile(io, fptr); + rb_io_wait_writable(fptr->fd); +#endif +} + +static void +io_wait_readable(VALUE io) +{ +#ifdef HAVE_RB_IO_MAYBE_WAIT + if (!rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) { + rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become readable!"); + } +#else + rb_io_t *fptr; + GetOpenFile(io, fptr); + rb_io_wait_readable(fptr->fd); +#endif +} + static VALUE -ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts) +ossl_start_ssl(VALUE self, int (*func)(SSL *), const char *funcname, VALUE opts) { SSL *ssl; - rb_io_t *fptr; int ret, ret2; VALUE cb_state; int nonblock = opts != Qfalse; -#if defined(SSL_R_CERTIFICATE_VERIFY_FAILED) - unsigned long err; -#endif rb_ivar_set(self, ID_callback_state, Qnil); GetSSL(self, ssl); - GetOpenFile(rb_attr_get(self, id_i_io), fptr); - for(;;){ - ret = func(ssl); + VALUE io = rb_attr_get(self, id_i_io); + for (;;) { + ret = func(ssl); - cb_state = rb_attr_get(self, ID_callback_state); + cb_state = rb_attr_get(self, ID_callback_state); if (!NIL_P(cb_state)) { - /* must cleanup OpenSSL error stack before re-raising */ - ossl_clear_error(); - rb_jump_tag(NUM2INT(cb_state)); - } + /* must cleanup OpenSSL error stack before re-raising */ + ossl_clear_error(); + rb_jump_tag(NUM2INT(cb_state)); + } - if (ret > 0) - break; + if (ret > 0) + break; - switch((ret2 = ssl_get_error(ssl, ret))){ - case SSL_ERROR_WANT_WRITE: + switch ((ret2 = ssl_get_error(ssl, ret))) { + case SSL_ERROR_WANT_WRITE: if (no_exception_p(opts)) { return sym_wait_writable; } write_would_block(nonblock); - rb_io_wait_writable(fptr->fd); + io_wait_writable(io); continue; - case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_READ: if (no_exception_p(opts)) { return sym_wait_readable; } read_would_block(nonblock); - rb_io_wait_readable(fptr->fd); + io_wait_readable(io); continue; - case SSL_ERROR_SYSCALL: - if (errno) rb_sys_fail(funcname); - ossl_raise(eSSLError, "%s SYSCALL returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); + case SSL_ERROR_SYSCALL: +#ifdef __APPLE__ + /* See ossl_ssl_write_internal() */ + if (errno == EPROTOTYPE) + continue; +#endif + if (errno) rb_sys_fail(funcname); + /* fallthrough */ + default: { + VALUE error_append = Qnil; #if defined(SSL_R_CERTIFICATE_VERIFY_FAILED) - case SSL_ERROR_SSL: - err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_SSL && - ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) { - const char *err_msg = ERR_reason_error_string(err), - *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl)); - if (!err_msg) - err_msg = "(null)"; - if (!verify_msg) - verify_msg = "(null)"; - ossl_clear_error(); /* let ossl_raise() not append message */ - ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s: %s (%s)", - funcname, ret2, errno, SSL_state_string_long(ssl), - err_msg, verify_msg); - } + unsigned long err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_SSL && + ERR_GET_REASON(err) == SSL_R_CERTIFICATE_VERIFY_FAILED) { + const char *err_msg = ERR_reason_error_string(err), + *verify_msg = X509_verify_cert_error_string(SSL_get_verify_result(ssl)); + if (!err_msg) + err_msg = "(null)"; + if (!verify_msg) + verify_msg = "(null)"; + ossl_clear_error(); /* let ossl_raise() not append message */ + error_append = rb_sprintf(": %s (%s)", err_msg, verify_msg); + } #endif - default: - ossl_raise(eSSLError, "%s returned=%d errno=%d state=%s", funcname, ret2, errno, SSL_state_string_long(ssl)); - } + ossl_raise(eSSLError, + "%s%s returned=%d errno=%d peeraddr=%"PRIsVALUE" state=%s%"PRIsVALUE, + funcname, + ret2 == SSL_ERROR_SYSCALL ? " SYSCALL" : "", + ret2, + errno, + peeraddr_ip_str(self), + SSL_state_string_long(ssl), + error_append); + } + } } return self; @@ -1711,8 +1846,7 @@ ossl_start_ssl(VALUE self, int (*func)(), const char *funcname, VALUE opts) * call-seq: * ssl.connect => self * - * Initiates an SSL/TLS handshake with a server. The handshake may be started - * after unencrypted data has been sent over the socket. + * Initiates an SSL/TLS handshake with a server. */ static VALUE ossl_ssl_connect(VALUE self) @@ -1759,8 +1893,7 @@ ossl_ssl_connect_nonblock(int argc, VALUE *argv, VALUE self) * call-seq: * ssl.accept => self * - * Waits for a SSL/TLS client to initiate a handshake. The handshake may be - * started after unencrypted data has been sent over the socket. + * Waits for a SSL/TLS client to initiate a handshake. */ static VALUE ossl_ssl_accept(VALUE self) @@ -1807,89 +1940,96 @@ static VALUE ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) { SSL *ssl; - int ilen, nread = 0; - VALUE len, str; - rb_io_t *fptr; - VALUE io, opts = Qnil; + int ilen; + VALUE len, str, cb_state; + VALUE opts = Qnil; if (nonblock) { - rb_scan_args(argc, argv, "11:", &len, &str, &opts); + rb_scan_args(argc, argv, "11:", &len, &str, &opts); } else { - rb_scan_args(argc, argv, "11", &len, &str); + rb_scan_args(argc, argv, "11", &len, &str); } + GetSSL(self, ssl); + if (!ssl_started(ssl)) + rb_raise(eSSLError, "SSL session is not started yet"); ilen = NUM2INT(len); if (NIL_P(str)) - str = rb_str_new(0, ilen); + str = rb_str_new(0, ilen); else { - StringValue(str); - if (RSTRING_LEN(str) >= ilen) - rb_str_modify(str); - else - rb_str_modify_expand(str, ilen - RSTRING_LEN(str)); + StringValue(str); + if (RSTRING_LEN(str) >= ilen) + rb_str_modify(str); + else + rb_str_modify_expand(str, ilen - RSTRING_LEN(str)); } - OBJ_TAINT(str); - rb_str_set_len(str, 0); - if (ilen == 0) - return str; - GetSSL(self, ssl); - io = rb_attr_get(self, id_i_io); - GetOpenFile(io, fptr); - if (ssl_started(ssl)) { - for (;;){ - nread = SSL_read(ssl, RSTRING_PTR(str), ilen); - switch(ssl_get_error(ssl, nread)){ - case SSL_ERROR_NONE: - goto end; - case SSL_ERROR_ZERO_RETURN: - if (no_exception_p(opts)) { return Qnil; } - rb_eof_error(); - case SSL_ERROR_WANT_WRITE: - if (no_exception_p(opts)) { return sym_wait_writable; } + if (ilen == 0) { + rb_str_set_len(str, 0); + return str; + } + + VALUE io = rb_attr_get(self, id_i_io); + + for (;;) { + rb_str_locktmp(str); + int nread = SSL_read(ssl, RSTRING_PTR(str), ilen); + rb_str_unlocktmp(str); + + cb_state = rb_attr_get(self, ID_callback_state); + if (!NIL_P(cb_state)) { + rb_ivar_set(self, ID_callback_state, Qnil); + ossl_clear_error(); + rb_jump_tag(NUM2INT(cb_state)); + } + + switch (ssl_get_error(ssl, nread)) { + case SSL_ERROR_NONE: + rb_str_set_len(str, nread); + return str; + case SSL_ERROR_ZERO_RETURN: + if (no_exception_p(opts)) { return Qnil; } + rb_eof_error(); + case SSL_ERROR_WANT_WRITE: + if (nonblock) { + if (no_exception_p(opts)) { return sym_wait_writable; } write_would_block(nonblock); - rb_io_wait_writable(fptr->fd); - continue; - case SSL_ERROR_WANT_READ: - if (no_exception_p(opts)) { return sym_wait_readable; } + } + io_wait_writable(io); + break; + case SSL_ERROR_WANT_READ: + if (nonblock) { + if (no_exception_p(opts)) { return sym_wait_readable; } read_would_block(nonblock); - rb_io_wait_readable(fptr->fd); - continue; - case SSL_ERROR_SYSCALL: - if (!ERR_peek_error()) { - if (errno) - rb_sys_fail(0); - else { - /* - * The underlying BIO returned 0. This is actually a - * protocol error. But unfortunately, not all - * implementations cleanly shutdown the TLS connection - * but just shutdown/close the TCP connection. So report - * EOF for now... - */ - if (no_exception_p(opts)) { return Qnil; } - rb_eof_error(); - } - } - /* fall through */ - default: - ossl_raise(eSSLError, "SSL_read"); - } + } + io_wait_readable(io); + break; + case SSL_ERROR_SYSCALL: + if (!ERR_peek_error()) { + if (errno) + rb_sys_fail(0); + else { + /* + * The underlying BIO returned 0. This is actually a + * protocol error. But unfortunately, not all + * implementations cleanly shutdown the TLS connection + * but just shutdown/close the TCP connection. So report + * EOF for now... + */ + if (no_exception_p(opts)) { return Qnil; } + rb_eof_error(); + } + } + /* fall through */ + default: + ossl_raise(eSSLError, "SSL_read"); } - } - else { - ID meth = nonblock ? rb_intern("read_nonblock") : rb_intern("sysread"); - rb_warning("SSL session is not started yet."); - if (nonblock) - return rb_funcall(io, meth, 3, len, str, opts); - else - return rb_funcall(io, meth, 2, len, str); + // Ensure the buffer is not modified during io_wait_*able() + rb_str_modify(str); + if (rb_str_capacity(str) < (size_t)ilen) + rb_raise(eSSLError, "read buffer was modified"); } - - end: - rb_str_set_len(str, nread); - return str; } /* @@ -1926,60 +2066,92 @@ ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self) } static VALUE -ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) +ossl_ssl_write_internal_safe(VALUE _args) { + VALUE *args = (VALUE*)_args; + VALUE self = args[0]; + VALUE str = args[1]; + VALUE opts = args[2]; + SSL *ssl; - int nwrite = 0; rb_io_t *fptr; - int nonblock = opts != Qfalse; - VALUE io; + int num, nonblock = opts != Qfalse; + VALUE cb_state; - StringValue(str); GetSSL(self, ssl); - io = rb_attr_get(self, id_i_io); + if (!ssl_started(ssl)) + rb_raise(eSSLError, "SSL session is not started yet"); + + VALUE io = rb_attr_get(self, id_i_io); GetOpenFile(io, fptr); - if (ssl_started(ssl)) { - for (;;){ - int num = RSTRING_LENINT(str); - - /* SSL_write(3ssl) manpage states num == 0 is undefined */ - if (num == 0) - goto end; - - nwrite = SSL_write(ssl, RSTRING_PTR(str), num); - switch(ssl_get_error(ssl, nwrite)){ - case SSL_ERROR_NONE: - goto end; - case SSL_ERROR_WANT_WRITE: - if (no_exception_p(opts)) { return sym_wait_writable; } - write_would_block(nonblock); - rb_io_wait_writable(fptr->fd); - continue; - case SSL_ERROR_WANT_READ: - if (no_exception_p(opts)) { return sym_wait_readable; } - read_would_block(nonblock); - rb_io_wait_readable(fptr->fd); + + /* SSL_write(3ssl) manpage states num == 0 is undefined */ + num = RSTRING_LENINT(str); + if (num == 0) + return INT2FIX(0); + + for (;;) { + int nwritten = SSL_write(ssl, RSTRING_PTR(str), num); + + cb_state = rb_attr_get(self, ID_callback_state); + if (!NIL_P(cb_state)) { + rb_ivar_set(self, ID_callback_state, Qnil); + ossl_clear_error(); + rb_jump_tag(NUM2INT(cb_state)); + } + + switch (ssl_get_error(ssl, nwritten)) { + case SSL_ERROR_NONE: + return INT2NUM(nwritten); + case SSL_ERROR_WANT_WRITE: + if (no_exception_p(opts)) { return sym_wait_writable; } + write_would_block(nonblock); + io_wait_writable(io); + continue; + case SSL_ERROR_WANT_READ: + if (no_exception_p(opts)) { return sym_wait_readable; } + read_would_block(nonblock); + io_wait_readable(io); + continue; + case SSL_ERROR_SYSCALL: +#ifdef __APPLE__ + /* + * It appears that send syscall can return EPROTOTYPE if the + * socket is being torn down. Retry to get a proper errno to + * make the error handling in line with the socket library. + * [Bug #14713] https://bugs.ruby-lang.org/issues/14713 + */ + if (errno == EPROTOTYPE) continue; - case SSL_ERROR_SYSCALL: - if (errno) rb_sys_fail(0); - default: - ossl_raise(eSSLError, "SSL_write"); - } +#endif + if (errno) rb_sys_fail(0); + /* fallthrough */ + default: + ossl_raise(eSSLError, "SSL_write"); } } - else { - ID meth = nonblock ? - rb_intern("write_nonblock") : rb_intern("syswrite"); - - rb_warning("SSL session is not started yet."); - if (nonblock) - return rb_funcall(io, meth, 2, str, opts); - else - return rb_funcall(io, meth, 1, str); +} + + +static VALUE +ossl_ssl_write_internal(VALUE self, VALUE str, VALUE opts) +{ + StringValue(str); + int frozen = RB_OBJ_FROZEN(str); + if (!frozen) { + rb_str_locktmp(str); + } + int state; + VALUE args[3] = {self, str, opts}; + VALUE result = rb_protect(ossl_ssl_write_internal_safe, (VALUE)args, &state); + if (!frozen) { + rb_str_unlocktmp(str); } - end: - return INT2NUM(nwrite); + if (state) { + rb_jump_tag(state); + } + return result; } /* @@ -2026,12 +2198,12 @@ ossl_ssl_stop(VALUE self) GetSSL(self, ssl); if (!ssl_started(ssl)) - return Qnil; + return Qnil; ret = SSL_shutdown(ssl); if (ret == 1) /* Have already received close_notify */ - return Qnil; + return Qnil; if (ret == 0) /* Sent close_notify, but we don't wait for reply */ - return Qnil; + return Qnil; /* * XXX: Something happened. Possibly it failed because the underlying socket @@ -2117,20 +2289,20 @@ ossl_ssl_get_peer_cert_chain(VALUE self) num = sk_X509_num(chain); ary = rb_ary_new2(num); for (i = 0; i < num; i++){ - cert = sk_X509_value(chain, i); - rb_ary_push(ary, ossl_x509_new(cert)); + cert = sk_X509_value(chain, i); + rb_ary_push(ary, ossl_x509_new(cert)); } return ary; } /* -* call-seq: -* ssl.ssl_version => String -* -* Returns a String representing the SSL/TLS version that was negotiated -* for the connection, for example "TLSv1.2". -*/ + * call-seq: + * ssl.ssl_version => String + * + * Returns a String representing the SSL/TLS version that was negotiated + * for the connection, for example "TLSv1.2". + */ static VALUE ossl_ssl_get_version(VALUE self) { @@ -2251,10 +2423,10 @@ ossl_ssl_set_hostname(VALUE self, VALUE arg) GetSSL(self, ssl); if (!NIL_P(arg)) - hostname = StringValueCStr(arg); + hostname = StringValueCStr(arg); if (!SSL_set_tlsext_host_name(ssl, hostname)) - ossl_raise(eSSLError, NULL); + ossl_raise(eSSLError, NULL); /* for SSLSocket#hostname */ rb_ivar_set(self, id_i_hostname, arg); @@ -2278,12 +2450,62 @@ ossl_ssl_get_verify_result(VALUE self) GetSSL(self, ssl); - return INT2NUM(SSL_get_verify_result(ssl)); + return LONG2NUM(SSL_get_verify_result(ssl)); } /* * call-seq: - * ssl.client_ca => [x509name, ...] + * ssl.finished_message => "finished message" + * + * Returns the last *Finished* message sent + * + */ +static VALUE +ossl_ssl_get_finished(VALUE self) +{ + SSL *ssl; + char sizer[1], *buf; + size_t len; + + GetSSL(self, ssl); + + len = SSL_get_finished(ssl, sizer, 0); + if (len == 0) + return Qnil; + + buf = ALLOCA_N(char, len); + SSL_get_finished(ssl, buf, len); + return rb_str_new(buf, len); +} + +/* + * call-seq: + * ssl.peer_finished_message => "peer finished message" + * + * Returns the last *Finished* message received + * + */ +static VALUE +ossl_ssl_get_peer_finished(VALUE self) +{ + SSL *ssl; + char sizer[1], *buf; + size_t len; + + GetSSL(self, ssl); + + len = SSL_get_peer_finished(ssl, sizer, 0); + if (len == 0) + return Qnil; + + buf = ALLOCA_N(char, len); + SSL_get_peer_finished(ssl, buf, len); + return rb_str_new(buf, len); +} + +/* + * call-seq: + * ssl.client_ca => [x509name, ...] or nil * * Returns the list of client CAs. Please note that in contrast to * SSLContext#client_ca= no array of X509::Certificate is returned but @@ -2301,10 +2523,12 @@ ossl_ssl_get_client_ca_list(VALUE self) GetSSL(self, ssl); ca = SSL_get_client_CA_list(ssl); + if (!ca) + return Qnil; return ossl_x509name_sk2ary(ca); } -# ifndef OPENSSL_NO_NEXTPROTONEG +# ifdef OSSL_USE_NEXTPROTONEG /* * call-seq: * ssl.npn_protocol => String | nil @@ -2323,13 +2547,12 @@ ossl_ssl_npn_protocol(VALUE self) SSL_get0_next_proto_negotiated(ssl, &out, &outlen); if (!outlen) - return Qnil; + return Qnil; else - return rb_str_new((const char *) out, outlen); + return rb_str_new((const char *) out, outlen); } # endif -# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB /* * call-seq: * ssl.alpn_protocol => String | nil @@ -2348,13 +2571,54 @@ ossl_ssl_alpn_protocol(VALUE self) SSL_get0_alpn_selected(ssl, &out, &outlen); if (!outlen) - return Qnil; + return Qnil; else - return rb_str_new((const char *) out, outlen); + return rb_str_new((const char *) out, outlen); +} + +/* + * call-seq: + * session.export_keying_material(label, length) -> String + * + * Enables use of shared session key material in accordance with RFC 5705. + */ +static VALUE +ossl_ssl_export_keying_material(int argc, VALUE *argv, VALUE self) +{ + SSL *ssl; + VALUE str; + VALUE label; + VALUE length; + VALUE context; + unsigned char *p; + size_t len; + int use_ctx = 0; + unsigned char *ctx = NULL; + size_t ctx_len = 0; + int ret; + + rb_scan_args(argc, argv, "21", &label, &length, &context); + StringValue(label); + + GetSSL(self, ssl); + + len = (size_t)NUM2LONG(length); + str = rb_str_new(0, len); + p = (unsigned char *)RSTRING_PTR(str); + if (!NIL_P(context)) { + use_ctx = 1; + StringValue(context); + ctx = (unsigned char *)RSTRING_PTR(context); + ctx_len = RSTRING_LEN(context); + } + ret = SSL_export_keying_material(ssl, p, len, (char *)RSTRING_PTR(label), + RSTRING_LENINT(label), ctx, ctx_len, use_ctx); + if (ret == 0 || ret == -1) { + ossl_raise(eSSLError, "SSL_export_keying_material"); + } + return str; } -# endif -# ifdef HAVE_SSL_GET_SERVER_TMP_KEY /* * call-seq: * ssl.tmp_key => PKey or nil @@ -2369,41 +2633,91 @@ ossl_ssl_tmp_key(VALUE self) GetSSL(self, ssl); if (!SSL_get_server_tmp_key(ssl, &key)) - return Qnil; - return ossl_pkey_new(key); + return Qnil; + return ossl_pkey_wrap(key); +} + +#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME +/* + * call-seq: + * ssl.sigalg => String or nil + * + * Returns the signature algorithm name, the IANA name of the signature scheme + * used by the local to sign the TLS handshake. + */ +static VALUE +ossl_ssl_get_sigalg(VALUE self) +{ + SSL *ssl; + const char *name; + + GetSSL(self, ssl); + if (!SSL_get0_signature_name(ssl, &name)) + return Qnil; + return rb_str_new_cstr(name); } -# endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */ + +/* + * call-seq: + * ssl.peer_sigalg => String or nil + * + * Returns the signature algorithm name, the IANA name of the signature scheme + * used by the peer to sign the TLS handshake. + */ +static VALUE +ossl_ssl_get_peer_sigalg(VALUE self) +{ + SSL *ssl; + const char *name; + + GetSSL(self, ssl); + if (!SSL_get0_peer_signature_name(ssl, &name)) + return Qnil; + return rb_str_new_cstr(name); +} +#endif + +#ifdef HAVE_SSL_GET0_GROUP_NAME +/* + * call-seq: + * ssl.group => String or nil + * + * Returns the name of the group that was used for the key agreement of the + * current TLS session establishment. + */ +static VALUE +ossl_ssl_get_group(VALUE self) +{ + SSL *ssl; + const char *name; + + GetSSL(self, ssl); + if (!(name = SSL_get0_group_name(ssl))) + return Qnil; + return rb_str_new_cstr(name); +} +#endif + #endif /* !defined(OPENSSL_NO_SOCK) */ -#undef rb_intern -#define rb_intern(s) rb_intern_const(s) void Init_ossl_ssl(void) { #if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); rb_mWaitReadable = rb_define_module_under(rb_cIO, "WaitReadable"); rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable"); #endif - id_call = rb_intern("call"); - ID_callback_state = rb_intern("callback_state"); +#ifndef OPENSSL_NO_SOCK + id_call = rb_intern_const("call"); + ID_callback_state = rb_intern_const("callback_state"); - ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0); - if (ossl_ssl_ex_vcb_idx < 0) - ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index"); ossl_ssl_ex_ptr_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_ptr_idx", 0, 0, 0); if (ossl_ssl_ex_ptr_idx < 0) - ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index"); + ossl_raise(rb_eRuntimeError, "SSL_get_ex_new_index"); ossl_sslctx_ex_ptr_idx = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_ptr_idx", 0, 0, 0); if (ossl_sslctx_ex_ptr_idx < 0) - ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index"); -#if !defined(HAVE_X509_STORE_UP_REF) - ossl_sslctx_ex_store_p = SSL_CTX_get_ex_new_index(0, (void *)"ossl_sslctx_ex_store_p", 0, 0, 0); - if (ossl_sslctx_ex_store_p < 0) - ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index"); -#endif + ossl_raise(rb_eRuntimeError, "SSL_CTX_get_ex_new_index"); /* Document-module: OpenSSL::SSL * @@ -2414,16 +2728,6 @@ Init_ossl_ssl(void) */ mSSL = rb_define_module_under(mOSSL, "SSL"); - /* Document-module: OpenSSL::ExtConfig - * - * This module contains configuration information about the SSL extension, - * for example if socket support is enabled, or the host name TLS extension - * is enabled. Constants in this module will always be defined, but contain - * +true+ or +false+ values depending on the configuration of your OpenSSL - * installation. - */ - mSSLExtConfig = rb_define_module_under(mOSSL, "ExtConfig"); - /* Document-class: OpenSSL::SSL::SSLError * * Generic error class raised by SSLSocket and SSLContext. @@ -2455,7 +2759,7 @@ Init_ossl_ssl(void) * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated. * It is recommended to use #add_certificate instead. */ - rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse); /* * Context private key @@ -2463,29 +2767,29 @@ Init_ossl_ssl(void) * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated. * It is recommended to use #add_certificate instead. */ - rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse); /* * A certificate or Array of certificates that will be sent to the client. */ - rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse); /* * The path to a file containing a PEM-format CA certificate */ - rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse); /* * The path to a directory containing CA certificates in PEM format. * * Files are looked up by subject's X509 name's hash value. */ - rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse); /* * Maximum session lifetime in seconds. */ - rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse); /* * Session verification mode. @@ -2498,12 +2802,12 @@ Init_ossl_ssl(void) * * See SSL_CTX_set_verify(3) for details. */ - rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse); /* * Number of CA certificates to walk when verifying a certificate chain. */ - rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse); /* * A callback for additional certificate verification. The callback is @@ -2517,7 +2821,7 @@ Init_ossl_ssl(void) * If the callback returns +false+, the chain verification is immediately * stopped and a bad_certificate alert is then sent. */ - rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse); /* * Whether to check the server certificate is valid for the hostname. @@ -2525,12 +2829,12 @@ Init_ossl_ssl(void) * In order to make this work, verify_mode must be set to VERIFY_PEER and * the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=. */ - rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse); /* * An OpenSSL::X509::Store used for certificate verification. */ - rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse); /* * An Array of extra X509 certificates to be added to the certificate @@ -2539,7 +2843,7 @@ Init_ossl_ssl(void) * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated. * It is recommended to use #add_certificate instead. */ - rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse); /* * A callback invoked when a client certificate is requested by a server @@ -2549,20 +2853,23 @@ Init_ossl_ssl(void) * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any * other value is returned the handshake is suspended. */ - rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse); -#if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) +#ifndef OPENSSL_NO_DH /* - * A callback invoked when ECDH parameters are required. + * A callback invoked when DH parameters are required for ephemeral DH key + * exchange. * - * The callback is invoked with the Session for the key exchange, an + * The callback is invoked with the SSLSocket, a * flag indicating the use of an export cipher and the keylength * required. * - * The callback is deprecated. This does not work with recent versions of - * OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead. + * The callback must return an OpenSSL::PKey::DH instance of the correct + * key length. + * + * <b>Deprecated in version 3.0.</b> Use #tmp_dh= instead. */ - rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("tmp_dh_callback"), 1, 1, Qfalse); #endif /* @@ -2570,7 +2877,7 @@ Init_ossl_ssl(void) * sessions for multiple applications to be distinguished, for example, by * name. */ - rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse); /* * A callback invoked on a server when a session is proposed by the client @@ -2579,7 +2886,7 @@ Init_ossl_ssl(void) * The callback is invoked with the SSLSocket and session id. The * callback may return a Session from an external cache. */ - rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse); /* * A callback invoked when a new session was negotiated. @@ -2587,7 +2894,7 @@ Init_ossl_ssl(void) * The callback is invoked with an SSLSocket. If +false+ is returned the * session will be removed from the internal cache. */ - rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse); /* * A callback invoked when a session is removed from the internal cache. @@ -2598,18 +2905,16 @@ Init_ossl_ssl(void) * multi-threaded application. The callback is called inside a global lock * and it can randomly cause deadlock on Ruby thread switching. */ - rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse); - - rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue); + rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse); /* - * A callback invoked whenever a new handshake is initiated. May be used - * to disable renegotiation entirely. + * A callback invoked whenever a new handshake is initiated on an + * established connection. May be used to disable renegotiation entirely. * * The callback is invoked with the active SSLSocket. The callback's - * return value is irrelevant, normal return indicates "approval" of the + * return value is ignored. A normal return indicates "approval" of the * renegotiation and will continue the process. To forbid renegotiation - * and to cancel the process, an Error may be raised within the callback. + * and to cancel the process, raise an exception within the callback. * * === Disable client renegotiation * @@ -2617,14 +2922,12 @@ Init_ossl_ssl(void) * renegotiation entirely. You may use a callback as follows to implement * this feature: * - * num_handshakes = 0 * ctx.renegotiation_cb = lambda do |ssl| - * num_handshakes += 1 - * raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1 + * raise RuntimeError, "Client renegotiation disabled" * end */ - rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse); -#ifndef OPENSSL_NO_NEXTPROTONEG + rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse); +#ifdef OSSL_USE_NEXTPROTONEG /* * An Enumerable of Strings. Each String represents a protocol to be * advertised as the list of supported protocols for Next Protocol @@ -2636,7 +2939,7 @@ Init_ossl_ssl(void) * * ctx.npn_protocols = ["http/1.1", "spdy/2"] */ - rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse); /* * A callback invoked on the client side when the client needs to select * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1 @@ -2653,10 +2956,9 @@ Init_ossl_ssl(void) * protocols.first * end */ - rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse); #endif -#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB /* * An Enumerable of Strings. Each String represents a protocol to be * advertised as the list of supported protocols for Application-Layer @@ -2668,7 +2970,7 @@ Init_ossl_ssl(void) * * ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"] */ - rb_attr(cSSLContext, rb_intern("alpn_protocols"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse); /* * A callback invoked on the server side when the server needs to select * a protocol from the list sent by the client. Supported in OpenSSL 1.0.2 @@ -2685,16 +2987,49 @@ Init_ossl_ssl(void) * protocols.first * end */ - rb_attr(cSSLContext, rb_intern("alpn_select_cb"), 1, 1, Qfalse); -#endif + rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse); + + /* + * A callback invoked when TLS key material is generated or received, in + * order to allow applications to store this keying material for debugging + * purposes. + * + * The callback is invoked with an SSLSocket and a string containing the + * key material in the format used by NSS for its SSLKEYLOGFILE debugging + * output. + * + * It is only compatible with OpenSSL >= 1.1.1. Even if LibreSSL implements + * SSL_CTX_set_keylog_callback() from v3.4.2, it does nothing (see + * https://github.com/libressl-portable/openbsd/commit/648d39f0f035835d0653342d139883b9661e9cb6). + * + * === Example + * + * context.keylog_cb = proc do |_sock, line| + * File.open('ssl_keylog_file', "a") do |f| + * f.write("#{line}\n") + * end + * end + */ + rb_attr(cSSLContext, rb_intern_const("keylog_cb"), 1, 1, Qfalse); rb_define_alias(cSSLContext, "ssl_timeout", "timeout"); rb_define_alias(cSSLContext, "ssl_timeout=", "timeout="); - rb_define_private_method(cSSLContext, "set_minmax_proto_version", - ossl_sslctx_set_minmax_proto_version, 2); + rb_define_method(cSSLContext, "min_version=", ossl_sslctx_set_min_version, 1); + rb_define_method(cSSLContext, "max_version=", ossl_sslctx_set_max_version, 1); rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0); rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1); - rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1); + rb_define_method(cSSLContext, "ciphersuites=", ossl_sslctx_set_ciphersuites, 1); +#ifdef HAVE_SSL_CTX_SET1_SIGALGS_LIST // Not in LibreSSL yet + rb_define_method(cSSLContext, "sigalgs=", ossl_sslctx_set_sigalgs, 1); +#endif +#ifdef HAVE_SSL_CTX_SET1_CLIENT_SIGALGS_LIST // Not in LibreSSL or AWS-LC yet + rb_define_method(cSSLContext, "client_sigalgs=", ossl_sslctx_set_client_sigalgs, 1); +#endif +#ifndef OPENSSL_NO_DH + rb_define_method(cSSLContext, "tmp_dh=", ossl_sslctx_set_tmp_dh, 1); +#endif + rb_define_method(cSSLContext, "groups=", ossl_sslctx_set_groups, 1); + rb_define_alias(cSSLContext, "ecdh_curves=", "groups="); rb_define_method(cSSLContext, "security_level", ossl_sslctx_get_security_level, 0); rb_define_method(cSSLContext, "security_level=", ossl_sslctx_set_security_level, 1); #ifdef SSL_MODE_SEND_FALLBACK_SCSV @@ -2767,11 +3102,6 @@ Init_ossl_ssl(void) * Document-class: OpenSSL::SSL::SSLSocket */ cSSLSocket = rb_define_class_under(mSSL, "SSLSocket", rb_cObject); -#ifdef OPENSSL_NO_SOCK - rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qtrue); - rb_define_method(cSSLSocket, "initialize", rb_f_notimplement, -1); -#else - rb_define_const(mSSLExtConfig, "OPENSSL_NO_SOCK", Qfalse); rb_define_alloc_func(cSSLSocket, ossl_ssl_s_alloc); rb_define_method(cSSLSocket, "initialize", ossl_ssl_initialize, -1); rb_undef_method(cSSLSocket, "initialize_copy"); @@ -2798,15 +3128,20 @@ Init_ossl_ssl(void) rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0); /* #hostname is defined in lib/openssl/ssl.rb */ rb_define_method(cSSLSocket, "hostname=", ossl_ssl_set_hostname, 1); -# ifdef HAVE_SSL_GET_SERVER_TMP_KEY + rb_define_method(cSSLSocket, "finished_message", ossl_ssl_get_finished, 0); + rb_define_method(cSSLSocket, "peer_finished_message", ossl_ssl_get_peer_finished, 0); rb_define_method(cSSLSocket, "tmp_key", ossl_ssl_tmp_key, 0); -# endif -# ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB rb_define_method(cSSLSocket, "alpn_protocol", ossl_ssl_alpn_protocol, 0); -# endif -# ifndef OPENSSL_NO_NEXTPROTONEG + rb_define_method(cSSLSocket, "export_keying_material", ossl_ssl_export_keying_material, -1); +# ifdef OSSL_USE_NEXTPROTONEG rb_define_method(cSSLSocket, "npn_protocol", ossl_ssl_npn_protocol, 0); # endif +#ifdef HAVE_SSL_GET0_PEER_SIGNATURE_NAME + rb_define_method(cSSLSocket, "sigalg", ossl_ssl_get_sigalg, 0); + rb_define_method(cSSLSocket, "peer_sigalg", ossl_ssl_get_peer_sigalg, 0); +#endif +#ifdef HAVE_SSL_GET0_GROUP_NAME + rb_define_method(cSSLSocket, "group", ossl_ssl_get_group, 0); #endif rb_define_const(mSSL, "VERIFY_NONE", INT2NUM(SSL_VERIFY_NONE)); @@ -2815,14 +3150,25 @@ Init_ossl_ssl(void) rb_define_const(mSSL, "VERIFY_CLIENT_ONCE", INT2NUM(SSL_VERIFY_CLIENT_ONCE)); rb_define_const(mSSL, "OP_ALL", ULONG2NUM(SSL_OP_ALL)); +#ifdef SSL_OP_CLEANSE_PLAINTEXT /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_CLEANSE_PLAINTEXT", ULONG2NUM(SSL_OP_CLEANSE_PLAINTEXT)); +#endif rb_define_const(mSSL, "OP_LEGACY_SERVER_CONNECT", ULONG2NUM(SSL_OP_LEGACY_SERVER_CONNECT)); -#ifdef SSL_OP_TLSEXT_PADDING /* OpenSSL 1.0.1h and OpenSSL 1.0.2 */ - rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING)); +#ifdef SSL_OP_ENABLE_KTLS /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_ENABLE_KTLS", ULONG2NUM(SSL_OP_ENABLE_KTLS)); #endif -#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG /* OpenSSL 1.0.1f and OpenSSL 1.0.2 */ + rb_define_const(mSSL, "OP_TLSEXT_PADDING", ULONG2NUM(SSL_OP_TLSEXT_PADDING)); rb_define_const(mSSL, "OP_SAFARI_ECDHE_ECDSA_BUG", ULONG2NUM(SSL_OP_SAFARI_ECDHE_ECDSA_BUG)); +#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_IGNORE_UNEXPECTED_EOF", ULONG2NUM(SSL_OP_IGNORE_UNEXPECTED_EOF)); +#endif +#ifdef SSL_OP_ALLOW_CLIENT_RENEGOTIATION /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_ALLOW_CLIENT_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_CLIENT_RENEGOTIATION)); +#endif +#ifdef SSL_OP_DISABLE_TLSEXT_CA_NAMES /* OpenSSL 3.0 */ + rb_define_const(mSSL, "OP_DISABLE_TLSEXT_CA_NAMES", ULONG2NUM(SSL_OP_DISABLE_TLSEXT_CA_NAMES)); #endif -#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1 */ +#ifdef SSL_OP_ALLOW_NO_DHE_KEX /* OpenSSL 1.1.1, missing in LibreSSL */ rb_define_const(mSSL, "OP_ALLOW_NO_DHE_KEX", ULONG2NUM(SSL_OP_ALLOW_NO_DHE_KEX)); #endif rb_define_const(mSSL, "OP_DONT_INSERT_EMPTY_FRAGMENTS", ULONG2NUM(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)); @@ -2830,23 +3176,29 @@ Init_ossl_ssl(void) rb_define_const(mSSL, "OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)); rb_define_const(mSSL, "OP_NO_COMPRESSION", ULONG2NUM(SSL_OP_NO_COMPRESSION)); rb_define_const(mSSL, "OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION", ULONG2NUM(SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)); -#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1 */ +#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC /* OpenSSL 1.1.1, missing in LibreSSL */ rb_define_const(mSSL, "OP_NO_ENCRYPT_THEN_MAC", ULONG2NUM(SSL_OP_NO_ENCRYPT_THEN_MAC)); #endif - rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE)); - rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG)); -#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1 */ - rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION)); +#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT /* OpenSSL 1.1.1, missing in LibreSSL */ + rb_define_const(mSSL, "OP_ENABLE_MIDDLEBOX_COMPAT", ULONG2NUM(SSL_OP_ENABLE_MIDDLEBOX_COMPAT)); +#endif +#ifdef SSL_OP_PRIORITIZE_CHACHA /* OpenSSL 1.1.1, missing in LibreSSL */ + rb_define_const(mSSL, "OP_PRIORITIZE_CHACHA", ULONG2NUM(SSL_OP_PRIORITIZE_CHACHA)); +#endif +#ifdef SSL_OP_NO_ANTI_REPLAY /* OpenSSL 1.1.1, missing in LibreSSL */ + rb_define_const(mSSL, "OP_NO_ANTI_REPLAY", ULONG2NUM(SSL_OP_NO_ANTI_REPLAY)); #endif - rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG)); - rb_define_const(mSSL, "OP_NO_SSLv3", ULONG2NUM(SSL_OP_NO_SSLv3)); rb_define_const(mSSL, "OP_NO_TLSv1", ULONG2NUM(SSL_OP_NO_TLSv1)); rb_define_const(mSSL, "OP_NO_TLSv1_1", ULONG2NUM(SSL_OP_NO_TLSv1_1)); rb_define_const(mSSL, "OP_NO_TLSv1_2", ULONG2NUM(SSL_OP_NO_TLSv1_2)); -#ifdef SSL_OP_NO_TLSv1_3 /* OpenSSL 1.1.1 */ rb_define_const(mSSL, "OP_NO_TLSv1_3", ULONG2NUM(SSL_OP_NO_TLSv1_3)); + rb_define_const(mSSL, "OP_CIPHER_SERVER_PREFERENCE", ULONG2NUM(SSL_OP_CIPHER_SERVER_PREFERENCE)); + rb_define_const(mSSL, "OP_TLS_ROLLBACK_BUG", ULONG2NUM(SSL_OP_TLS_ROLLBACK_BUG)); +#ifdef SSL_OP_NO_RENEGOTIATION /* OpenSSL 1.1.1, missing in LibreSSL */ + rb_define_const(mSSL, "OP_NO_RENEGOTIATION", ULONG2NUM(SSL_OP_NO_RENEGOTIATION)); #endif + rb_define_const(mSSL, "OP_CRYPTOPRO_TLSEXT_BUG", ULONG2NUM(SSL_OP_CRYPTOPRO_TLSEXT_BUG)); /* SSL_OP_* flags for DTLS */ #if 0 @@ -2905,22 +3257,19 @@ Init_ossl_ssl(void) rb_define_const(mSSL, "TLS1_1_VERSION", INT2NUM(TLS1_1_VERSION)); /* TLS 1.2 */ rb_define_const(mSSL, "TLS1_2_VERSION", INT2NUM(TLS1_2_VERSION)); -#ifdef TLS1_3_VERSION /* OpenSSL 1.1.1 */ /* TLS 1.3 */ rb_define_const(mSSL, "TLS1_3_VERSION", INT2NUM(TLS1_3_VERSION)); -#endif - sym_exception = ID2SYM(rb_intern("exception")); - sym_wait_readable = ID2SYM(rb_intern("wait_readable")); - sym_wait_writable = ID2SYM(rb_intern("wait_writable")); + sym_exception = ID2SYM(rb_intern_const("exception")); + sym_wait_readable = ID2SYM(rb_intern_const("wait_readable")); + sym_wait_writable = ID2SYM(rb_intern_const("wait_writable")); - id_tmp_dh_callback = rb_intern("tmp_dh_callback"); - id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback"); - id_npn_protocols_encoded = rb_intern("npn_protocols_encoded"); + id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded"); + id_each = rb_intern_const("each"); #define DefIVarID(name) do \ - id_i_##name = rb_intern("@"#name); while (0) + id_i_##name = rb_intern_const("@"#name); while (0) DefIVarID(cert_store); DefIVarID(ca_file); @@ -2934,7 +3283,6 @@ Init_ossl_ssl(void) DefIVarID(key); DefIVarID(extra_chain_cert); DefIVarID(client_cert_cb); - DefIVarID(tmp_ecdh_callback); DefIVarID(timeout); DefIVarID(session_id_context); DefIVarID(session_get_cb); @@ -2946,8 +3294,11 @@ Init_ossl_ssl(void) DefIVarID(alpn_select_cb); DefIVarID(servername_cb); DefIVarID(verify_hostname); + DefIVarID(keylog_cb); + DefIVarID(tmp_dh_callback); DefIVarID(io); DefIVarID(context); DefIVarID(hostname); +#endif /* !defined(OPENSSL_NO_SOCK) */ } diff --git a/ext/openssl/ossl_ssl.h b/ext/openssl/ossl_ssl.h index 535c56097c..a87e62d450 100644 --- a/ext/openssl/ossl_ssl.h +++ b/ext/openssl/ossl_ssl.h @@ -5,23 +5,23 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_SSL_H_) #define _OSSL_SSL_H_ #define GetSSL(obj, ssl) do { \ - TypedData_Get_Struct((obj), SSL, &ossl_ssl_type, (ssl)); \ - if (!(ssl)) { \ - ossl_raise(rb_eRuntimeError, "SSL is not initialized"); \ - } \ + TypedData_Get_Struct((obj), SSL, &ossl_ssl_type, (ssl)); \ + if (!(ssl)) { \ + ossl_raise(rb_eRuntimeError, "SSL is not initialized"); \ + } \ } while (0) #define GetSSLSession(obj, sess) do { \ - TypedData_Get_Struct((obj), SSL_SESSION, &ossl_ssl_session_type, (sess)); \ - if (!(sess)) { \ - ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \ - } \ + TypedData_Get_Struct((obj), SSL_SESSION, &ossl_ssl_session_type, (sess)); \ + if (!(sess)) { \ + ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \ + } \ } while (0) extern const rb_data_type_t ossl_ssl_type; diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c index 5514087387..8a2fbf4100 100644 --- a/ext/openssl/ossl_ssl_session.c +++ b/ext/openssl/ossl_ssl_session.c @@ -4,6 +4,7 @@ #include "ossl.h" +#ifndef OPENSSL_NO_SOCK VALUE cSSLSession; static VALUE eSSLSession; @@ -16,14 +17,14 @@ ossl_ssl_session_free(void *ptr) const rb_data_type_t ossl_ssl_session_type = { "OpenSSL/SSL/Session", { - 0, ossl_ssl_session_free, + 0, ossl_ssl_session_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE ossl_ssl_session_alloc(VALUE klass) { - return TypedData_Wrap_Struct(klass, &ossl_ssl_session_type, NULL); + return TypedData_Wrap_Struct(klass, &ossl_ssl_session_type, NULL); } /* @@ -34,45 +35,41 @@ static VALUE ossl_ssl_session_alloc(VALUE klass) * Creates a new Session object from an instance of SSLSocket or DER/PEM encoded * String. */ -static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1) +static VALUE +ossl_ssl_session_initialize(VALUE self, VALUE arg1) { - SSL_SESSION *ctx = NULL; - - if (RDATA(self)->data) - ossl_raise(eSSLSession, "SSL Session already initialized"); - - if (rb_obj_is_instance_of(arg1, cSSLSocket)) { - SSL *ssl; - - GetSSL(arg1, ssl); - - if ((ctx = SSL_get1_session(ssl)) == NULL) - ossl_raise(eSSLSession, "no session available"); - } else { - BIO *in = ossl_obj2bio(&arg1); + SSL_SESSION *ctx; - ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); + if (RTYPEDDATA_DATA(self)) + ossl_raise(eSSLSession, "SSL Session already initialized"); - if (!ctx) { - OSSL_BIO_reset(in); - ctx = d2i_SSL_SESSION_bio(in, NULL); - } + if (rb_obj_is_instance_of(arg1, cSSLSocket)) { + SSL *ssl; - BIO_free(in); + GetSSL(arg1, ssl); - if (!ctx) - ossl_raise(rb_eArgError, "unknown type"); - } + if ((ctx = SSL_get1_session(ssl)) == NULL) + ossl_raise(eSSLSession, "no session available"); + } + else { + BIO *in = ossl_obj2bio(&arg1); - /* should not happen */ - if (ctx == NULL) - ossl_raise(eSSLSession, "ctx not set - internal error"); + ctx = d2i_SSL_SESSION_bio(in, NULL); + if (!ctx) { + OSSL_BIO_reset(in); + ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL); + } + BIO_free(in); + if (!ctx) + ossl_raise(rb_eArgError, "unknown type"); + } - RDATA(self)->data = ctx; + RTYPEDDATA_DATA(self) = ctx; - return self; + return self; } +/* :nodoc: */ static VALUE ossl_ssl_session_initialize_copy(VALUE self, VALUE other) { @@ -83,9 +80,9 @@ ossl_ssl_session_initialize_copy(VALUE self, VALUE other) GetSSLSession(other, sess_other); sess_new = ASN1_dup((i2d_of_void *)i2d_SSL_SESSION, (d2i_of_void *)d2i_SSL_SESSION, - (char *)sess_other); + (char *)sess_other); if (!sess_new) - ossl_raise(eSSLSession, "ASN1_dup"); + ossl_raise(eSSLSession, "ASN1_dup"); RTYPEDDATA_DATA(self) = sess_new; SSL_SESSION_free(sess); @@ -102,9 +99,9 @@ ossl_SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b) const unsigned char *b_sid = SSL_SESSION_get_id(b, &b_len); if (SSL_SESSION_get_protocol_version(a) != SSL_SESSION_get_protocol_version(b)) - return 1; + return 1; if (a_len != b_len) - return 1; + return 1; return CRYPTO_memcmp(a_sid, b_sid, a_len); } @@ -117,15 +114,15 @@ ossl_SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b) */ static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2) { - SSL_SESSION *ctx1, *ctx2; + SSL_SESSION *ctx1, *ctx2; - GetSSLSession(val1, ctx1); - GetSSLSession(val2, ctx2); + GetSSLSession(val1, ctx1); + GetSSLSession(val2, ctx2); - switch (ossl_SSL_SESSION_cmp(ctx1, ctx2)) { - case 0: return Qtrue; - default: return Qfalse; - } + switch (ossl_SSL_SESSION_cmp(ctx1, ctx2)) { + case 0: return Qtrue; + default: return Qfalse; + } } /* @@ -143,7 +140,7 @@ ossl_ssl_session_get_time(VALUE self) GetSSLSession(self, ctx); t = SSL_SESSION_get_time(ctx); if (t == 0) - return Qnil; + return Qnil; return rb_funcall(rb_cTime, rb_intern("at"), 1, LONG2NUM(t)); } @@ -178,16 +175,16 @@ ossl_ssl_session_get_timeout(VALUE self) */ static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v) { - SSL_SESSION *ctx; - long t; - - GetSSLSession(self, ctx); - if (rb_obj_is_instance_of(time_v, rb_cTime)) { - time_v = rb_funcall(time_v, rb_intern("to_i"), 0); - } - t = NUM2LONG(time_v); - SSL_SESSION_set_time(ctx, t); - return ossl_ssl_session_get_time(self); + SSL_SESSION *ctx; + long t; + + GetSSLSession(self, ctx); + if (rb_obj_is_instance_of(time_v, rb_cTime)) { + time_v = rb_funcall(time_v, rb_intern("to_i"), 0); + } + t = NUM2LONG(time_v); + SSL_SESSION_set_time(ctx, t); + return ossl_ssl_session_get_time(self); } /* @@ -198,13 +195,13 @@ static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v) */ static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v) { - SSL_SESSION *ctx; - long t; + SSL_SESSION *ctx; + long t; - GetSSLSession(self, ctx); - t = NUM2LONG(time_v); - SSL_SESSION_set_timeout(ctx, t); - return ossl_ssl_session_get_timeout(self); + GetSSLSession(self, ctx); + t = NUM2LONG(time_v); + SSL_SESSION_set_timeout(ctx, t); + return ossl_ssl_session_get_timeout(self); } /* @@ -212,18 +209,18 @@ static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v) * session.id -> String * * Returns the Session ID. -*/ + */ static VALUE ossl_ssl_session_get_id(VALUE self) { - SSL_SESSION *ctx; - const unsigned char *p = NULL; - unsigned int i = 0; + SSL_SESSION *ctx; + const unsigned char *p = NULL; + unsigned int i = 0; - GetSSLSession(self, ctx); + GetSSLSession(self, ctx); - p = SSL_SESSION_get_id(ctx, &i); + p = SSL_SESSION_get_id(ctx, &i); - return rb_str_new((const char *) p, i); + return rb_str_new((const char *) p, i); } /* @@ -234,22 +231,22 @@ static VALUE ossl_ssl_session_get_id(VALUE self) */ static VALUE ossl_ssl_session_to_der(VALUE self) { - SSL_SESSION *ctx; - unsigned char *p; - int len; - VALUE str; - - GetSSLSession(self, ctx); - len = i2d_SSL_SESSION(ctx, NULL); - if (len <= 0) { - ossl_raise(eSSLSession, "i2d_SSL_SESSION"); - } - - str = rb_str_new(0, len); - p = (unsigned char *)RSTRING_PTR(str); - i2d_SSL_SESSION(ctx, &p); - ossl_str_adjust(str, p); - return str; + SSL_SESSION *ctx; + unsigned char *p; + int len; + VALUE str; + + GetSSLSession(self, ctx); + len = i2d_SSL_SESSION(ctx, NULL); + if (len <= 0) { + ossl_raise(eSSLSession, "i2d_SSL_SESSION"); + } + + str = rb_str_new(0, len); + p = (unsigned char *)RSTRING_PTR(str); + i2d_SSL_SESSION(ctx, &p); + ossl_str_adjust(str, p); + return str; } /* @@ -260,22 +257,22 @@ static VALUE ossl_ssl_session_to_der(VALUE self) */ static VALUE ossl_ssl_session_to_pem(VALUE self) { - SSL_SESSION *ctx; - BIO *out; + SSL_SESSION *ctx; + BIO *out; - GetSSLSession(self, ctx); + GetSSLSession(self, ctx); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSSLSession, "BIO_s_mem()"); - } + if (!(out = BIO_new(BIO_s_mem()))) { + ossl_raise(eSSLSession, "BIO_s_mem()"); + } - if (!PEM_write_bio_SSL_SESSION(out, ctx)) { - BIO_free(out); - ossl_raise(eSSLSession, "SSL_SESSION_print()"); - } + if (!PEM_write_bio_SSL_SESSION(out, ctx)) { + BIO_free(out); + ossl_raise(eSSLSession, "SSL_SESSION_print()"); + } - return ossl_membio2str(out); + return ossl_membio2str(out); } @@ -287,46 +284,44 @@ static VALUE ossl_ssl_session_to_pem(VALUE self) */ static VALUE ossl_ssl_session_to_text(VALUE self) { - SSL_SESSION *ctx; - BIO *out; + SSL_SESSION *ctx; + BIO *out; - GetSSLSession(self, ctx); + GetSSLSession(self, ctx); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eSSLSession, "BIO_s_mem()"); - } + if (!(out = BIO_new(BIO_s_mem()))) { + ossl_raise(eSSLSession, "BIO_s_mem()"); + } - if (!SSL_SESSION_print(out, ctx)) { - BIO_free(out); - ossl_raise(eSSLSession, "SSL_SESSION_print()"); - } + if (!SSL_SESSION_print(out, ctx)) { + BIO_free(out); + ossl_raise(eSSLSession, "SSL_SESSION_print()"); + } - return ossl_membio2str(out); + return ossl_membio2str(out); } +#endif /* !defined(OPENSSL_NO_SOCK) */ void Init_ossl_ssl_session(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - mSSL = rb_define_module_under(mOSSL, "SSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); -#endif - cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject); - eSSLSession = rb_define_class_under(cSSLSession, "SessionError", eOSSLError); - - rb_define_alloc_func(cSSLSession, ossl_ssl_session_alloc); - rb_define_method(cSSLSession, "initialize", ossl_ssl_session_initialize, 1); - rb_define_method(cSSLSession, "initialize_copy", ossl_ssl_session_initialize_copy, 1); - - rb_define_method(cSSLSession, "==", ossl_ssl_session_eq, 1); - - rb_define_method(cSSLSession, "time", ossl_ssl_session_get_time, 0); - rb_define_method(cSSLSession, "time=", ossl_ssl_session_set_time, 1); - rb_define_method(cSSLSession, "timeout", ossl_ssl_session_get_timeout, 0); - rb_define_method(cSSLSession, "timeout=", ossl_ssl_session_set_timeout, 1); - rb_define_method(cSSLSession, "id", ossl_ssl_session_get_id, 0); - rb_define_method(cSSLSession, "to_der", ossl_ssl_session_to_der, 0); - rb_define_method(cSSLSession, "to_pem", ossl_ssl_session_to_pem, 0); - rb_define_method(cSSLSession, "to_text", ossl_ssl_session_to_text, 0); +#ifndef OPENSSL_NO_SOCK + cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject); + eSSLSession = rb_define_class_under(cSSLSession, "SessionError", eOSSLError); + + rb_define_alloc_func(cSSLSession, ossl_ssl_session_alloc); + rb_define_method(cSSLSession, "initialize", ossl_ssl_session_initialize, 1); + rb_define_method(cSSLSession, "initialize_copy", ossl_ssl_session_initialize_copy, 1); + + rb_define_method(cSSLSession, "==", ossl_ssl_session_eq, 1); + + rb_define_method(cSSLSession, "time", ossl_ssl_session_get_time, 0); + rb_define_method(cSSLSession, "time=", ossl_ssl_session_set_time, 1); + rb_define_method(cSSLSession, "timeout", ossl_ssl_session_get_timeout, 0); + rb_define_method(cSSLSession, "timeout=", ossl_ssl_session_set_timeout, 1); + rb_define_method(cSSLSession, "id", ossl_ssl_session_get_id, 0); + rb_define_method(cSSLSession, "to_der", ossl_ssl_session_to_der, 0); + rb_define_method(cSSLSession, "to_pem", ossl_ssl_session_to_pem, 0); + rb_define_method(cSSLSession, "to_text", ossl_ssl_session_to_text, 0); +#endif /* !defined(OPENSSL_NO_SOCK) */ } diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c new file mode 100644 index 0000000000..b31a854a63 --- /dev/null +++ b/ext/openssl/ossl_ts.c @@ -0,0 +1,1551 @@ +/* + * + * Copyright (C) 2010 Martin Bosslet <Martin.Bosslet@googlemail.com> + * All rights reserved. + */ +/* + * This program is licenced under the same licence as Ruby. + * (See the file 'COPYING'.) + */ +#include "ossl.h" + +#ifndef OPENSSL_NO_TS + +#define NewTSRequest(klass) \ + TypedData_Wrap_Struct((klass), &ossl_ts_req_type, 0) +#define SetTSRequest(obj, req) do { \ + if (!(req)) { \ + ossl_raise(rb_eRuntimeError, "TS_REQ wasn't initialized."); \ + } \ + RTYPEDDATA_DATA(obj) = (req); \ +} while (0) +#define GetTSRequest(obj, req) do { \ + TypedData_Get_Struct((obj), TS_REQ, &ossl_ts_req_type, (req)); \ + if (!(req)) { \ + ossl_raise(rb_eRuntimeError, "TS_REQ wasn't initialized."); \ + } \ +} while (0) + +#define NewTSResponse(klass) \ + TypedData_Wrap_Struct((klass), &ossl_ts_resp_type, 0) +#define SetTSResponse(obj, resp) do { \ + if (!(resp)) { \ + ossl_raise(rb_eRuntimeError, "TS_RESP wasn't initialized."); \ + } \ + RTYPEDDATA_DATA(obj) = (resp); \ +} while (0) +#define GetTSResponse(obj, resp) do { \ + TypedData_Get_Struct((obj), TS_RESP, &ossl_ts_resp_type, (resp)); \ + if (!(resp)) { \ + ossl_raise(rb_eRuntimeError, "TS_RESP wasn't initialized."); \ + } \ +} while (0) + +#define NewTSTokenInfo(klass) \ + TypedData_Wrap_Struct((klass), &ossl_ts_token_info_type, 0) +#define SetTSTokenInfo(obj, info) do { \ + if (!(info)) { \ + ossl_raise(rb_eRuntimeError, "TS_TST_INFO wasn't initialized."); \ + } \ + RTYPEDDATA_DATA(obj) = (info); \ +} while (0) +#define GetTSTokenInfo(obj, info) do { \ + TypedData_Get_Struct((obj), TS_TST_INFO, &ossl_ts_token_info_type, (info)); \ + if (!(info)) { \ + ossl_raise(rb_eRuntimeError, "TS_TST_INFO wasn't initialized."); \ + } \ +} while (0) + +#define ossl_tsfac_get_default_policy_id(o) rb_attr_get((o),rb_intern("@default_policy_id")) +#define ossl_tsfac_get_serial_number(o) rb_attr_get((o),rb_intern("@serial_number")) +#define ossl_tsfac_get_gen_time(o) rb_attr_get((o),rb_intern("@gen_time")) +#define ossl_tsfac_get_additional_certs(o) rb_attr_get((o),rb_intern("@additional_certs")) +#define ossl_tsfac_get_allowed_digests(o) rb_attr_get((o),rb_intern("@allowed_digests")) + +static VALUE mTimestamp; +static VALUE eTimestampError; +static VALUE cTimestampRequest; +static VALUE cTimestampResponse; +static VALUE cTimestampTokenInfo; +static VALUE cTimestampFactory; +static VALUE sBAD_ALG, sBAD_REQUEST, sBAD_DATA_FORMAT, sTIME_NOT_AVAILABLE; +static VALUE sUNACCEPTED_POLICY, sUNACCEPTED_EXTENSION, sADD_INFO_NOT_AVAILABLE; +static VALUE sSYSTEM_FAILURE; + +static void +ossl_ts_req_free(void *ptr) +{ + TS_REQ_free(ptr); +} + +static const rb_data_type_t ossl_ts_req_type = { + "OpenSSL/Timestamp/Request", + { + 0, ossl_ts_req_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static void +ossl_ts_resp_free(void *ptr) +{ + TS_RESP_free(ptr); +} + +static const rb_data_type_t ossl_ts_resp_type = { + "OpenSSL/Timestamp/Response", + { + 0, ossl_ts_resp_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static void +ossl_ts_token_info_free(void *ptr) +{ + TS_TST_INFO_free(ptr); +} + +static const rb_data_type_t ossl_ts_token_info_type = { + "OpenSSL/Timestamp/TokenInfo", + { + 0, ossl_ts_token_info_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static VALUE +asn1_to_der(void *template, int (*i2d)(void *template, unsigned char **pp)) +{ + VALUE str; + int len; + unsigned char *p; + + if((len = i2d(template, NULL)) <= 0) + ossl_raise(eTimestampError, "Error when encoding to DER"); + str = rb_str_new(0, len); + p = (unsigned char *)RSTRING_PTR(str); + if(i2d(template, &p) <= 0) + ossl_raise(eTimestampError, "Error when encoding to DER"); + rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str)); + + return str; +} + +static VALUE +obj_to_asn1obj_i(VALUE obj) +{ + return (VALUE)ossl_to_asn1obj(obj); +} + +static VALUE +ossl_ts_req_alloc(VALUE klass) +{ + TS_REQ *req; + VALUE obj; + + obj = NewTSRequest(klass); + if (!(req = TS_REQ_new())) + ossl_raise(eTimestampError, NULL); + SetTSRequest(obj, req); + + /* Defaults */ + TS_REQ_set_version(req, 1); + TS_REQ_set_cert_req(req, 1); + + return obj; +} + +/* + * When creating a Request with the +File+ or +string+ parameter, the + * corresponding +File+ or +string+ must be DER-encoded. + * + * call-seq: + * OpenSSL::Timestamp::Request.new(file) -> request + * OpenSSL::Timestamp::Request.new(string) -> request + * OpenSSL::Timestamp::Request.new -> empty request + */ +static VALUE +ossl_ts_req_initialize(int argc, VALUE *argv, VALUE self) +{ + TS_REQ *ts_req = DATA_PTR(self); + BIO *in; + VALUE arg; + + if(rb_scan_args(argc, argv, "01", &arg) == 0) { + return self; + } + + arg = ossl_to_der_if_possible(arg); + in = ossl_obj2bio(&arg); + ts_req = d2i_TS_REQ_bio(in, &ts_req); + BIO_free(in); + if (!ts_req) { + DATA_PTR(self) = NULL; + ossl_raise(eTimestampError, "Error when decoding the timestamp request"); + } + DATA_PTR(self) = ts_req; + + return self; +} + +/* + * Returns the 'short name' of the object identifier that represents the + * algorithm that was used to create the message imprint digest. + * + * call-seq: + * request.algorithm -> string + */ +static VALUE +ossl_ts_req_get_algorithm(VALUE self) +{ + TS_REQ *req; + TS_MSG_IMPRINT *mi; + X509_ALGOR *algor; + const ASN1_OBJECT *obj; + + GetTSRequest(self, req); + mi = TS_REQ_get_msg_imprint(req); + algor = TS_MSG_IMPRINT_get_algo(mi); + X509_ALGOR_get0(&obj, NULL, NULL, algor); + return ossl_asn1obj_to_string(obj); +} + +/* + * Allows to set the object identifier or the 'short name' of the + * algorithm that was used to create the message imprint digest. + * + * ===Example: + * request.algorithm = "SHA1" + * + * call-seq: + * request.algorithm = "string" -> string + */ +static VALUE +ossl_ts_req_set_algorithm(VALUE self, VALUE algo) +{ + TS_REQ *req; + TS_MSG_IMPRINT *mi; + ASN1_OBJECT *obj; + X509_ALGOR *algor; + + GetTSRequest(self, req); + obj = ossl_to_asn1obj(algo); + mi = TS_REQ_get_msg_imprint(req); + algor = TS_MSG_IMPRINT_get_algo(mi); + if (!X509_ALGOR_set0(algor, obj, V_ASN1_NULL, NULL)) { + ASN1_OBJECT_free(obj); + ossl_raise(eTimestampError, "X509_ALGOR_set0"); + } + + return algo; +} + +/* + * Returns the message imprint (digest) of the data to be timestamped. + * + * call-seq: + * request.message_imprint -> string or nil + */ +static VALUE +ossl_ts_req_get_msg_imprint(VALUE self) +{ + TS_REQ *req; + TS_MSG_IMPRINT *mi; + ASN1_OCTET_STRING *hashed_msg; + VALUE ret; + + GetTSRequest(self, req); + mi = TS_REQ_get_msg_imprint(req); + hashed_msg = TS_MSG_IMPRINT_get_msg(mi); + + ret = asn1str_to_str(hashed_msg); + + return ret; +} + +/* + * Set the message imprint digest. + * + * call-seq: + * request.message_imprint = "string" -> string + */ +static VALUE +ossl_ts_req_set_msg_imprint(VALUE self, VALUE hash) +{ + TS_REQ *req; + TS_MSG_IMPRINT *mi; + StringValue(hash); + + GetTSRequest(self, req); + mi = TS_REQ_get_msg_imprint(req); + if (!TS_MSG_IMPRINT_set_msg(mi, (unsigned char *)RSTRING_PTR(hash), RSTRING_LENINT(hash))) + ossl_raise(eTimestampError, "TS_MSG_IMPRINT_set_msg"); + + return hash; +} + +/* + * Returns the version of this request. +1+ is the default value. + * + * call-seq: + * request.version -> Integer + */ +static VALUE +ossl_ts_req_get_version(VALUE self) +{ + TS_REQ *req; + + GetTSRequest(self, req); + return LONG2NUM(TS_REQ_get_version(req)); +} + +/* + * Sets the version number for this Request. This should be +1+ for compliant + * servers. + * + * call-seq: + * request.version = number -> Integer + */ +static VALUE +ossl_ts_req_set_version(VALUE self, VALUE version) +{ + TS_REQ *req; + long ver; + + if ((ver = NUM2LONG(version)) < 0) + ossl_raise(eTimestampError, "version must be >= 0!"); + GetTSRequest(self, req); + if (!TS_REQ_set_version(req, ver)) + ossl_raise(eTimestampError, "TS_REQ_set_version"); + + return version; +} + +/* + * Returns the 'short name' of the object identifier that represents the + * timestamp policy under which the server shall create the timestamp. + * + * call-seq: + * request.policy_id -> string or nil + */ +static VALUE +ossl_ts_req_get_policy_id(VALUE self) +{ + TS_REQ *req; + + GetTSRequest(self, req); + if (!TS_REQ_get_policy_id(req)) + return Qnil; + return ossl_asn1obj_to_string(TS_REQ_get_policy_id(req)); +} + +/* + * Allows to set the object identifier that represents the + * timestamp policy under which the server shall create the timestamp. This + * may be left +nil+, implying that the timestamp server will issue the + * timestamp using some default policy. + * + * ===Example: + * request.policy_id = "1.2.3.4.5" + * + * call-seq: + * request.policy_id = "string" -> string + */ +static VALUE +ossl_ts_req_set_policy_id(VALUE self, VALUE oid) +{ + TS_REQ *req; + ASN1_OBJECT *obj; + int ok; + + GetTSRequest(self, req); + obj = ossl_to_asn1obj(oid); + ok = TS_REQ_set_policy_id(req, obj); + ASN1_OBJECT_free(obj); + if (!ok) + ossl_raise(eTimestampError, "TS_REQ_set_policy_id"); + + return oid; +} + +/* + * Returns the nonce (number used once) that the server shall include in its + * response. + * + * call-seq: + * request.nonce -> BN or nil + */ +static VALUE +ossl_ts_req_get_nonce(VALUE self) +{ + TS_REQ *req; + const ASN1_INTEGER * nonce; + + GetTSRequest(self, req); + if (!(nonce = TS_REQ_get_nonce(req))) + return Qnil; + return asn1integer_to_num(nonce); +} + +/* + * Sets the nonce (number used once) that the server shall include in its + * response. If the nonce is set, the server must return the same nonce value in + * a valid Response. + * + * call-seq: + * request.nonce = number -> BN + */ +static VALUE +ossl_ts_req_set_nonce(VALUE self, VALUE num) +{ + TS_REQ *req; + ASN1_INTEGER *nonce; + int ok; + + GetTSRequest(self, req); + nonce = num_to_asn1integer(num, NULL); + ok = TS_REQ_set_nonce(req, nonce); + ASN1_INTEGER_free(nonce); + if (!ok) + ossl_raise(eTimestampError, NULL); + return num; +} + +/* + * Indicates whether the response shall contain the timestamp authority's + * certificate or not. + * + * call-seq: + * request.cert_requested? -> true or false + */ +static VALUE +ossl_ts_req_get_cert_requested(VALUE self) +{ + TS_REQ *req; + + GetTSRequest(self, req); + return TS_REQ_get_cert_req(req) ? Qtrue: Qfalse; +} + +/* + * Specify whether the response shall contain the timestamp authority's + * certificate or not. The default value is +true+. + * + * call-seq: + * request.cert_requested = boolean -> true or false + */ +static VALUE +ossl_ts_req_set_cert_requested(VALUE self, VALUE requested) +{ + TS_REQ *req; + + GetTSRequest(self, req); + TS_REQ_set_cert_req(req, RTEST(requested)); + + return requested; +} + +/* + * DER-encodes this Request. + * + * call-seq: + * request.to_der -> DER-encoded string + */ +static VALUE +ossl_ts_req_to_der(VALUE self) +{ + TS_REQ *req; + TS_MSG_IMPRINT *mi; + X509_ALGOR *algo; + const ASN1_OBJECT *obj; + ASN1_OCTET_STRING *hashed_msg; + + GetTSRequest(self, req); + mi = TS_REQ_get_msg_imprint(req); + + algo = TS_MSG_IMPRINT_get_algo(mi); + X509_ALGOR_get0(&obj, NULL, NULL, algo); + if (OBJ_obj2nid(obj) == NID_undef) + ossl_raise(eTimestampError, "Message imprint missing algorithm"); + + hashed_msg = TS_MSG_IMPRINT_get_msg(mi); + if (!ASN1_STRING_length(hashed_msg)) + ossl_raise(eTimestampError, "Message imprint missing hashed message"); + + return asn1_to_der((void *)req, (int (*)(void *, unsigned char **))i2d_TS_REQ); +} + +static VALUE +ossl_ts_req_to_text(VALUE self) +{ + TS_REQ *req; + BIO *out; + + GetTSRequest(self, req); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_REQ_print_bio(out, req)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + +static VALUE +ossl_ts_resp_alloc(VALUE klass) +{ + TS_RESP *resp; + VALUE obj; + + obj = NewTSResponse(klass); + if (!(resp = TS_RESP_new())) + ossl_raise(eTimestampError, NULL); + SetTSResponse(obj, resp); + + return obj; +} + +/* + * Creates a Response from a +File+ or +string+ parameter, the + * corresponding +File+ or +string+ must be DER-encoded. Please note + * that Response is an immutable read-only class. If you'd like to create + * timestamps please refer to Factory instead. + * + * call-seq: + * OpenSSL::Timestamp::Response.new(file) -> response + * OpenSSL::Timestamp::Response.new(string) -> response + */ +static VALUE +ossl_ts_resp_initialize(VALUE self, VALUE der) +{ + TS_RESP *ts_resp = DATA_PTR(self); + BIO *in; + + der = ossl_to_der_if_possible(der); + in = ossl_obj2bio(&der); + ts_resp = d2i_TS_RESP_bio(in, &ts_resp); + BIO_free(in); + if (!ts_resp) { + DATA_PTR(self) = NULL; + ossl_raise(eTimestampError, "Error when decoding the timestamp response"); + } + DATA_PTR(self) = ts_resp; + + return self; +} + +/* + * Returns one of GRANTED, GRANTED_WITH_MODS, REJECTION, WAITING, + * REVOCATION_WARNING or REVOCATION_NOTIFICATION. A timestamp token has + * been created only in case +status+ is equal to GRANTED or GRANTED_WITH_MODS. + * + * call-seq: + * response.status -> BN (never nil) + */ +static VALUE +ossl_ts_resp_get_status(VALUE self) +{ + TS_RESP *resp; + TS_STATUS_INFO *si; + const ASN1_INTEGER *st; + + GetTSResponse(self, resp); + si = TS_RESP_get_status_info(resp); + st = TS_STATUS_INFO_get0_status(si); + + return asn1integer_to_num(st); +} + +/* + * In cases no timestamp token has been created, this field contains further + * info about the reason why response creation failed. The method returns either + * nil (the request was successful and a timestamp token was created) or one of + * the following: + * * :BAD_ALG - Indicates that the timestamp server rejects the message + * imprint algorithm used in the Request + * * :BAD_REQUEST - Indicates that the timestamp server was not able to process + * the Request properly + * * :BAD_DATA_FORMAT - Indicates that the timestamp server was not able to + * parse certain data in the Request + * * :TIME_NOT_AVAILABLE - Indicates that the server could not access its time + * source + * * :UNACCEPTED_POLICY - Indicates that the requested policy identifier is not + * recognized or supported by the timestamp server + * * :UNACCEPTED_EXTENSIION - Indicates that an extension in the Request is + * not supported by the timestamp server + * * :ADD_INFO_NOT_AVAILABLE -Indicates that additional information requested + * is either not understood or currently not available + * * :SYSTEM_FAILURE - Timestamp creation failed due to an internal error that + * occurred on the timestamp server + * + * call-seq: + * response.failure_info -> nil or symbol + */ +static VALUE +ossl_ts_resp_get_failure_info(VALUE self) +{ + TS_RESP *resp; + TS_STATUS_INFO *si; + const ASN1_BIT_STRING *fi; + + GetTSResponse(self, resp); + si = TS_RESP_get_status_info(resp); + fi = TS_STATUS_INFO_get0_failure_info(si); + if (!fi) + return Qnil; + if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_ALG)) + return sBAD_ALG; + if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_REQUEST)) + return sBAD_REQUEST; + if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_BAD_DATA_FORMAT)) + return sBAD_DATA_FORMAT; + if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_TIME_NOT_AVAILABLE)) + return sTIME_NOT_AVAILABLE; + if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_UNACCEPTED_POLICY)) + return sUNACCEPTED_POLICY; + if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_UNACCEPTED_EXTENSION)) + return sUNACCEPTED_EXTENSION; + if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_ADD_INFO_NOT_AVAILABLE)) + return sADD_INFO_NOT_AVAILABLE; + if (ASN1_BIT_STRING_get_bit(fi, TS_INFO_SYSTEM_FAILURE)) + return sSYSTEM_FAILURE; + + ossl_raise(eTimestampError, "Unrecognized failure info."); +} + +/* + * In cases of failure this field may contain an array of strings further + * describing the origin of the failure. + * + * call-seq: + * response.status_text -> Array of strings or nil + */ +static VALUE +ossl_ts_resp_get_status_text(VALUE self) +{ + TS_RESP *resp; + TS_STATUS_INFO *si; + const STACK_OF(ASN1_UTF8STRING) *text; + ASN1_UTF8STRING *current; + int i; + VALUE ret = rb_ary_new(); + + GetTSResponse(self, resp); + si = TS_RESP_get_status_info(resp); + if ((text = TS_STATUS_INFO_get0_text(si))) { + for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) { + current = sk_ASN1_UTF8STRING_value(text, i); + rb_ary_push(ret, asn1str_to_str(current)); + } + } + + return ret; +} + +/* + * If a timestamp token is present, this returns it in the form of a + * OpenSSL::PKCS7. + * + * call-seq: + * response.token -> nil or OpenSSL::PKCS7 + */ +static VALUE +ossl_ts_resp_get_token(VALUE self) +{ + TS_RESP *resp; + PKCS7 *p7; + + GetTSResponse(self, resp); + if (!(p7 = TS_RESP_get_token(resp))) + return Qnil; + return ossl_pkcs7_new(p7); +} + +/* + * Get the response's token info if present. + * + * call-seq: + * response.token_info -> nil or OpenSSL::Timestamp::TokenInfo + */ +static VALUE +ossl_ts_resp_get_token_info(VALUE self) +{ + TS_RESP *resp; + TS_TST_INFO *info, *copy; + VALUE obj; + + GetTSResponse(self, resp); + if (!(info = TS_RESP_get_tst_info(resp))) + return Qnil; + + obj = NewTSTokenInfo(cTimestampTokenInfo); + + if (!(copy = TS_TST_INFO_dup(info))) + ossl_raise(eTimestampError, NULL); + + SetTSTokenInfo(obj, copy); + + return obj; +} + +/* + * If the Request specified to request the TSA certificate + * (Request#cert_requested = true), then this field contains the + * certificate of the timestamp authority. + * + * call-seq: + * response.tsa_certificate -> OpenSSL::X509::Certificate or nil + */ +static VALUE +ossl_ts_resp_get_tsa_certificate(VALUE self) +{ + TS_RESP *resp; + PKCS7 *p7; + PKCS7_SIGNER_INFO *ts_info; + X509 *cert; + + GetTSResponse(self, resp); + if (!(p7 = TS_RESP_get_token(resp))) + return Qnil; + ts_info = sk_PKCS7_SIGNER_INFO_value(p7->d.sign->signer_info, 0); + cert = PKCS7_cert_from_signer_info(p7, ts_info); + if (!cert) + return Qnil; + return ossl_x509_new(cert); +} + +/* + * Returns the Response in DER-encoded form. + * + * call-seq: + * response.to_der -> string + */ +static VALUE +ossl_ts_resp_to_der(VALUE self) +{ + TS_RESP *resp; + + GetTSResponse(self, resp); + return asn1_to_der((void *)resp, (int (*)(void *, unsigned char **))i2d_TS_RESP); +} + +static VALUE +ossl_ts_resp_to_text(VALUE self) +{ + TS_RESP *resp; + BIO *out; + + GetTSResponse(self, resp); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_RESP_print_bio(out, resp)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + +/* + * Verifies a timestamp token by checking the signature, validating the + * certificate chain implied by tsa_certificate and by checking conformance to + * a given Request. Mandatory parameters are the Request associated to this + * Response, and an OpenSSL::X509::Store of trusted roots. + * + * Intermediate certificates can optionally be supplied for creating the + * certificate chain. These intermediate certificates must all be + * instances of OpenSSL::X509::Certificate. + * + * If validation fails, several kinds of exceptions can be raised: + * * TypeError if types don't fit + * * TimestampError if something is wrong with the timestamp token itself, if + * it is not conformant to the Request, or if validation of the timestamp + * certificate chain fails. + * + * call-seq: + * response.verify(Request, root_store) -> Response + * response.verify(Request, root_store, [intermediate_cert]) -> Response + */ +static VALUE +ossl_ts_resp_verify(int argc, VALUE *argv, VALUE self) +{ + VALUE ts_req, store, intermediates; + TS_RESP *resp; + TS_REQ *req; + X509_STORE *x509st; + TS_VERIFY_CTX *ctx; + STACK_OF(X509) *x509inter = NULL; + PKCS7* p7; + X509 *cert; + int status, i, ok; + + rb_scan_args(argc, argv, "21", &ts_req, &store, &intermediates); + + GetTSResponse(self, resp); + GetTSRequest(ts_req, req); + x509st = GetX509StorePtr(store); + + if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(req, NULL))) { + ossl_raise(eTimestampError, "Error when creating the verification context."); + } + + if (!NIL_P(intermediates)) { + x509inter = ossl_protect_x509_ary2sk(intermediates, &status); + if (status) { + TS_VERIFY_CTX_free(ctx); + rb_jump_tag(status); + } + } else if (!(x509inter = sk_X509_new_null())) { + TS_VERIFY_CTX_free(ctx); + ossl_raise(eTimestampError, "sk_X509_new_null"); + } + + if (!(p7 = TS_RESP_get_token(resp))) { + TS_VERIFY_CTX_free(ctx); + sk_X509_pop_free(x509inter, X509_free); + ossl_raise(eTimestampError, "TS_RESP_get_token"); + } + for (i=0; i < sk_X509_num(p7->d.sign->cert); i++) { + cert = sk_X509_value(p7->d.sign->cert, i); + if (!sk_X509_push(x509inter, cert)) { + sk_X509_pop_free(x509inter, X509_free); + TS_VERIFY_CTX_free(ctx); + ossl_raise(eTimestampError, "sk_X509_push"); + } + X509_up_ref(cert); + } + + if (!X509_STORE_up_ref(x509st)) { + sk_X509_pop_free(x509inter, X509_free); + TS_VERIFY_CTX_free(ctx); + ossl_raise(eTimestampError, "X509_STORE_up_ref"); + } + +#ifdef HAVE_TS_VERIFY_CTX_SET0_CERTS + TS_VERIFY_CTX_set0_certs(ctx, x509inter); + TS_VERIFY_CTX_set0_store(ctx, x509st); +#else +# if OSSL_OPENSSL_PREREQ(3, 0, 0) || OSSL_IS_LIBRESSL + TS_VERIFY_CTX_set_certs(ctx, x509inter); +# else + TS_VERIFY_CTS_set_certs(ctx, x509inter); +# endif + TS_VERIFY_CTX_set_store(ctx, x509st); +#endif + TS_VERIFY_CTX_add_flags(ctx, TS_VFY_SIGNATURE); + + ok = TS_RESP_verify_response(ctx, resp); + TS_VERIFY_CTX_free(ctx); + + if (!ok) + ossl_raise(eTimestampError, "TS_RESP_verify_response"); + + return self; +} + +static VALUE +ossl_ts_token_info_alloc(VALUE klass) +{ + TS_TST_INFO *info; + VALUE obj; + + obj = NewTSTokenInfo(klass); + if (!(info = TS_TST_INFO_new())) + ossl_raise(eTimestampError, NULL); + SetTSTokenInfo(obj, info); + + return obj; +} + +/* + * Creates a TokenInfo from a +File+ or +string+ parameter, the + * corresponding +File+ or +string+ must be DER-encoded. Please note + * that TokenInfo is an immutable read-only class. If you'd like to create + * timestamps please refer to Factory instead. + * + * call-seq: + * OpenSSL::Timestamp::TokenInfo.new(file) -> token-info + * OpenSSL::Timestamp::TokenInfo.new(string) -> token-info + */ +static VALUE +ossl_ts_token_info_initialize(VALUE self, VALUE der) +{ + TS_TST_INFO *info = DATA_PTR(self); + BIO *in; + + der = ossl_to_der_if_possible(der); + in = ossl_obj2bio(&der); + info = d2i_TS_TST_INFO_bio(in, &info); + BIO_free(in); + if (!info) { + DATA_PTR(self) = NULL; + ossl_raise(eTimestampError, "Error when decoding the timestamp token info"); + } + DATA_PTR(self) = info; + + return self; +} + +/* + * Returns the version number of the token info. With compliant servers, + * this value should be +1+ if present. If status is GRANTED or + * GRANTED_WITH_MODS. + * + * call-seq: + * token_info.version -> Integer or nil + */ +static VALUE +ossl_ts_token_info_get_version(VALUE self) +{ + TS_TST_INFO *info; + + GetTSTokenInfo(self, info); + return LONG2NUM(TS_TST_INFO_get_version(info)); +} + +/* + * Returns the timestamp policy object identifier of the policy this timestamp + * was created under. If status is GRANTED or GRANTED_WITH_MODS, this is never + * +nil+. + * + * ===Example: + * id = token_info.policy_id + * puts id -> "1.2.3.4.5" + * + * call-seq: + * token_info.policy_id -> string or nil + */ +static VALUE +ossl_ts_token_info_get_policy_id(VALUE self) +{ + TS_TST_INFO *info; + + GetTSTokenInfo(self, info); + return ossl_asn1obj_to_string(TS_TST_INFO_get_policy_id(info)); +} + +/* + * Returns the 'short name' of the object identifier representing the algorithm + * that was used to derive the message imprint digest. For valid timestamps, + * this is the same value that was already given in the Request. If status is + * GRANTED or GRANTED_WITH_MODS, this is never +nil+. + * + * ===Example: + * algo = token_info.algorithm + * puts algo -> "SHA1" + * + * call-seq: + * token_info.algorithm -> string or nil + */ +static VALUE +ossl_ts_token_info_get_algorithm(VALUE self) +{ + TS_TST_INFO *info; + TS_MSG_IMPRINT *mi; + X509_ALGOR *algo; + const ASN1_OBJECT *obj; + + GetTSTokenInfo(self, info); + mi = TS_TST_INFO_get_msg_imprint(info); + algo = TS_MSG_IMPRINT_get_algo(mi); + X509_ALGOR_get0(&obj, NULL, NULL, algo); + return ossl_asn1obj_to_string(obj); +} + +/* + * Returns the message imprint digest. For valid timestamps, + * this is the same value that was already given in the Request. + * If status is GRANTED or GRANTED_WITH_MODS, this is never +nil+. + * + * ===Example: + * mi = token_info.msg_imprint + * puts mi -> "DEADBEEF" + * + * call-seq: + * token_info.msg_imprint -> string. + */ +static VALUE +ossl_ts_token_info_get_msg_imprint(VALUE self) +{ + TS_TST_INFO *info; + TS_MSG_IMPRINT *mi; + ASN1_OCTET_STRING *hashed_msg; + VALUE ret; + + GetTSTokenInfo(self, info); + mi = TS_TST_INFO_get_msg_imprint(info); + hashed_msg = TS_MSG_IMPRINT_get_msg(mi); + ret = asn1str_to_str(hashed_msg); + + return ret; +} + +/* + * Returns serial number of the timestamp token. This value shall never be the + * same for two timestamp tokens issued by a dedicated timestamp authority. + * If status is GRANTED or GRANTED_WITH_MODS, this is never +nil+. + * + * call-seq: + * token_info.serial_number -> BN or nil + */ +static VALUE +ossl_ts_token_info_get_serial_number(VALUE self) +{ + TS_TST_INFO *info; + + GetTSTokenInfo(self, info); + return asn1integer_to_num(TS_TST_INFO_get_serial(info)); +} + +/* + * Returns time when this timestamp token was created. If status is GRANTED or + * GRANTED_WITH_MODS, this is never +nil+. + * + * call-seq: + * token_info.gen_time -> Time + */ +static VALUE +ossl_ts_token_info_get_gen_time(VALUE self) +{ + TS_TST_INFO *info; + + GetTSTokenInfo(self, info); + return asn1time_to_time(TS_TST_INFO_get_time(info)); +} + +/* + * If the ordering field is missing, or if the ordering field is present + * and set to false, then the genTime field only indicates the time at + * which the time-stamp token has been created by the TSA. In such a + * case, the ordering of time-stamp tokens issued by the same TSA or + * different TSAs is only possible when the difference between the + * genTime of the first time-stamp token and the genTime of the second + * time-stamp token is greater than the sum of the accuracies of the + * genTime for each time-stamp token. + * + * If the ordering field is present and set to true, every time-stamp + * token from the same TSA can always be ordered based on the genTime + * field, regardless of the genTime accuracy. + * + * call-seq: + * token_info.ordering -> true, falses or nil + */ +static VALUE +ossl_ts_token_info_get_ordering(VALUE self) +{ + TS_TST_INFO *info; + + GetTSTokenInfo(self, info); + return TS_TST_INFO_get_ordering(info) ? Qtrue : Qfalse; +} + +/* + * If the timestamp token is valid then this field contains the same nonce that + * was passed to the timestamp server in the initial Request. + * + * call-seq: + * token_info.nonce -> BN or nil + */ +static VALUE +ossl_ts_token_info_get_nonce(VALUE self) +{ + TS_TST_INFO *info; + const ASN1_INTEGER *nonce; + + GetTSTokenInfo(self, info); + if (!(nonce = TS_TST_INFO_get_nonce(info))) + return Qnil; + + return asn1integer_to_num(nonce); +} + +/* + * Returns the TokenInfo in DER-encoded form. + * + * call-seq: + * token_info.to_der -> string + */ +static VALUE +ossl_ts_token_info_to_der(VALUE self) +{ + TS_TST_INFO *info; + + GetTSTokenInfo(self, info); + return asn1_to_der((void *)info, (int (*)(void *, unsigned char **))i2d_TS_TST_INFO); +} + +static VALUE +ossl_ts_token_info_to_text(VALUE self) +{ + TS_TST_INFO *info; + BIO *out; + + GetTSTokenInfo(self, info); + + out = BIO_new(BIO_s_mem()); + if (!out) ossl_raise(eTimestampError, NULL); + + if (!TS_TST_INFO_print_bio(out, info)) { + BIO_free(out); + ossl_raise(eTimestampError, NULL); + } + + return ossl_membio2str(out); +} + +static ASN1_INTEGER * +ossl_tsfac_serial_cb(struct TS_resp_ctx *ctx, void *data) +{ + ASN1_INTEGER **snptr = (ASN1_INTEGER **)data; + ASN1_INTEGER *sn = *snptr; + *snptr = NULL; + return sn; +} + +static int +#if !defined(LIBRESSL_VERSION_NUMBER) +ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, long *sec, long *usec) +#else +ossl_tsfac_time_cb(struct TS_resp_ctx *ctx, void *data, time_t *sec, long *usec) +#endif +{ + *sec = *((long *)data); + *usec = 0; + return 1; +} + +static VALUE +ossl_evp_md_fetch_i(VALUE args_) +{ + VALUE *args = (VALUE *)args_, md_holder; + const EVP_MD *md; + + md = ossl_evp_md_fetch(args[1], &md_holder); + rb_ary_push(args[0], md_holder); + return (VALUE)md; +} + +static VALUE +ossl_obj2bio_i(VALUE arg) +{ + return (VALUE)ossl_obj2bio((VALUE *)arg); +} + +/* + * Creates a Response with the help of an OpenSSL::PKey, an + * OpenSSL::X509::Certificate and a Request. + * + * Mandatory parameters for timestamp creation that need to be set in the + * Request: + * + * * Request#algorithm + * * Request#message_imprint + * + * Mandatory parameters that need to be set in the Factory: + * * Factory#serial_number + * * Factory#gen_time + * * Factory#allowed_digests + * + * In addition one of either Request#policy_id or Factory#default_policy_id + * must be set. + * + * Raises a TimestampError if creation fails, though successfully created error + * responses may be returned. + * + * call-seq: + * factory.create_timestamp(key, certificate, request) -> Response + */ +static VALUE +ossl_tsfac_create_ts(VALUE self, VALUE key, VALUE certificate, VALUE request) +{ + VALUE serial_number, def_policy_id, gen_time, additional_certs, + allowed_digests, allowed_digests_tmp = Qnil; + VALUE str; + STACK_OF(X509) *inter_certs; + VALUE tsresp, ret = Qnil; + EVP_PKEY *sign_key; + X509 *tsa_cert; + TS_REQ *req; + TS_RESP *response = NULL; + TS_RESP_CTX *ctx = NULL; + BIO *req_bio; + ASN1_INTEGER *asn1_serial = NULL; + ASN1_OBJECT *def_policy_id_obj = NULL; + long lgen_time; + const char * err_msg = NULL; + int status = 0; + + tsresp = NewTSResponse(cTimestampResponse); + tsa_cert = GetX509CertPtr(certificate); + sign_key = GetPrivPKeyPtr(key); + GetTSRequest(request, req); + + gen_time = ossl_tsfac_get_gen_time(self); + if (!rb_obj_is_instance_of(gen_time, rb_cTime)) { + err_msg = "@gen_time must be a Time."; + goto end; + } + lgen_time = NUM2LONG(rb_funcall(gen_time, rb_intern("to_i"), 0)); + + serial_number = ossl_tsfac_get_serial_number(self); + if (NIL_P(serial_number)) { + err_msg = "@serial_number must be set."; + goto end; + } + asn1_serial = num_to_asn1integer(serial_number, NULL); + + def_policy_id = ossl_tsfac_get_default_policy_id(self); + if (NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req)) { + err_msg = "No policy id in the request and no default policy set"; + goto end; + } + if (!NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req)) { + def_policy_id_obj = (ASN1_OBJECT*)rb_protect(obj_to_asn1obj_i, (VALUE)def_policy_id, &status); + if (status) + goto end; + } + + if (!(ctx = TS_RESP_CTX_new())) { + err_msg = "Memory allocation failed."; + goto end; + } + + TS_RESP_CTX_set_serial_cb(ctx, ossl_tsfac_serial_cb, &asn1_serial); + if (!TS_RESP_CTX_set_signer_cert(ctx, tsa_cert)) { + err_msg = "Certificate does not contain the timestamping extension"; + goto end; + } + + additional_certs = ossl_tsfac_get_additional_certs(self); + if (rb_obj_is_kind_of(additional_certs, rb_cArray)) { + inter_certs = ossl_protect_x509_ary2sk(additional_certs, &status); + if (status) + goto end; + + /* this dups the sk_X509 and ups each cert's ref count */ + TS_RESP_CTX_set_certs(ctx, inter_certs); + sk_X509_pop_free(inter_certs, X509_free); + } + + TS_RESP_CTX_set_signer_key(ctx, sign_key); + if (!NIL_P(def_policy_id) && !TS_REQ_get_policy_id(req)) + TS_RESP_CTX_set_def_policy(ctx, def_policy_id_obj); + if (TS_REQ_get_policy_id(req)) + TS_RESP_CTX_set_def_policy(ctx, TS_REQ_get_policy_id(req)); + TS_RESP_CTX_set_time_cb(ctx, ossl_tsfac_time_cb, &lgen_time); + + allowed_digests = ossl_tsfac_get_allowed_digests(self); + if (rb_obj_is_kind_of(allowed_digests, rb_cArray)) { + allowed_digests_tmp = rb_ary_new_capa(RARRAY_LEN(allowed_digests)); + for (long i = 0; i < RARRAY_LEN(allowed_digests); i++) { + VALUE args[] = { + allowed_digests_tmp, + rb_ary_entry(allowed_digests, i), + }; + const EVP_MD *md = (const EVP_MD *)rb_protect(ossl_evp_md_fetch_i, + (VALUE)args, &status); + if (status) + goto end; + if (!TS_RESP_CTX_add_md(ctx, md)) + goto end; + } + } + + str = rb_protect(ossl_to_der, request, &status); + if (status) + goto end; + + req_bio = (BIO*)rb_protect(ossl_obj2bio_i, (VALUE)&str, &status); + if (status) + goto end; + + response = TS_RESP_create_response(ctx, req_bio); + BIO_free(req_bio); + RB_GC_GUARD(allowed_digests_tmp); + + if (!response) { + err_msg = "Error during response generation"; + goto end; + } + + /* bad responses aren't exceptional, but openssl still sets error + * information. */ + ossl_clear_error(); + + SetTSResponse(tsresp, response); + ret = tsresp; + + end: + ASN1_INTEGER_free(asn1_serial); + ASN1_OBJECT_free(def_policy_id_obj); + TS_RESP_CTX_free(ctx); + if (err_msg) + rb_exc_raise(ossl_make_error(eTimestampError, rb_str_new_cstr(err_msg))); + if (status) + rb_jump_tag(status); + return ret; +} + +/* + * INIT + */ +void +Init_ossl_ts(void) +{ + /* + * Possible return value for +Response#failure_info+. Indicates that the + * timestamp server rejects the message imprint algorithm used in the + * +Request+ + */ + sBAD_ALG = ID2SYM(rb_intern_const("BAD_ALG")); + + /* + * Possible return value for +Response#failure_info+. Indicates that the + * timestamp server was not able to process the +Request+ properly. + */ + sBAD_REQUEST = ID2SYM(rb_intern_const("BAD_REQUEST")); + /* + * Possible return value for +Response#failure_info+. Indicates that the + * timestamp server was not able to parse certain data in the +Request+. + */ + sBAD_DATA_FORMAT = ID2SYM(rb_intern_const("BAD_DATA_FORMAT")); + + sTIME_NOT_AVAILABLE = ID2SYM(rb_intern_const("TIME_NOT_AVAILABLE")); + sUNACCEPTED_POLICY = ID2SYM(rb_intern_const("UNACCEPTED_POLICY")); + sUNACCEPTED_EXTENSION = ID2SYM(rb_intern_const("UNACCEPTED_EXTENSION")); + sADD_INFO_NOT_AVAILABLE = ID2SYM(rb_intern_const("ADD_INFO_NOT_AVAILABLE")); + sSYSTEM_FAILURE = ID2SYM(rb_intern_const("SYSTEM_FAILURE")); + + /* Document-class: OpenSSL::Timestamp + * Provides classes and methods to request, create and validate + * {RFC3161-compliant}[http://www.ietf.org/rfc/rfc3161.txt] timestamps. + * Request may be used to either create requests from scratch or to parse + * existing requests that again can be used to request timestamps from a + * timestamp server, e.g. via the net/http. The resulting timestamp + * response may be parsed using Response. + * + * Please note that Response is read-only and immutable. To create a + * Response, an instance of Factory as well as a valid Request are needed. + * + * ===Create a Response: + * #Assumes ts.p12 is a PKCS#12-compatible file with a private key + * #and a certificate that has an extended key usage of 'timeStamping' + * p12 = OpenSSL::PKCS12.new(File.binread('ts.p12'), 'pwd') + * md = OpenSSL::Digest.new('SHA1') + * hash = md.digest(data) #some binary data to be timestamped + * req = OpenSSL::Timestamp::Request.new + * req.algorithm = 'SHA1' + * req.message_imprint = hash + * req.policy_id = "1.2.3.4.5" + * req.nonce = 42 + * fac = OpenSSL::Timestamp::Factory.new + * fac.gen_time = Time.now + * fac.serial_number = 1 + * timestamp = fac.create_timestamp(p12.key, p12.certificate, req) + * + * ===Verify a timestamp response: + * #Assume we have a timestamp token in a file called ts.der + * ts = OpenSSL::Timestamp::Response.new(File.binread('ts.der')) + * #Assume we have the Request for this token in a file called req.der + * req = OpenSSL::Timestamp::Request.new(File.binread('req.der')) + * # Assume the associated root CA certificate is contained in a + * # DER-encoded file named root.cer + * root = OpenSSL::X509::Certificate.new(File.binread('root.cer')) + * # get the necessary intermediate certificates, available in + * # DER-encoded form in inter1.cer and inter2.cer + * inter1 = OpenSSL::X509::Certificate.new(File.binread('inter1.cer')) + * inter2 = OpenSSL::X509::Certificate.new(File.binread('inter2.cer')) + * ts.verify(req, root, inter1, inter2) -> ts or raises an exception if validation fails + * + */ + mTimestamp = rb_define_module_under(mOSSL, "Timestamp"); + + /* Document-class: OpenSSL::Timestamp::TimestampError + * Generic exception class of the Timestamp module. + */ + eTimestampError = rb_define_class_under(mTimestamp, "TimestampError", eOSSLError); + + /* Document-class: OpenSSL::Timestamp::Response + * Immutable and read-only representation of a timestamp response returned + * from a timestamp server after receiving an associated Request. Allows + * access to specific information about the response but also allows to + * verify the Response. + */ + cTimestampResponse = rb_define_class_under(mTimestamp, "Response", rb_cObject); + rb_define_alloc_func(cTimestampResponse, ossl_ts_resp_alloc); + rb_define_method(cTimestampResponse, "initialize", ossl_ts_resp_initialize, 1); + rb_define_method(cTimestampResponse, "status", ossl_ts_resp_get_status, 0); + rb_define_method(cTimestampResponse, "failure_info", ossl_ts_resp_get_failure_info, 0); + rb_define_method(cTimestampResponse, "status_text", ossl_ts_resp_get_status_text, 0); + rb_define_method(cTimestampResponse, "token", ossl_ts_resp_get_token, 0); + rb_define_method(cTimestampResponse, "token_info", ossl_ts_resp_get_token_info, 0); + rb_define_method(cTimestampResponse, "tsa_certificate", ossl_ts_resp_get_tsa_certificate, 0); + rb_define_method(cTimestampResponse, "to_der", ossl_ts_resp_to_der, 0); + rb_define_method(cTimestampResponse, "to_text", ossl_ts_resp_to_text, 0); + rb_define_method(cTimestampResponse, "verify", ossl_ts_resp_verify, -1); + + /* Document-class: OpenSSL::Timestamp::TokenInfo + * Immutable and read-only representation of a timestamp token info from a + * Response. + */ + cTimestampTokenInfo = rb_define_class_under(mTimestamp, "TokenInfo", rb_cObject); + rb_define_alloc_func(cTimestampTokenInfo, ossl_ts_token_info_alloc); + rb_define_method(cTimestampTokenInfo, "initialize", ossl_ts_token_info_initialize, 1); + rb_define_method(cTimestampTokenInfo, "version", ossl_ts_token_info_get_version, 0); + rb_define_method(cTimestampTokenInfo, "policy_id", ossl_ts_token_info_get_policy_id, 0); + rb_define_method(cTimestampTokenInfo, "algorithm", ossl_ts_token_info_get_algorithm, 0); + rb_define_method(cTimestampTokenInfo, "message_imprint", ossl_ts_token_info_get_msg_imprint, 0); + rb_define_method(cTimestampTokenInfo, "serial_number", ossl_ts_token_info_get_serial_number, 0); + rb_define_method(cTimestampTokenInfo, "gen_time", ossl_ts_token_info_get_gen_time, 0); + rb_define_method(cTimestampTokenInfo, "ordering", ossl_ts_token_info_get_ordering, 0); + rb_define_method(cTimestampTokenInfo, "nonce", ossl_ts_token_info_get_nonce, 0); + rb_define_method(cTimestampTokenInfo, "to_der", ossl_ts_token_info_to_der, 0); + rb_define_method(cTimestampTokenInfo, "to_text", ossl_ts_token_info_to_text, 0); + + /* Document-class: OpenSSL::Timestamp::Request + * Allows to create timestamp requests or parse existing ones. A Request is + * also needed for creating timestamps from scratch with Factory. When + * created from scratch, some default values are set: + * * version is set to +1+ + * * cert_requested is set to +true+ + * * algorithm, message_imprint, policy_id, and nonce are set to +false+ + */ + cTimestampRequest = rb_define_class_under(mTimestamp, "Request", rb_cObject); + rb_define_alloc_func(cTimestampRequest, ossl_ts_req_alloc); + rb_define_method(cTimestampRequest, "initialize", ossl_ts_req_initialize, -1); + rb_define_method(cTimestampRequest, "version=", ossl_ts_req_set_version, 1); + rb_define_method(cTimestampRequest, "version", ossl_ts_req_get_version, 0); + rb_define_method(cTimestampRequest, "algorithm=", ossl_ts_req_set_algorithm, 1); + rb_define_method(cTimestampRequest, "algorithm", ossl_ts_req_get_algorithm, 0); + rb_define_method(cTimestampRequest, "message_imprint=", ossl_ts_req_set_msg_imprint, 1); + rb_define_method(cTimestampRequest, "message_imprint", ossl_ts_req_get_msg_imprint, 0); + rb_define_method(cTimestampRequest, "policy_id=", ossl_ts_req_set_policy_id, 1); + rb_define_method(cTimestampRequest, "policy_id", ossl_ts_req_get_policy_id, 0); + rb_define_method(cTimestampRequest, "nonce=", ossl_ts_req_set_nonce, 1); + rb_define_method(cTimestampRequest, "nonce", ossl_ts_req_get_nonce, 0); + rb_define_method(cTimestampRequest, "cert_requested=", ossl_ts_req_set_cert_requested, 1); + rb_define_method(cTimestampRequest, "cert_requested?", ossl_ts_req_get_cert_requested, 0); + rb_define_method(cTimestampRequest, "to_der", ossl_ts_req_to_der, 0); + rb_define_method(cTimestampRequest, "to_text", ossl_ts_req_to_text, 0); + + /* + * Indicates a successful response. Equal to +0+. + */ + rb_define_const(cTimestampResponse, "GRANTED", INT2NUM(TS_STATUS_GRANTED)); + /* + * Indicates a successful response that probably contains modifications + * from the initial request. Equal to +1+. + */ + rb_define_const(cTimestampResponse, "GRANTED_WITH_MODS", INT2NUM(TS_STATUS_GRANTED_WITH_MODS)); + /* + * Indicates a failure. No timestamp token was created. Equal to +2+. + */ + rb_define_const(cTimestampResponse, "REJECTION", INT2NUM(TS_STATUS_REJECTION)); + /* + * Indicates a failure. No timestamp token was created. Equal to +3+. + */ + rb_define_const(cTimestampResponse, "WAITING", INT2NUM(TS_STATUS_WAITING)); + /* + * Indicates a failure. No timestamp token was created. Revocation of a + * certificate is imminent. Equal to +4+. + */ + rb_define_const(cTimestampResponse, "REVOCATION_WARNING", INT2NUM(TS_STATUS_REVOCATION_WARNING)); + /* + * Indicates a failure. No timestamp token was created. A certificate + * has been revoked. Equal to +5+. + */ + rb_define_const(cTimestampResponse, "REVOCATION_NOTIFICATION", INT2NUM(TS_STATUS_REVOCATION_NOTIFICATION)); + + /* Document-class: OpenSSL::Timestamp::Factory + * + * Used to generate a Response from scratch. + * + * Please bear in mind that the implementation will always apply and prefer + * the policy object identifier given in the request over the default policy + * id specified in the Factory. As a consequence, +default_policy_id+ will + * only be applied if no Request#policy_id was given. But this also means + * that one needs to check the policy identifier in the request manually + * before creating the Response, e.g. to check whether it complies to a + * specific set of acceptable policies. + * + * There exists also the possibility to add certificates (instances of + * OpenSSL::X509::Certificate) besides the timestamping certificate + * that will be included in the resulting timestamp token if + * Request#cert_requested? is +true+. Ideally, one would also include any + * intermediate certificates (the root certificate can be left out - in + * order to trust it any verifying party will have to be in its possession + * anyway). This simplifies validation of the timestamp since these + * intermediate certificates are "already there" and need not be passed as + * external parameters to Response#verify anymore, thus minimizing external + * resources needed for verification. + * + * ===Example: Inclusion of (untrusted) intermediate certificates + * + * Assume we received a timestamp request that has set Request#policy_id to + * +nil+ and Request#cert_requested? to true. The raw request bytes are + * stored in a variable called +req_raw+. We'd still like to integrate + * the necessary intermediate certificates (in +inter1.cer+ and + * +inter2.cer+) to simplify validation of the resulting Response. +ts.p12+ + * is a PKCS#12-compatible file including the private key and the + * timestamping certificate. + * + * req = OpenSSL::Timestamp::Request.new(raw_bytes) + * p12 = OpenSSL::PKCS12.new(File.binread('ts.p12'), 'pwd') + * inter1 = OpenSSL::X509::Certificate.new(File.binread('inter1.cer')) + * inter2 = OpenSSL::X509::Certificate.new(File.binread('inter2.cer')) + * fac = OpenSSL::Timestamp::Factory.new + * fac.gen_time = Time.now + * fac.serial_number = 1 + * fac.allowed_digests = ["sha256", "sha384", "sha512"] + * #needed because the Request contained no policy identifier + * fac.default_policy_id = '1.2.3.4.5' + * fac.additional_certificates = [ inter1, inter2 ] + * timestamp = fac.create_timestamp(p12.key, p12.certificate, req) + */ + cTimestampFactory = rb_define_class_under(mTimestamp, "Factory", rb_cObject); + /* + * The list of digest algorithms that the factory is allowed + * create timestamps for. Known vulnerable or weak algorithms should not be + * allowed where possible. Must be an Array of String or OpenSSL::Digest + * subclass instances. + */ + rb_attr(cTimestampFactory, rb_intern_const("allowed_digests"), 1, 1, 0); + /* + * A String representing the default policy object identifier, or +nil+. + * + * Request#policy_id will always be preferred over this if present in the + * Request, only if Request#policy_id is +nil+ default_policy will be used. + * If none of both is present, a TimestampError will be raised when trying + * to create a Response. + */ + rb_attr(cTimestampFactory, rb_intern_const("default_policy_id"), 1, 1, 0); + /* + * The serial number to be used for timestamp creation. Must be present for + * timestamp creation. Must be an instance of OpenSSL::BN or Integer. + */ + rb_attr(cTimestampFactory, rb_intern_const("serial_number"), 1, 1, 0); + /* + * The Time value to be used in the Response. Must be present for timestamp + * creation. + */ + rb_attr(cTimestampFactory, rb_intern_const("gen_time"), 1, 1, 0); + /* + * Additional certificates apart from the timestamp certificate (e.g. + * intermediate certificates) to be added to the Response. + * Must be an Array of OpenSSL::X509::Certificate, or +nil+. + */ + rb_attr(cTimestampFactory, rb_intern_const("additional_certs"), 1, 1, 0); + rb_define_method(cTimestampFactory, "create_timestamp", ossl_tsfac_create_ts, 3); +} +#else /* OPENSSL_NO_TS */ +void +Init_ossl_ts(void) +{ +} +#endif diff --git a/ext/openssl/ossl_ts.h b/ext/openssl/ossl_ts.h new file mode 100644 index 0000000000..eeca3046eb --- /dev/null +++ b/ext/openssl/ossl_ts.h @@ -0,0 +1,16 @@ +/* + * + * Copyright (C) 2010 Martin Bosslet <Martin.Bosslet@googlemail.com> + * All rights reserved. + */ +/* + * This program is licenced under the same licence as Ruby. + * (See the file 'COPYING'.) + */ + +#if !defined(_OSSL_TS_H_) +#define _OSSL_TS_H_ + +void Init_ossl_ts(void); + +#endif diff --git a/ext/openssl/ossl_version.h b/ext/openssl/ossl_version.h deleted file mode 100644 index c162f8c2a8..0000000000 --- a/ext/openssl/ossl_version.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_VERSION_H_) -#define _OSSL_VERSION_H_ - -#define OSSL_VERSION "2.1.2" - -#endif /* _OSSL_VERSION_H_ */ diff --git a/ext/openssl/ossl_x509.c b/ext/openssl/ossl_x509.c index 8a061b0687..bc3914fda2 100644 --- a/ext/openssl/ossl_x509.c +++ b/ext/openssl/ossl_x509.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,7 +13,8 @@ VALUE mX509; #define DefX509Const(x) rb_define_const(mX509, #x, INT2NUM(X509_##x)) #define DefX509Default(x,i) \ - rb_define_const(mX509, "DEFAULT_" #x, rb_str_new2(X509_get_default_##i())) + rb_define_const(mX509, "DEFAULT_" #x, \ + rb_obj_freeze(rb_str_new_cstr(X509_get_default_##i()))) ASN1_TIME * ossl_x509_time_adjust(ASN1_TIME *s, VALUE time) @@ -29,10 +30,6 @@ ossl_x509_time_adjust(ASN1_TIME *s, VALUE time) void Init_ossl_x509(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); -#endif - mX509 = rb_define_module_under(mOSSL, "X509"); Init_ossl_x509attr(); @@ -44,7 +41,11 @@ Init_ossl_x509(void) Init_ossl_x509revoked(); Init_ossl_x509store(); + /* Constants are up-to-date with 1.1.1. */ + + /* Certificate verification error code */ DefX509Const(V_OK); + DefX509Const(V_ERR_UNSPECIFIED); DefX509Const(V_ERR_UNABLE_TO_GET_ISSUER_CERT); DefX509Const(V_ERR_UNABLE_TO_GET_CRL); DefX509Const(V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE); @@ -76,8 +77,65 @@ Init_ossl_x509(void) DefX509Const(V_ERR_AKID_SKID_MISMATCH); DefX509Const(V_ERR_AKID_ISSUER_SERIAL_MISMATCH); DefX509Const(V_ERR_KEYUSAGE_NO_CERTSIGN); + DefX509Const(V_ERR_UNABLE_TO_GET_CRL_ISSUER); + DefX509Const(V_ERR_UNHANDLED_CRITICAL_EXTENSION); + DefX509Const(V_ERR_KEYUSAGE_NO_CRL_SIGN); + DefX509Const(V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION); + DefX509Const(V_ERR_INVALID_NON_CA); + DefX509Const(V_ERR_PROXY_PATH_LENGTH_EXCEEDED); + DefX509Const(V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE); + DefX509Const(V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED); + DefX509Const(V_ERR_INVALID_EXTENSION); + DefX509Const(V_ERR_INVALID_POLICY_EXTENSION); + DefX509Const(V_ERR_NO_EXPLICIT_POLICY); + DefX509Const(V_ERR_DIFFERENT_CRL_SCOPE); + DefX509Const(V_ERR_UNSUPPORTED_EXTENSION_FEATURE); + DefX509Const(V_ERR_UNNESTED_RESOURCE); + DefX509Const(V_ERR_PERMITTED_VIOLATION); + DefX509Const(V_ERR_EXCLUDED_VIOLATION); + DefX509Const(V_ERR_SUBTREE_MINMAX); DefX509Const(V_ERR_APPLICATION_VERIFICATION); + DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_TYPE); + DefX509Const(V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX); + DefX509Const(V_ERR_UNSUPPORTED_NAME_SYNTAX); + DefX509Const(V_ERR_CRL_PATH_VALIDATION_ERROR); +#if defined(X509_V_ERR_PATH_LOOP) /* OpenSSL 1.1.0, missing in LibreSSL */ + DefX509Const(V_ERR_PATH_LOOP); +#endif +#if defined(X509_V_ERR_SUITE_B_INVALID_VERSION) /* OpenSSL 1.1.0, missing in LibreSSL */ + DefX509Const(V_ERR_SUITE_B_INVALID_VERSION); + DefX509Const(V_ERR_SUITE_B_INVALID_ALGORITHM); + DefX509Const(V_ERR_SUITE_B_INVALID_CURVE); + DefX509Const(V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM); + DefX509Const(V_ERR_SUITE_B_LOS_NOT_ALLOWED); + DefX509Const(V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256); +#endif + DefX509Const(V_ERR_HOSTNAME_MISMATCH); + DefX509Const(V_ERR_EMAIL_MISMATCH); + DefX509Const(V_ERR_IP_ADDRESS_MISMATCH); +#if defined(X509_V_ERR_DANE_NO_MATCH) /* OpenSSL 1.1.0, missing in LibreSSL */ + DefX509Const(V_ERR_DANE_NO_MATCH); +#endif + DefX509Const(V_ERR_EE_KEY_TOO_SMALL); + DefX509Const(V_ERR_CA_KEY_TOO_SMALL); + DefX509Const(V_ERR_CA_MD_TOO_WEAK); + DefX509Const(V_ERR_INVALID_CALL); + DefX509Const(V_ERR_STORE_LOOKUP); +#if defined(X509_V_ERR_NO_VALID_SCTS) /* OpenSSL 1.1.0, missing in LibreSSL */ + DefX509Const(V_ERR_NO_VALID_SCTS); +#endif +#if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION) /* OpenSSL 1.1.0, missing in LibreSSL */ + DefX509Const(V_ERR_PROXY_SUBJECT_NAME_VIOLATION); +#endif +#if defined(X509_V_ERR_OCSP_VERIFY_NEEDED) /* OpenSSL 1.1.1, missing in LibreSSL */ + DefX509Const(V_ERR_OCSP_VERIFY_NEEDED); + DefX509Const(V_ERR_OCSP_VERIFY_FAILED); + DefX509Const(V_ERR_OCSP_CERT_UNKNOWN); +#endif + /* Certificate verify flags */ + /* Set by Store#flags= and StoreContext#flags=. */ + DefX509Const(V_FLAG_USE_CHECK_TIME); /* Set by Store#flags= and StoreContext#flags=. Enables CRL checking for the * certificate chain leaf. */ DefX509Const(V_FLAG_CRL_CHECK); @@ -116,23 +174,31 @@ Init_ossl_x509(void) /* Set by Store#flags= and StoreContext#flags=. Enables checking of the * signature of the root self-signed CA. */ DefX509Const(V_FLAG_CHECK_SS_SIGNATURE); -#if defined(X509_V_FLAG_TRUSTED_FIRST) /* Set by Store#flags= and StoreContext#flags=. When constructing a * certificate chain, search the Store first for the issuer certificate. * Enabled by default in OpenSSL >= 1.1.0. */ DefX509Const(V_FLAG_TRUSTED_FIRST); +#if defined(X509_V_FLAG_SUITEB_128_LOS_ONLY) /* OpenSSL 1.1.0, missing in LibreSSL */ + /* Set by Store#flags= and StoreContext#flags=. + * Enables Suite B 128 bit only mode. */ + DefX509Const(V_FLAG_SUITEB_128_LOS_ONLY); + /* Set by Store#flags= and StoreContext#flags=. + * Enables Suite B 192 bit only mode. */ + DefX509Const(V_FLAG_SUITEB_192_LOS); + /* Set by Store#flags= and StoreContext#flags=. + * Enables Suite B 128 bit mode allowing 192 bit algorithms. */ + DefX509Const(V_FLAG_SUITEB_128_LOS); #endif -#if defined(X509_V_FLAG_NO_ALT_CHAINS) + /* Set by Store#flags= and StoreContext#flags=. + * Allows partial chains if at least one certificate is in trusted store. */ + DefX509Const(V_FLAG_PARTIAL_CHAIN); /* Set by Store#flags= and StoreContext#flags=. Suppresses searching for * a alternative chain. No effect in OpenSSL >= 1.1.0. */ DefX509Const(V_FLAG_NO_ALT_CHAINS); -#endif -#if defined(X509_V_FLAG_NO_CHECK_TIME) /* Set by Store#flags= and StoreContext#flags=. Suppresses checking the * validity period of certificates and CRLs. No effect when the current * time is explicitly set by Store#time= or StoreContext#time=. */ DefX509Const(V_FLAG_NO_CHECK_TIME); -#endif /* Set by Store#purpose=. SSL/TLS client. */ DefX509Const(PURPOSE_SSL_CLIENT); diff --git a/ext/openssl/ossl_x509.h b/ext/openssl/ossl_x509.h index 4fadfa6b82..d25167ee7b 100644 --- a/ext/openssl/ossl_x509.h +++ b/ext/openssl/ossl_x509.h @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #if !defined(_OSSL_X509_H_) #define _OSSL_X509_H_ @@ -28,7 +28,6 @@ void Init_ossl_x509(void); * X509Attr */ extern VALUE cX509Attr; -extern VALUE eX509AttrError; VALUE ossl_x509attr_new(X509_ATTRIBUTE *); X509_ATTRIBUTE *GetX509AttrPtr(VALUE); @@ -38,7 +37,6 @@ void Init_ossl_x509attr(void); * X509Cert */ extern VALUE cX509Cert; -extern VALUE eX509CertError; VALUE ossl_x509_new(X509 *); X509 *GetX509CertPtr(VALUE); @@ -48,9 +46,6 @@ void Init_ossl_x509cert(void); /* * X509CRL */ -extern VALUE cX509CRL; -extern VALUE eX509CRLError; - VALUE ossl_x509crl_new(X509_CRL *); X509_CRL *GetX509CRLPtr(VALUE); void Init_ossl_x509crl(void); @@ -59,8 +54,6 @@ void Init_ossl_x509crl(void); * X509Extension */ extern VALUE cX509Ext; -extern VALUE cX509ExtFactory; -extern VALUE eX509ExtError; VALUE ossl_x509ext_new(X509_EXTENSION *); X509_EXTENSION *GetX509ExtPtr(VALUE); @@ -69,9 +62,6 @@ void Init_ossl_x509ext(void); /* * X509Name */ -extern VALUE cX509Name; -extern VALUE eX509NameError; - VALUE ossl_x509name_new(X509_NAME *); X509_NAME *GetX509NamePtr(VALUE); void Init_ossl_x509name(void); @@ -79,9 +69,6 @@ void Init_ossl_x509name(void); /* * X509Request */ -extern VALUE cX509Req; -extern VALUE eX509ReqError; - X509_REQ *GetX509ReqPtr(VALUE); void Init_ossl_x509req(void); @@ -89,7 +76,6 @@ void Init_ossl_x509req(void); * X509Revoked */ extern VALUE cX509Rev; -extern VALUE eX509RevError; VALUE ossl_x509revoked_new(X509_REVOKED *); X509_REVOKED *DupX509RevokedPtr(VALUE); @@ -98,12 +84,7 @@ void Init_ossl_x509revoked(void); /* * X509Store and X509StoreContext */ -extern VALUE cX509Store; -extern VALUE cX509StoreContext; -extern VALUE eX509StoreError; - X509_STORE *GetX509StorePtr(VALUE); - void Init_ossl_x509store(void); /* diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index 60846cfe9d..4769e56e1e 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509attr_type, 0) #define SetX509Attr(obj, attr) do { \ if (!(attr)) { \ - ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (attr); \ } while (0) #define GetX509Attr(obj, attr) do { \ TypedData_Get_Struct((obj), X509_ATTRIBUTE, &ossl_x509attr_type, (attr)); \ if (!(attr)) { \ - ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "ATTR wasn't initialized!"); \ } \ } while (0) @@ -28,7 +28,7 @@ * Classes */ VALUE cX509Attr; -VALUE eX509AttrError; +static VALUE eX509AttrError; static void ossl_x509attr_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509attr_free(void *ptr) static const rb_data_type_t ossl_x509attr_type = { "OpenSSL/X509/ATTRIBUTE", { - 0, ossl_x509attr_free, + 0, ossl_x509attr_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -54,14 +54,9 @@ ossl_x509attr_new(X509_ATTRIBUTE *attr) VALUE obj; obj = NewX509Attr(cX509Attr); - if (!attr) { - new = X509_ATTRIBUTE_new(); - } else { - new = X509_ATTRIBUTE_dup(attr); - } - if (!new) { - ossl_raise(eX509AttrError, NULL); - } + new = X509_ATTRIBUTE_dup(attr); + if (!new) + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); SetX509Attr(obj, new); return obj; @@ -88,7 +83,7 @@ ossl_x509attr_alloc(VALUE klass) obj = NewX509Attr(klass); if (!(attr = X509_ATTRIBUTE_new())) - ossl_raise(eX509AttrError, NULL); + ossl_raise(eX509AttrError, NULL); SetX509Attr(obj, attr); return obj; @@ -107,15 +102,15 @@ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) GetX509Attr(self, attr); if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){ - oid = ossl_to_der_if_possible(oid); - StringValue(oid); - p = (unsigned char *)RSTRING_PTR(oid); - x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid)); - DATA_PTR(self) = attr; - if(!x){ - ossl_raise(eX509AttrError, NULL); - } - return self; + oid = ossl_to_der_if_possible(oid); + StringValue(oid); + p = (unsigned char *)RSTRING_PTR(oid); + x = d2i_X509_ATTRIBUTE(&attr, &p, RSTRING_LEN(oid)); + DATA_PTR(self) = attr; + if(!x){ + ossl_raise(eX509AttrError, NULL); + } + return self; } rb_funcall(self, rb_intern("oid="), 1, oid); rb_funcall(self, rb_intern("value="), 1, value); @@ -123,6 +118,7 @@ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509attr_initialize_copy(VALUE self, VALUE other) { @@ -134,7 +130,7 @@ ossl_x509attr_initialize_copy(VALUE self, VALUE other) attr_new = X509_ATTRIBUTE_dup(attr_other); if (!attr_new) - ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_dup"); SetX509Attr(self, attr_new); X509_ATTRIBUTE_free(attr); @@ -158,8 +154,8 @@ ossl_x509attr_set_oid(VALUE self, VALUE oid) obj = OBJ_txt2obj(s, 0); if(!obj) ossl_raise(eX509AttrError, NULL); if (!X509_ATTRIBUTE_set1_object(attr, obj)) { - ASN1_OBJECT_free(obj); - ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_object"); + ASN1_OBJECT_free(obj); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_object"); } ASN1_OBJECT_free(obj); @@ -168,29 +164,18 @@ ossl_x509attr_set_oid(VALUE self, VALUE oid) /* * call-seq: - * attr.oid => string + * attr.oid -> string + * + * Returns the OID of the attribute. Returns the short name or the dotted + * decimal notation. */ static VALUE ossl_x509attr_get_oid(VALUE self) { X509_ATTRIBUTE *attr; - ASN1_OBJECT *oid; - BIO *out; - VALUE ret; - int nid; GetX509Attr(self, attr); - oid = X509_ATTRIBUTE_get0_object(attr); - if ((nid = OBJ_obj2nid(oid)) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); - else{ - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509AttrError, NULL); - i2a_ASN1_OBJECT(out, oid); - ret = ossl_membio2str(out); - } - - return ret; + return ossl_asn1obj_to_string(X509_ATTRIBUTE_get0_object(attr)); } /* @@ -201,37 +186,36 @@ static VALUE ossl_x509attr_set_value(VALUE self, VALUE value) { X509_ATTRIBUTE *attr; - VALUE asn1_value; - int i, asn1_tag; + GetX509Attr(self, attr); OSSL_Check_Kind(value, cASN1Data); - asn1_tag = NUM2INT(rb_attr_get(value, rb_intern("@tag"))); - asn1_value = rb_attr_get(value, rb_intern("@value")); - if (asn1_tag != V_ASN1_SET) - ossl_raise(eASN1Error, "argument must be ASN1::Set"); - if (!RB_TYPE_P(asn1_value, T_ARRAY)) - ossl_raise(eASN1Error, "ASN1::Set has non-array value"); + VALUE der = ossl_to_der(value); + const unsigned char *p = (const unsigned char *)RSTRING_PTR(der); + STACK_OF(ASN1_TYPE) *sk = d2i_ASN1_SET_ANY(NULL, &p, RSTRING_LEN(der)); + if (!sk) + ossl_raise(eX509AttrError, "attribute value must be ASN1::Set"); - GetX509Attr(self, attr); if (X509_ATTRIBUTE_count(attr)) { /* populated, reset first */ - ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); - X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1); - if (!new_attr) - ossl_raise(eX509AttrError, NULL); - SetX509Attr(self, new_attr); - X509_ATTRIBUTE_free(attr); - attr = new_attr; + ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr); + X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, 0, NULL, -1); + if (!new_attr) { + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_create_by_OBJ"); + } + SetX509Attr(self, new_attr); + X509_ATTRIBUTE_free(attr); + attr = new_attr; } - for (i = 0; i < RARRAY_LEN(asn1_value); i++) { - ASN1_TYPE *a1type = ossl_asn1_get_asn1type(RARRAY_AREF(asn1_value, i)); - if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type), - a1type->value.ptr, -1)) { - ASN1_TYPE_free(a1type); - ossl_raise(eX509AttrError, NULL); - } - ASN1_TYPE_free(a1type); + for (int i = 0; i < sk_ASN1_TYPE_num(sk); i++) { + ASN1_TYPE *a1type = sk_ASN1_TYPE_value(sk, i); + if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type), + a1type->value.ptr, -1)) { + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + ossl_raise(eX509AttrError, "X509_ATTRIBUTE_set1_data"); + } } + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); return value; } @@ -252,21 +236,21 @@ ossl_x509attr_get_value(VALUE self) GetX509Attr(self, attr); /* there is no X509_ATTRIBUTE_get0_set() :( */ if (!(sk = sk_ASN1_TYPE_new_null())) - ossl_raise(eX509AttrError, "sk_new"); + ossl_raise(eX509AttrError, "sk_new"); count = X509_ATTRIBUTE_count(attr); for (i = 0; i < count; i++) - sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i)); + sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i)); if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) { - sk_ASN1_TYPE_free(sk); - ossl_raise(eX509AttrError, NULL); + sk_ASN1_TYPE_free(sk); + ossl_raise(eX509AttrError, NULL); } str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_ASN1_SET_ANY(sk, &p) <= 0) { - sk_ASN1_TYPE_free(sk); - ossl_raise(eX509AttrError, NULL); + sk_ASN1_TYPE_free(sk); + ossl_raise(eX509AttrError, NULL); } ossl_str_adjust(str, p); sk_ASN1_TYPE_free(sk); @@ -288,11 +272,11 @@ ossl_x509attr_to_der(VALUE self) GetX509Attr(self, attr); if((len = i2d_X509_ATTRIBUTE(attr, NULL)) <= 0) - ossl_raise(eX509AttrError, NULL); + ossl_raise(eX509AttrError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_X509_ATTRIBUTE(attr, &p) <= 0) - ossl_raise(eX509AttrError, NULL); + ossl_raise(eX509AttrError, NULL); ossl_str_adjust(str, p); return str; @@ -304,12 +288,6 @@ ossl_x509attr_to_der(VALUE self) void Init_ossl_x509attr(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509AttrError = rb_define_class_under(mX509, "AttributeError", eOSSLError); cX509Attr = rb_define_class_under(mX509, "Attribute", rb_cObject); diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 40542c4a78..95679c7d24 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509_type, 0) #define SetX509(obj, x509) do { \ if (!(x509)) { \ - ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (x509); \ } while (0) #define GetX509(obj, x509) do { \ TypedData_Get_Struct((obj), X509, &ossl_x509_type, (x509)); \ if (!(x509)) { \ - ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CERT wasn't initialized!"); \ } \ } while (0) @@ -28,7 +28,7 @@ * Classes */ VALUE cX509Cert; -VALUE eX509CertError; +static VALUE eX509CertError; static void ossl_x509_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509_free(void *ptr) static const rb_data_type_t ossl_x509_type = { "OpenSSL/X509", { - 0, ossl_x509_free, + 0, ossl_x509_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -54,14 +54,9 @@ ossl_x509_new(X509 *x509) VALUE obj; obj = NewX509(cX509Cert); - if (!x509) { - new = X509_new(); - } else { - new = X509_dup(x509); - } - if (!new) { - ossl_raise(eX509CertError, NULL); - } + new = X509_dup(x509); + if (!new) + ossl_raise(eX509CertError, "X509_dup"); SetX509(obj, new); return obj; @@ -115,28 +110,32 @@ static VALUE ossl_x509_initialize(int argc, VALUE *argv, VALUE self) { BIO *in; - X509 *x509, *x = DATA_PTR(self); + X509 *x509, *x509_orig = RTYPEDDATA_DATA(self); VALUE arg; + rb_check_frozen(self); if (rb_scan_args(argc, argv, "01", &arg) == 0) { - /* create just empty X509Cert */ - return self; + /* create just empty X509Cert */ + return self; } arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); - x509 = PEM_read_bio_X509(in, &x, NULL, NULL); - DATA_PTR(self) = x; + x509 = d2i_X509_bio(in, NULL); if (!x509) { - OSSL_BIO_reset(in); - x509 = d2i_X509_bio(in, &x); - DATA_PTR(self) = x; + OSSL_BIO_reset(in); + x509 = PEM_read_bio_X509(in, NULL, NULL, NULL); } BIO_free(in); - if (!x509) ossl_raise(eX509CertError, NULL); + if (!x509) + ossl_raise(eX509CertError, "PEM_read_bio_X509"); + + RTYPEDDATA_DATA(self) = x509; + X509_free(x509_orig); return self; } +/* :nodoc: */ static VALUE ossl_x509_copy(VALUE self, VALUE other) { @@ -171,11 +170,11 @@ ossl_x509_to_der(VALUE self) GetX509(self, x509); if ((len = i2d_X509(x509, NULL)) <= 0) - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_X509(x509, &p) <= 0) - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); ossl_str_adjust(str, p); return str; @@ -197,8 +196,8 @@ ossl_x509_to_pem(VALUE self) if (!out) ossl_raise(eX509CertError, NULL); if (!PEM_write_bio_X509(out, x509)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); + BIO_free(out); + ossl_raise(eX509CertError, NULL); } str = ossl_membio2str(out); @@ -222,8 +221,8 @@ ossl_x509_to_text(VALUE self) if (!out) ossl_raise(eX509CertError, NULL); if (!X509_print(out, x509)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); + BIO_free(out); + ossl_raise(eX509CertError, NULL); } str = ossl_membio2str(out); @@ -243,7 +242,7 @@ ossl_x509_to_req(VALUE self) GetX509(self, x509); if (!(req = X509_to_X509_REQ(x509, NULL, EVP_md5()))) { - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } obj = ossl_x509req_new(req); X509_REQ_free(req); @@ -277,11 +276,11 @@ ossl_x509_set_version(VALUE self, VALUE version) long ver; if ((ver = NUM2LONG(version)) < 0) { - ossl_raise(eX509CertError, "version must be >= 0!"); + ossl_raise(eX509CertError, "version must be >= 0!"); } GetX509(self, x509); if (!X509_set_version(x509, ver)) { - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return version; @@ -319,25 +318,23 @@ ossl_x509_set_serial(VALUE self, VALUE num) /* * call-seq: * cert.signature_algorithm => string + * + * Returns the signature algorithm used to sign this certificate. This returns + * the algorithm name found in the TBSCertificate structure, not the outer + * \Certificate structure. + * + * Returns the long name of the signature algorithm, or the dotted decimal + * notation if \OpenSSL does not define a long name for it. */ static VALUE ossl_x509_get_signature_algorithm(VALUE self) { X509 *x509; - BIO *out; - VALUE str; + const ASN1_OBJECT *obj; GetX509(self, x509); - out = BIO_new(BIO_s_mem()); - if (!out) ossl_raise(eX509CertError, NULL); - - if (!i2a_ASN1_OBJECT(out, X509_get0_tbs_sigalg(x509)->algorithm)) { - BIO_free(out); - ossl_raise(eX509CertError, NULL); - } - str = ossl_membio2str(out); - - return str; + X509_ALGOR_get0(&obj, NULL, NULL, X509_get0_tbs_sigalg(x509)); + return ossl_asn1obj_to_string_long_name(obj); } /* @@ -352,7 +349,7 @@ ossl_x509_get_subject(VALUE self) GetX509(self, x509); if (!(name = X509_get_subject_name(x509))) { /* NO DUP - don't free! */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return ossl_x509name_new(name); @@ -369,7 +366,7 @@ ossl_x509_set_subject(VALUE self, VALUE subject) GetX509(self, x509); if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return subject; @@ -387,7 +384,7 @@ ossl_x509_get_issuer(VALUE self) GetX509(self, x509); if(!(name = X509_get_issuer_name(x509))) { /* NO DUP - don't free! */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return ossl_x509name_new(name); @@ -404,7 +401,7 @@ ossl_x509_set_issuer(VALUE self, VALUE issuer) GetX509(self, x509); if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return issuer; @@ -422,7 +419,7 @@ ossl_x509_get_not_before(VALUE self) GetX509(self, x509); if (!(asn1time = X509_get0_notBefore(x509))) { - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return asn1time_to_time(asn1time); @@ -441,8 +438,8 @@ ossl_x509_set_not_before(VALUE self, VALUE time) GetX509(self, x509); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_set1_notBefore(x509, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509CertError, "X509_set_notBefore"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509CertError, "X509_set_notBefore"); } ASN1_TIME_free(asn1time); @@ -461,7 +458,7 @@ ossl_x509_get_not_after(VALUE self) GetX509(self, x509); if (!(asn1time = X509_get0_notAfter(x509))) { - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return asn1time_to_time(asn1time); @@ -480,8 +477,8 @@ ossl_x509_set_not_after(VALUE self, VALUE time) GetX509(self, x509); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_set1_notAfter(x509, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509CertError, "X509_set_notAfter"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509CertError, "X509_set_notAfter"); } ASN1_TIME_free(asn1time); @@ -500,10 +497,10 @@ ossl_x509_get_public_key(VALUE self) GetX509(self, x509); if (!(pkey = X509_get_pubkey(x509))) { /* adds an reference */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } - return ossl_pkey_new(pkey); /* NO DUP - OK */ + return ossl_pkey_wrap(pkey); } /* @@ -520,7 +517,7 @@ ossl_x509_set_public_key(VALUE self, VALUE key) pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); if (!X509_set_pubkey(x509, pkey)) - ossl_raise(eX509CertError, "X509_set_pubkey"); + ossl_raise(eX509CertError, "X509_set_pubkey"); return key; } @@ -534,13 +531,14 @@ ossl_x509_sign(VALUE self, VALUE key, VALUE digest) X509 *x509; EVP_PKEY *pkey; const EVP_MD *md; + VALUE md_holder; pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); + /* NULL needed for some key types, e.g. Ed25519 */ + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); GetX509(self, x509); - if (!X509_sign(x509, pkey, md)) { - ossl_raise(eX509CertError, NULL); - } + if (!X509_sign(x509, pkey, md)) + ossl_raise(eX509CertError, "X509_sign"); return self; } @@ -563,12 +561,12 @@ ossl_x509_verify(VALUE self, VALUE key) ossl_pkey_check_public_key(pkey); switch (X509_verify(x509, pkey)) { case 1: - return Qtrue; + return Qtrue; case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; default: - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } } @@ -589,8 +587,8 @@ ossl_x509_check_private_key(VALUE self, VALUE key) pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ GetX509(self, x509); if (!X509_check_private_key(x509, pkey)) { - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; } return Qtrue; @@ -610,13 +608,10 @@ ossl_x509_get_extensions(VALUE self) GetX509(self, x509); count = X509_get_ext_count(x509); - if (count < 0) { - return rb_ary_new(); - } - ary = rb_ary_new2(count); + ary = rb_ary_new_capa(count); for (i=0; i<count; i++) { - ext = X509_get_ext(x509, i); /* NO DUP - don't free! */ - rb_ary_push(ary, ossl_x509ext_new(ext)); + ext = X509_get_ext(x509, i); /* NO DUP - don't free! */ + rb_ary_push(ary, ossl_x509ext_new(ext)); } return ary; @@ -636,16 +631,16 @@ ossl_x509_set_extensions(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); /* All ary's members should be X509Extension */ for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); } GetX509(self, x509); - while ((ext = X509_delete_ext(x509, 0))) - X509_EXTENSION_free(ext); + for (i = X509_get_ext_count(x509); i > 0; i--) + X509_EXTENSION_free(X509_delete_ext(x509, 0)); for (i=0; i<RARRAY_LEN(ary); i++) { - ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); - if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */ - ossl_raise(eX509CertError, NULL); - } + ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); + if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext */ + ossl_raise(eX509CertError, "X509_add_ext"); + } } return ary; @@ -664,32 +659,24 @@ ossl_x509_add_extension(VALUE self, VALUE extension) GetX509(self, x509); ext = GetX509ExtPtr(extension); if (!X509_add_ext(x509, ext, -1)) { /* DUPs ext - FREE it */ - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509CertError, NULL); } return extension; } -static VALUE -ossl_x509_inspect(VALUE self) -{ - return rb_sprintf("#<%"PRIsVALUE": subject=%+"PRIsVALUE", " - "issuer=%+"PRIsVALUE", serial=%+"PRIsVALUE", " - "not_before=%+"PRIsVALUE", not_after=%+"PRIsVALUE">", - rb_obj_class(self), - ossl_x509_get_subject(self), - ossl_x509_get_issuer(self), - ossl_x509_get_serial(self), - ossl_x509_get_not_before(self), - ossl_x509_get_not_after(self)); -} - /* * call-seq: * cert1 == cert2 -> true | false * * Compares the two certificates. Note that this takes into account all fields, * not just the issuer name and the serial number. + * + * This method uses X509_cmp() from OpenSSL, which compares certificates based + * on their cached DER encodings. The comparison can be unreliable if a + * certificate is incomplete. + * + * See also the man page X509_cmp(3). */ static VALUE ossl_x509_eq(VALUE self, VALUE other) @@ -698,24 +685,199 @@ ossl_x509_eq(VALUE self, VALUE other) GetX509(self, a); if (!rb_obj_is_kind_of(other, cX509Cert)) - return Qfalse; + return Qfalse; GetX509(other, b); return !X509_cmp(a, b) ? Qtrue : Qfalse; } /* + * call-seq: + * cert.tbs_bytes => string + * + * Returns the DER-encoded bytes of the certificate's to be signed certificate. + * This is mainly useful for validating embedded certificate transparency signatures. + */ +static VALUE +ossl_x509_tbs_bytes(VALUE self) +{ + X509 *x509; + int len; + unsigned char *p0; + VALUE str; + + GetX509(self, x509); + len = i2d_re_X509_tbs(x509, NULL); + if (len <= 0) { + ossl_raise(eX509CertError, "i2d_re_X509_tbs"); + } + str = rb_str_new(NULL, len); + p0 = (unsigned char *)RSTRING_PTR(str); + if (i2d_re_X509_tbs(x509, &p0) <= 0) { + ossl_raise(eX509CertError, "i2d_re_X509_tbs"); + } + ossl_str_adjust(str, p0); + + return str; +} + +struct load_chained_certificates_arguments { + VALUE certificates; + X509 *certificate; +}; + +static VALUE +load_chained_certificates_append_push(VALUE _arguments) { + struct load_chained_certificates_arguments *arguments = (struct load_chained_certificates_arguments*)_arguments; + + if (arguments->certificates == Qnil) { + arguments->certificates = rb_ary_new(); + } + + rb_ary_push(arguments->certificates, ossl_x509_new(arguments->certificate)); + + return Qnil; +} + +static VALUE +load_chained_certificate_append_ensure(VALUE _arguments) { + struct load_chained_certificates_arguments *arguments = (struct load_chained_certificates_arguments*)_arguments; + + X509_free(arguments->certificate); + + return Qnil; +} + +inline static VALUE +load_chained_certificates_append(VALUE certificates, X509 *certificate) { + struct load_chained_certificates_arguments arguments; + arguments.certificates = certificates; + arguments.certificate = certificate; + + rb_ensure(load_chained_certificates_append_push, (VALUE)&arguments, load_chained_certificate_append_ensure, (VALUE)&arguments); + + return arguments.certificates; +} + +static VALUE +load_chained_certificates_PEM(BIO *in) { + VALUE certificates = Qnil; + X509 *certificate = PEM_read_bio_X509(in, NULL, NULL, NULL); + + /* If we cannot read even one certificate: */ + if (certificate == NULL) { + /* If we cannot read one certificate because we could not read the PEM encoding: */ + if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) { + ossl_clear_error(); + } + + if (ERR_peek_last_error()) + ossl_raise(eX509CertError, NULL); + else + return Qnil; + } + + certificates = load_chained_certificates_append(Qnil, certificate); + + while ((certificate = PEM_read_bio_X509(in, NULL, NULL, NULL))) { + load_chained_certificates_append(certificates, certificate); + } + + /* We tried to read one more certificate but could not read start line: */ + if (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE) { + /* This is not an error, it means we are finished: */ + ossl_clear_error(); + + return certificates; + } + + /* Alternatively, if we reached the end of the file and there was no error: */ + if (BIO_eof(in) && !ERR_peek_last_error()) { + return certificates; + } else { + /* Otherwise, we tried to read a certificate but failed somewhere: */ + ossl_raise(eX509CertError, NULL); + } +} + +static VALUE +load_chained_certificates_DER(BIO *in) { + X509 *certificate = d2i_X509_bio(in, NULL); + + /* If we cannot read one certificate: */ + if (certificate == NULL) { + /* Ignore error. We could not load. */ + ossl_clear_error(); + + return Qnil; + } + + return load_chained_certificates_append(Qnil, certificate); +} + +static VALUE +load_chained_certificates(VALUE _io) { + BIO *in = (BIO*)_io; + VALUE certificates = Qnil; + + /* + DER is a binary format and it may contain octets within it that look like + PEM encoded certificates. So we need to check DER first. + */ + certificates = load_chained_certificates_DER(in); + + if (certificates != Qnil) + return certificates; + + OSSL_BIO_reset(in); + + certificates = load_chained_certificates_PEM(in); + + if (certificates != Qnil) + return certificates; + + /* Otherwise we couldn't read the output correctly so fail: */ + ossl_raise(eX509CertError, "Could not detect format of certificate data!"); +} + +static VALUE +load_chained_certificates_ensure(VALUE _io) { + BIO *in = (BIO*)_io; + + BIO_free(in); + + return Qnil; +} + +/* + * call-seq: + * OpenSSL::X509::Certificate.load(string) -> [certs...] + * OpenSSL::X509::Certificate.load(file) -> [certs...] + * + * Read the chained certificates from the given input. Supports both PEM + * and DER encoded certificates. + * + * PEM is a text format and supports more than one certificate. + * + * DER is a binary format and only supports one certificate. + * + * If the file is empty, or contains only unrelated data, an + * +OpenSSL::X509::CertificateError+ exception will be raised. + */ +static VALUE +ossl_x509_load(VALUE klass, VALUE buffer) +{ + BIO *in = ossl_obj2bio(&buffer); + + return rb_ensure(load_chained_certificates, (VALUE)in, load_chained_certificates_ensure, (VALUE)in); +} + +/* * INIT */ void Init_ossl_x509cert(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509CertError = rb_define_class_under(mX509, "CertificateError", eOSSLError); /* Document-class: OpenSSL::X509::Certificate @@ -730,7 +892,7 @@ Init_ossl_x509cert(void) * Certificate is capable of handling DER-encoded certificates and * certificates encoded in OpenSSL's PEM format. * - * raw = File.read "cert.cer" # DER- or PEM-encoded + * raw = File.binread "cert.cer" # DER- or PEM-encoded * certificate = OpenSSL::X509::Certificate.new raw * * === Saving a certificate to a file @@ -788,7 +950,7 @@ Init_ossl_x509cert(void) * root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true)) * root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) * root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false)) - * root_ca.sign(root_key, OpenSSL::Digest::SHA256.new) + * root_ca.sign(root_key, OpenSSL::Digest.new('SHA256')) * * The next step is to create the end-entity certificate using the root CA * certificate. @@ -807,11 +969,13 @@ Init_ossl_x509cert(void) * ef.issuer_certificate = root_ca * cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true)) * cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false)) - * cert.sign(root_key, OpenSSL::Digest::SHA256.new) + * cert.sign(root_key, OpenSSL::Digest.new('SHA256')) * */ cX509Cert = rb_define_class_under(mX509, "Certificate", rb_cObject); + rb_define_singleton_method(cX509Cert, "load", ossl_x509_load, 1); + rb_define_alloc_func(cX509Cert, ossl_x509_alloc); rb_define_method(cX509Cert, "initialize", ossl_x509_initialize, -1); rb_define_method(cX509Cert, "initialize_copy", ossl_x509_copy, 1); @@ -841,6 +1005,6 @@ Init_ossl_x509cert(void) rb_define_method(cX509Cert, "extensions", ossl_x509_get_extensions, 0); rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1); rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1); - rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0); rb_define_method(cX509Cert, "==", ossl_x509_eq, 1); + rb_define_method(cX509Cert, "tbs_bytes", ossl_x509_tbs_bytes, 0); } diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c index b0badf45c4..a221429c34 100644 --- a/ext/openssl/ossl_x509crl.c +++ b/ext/openssl/ossl_x509crl.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,22 +13,22 @@ TypedData_Wrap_Struct((klass), &ossl_x509crl_type, 0) #define SetX509CRL(obj, crl) do { \ if (!(crl)) { \ - ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (crl); \ } while (0) #define GetX509CRL(obj, crl) do { \ TypedData_Get_Struct((obj), X509_CRL, &ossl_x509crl_type, (crl)); \ if (!(crl)) { \ - ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CRL wasn't initialized!"); \ } \ } while (0) /* * Classes */ -VALUE cX509CRL; -VALUE eX509CRLError; +static VALUE cX509CRL; +static VALUE eX509CRLError; static void ossl_x509crl_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509crl_free(void *ptr) static const rb_data_type_t ossl_x509crl_type = { "OpenSSL/X509/CRL", { - 0, ossl_x509crl_free, + 0, ossl_x509crl_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -64,8 +64,9 @@ ossl_x509crl_new(X509_CRL *crl) VALUE obj; obj = NewX509CRL(cX509CRL); - tmp = crl ? X509_CRL_dup(crl) : X509_CRL_new(); - if(!tmp) ossl_raise(eX509CRLError, NULL); + tmp = X509_CRL_dup(crl); + if (!tmp) + ossl_raise(eX509CRLError, "X509_CRL_dup"); SetX509CRL(obj, tmp); return obj; @@ -82,7 +83,7 @@ ossl_x509crl_alloc(VALUE klass) obj = NewX509CRL(klass); if (!(crl = X509_CRL_new())) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } SetX509CRL(obj, crl); @@ -93,27 +94,31 @@ static VALUE ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self) { BIO *in; - X509_CRL *crl, *x = DATA_PTR(self); + X509_CRL *crl, *crl_orig = RTYPEDDATA_DATA(self); VALUE arg; + rb_check_frozen(self); if (rb_scan_args(argc, argv, "01", &arg) == 0) { - return self; + return self; } arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); - crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL); - DATA_PTR(self) = x; + crl = d2i_X509_CRL_bio(in, NULL); if (!crl) { - OSSL_BIO_reset(in); - crl = d2i_X509_CRL_bio(in, &x); - DATA_PTR(self) = x; + OSSL_BIO_reset(in); + crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); } BIO_free(in); - if (!crl) ossl_raise(eX509CRLError, NULL); + if (!crl) + ossl_raise(eX509CRLError, "PEM_read_bio_X509_CRL"); + + RTYPEDDATA_DATA(self) = crl; + X509_CRL_free(crl_orig); return self; } +/* :nodoc: */ static VALUE ossl_x509crl_copy(VALUE self, VALUE other) { @@ -124,7 +129,7 @@ ossl_x509crl_copy(VALUE self, VALUE other) GetX509CRL(self, a); GetX509CRL(other, b); if (!(crl = X509_CRL_dup(b))) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } X509_CRL_free(a); DATA_PTR(self) = crl; @@ -151,34 +156,36 @@ ossl_x509crl_set_version(VALUE self, VALUE version) long ver; if ((ver = NUM2LONG(version)) < 0) { - ossl_raise(eX509CRLError, "version must be >= 0!"); + ossl_raise(eX509CRLError, "version must be >= 0!"); } GetX509CRL(self, crl); if (!X509_CRL_set_version(crl, ver)) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } return version; } +/* + * call-seq: + * crl.signature_algorithm -> string + * + * Returns the signature algorithm used to sign this CRL. + * + * Returns the long name of the signature algorithm, or the dotted decimal + * notation if \OpenSSL does not define a long name for it. + */ static VALUE ossl_x509crl_get_signature_algorithm(VALUE self) { X509_CRL *crl; const X509_ALGOR *alg; - BIO *out; + const ASN1_OBJECT *obj; GetX509CRL(self, crl); - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); - } X509_CRL_get0_signature(crl, NULL, &alg); - if (!i2a_ASN1_OBJECT(out, alg->algorithm)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); - } - - return ossl_membio2str(out); + X509_ALGOR_get0(&obj, NULL, NULL, alg); + return ossl_asn1obj_to_string_long_name(obj); } static VALUE @@ -199,7 +206,7 @@ ossl_x509crl_set_issuer(VALUE self, VALUE issuer) GetX509CRL(self, crl); if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */ - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } return issuer; } @@ -213,7 +220,7 @@ ossl_x509crl_get_last_update(VALUE self) GetX509CRL(self, crl); time = X509_CRL_get0_lastUpdate(crl); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -227,8 +234,8 @@ ossl_x509crl_set_last_update(VALUE self, VALUE time) GetX509CRL(self, crl); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_CRL_set1_lastUpdate(crl, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509CRLError, "X509_CRL_set_lastUpdate"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509CRLError, "X509_CRL_set_lastUpdate"); } ASN1_TIME_free(asn1time); @@ -244,7 +251,7 @@ ossl_x509crl_get_next_update(VALUE self) GetX509CRL(self, crl); time = X509_CRL_get0_nextUpdate(crl); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -258,8 +265,8 @@ ossl_x509crl_set_next_update(VALUE self, VALUE time) GetX509CRL(self, crl); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_CRL_set1_nextUpdate(crl, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509CRLError, "X509_CRL_set_nextUpdate"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509CRLError, "X509_CRL_set_nextUpdate"); } ASN1_TIME_free(asn1time); @@ -271,21 +278,19 @@ ossl_x509crl_get_revoked(VALUE self) { X509_CRL *crl; int i, num; - X509_REVOKED *rev; - VALUE ary, revoked; + STACK_OF(X509_REVOKED) *sk; + VALUE ary; GetX509CRL(self, crl); - num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); - if (num < 0) { - OSSL_Debug("num < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(num); + sk = X509_CRL_get_REVOKED(crl); + if (!sk) + return rb_ary_new(); + + num = sk_X509_REVOKED_num(sk); + ary = rb_ary_new_capa(num); for(i=0; i<num; i++) { - /* NO DUP - don't free! */ - rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); - revoked = ossl_x509revoked_new(rev); - rb_ary_push(ary, revoked); + X509_REVOKED *rev = sk_X509_REVOKED_value(sk, i); + rb_ary_push(ary, ossl_x509revoked_new(rev)); } return ary; @@ -302,19 +307,19 @@ ossl_x509crl_set_revoked(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); /* All ary members should be X509 Revoked */ for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Rev); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Rev); } GetX509CRL(self, crl); if ((sk = X509_CRL_get_REVOKED(crl))) { - while ((rev = sk_X509_REVOKED_pop(sk))) - X509_REVOKED_free(rev); + while ((rev = sk_X509_REVOKED_pop(sk))) + X509_REVOKED_free(rev); } for (i=0; i<RARRAY_LEN(ary); i++) { - rev = DupX509RevokedPtr(RARRAY_AREF(ary, i)); - if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ - X509_REVOKED_free(rev); - ossl_raise(eX509CRLError, "X509_CRL_add0_revoked"); - } + rev = DupX509RevokedPtr(RARRAY_AREF(ary, i)); + if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ + X509_REVOKED_free(rev); + ossl_raise(eX509CRLError, "X509_CRL_add0_revoked"); + } } X509_CRL_sort(crl); @@ -330,8 +335,8 @@ ossl_x509crl_add_revoked(VALUE self, VALUE revoked) GetX509CRL(self, crl); rev = DupX509RevokedPtr(revoked); if (!X509_CRL_add0_revoked(crl, rev)) { /* NO DUP - don't free! */ - X509_REVOKED_free(rev); - ossl_raise(eX509CRLError, "X509_CRL_add0_revoked"); + X509_REVOKED_free(rev); + ossl_raise(eX509CRLError, "X509_CRL_add0_revoked"); } X509_CRL_sort(crl); @@ -344,13 +349,14 @@ ossl_x509crl_sign(VALUE self, VALUE key, VALUE digest) X509_CRL *crl; EVP_PKEY *pkey; const EVP_MD *md; + VALUE md_holder; GetX509CRL(self, crl); pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); - if (!X509_CRL_sign(crl, pkey, md)) { - ossl_raise(eX509CRLError, NULL); - } + /* NULL needed for some key types, e.g. Ed25519 */ + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); + if (!X509_CRL_sign(crl, pkey, md)) + ossl_raise(eX509CRLError, "X509_CRL_sign"); return self; } @@ -366,12 +372,12 @@ ossl_x509crl_verify(VALUE self, VALUE key) ossl_pkey_check_public_key(pkey); switch (X509_CRL_verify(crl, pkey)) { case 1: - return Qtrue; + return Qtrue; case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; default: - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } } @@ -383,11 +389,11 @@ ossl_x509crl_to_der(VALUE self) GetX509CRL(self, crl); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } if (!i2d_X509_CRL_bio(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); + BIO_free(out); + ossl_raise(eX509CRLError, NULL); } return ossl_membio2str(out); @@ -401,11 +407,11 @@ ossl_x509crl_to_pem(VALUE self) GetX509CRL(self, crl); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } if (!PEM_write_bio_X509_CRL(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); + BIO_free(out); + ossl_raise(eX509CRLError, NULL); } return ossl_membio2str(out); @@ -419,11 +425,11 @@ ossl_x509crl_to_text(VALUE self) GetX509CRL(self, crl); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } if (!X509_CRL_print(out, crl)) { - BIO_free(out); - ossl_raise(eX509CRLError, NULL); + BIO_free(out); + ossl_raise(eX509CRLError, NULL); } return ossl_membio2str(out); @@ -442,14 +448,10 @@ ossl_x509crl_get_extensions(VALUE self) GetX509CRL(self, crl); count = X509_CRL_get_ext_count(crl); - if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(count); + ary = rb_ary_new_capa(count); for (i=0; i<count; i++) { - ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */ - rb_ary_push(ary, ossl_x509ext_new(ext)); + ext = X509_CRL_get_ext(crl, i); /* NO DUP - don't free! */ + rb_ary_push(ary, ossl_x509ext_new(ext)); } return ary; @@ -468,16 +470,16 @@ ossl_x509crl_set_extensions(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); /* All ary members should be X509 Extensions */ for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); } GetX509CRL(self, crl); - while ((ext = X509_CRL_delete_ext(crl, 0))) - X509_EXTENSION_free(ext); + for (i = X509_CRL_get_ext_count(crl); i > 0; i--) + X509_EXTENSION_free(X509_CRL_delete_ext(crl, 0)); for (i=0; i<RARRAY_LEN(ary); i++) { - ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */ - if (!X509_CRL_add_ext(crl, ext, -1)) { - ossl_raise(eX509CRLError, NULL); - } + ext = GetX509ExtPtr(RARRAY_AREF(ary, i)); /* NO NEED TO DUP */ + if (!X509_CRL_add_ext(crl, ext, -1)) { + ossl_raise(eX509CRLError, "X509_CRL_add_ext"); + } } return ary; @@ -492,7 +494,7 @@ ossl_x509crl_add_extension(VALUE self, VALUE extension) GetX509CRL(self, crl); ext = GetX509ExtPtr(extension); if (!X509_CRL_add_ext(crl, ext, -1)) { - ossl_raise(eX509CRLError, NULL); + ossl_raise(eX509CRLError, NULL); } return extension; @@ -504,12 +506,6 @@ ossl_x509crl_add_extension(VALUE self, VALUE extension) void Init_ossl_x509crl(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509CRLError = rb_define_class_under(mX509, "CRLError", eOSSLError); cX509CRL = rb_define_class_under(mX509, "CRL", rb_cObject); diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c index 30ec09d7a3..ef66ecc3fe 100644 --- a/ext/openssl/ossl_x509ext.c +++ b/ext/openssl/ossl_x509ext.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509ext_type, 0) #define SetX509Ext(obj, ext) do { \ if (!(ext)) { \ - ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (ext); \ } while (0) #define GetX509Ext(obj, ext) do { \ TypedData_Get_Struct((obj), X509_EXTENSION, &ossl_x509ext_type, (ext)); \ if (!(ext)) { \ - ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "EXT wasn't initialized!"); \ } \ } while (0) #define MakeX509ExtFactory(klass, obj, ctx) do { \ @@ -33,7 +33,7 @@ #define GetX509ExtFactory(obj, ctx) do { \ TypedData_Get_Struct((obj), X509V3_CTX, &ossl_x509extfactory_type, (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "CTX wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "CTX wasn't initialized!"); \ } \ } while (0) @@ -41,8 +41,8 @@ * Classes */ VALUE cX509Ext; -VALUE cX509ExtFactory; -VALUE eX509ExtError; +static VALUE cX509ExtFactory; +static VALUE eX509ExtError; static void ossl_x509ext_free(void *ptr) @@ -53,9 +53,9 @@ ossl_x509ext_free(void *ptr) static const rb_data_type_t ossl_x509ext_type = { "OpenSSL/X509/EXTENSION", { - 0, ossl_x509ext_free, + 0, ossl_x509ext_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -68,14 +68,9 @@ ossl_x509ext_new(X509_EXTENSION *ext) VALUE obj; obj = NewX509Ext(cX509Ext); - if (!ext) { - new = X509_EXTENSION_new(); - } else { - new = X509_EXTENSION_dup(ext); - } - if (!new) { - ossl_raise(eX509ExtError, NULL); - } + new = X509_EXTENSION_dup(ext); + if (!new) + ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); SetX509Ext(obj, new); return obj; @@ -106,9 +101,9 @@ ossl_x509extfactory_free(void *ctx) static const rb_data_type_t ossl_x509extfactory_type = { "OpenSSL/X509/EXTENSION/Factory", { - 0, ossl_x509extfactory_free, + 0, ossl_x509extfactory_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -180,15 +175,15 @@ ossl_x509extfactory_initialize(int argc, VALUE *argv, VALUE self) /*GetX509ExtFactory(self, ctx);*/ rb_scan_args(argc, argv, "04", - &issuer_cert, &subject_cert, &subject_req, &crl); + &issuer_cert, &subject_cert, &subject_req, &crl); if (!NIL_P(issuer_cert)) - ossl_x509extfactory_set_issuer_cert(self, issuer_cert); + ossl_x509extfactory_set_issuer_cert(self, issuer_cert); if (!NIL_P(subject_cert)) - ossl_x509extfactory_set_subject_cert(self, subject_cert); + ossl_x509extfactory_set_subject_cert(self, subject_cert); if (!NIL_P(subject_req)) - ossl_x509extfactory_set_subject_req(self, subject_req); + ossl_x509extfactory_set_subject_req(self, subject_req); if (!NIL_P(crl)) - ossl_x509extfactory_set_crl(self, crl); + ossl_x509extfactory_set_crl(self, crl); return self; } @@ -209,15 +204,16 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) int nid; VALUE rconf; CONF *conf; + const char *oid_cstr = NULL; rb_scan_args(argc, argv, "21", &oid, &value, &critical); - StringValueCStr(oid); StringValue(value); if(NIL_P(critical)) critical = Qfalse; - nid = OBJ_ln2nid(RSTRING_PTR(oid)); - if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid)); - if(!nid) ossl_raise(eX509ExtError, "unknown OID `%"PRIsVALUE"'", oid); + oid_cstr = StringValueCStr(oid); + nid = OBJ_ln2nid(oid_cstr); + if (nid != NID_undef) + oid_cstr = OBJ_nid2sn(nid); valstr = rb_str_new2(RTEST(critical) ? "critical," : ""); rb_str_append(valstr, value); @@ -226,13 +222,13 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) GetX509ExtFactory(self, ctx); obj = NewX509Ext(cX509Ext); rconf = rb_iv_get(self, "@config"); - conf = NIL_P(rconf) ? NULL : DupConfigPtr(rconf); + conf = NIL_P(rconf) ? NULL : GetConfig(rconf); X509V3_set_nconf(ctx, conf); - ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr)); + + ext = X509V3_EXT_nconf(conf, ctx, oid_cstr, RSTRING_PTR(valstr)); X509V3_set_ctx_nodb(ctx); - NCONF_free(conf); if (!ext){ - ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr); + ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr); } SetX509Ext(obj, ext); @@ -250,7 +246,7 @@ ossl_x509ext_alloc(VALUE klass) obj = NewX509Ext(klass); if(!(ext = X509_EXTENSION_new())){ - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); } SetX509Ext(obj, ext); @@ -278,14 +274,14 @@ ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self) GetX509Ext(self, ext); if(rb_scan_args(argc, argv, "12", &oid, &value, &critical) == 1){ - oid = ossl_to_der_if_possible(oid); - StringValue(oid); - p = (unsigned char *)RSTRING_PTR(oid); - x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid)); - DATA_PTR(self) = ext; - if(!x) - ossl_raise(eX509ExtError, NULL); - return self; + oid = ossl_to_der_if_possible(oid); + StringValue(oid); + p = (unsigned char *)RSTRING_PTR(oid); + x = d2i_X509_EXTENSION(&ext, &p, RSTRING_LEN(oid)); + DATA_PTR(self) = ext; + if(!x) + ossl_raise(eX509ExtError, NULL); + return self; } rb_funcall(self, rb_intern("oid="), 1, oid); rb_funcall(self, rb_intern("value="), 1, value); @@ -294,6 +290,7 @@ ossl_x509ext_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509ext_initialize_copy(VALUE self, VALUE other) { @@ -305,7 +302,7 @@ ossl_x509ext_initialize_copy(VALUE self, VALUE other) ext_new = X509_EXTENSION_dup(ext_other); if (!ext_new) - ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); + ossl_raise(eX509ExtError, "X509_EXTENSION_dup"); SetX509Ext(self, ext_new); X509_EXTENSION_free(ext); @@ -322,10 +319,10 @@ ossl_x509ext_set_oid(VALUE self, VALUE oid) GetX509Ext(self, ext); obj = OBJ_txt2obj(StringValueCStr(oid), 0); if (!obj) - ossl_raise(eX509ExtError, "OBJ_txt2obj"); + ossl_raise(eX509ExtError, "OBJ_txt2obj"); if (!X509_EXTENSION_set_object(ext, obj)) { - ASN1_OBJECT_free(obj); - ossl_raise(eX509ExtError, "X509_EXTENSION_set_object"); + ASN1_OBJECT_free(obj); + ossl_raise(eX509ExtError, "X509_EXTENSION_set_object"); } ASN1_OBJECT_free(obj); @@ -344,8 +341,8 @@ ossl_x509ext_set_value(VALUE self, VALUE data) asn1s = X509_EXTENSION_get_data(ext); if (!ASN1_OCTET_STRING_set(asn1s, (unsigned char *)RSTRING_PTR(data), - RSTRING_LENINT(data))) { - ossl_raise(eX509ExtError, "ASN1_OCTET_STRING_set"); + RSTRING_LENINT(data))) { + ossl_raise(eX509ExtError, "ASN1_OCTET_STRING_set"); } return data; @@ -362,27 +359,20 @@ ossl_x509ext_set_critical(VALUE self, VALUE flag) return flag; } +/* + * call-seq: + * ext.oid -> string + * + * Returns the OID of the extension. Returns the short name or the dotted + * decimal notation. + */ static VALUE ossl_x509ext_get_oid(VALUE obj) { X509_EXTENSION *ext; - ASN1_OBJECT *extobj; - BIO *out; - VALUE ret; - int nid; GetX509Ext(obj, ext); - extobj = X509_EXTENSION_get_object(ext); - if ((nid = OBJ_obj2nid(extobj)) != NID_undef) - ret = rb_str_new2(OBJ_nid2sn(nid)); - else{ - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509ExtError, NULL); - i2a_ASN1_OBJECT(out, extobj); - ret = ossl_membio2str(out); - } - - return ret; + return ossl_asn1obj_to_string(X509_EXTENSION_get_object(ext)); } static VALUE @@ -394,15 +384,28 @@ ossl_x509ext_get_value(VALUE obj) GetX509Ext(obj, ext); if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); if (!X509V3_EXT_print(out, ext, 0, 0)) - ASN1_STRING_print(out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); + ASN1_STRING_print(out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); ret = ossl_membio2str(out); return ret; } static VALUE +ossl_x509ext_get_value_der(VALUE obj) +{ + X509_EXTENSION *ext; + ASN1_OCTET_STRING *value; + + GetX509Ext(obj, ext); + if ((value = X509_EXTENSION_get_data(ext)) == NULL) + ossl_raise(eX509ExtError, NULL); + + return asn1str_to_str(value); +} + +static VALUE ossl_x509ext_get_critical(VALUE obj) { X509_EXTENSION *ext; @@ -421,11 +424,11 @@ ossl_x509ext_to_der(VALUE obj) GetX509Ext(obj, ext); if((len = i2d_X509_EXTENSION(ext, NULL)) <= 0) - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_X509_EXTENSION(ext, &p) < 0) - ossl_raise(eX509ExtError, NULL); + ossl_raise(eX509ExtError, NULL); ossl_str_adjust(str, p); return str; @@ -438,12 +441,6 @@ void Init_ossl_x509ext(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509ExtError = rb_define_class_under(mX509, "ExtensionError", eOSSLError); cX509ExtFactory = rb_define_class_under(mX509, "ExtensionFactory", rb_cObject); @@ -472,6 +469,7 @@ Init_ossl_x509ext(void) rb_define_method(cX509Ext, "critical=", ossl_x509ext_set_critical, 1); rb_define_method(cX509Ext, "oid", ossl_x509ext_get_oid, 0); rb_define_method(cX509Ext, "value", ossl_x509ext_get_value, 0); + rb_define_method(cX509Ext, "value_der", ossl_x509ext_get_value_der, 0); rb_define_method(cX509Ext, "critical?", ossl_x509ext_get_critical, 0); rb_define_method(cX509Ext, "to_der", ossl_x509ext_to_der, 0); } diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index 1ea8400dbb..5b3c3f7261 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,27 +13,27 @@ TypedData_Wrap_Struct((klass), &ossl_x509name_type, 0) #define SetX509Name(obj, name) do { \ if (!(name)) { \ - ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ } \ RTYPEDDATA_DATA(obj) = (name); \ } while (0) #define GetX509Name(obj, name) do { \ TypedData_Get_Struct((obj), X509_NAME, &ossl_x509name_type, (name)); \ if (!(name)) { \ - ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ + ossl_raise(rb_eRuntimeError, "Name wasn't initialized."); \ } \ } while (0) #define OBJECT_TYPE_TEMPLATE \ - rb_const_get(cX509Name, rb_intern("OBJECT_TYPE_TEMPLATE")) + rb_const_get(cX509Name, rb_intern("OBJECT_TYPE_TEMPLATE")) #define DEFAULT_OBJECT_TYPE \ - rb_const_get(cX509Name, rb_intern("DEFAULT_OBJECT_TYPE")) + rb_const_get(cX509Name, rb_intern("DEFAULT_OBJECT_TYPE")) /* * Classes */ -VALUE cX509Name; -VALUE eX509NameError; +static VALUE cX509Name; +static VALUE eX509NameError; static void ossl_x509name_free(void *ptr) @@ -44,9 +44,9 @@ ossl_x509name_free(void *ptr) static const rb_data_type_t ossl_x509name_type = { "OpenSSL/X509/NAME", { - 0, ossl_x509name_free, + 0, ossl_x509name_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -59,14 +59,9 @@ ossl_x509name_new(X509_NAME *name) VALUE obj; obj = NewX509Name(cX509Name); - if (!name) { - new = X509_NAME_new(); - } else { - new = X509_NAME_dup(name); - } - if (!new) { - ossl_raise(eX509NameError, NULL); - } + new = X509_NAME_dup(name); + if (!new) + ossl_raise(eX509NameError, "X509_NAME_dup"); SetX509Name(obj, new); return obj; @@ -93,7 +88,7 @@ ossl_x509name_alloc(VALUE klass) obj = NewX509Name(klass); if (!(name = X509_NAME_new())) { - ossl_raise(eX509NameError, NULL); + ossl_raise(eX509NameError, NULL); } SetX509Name(obj, name); @@ -150,33 +145,34 @@ ossl_x509name_initialize(int argc, VALUE *argv, VALUE self) GetX509Name(self, name); if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) { - return self; + return self; } else { - VALUE tmp = rb_check_array_type(arg); - if (!NIL_P(tmp)) { - VALUE args; - if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE; - args = rb_ary_new3(2, self, template); - rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args); - } - else{ - const unsigned char *p; - VALUE str = ossl_to_der_if_possible(arg); - X509_NAME *x; - StringValue(str); - p = (unsigned char *)RSTRING_PTR(str); - x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str)); - DATA_PTR(self) = name; - if(!x){ - ossl_raise(eX509NameError, NULL); - } - } + VALUE tmp = rb_check_array_type(arg); + if (!NIL_P(tmp)) { + VALUE args; + if(NIL_P(template)) template = OBJECT_TYPE_TEMPLATE; + args = rb_ary_new3(2, self, template); + rb_block_call(tmp, rb_intern("each"), 0, 0, ossl_x509name_init_i, args); + } + else{ + const unsigned char *p; + VALUE str = ossl_to_der_if_possible(arg); + X509_NAME *x; + StringValue(str); + p = (unsigned char *)RSTRING_PTR(str); + x = d2i_X509_NAME(&name, &p, RSTRING_LEN(str)); + DATA_PTR(self) = name; + if(!x){ + ossl_raise(eX509NameError, NULL); + } + } } return self; } +/* :nodoc: */ static VALUE ossl_x509name_initialize_copy(VALUE self, VALUE other) { @@ -188,7 +184,7 @@ ossl_x509name_initialize_copy(VALUE self, VALUE other) name_new = X509_NAME_dup(name_other); if (!name_new) - ossl_raise(eX509NameError, "X509_NAME_dup"); + ossl_raise(eX509NameError, "X509_NAME_dup"); SetX509Name(self, name_new); X509_NAME_free(name); @@ -225,8 +221,8 @@ VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self) int loc = -1, set = 0; if (!kwargs_ids[0]) { - kwargs_ids[0] = rb_intern_const("loc"); - kwargs_ids[1] = rb_intern_const("set"); + kwargs_ids[0] = rb_intern_const("loc"); + kwargs_ids[1] = rb_intern_const("set"); } rb_scan_args(argc, argv, "21:", &oid, &value, &type, &opts); rb_get_kwargs(opts, kwargs_ids, 0, 2, kwargs); @@ -234,14 +230,14 @@ VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self) StringValue(value); if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid); if (kwargs[0] != Qundef) - loc = NUM2INT(kwargs[0]); + loc = NUM2INT(kwargs[0]); if (kwargs[1] != Qundef) - set = NUM2INT(kwargs[1]); + set = NUM2INT(kwargs[1]); GetX509Name(self, name); if (!X509_NAME_add_entry_by_txt(name, oid_name, NUM2INT(type), - (unsigned char *)RSTRING_PTR(value), - RSTRING_LENINT(value), loc, set)) - ossl_raise(eX509NameError, "X509_NAME_add_entry_by_txt"); + (unsigned char *)RSTRING_PTR(value), + RSTRING_LENINT(value), loc, set)) + ossl_raise(eX509NameError, "X509_NAME_add_entry_by_txt"); return self; } @@ -254,7 +250,7 @@ ossl_x509name_to_s_old(VALUE self) GetX509Name(self, name); buf = X509_NAME_oneline(name, NULL, 0); if (!buf) - ossl_raise(eX509NameError, "X509_NAME_oneline"); + ossl_raise(eX509NameError, "X509_NAME_oneline"); return ossl_buf2str(buf, rb_long2int(strlen(buf))); } @@ -268,11 +264,11 @@ x509name_print(VALUE self, unsigned long iflag) GetX509Name(self, name); out = BIO_new(BIO_s_mem()); if (!out) - ossl_raise(eX509NameError, NULL); + ossl_raise(eX509NameError, NULL); ret = X509_NAME_print_ex(out, name, 0, iflag); if (ret < 0 || (iflag == XN_FLAG_COMPAT && ret == 0)) { - BIO_free(out); - ossl_raise(eX509NameError, "X509_NAME_print_ex"); + BIO_free(out); + ossl_raise(eX509NameError, "X509_NAME_print_ex"); } return ossl_membio2str(out); } @@ -291,7 +287,14 @@ x509name_print(VALUE self, unsigned long iflag) * * OpenSSL::X509::Name::MULTILINE * * If _format_ is omitted, the largely broken and traditional OpenSSL format - * is used. + * (<tt>X509_NAME_oneline()</tt> format) is chosen. + * + * <b>Use of this method is discouraged.</b> None of the formats other than + * OpenSSL::X509::Name::RFC2253 is standardized and may show an inconsistent + * behavior through \OpenSSL versions. + * + * It is recommended to use #to_utf8 instead, which is equivalent to calling + * <tt>name.to_s(OpenSSL::X509::Name::RFC2253).force_encoding("UTF-8")</tt>. */ static VALUE ossl_x509name_to_s(int argc, VALUE *argv, VALUE self) @@ -299,9 +302,9 @@ ossl_x509name_to_s(int argc, VALUE *argv, VALUE self) rb_check_arity(argc, 0, 1); /* name.to_s(nil) was allowed */ if (!argc || NIL_P(argv[0])) - return ossl_x509name_to_s_old(self); + return ossl_x509name_to_s_old(self); else - return x509name_print(self, NUM2ULONG(argv[0])); + return x509name_print(self, NUM2ULONG(argv[0])); } /* @@ -324,7 +327,7 @@ static VALUE ossl_x509name_inspect(VALUE self) { return rb_enc_sprintf(rb_utf8_encoding(), "#<%"PRIsVALUE" %"PRIsVALUE">", - rb_obj_class(self), ossl_x509name_to_utf8(self)); + rb_obj_class(self), ossl_x509name_to_utf8(self)); } /* @@ -338,38 +341,22 @@ static VALUE ossl_x509name_to_a(VALUE self) { X509_NAME *name; - X509_NAME_ENTRY *entry; - int i,entries,nid; - char long_name[512]; - const char *short_name; - VALUE ary, vname, ret; - ASN1_STRING *value; + int entries; + VALUE ret; GetX509Name(self, name); entries = X509_NAME_entry_count(name); - if (entries < 0) { - OSSL_Debug("name entries < 0!"); - return rb_ary_new(); - } - ret = rb_ary_new2(entries); - for (i=0; i<entries; i++) { - if (!(entry = X509_NAME_get_entry(name, i))) { - ossl_raise(eX509NameError, NULL); - } - if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), - X509_NAME_ENTRY_get_object(entry))) { - ossl_raise(eX509NameError, NULL); - } - nid = OBJ_ln2nid(long_name); - if (nid == NID_undef) { - vname = rb_str_new2((const char *) &long_name); - } else { - short_name = OBJ_nid2sn(nid); - vname = rb_str_new2(short_name); /*do not free*/ - } - value = X509_NAME_ENTRY_get_data(entry); - ary = rb_ary_new3(3, vname, asn1str_to_str(value), INT2NUM(value->type)); - rb_ary_push(ret, ary); + ret = rb_ary_new_capa(entries); + for (int i = 0; i < entries; i++) { + const X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i); + if (!entry) + ossl_raise(eX509NameError, "X509_NAME_get_entry"); + const ASN1_OBJECT *obj = X509_NAME_ENTRY_get_object(entry); + VALUE vname = ossl_asn1obj_to_string(obj); + const ASN1_STRING *data = X509_NAME_ENTRY_get_data(entry); + VALUE vdata = asn1str_to_str(data); + VALUE type = INT2NUM(ASN1_STRING_type(data)); + rb_ary_push(ret, rb_ary_new_from_args(3, vname, vdata, type)); } return ret; } @@ -387,17 +374,21 @@ ossl_x509name_cmp0(VALUE self, VALUE other) /* * call-seq: - * name.cmp(other) -> -1 | 0 | 1 - * name <=> other -> -1 | 0 | 1 + * name.cmp(other) -> -1 | 0 | 1 | nil + * name <=> other -> -1 | 0 | 1 | nil * * Compares this Name with _other_ and returns +0+ if they are the same and +-1+ * or ++1+ if they are greater or less than each other respectively. + * Returns +nil+ if they are not comparable (i.e. different types). */ static VALUE ossl_x509name_cmp(VALUE self, VALUE other) { int result; + if (!rb_obj_is_kind_of(other, cX509Name)) + return Qnil; + result = ossl_x509name_cmp0(self, other); if (result < 0) return INT2FIX(-1); if (result > 0) return INT2FIX(1); @@ -415,7 +406,7 @@ static VALUE ossl_x509name_eql(VALUE self, VALUE other) { if (!rb_obj_is_kind_of(other, cX509Name)) - return Qfalse; + return Qfalse; return ossl_x509name_cmp0(self, other) == 0 ? Qtrue : Qfalse; } @@ -475,11 +466,11 @@ ossl_x509name_to_der(VALUE self) GetX509Name(self, name); if((len = i2d_X509_NAME(name, NULL)) <= 0) - ossl_raise(eX509NameError, NULL); + ossl_raise(eX509NameError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if(i2d_X509_NAME(name, &p) <= 0) - ossl_raise(eX509NameError, NULL); + ossl_raise(eX509NameError, NULL); ossl_str_adjust(str, p); return str; @@ -494,7 +485,7 @@ ossl_x509name_to_der(VALUE self) * You can create a Name by parsing a distinguished name String or by * supplying the distinguished name as an Array. * - * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example' + * name = OpenSSL::X509::Name.parse_rfc2253 'DC=example,CN=nobody' * * name = OpenSSL::X509::Name.new [['CN', 'nobody'], ['DC', 'example']] */ @@ -505,12 +496,6 @@ Init_ossl_x509name(void) #undef rb_intern VALUE utf8str, ptrstr, ia5str, hash; -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - id_aref = rb_intern("[]"); eX509NameError = rb_define_class_under(mX509, "NameError", eOSSLError); cX509Name = rb_define_class_under(mX509, "Name", rb_cObject); @@ -549,6 +534,7 @@ Init_ossl_x509name(void) rb_hash_aset(hash, rb_str_new2("DC"), ia5str); rb_hash_aset(hash, rb_str_new2("domainComponent"), ia5str); rb_hash_aset(hash, rb_str_new2("emailAddress"), ia5str); + rb_obj_freeze(hash); /* * The default object type template for name entries. diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c index 2c20042a92..433cc461a9 100644 --- a/ext/openssl/ossl_x509req.c +++ b/ext/openssl/ossl_x509req.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,22 +13,22 @@ TypedData_Wrap_Struct((klass), &ossl_x509req_type, 0) #define SetX509Req(obj, req) do { \ if (!(req)) { \ - ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (req); \ } while (0) #define GetX509Req(obj, req) do { \ TypedData_Get_Struct((obj), X509_REQ, &ossl_x509req_type, (req)); \ if (!(req)) { \ - ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "Req wasn't initialized!"); \ } \ } while (0) /* * Classes */ -VALUE cX509Req; -VALUE eX509ReqError; +static VALUE cX509Req; +static VALUE eX509ReqError; static void ossl_x509req_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509req_free(void *ptr) static const rb_data_type_t ossl_x509req_type = { "OpenSSL/X509/REQ", { - 0, ossl_x509req_free, + 0, ossl_x509req_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -68,7 +68,7 @@ ossl_x509req_alloc(VALUE klass) obj = NewX509Req(klass); if (!(req = X509_REQ_new())) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } SetX509Req(obj, req); @@ -79,27 +79,31 @@ static VALUE ossl_x509req_initialize(int argc, VALUE *argv, VALUE self) { BIO *in; - X509_REQ *req, *x = DATA_PTR(self); + X509_REQ *req, *req_orig = RTYPEDDATA_DATA(self); VALUE arg; + rb_check_frozen(self); if (rb_scan_args(argc, argv, "01", &arg) == 0) { - return self; + return self; } arg = ossl_to_der_if_possible(arg); in = ossl_obj2bio(&arg); - req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL); - DATA_PTR(self) = x; + req = d2i_X509_REQ_bio(in, NULL); if (!req) { - OSSL_BIO_reset(in); - req = d2i_X509_REQ_bio(in, &x); - DATA_PTR(self) = x; + OSSL_BIO_reset(in); + req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); } BIO_free(in); - if (!req) ossl_raise(eX509ReqError, NULL); + if (!req) + ossl_raise(eX509ReqError, "PEM_read_bio_X509_REQ"); + + RTYPEDDATA_DATA(self) = req; + X509_REQ_free(req_orig); return self; } +/* :nodoc: */ static VALUE ossl_x509req_copy(VALUE self, VALUE other) { @@ -110,7 +114,7 @@ ossl_x509req_copy(VALUE self, VALUE other) GetX509Req(self, a); GetX509Req(other, b); if (!(req = X509_REQ_dup(b))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } X509_REQ_free(a); DATA_PTR(self) = req; @@ -126,11 +130,11 @@ ossl_x509req_to_pem(VALUE self) GetX509Req(self, req); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } if (!PEM_write_bio_X509_REQ(out, req)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); + BIO_free(out); + ossl_raise(eX509ReqError, NULL); } return ossl_membio2str(out); @@ -146,11 +150,11 @@ ossl_x509req_to_der(VALUE self) GetX509Req(self, req); if ((len = i2d_X509_REQ(req, NULL)) <= 0) - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); str = rb_str_new(0, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_X509_REQ(req, &p) <= 0) - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); ossl_str_adjust(str, p); return str; @@ -164,11 +168,11 @@ ossl_x509req_to_text(VALUE self) GetX509Req(self, req); if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } if (!X509_REQ_print(out, req)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); + BIO_free(out); + ossl_raise(eX509ReqError, NULL); } return ossl_membio2str(out); @@ -187,7 +191,7 @@ ossl_x509req_to_x509(VALUE self, VALUE days, VALUE key) GetX509Req(self, req); ... if (!(x509 = X509_REQ_to_X509(req, d, pkey))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } return ossl_x509_new(x509); @@ -213,11 +217,11 @@ ossl_x509req_set_version(VALUE self, VALUE version) long ver; if ((ver = NUM2LONG(version)) < 0) { - ossl_raise(eX509ReqError, "version must be >= 0!"); + ossl_raise(eX509ReqError, "version must be >= 0!"); } GetX509Req(self, req); if (!X509_REQ_set_version(req, ver)) { - ossl_raise(eX509ReqError, "X509_REQ_set_version"); + ossl_raise(eX509ReqError, "X509_REQ_set_version"); } return version; @@ -231,7 +235,7 @@ ossl_x509req_get_subject(VALUE self) GetX509Req(self, req); if (!(name = X509_REQ_get_subject_name(req))) { /* NO DUP - don't free */ - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } return ossl_x509name_new(name); @@ -245,31 +249,32 @@ ossl_x509req_set_subject(VALUE self, VALUE subject) GetX509Req(self, req); /* DUPs name */ if (!X509_REQ_set_subject_name(req, GetX509NamePtr(subject))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } return subject; } +/* + * call-seq: + * req.signature_algorithm -> string + * + * Returns the signature algorithm used to sign this request. + * + * Returns the long name of the signature algorithm, or the dotted decimal + * notation if \OpenSSL does not define a long name for it. + */ static VALUE ossl_x509req_get_signature_algorithm(VALUE self) { X509_REQ *req; const X509_ALGOR *alg; - BIO *out; + const ASN1_OBJECT *obj; GetX509Req(self, req); - - if (!(out = BIO_new(BIO_s_mem()))) { - ossl_raise(eX509ReqError, NULL); - } X509_REQ_get0_signature(req, NULL, &alg); - if (!i2a_ASN1_OBJECT(out, alg->algorithm)) { - BIO_free(out); - ossl_raise(eX509ReqError, NULL); - } - - return ossl_membio2str(out); + X509_ALGOR_get0(&obj, NULL, NULL, alg); + return ossl_asn1obj_to_string_long_name(obj); } static VALUE @@ -280,10 +285,10 @@ ossl_x509req_get_public_key(VALUE self) GetX509Req(self, req); if (!(pkey = X509_REQ_get_pubkey(req))) { /* adds reference */ - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } - return ossl_pkey_new(pkey); /* NO DUP - OK */ + return ossl_pkey_wrap(pkey); } static VALUE @@ -296,7 +301,7 @@ ossl_x509req_set_public_key(VALUE self, VALUE key) pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); if (!X509_REQ_set_pubkey(req, pkey)) - ossl_raise(eX509ReqError, "X509_REQ_set_pubkey"); + ossl_raise(eX509ReqError, "X509_REQ_set_pubkey"); return key; } @@ -306,13 +311,14 @@ ossl_x509req_sign(VALUE self, VALUE key, VALUE digest) X509_REQ *req; EVP_PKEY *pkey; const EVP_MD *md; + VALUE md_holder; GetX509Req(self, req); pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ - md = ossl_evp_get_digestbyname(digest); - if (!X509_REQ_sign(req, pkey, md)) { - ossl_raise(eX509ReqError, NULL); - } + /* NULL needed for some key types, e.g. Ed25519 */ + md = NIL_P(digest) ? NULL : ossl_evp_md_fetch(digest, &md_holder); + if (!X509_REQ_sign(req, pkey, md)) + ossl_raise(eX509ReqError, "X509_REQ_sign"); return self; } @@ -331,12 +337,12 @@ ossl_x509req_verify(VALUE self, VALUE key) ossl_pkey_check_public_key(pkey); switch (X509_REQ_verify(req, pkey)) { case 1: - return Qtrue; + return Qtrue; case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; default: - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } } @@ -352,13 +358,13 @@ ossl_x509req_get_attributes(VALUE self) count = X509_REQ_get_attr_count(req); if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); + OSSL_Debug("count < 0???"); + return rb_ary_new(); } ary = rb_ary_new2(count); for (i=0; i<count; i++) { - attr = X509_REQ_get_attr(req, i); - rb_ary_push(ary, ossl_x509attr_new(attr)); + attr = X509_REQ_get_attr(req, i); + rb_ary_push(ary, ossl_x509attr_new(attr)); } return ary; @@ -374,17 +380,17 @@ ossl_x509req_set_attributes(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); for (i=0;i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Attr); } GetX509Req(self, req); - while ((attr = X509_REQ_delete_attr(req, 0))) - X509_ATTRIBUTE_free(attr); + for (i = X509_REQ_get_attr_count(req); i > 0; i--) + X509_ATTRIBUTE_free(X509_REQ_delete_attr(req, 0)); for (i=0;i<RARRAY_LEN(ary); i++) { - item = RARRAY_AREF(ary, i); - attr = GetX509AttrPtr(item); - if (!X509_REQ_add1_attr(req, attr)) { - ossl_raise(eX509ReqError, NULL); - } + item = RARRAY_AREF(ary, i); + attr = GetX509AttrPtr(item); + if (!X509_REQ_add1_attr(req, attr)) { + ossl_raise(eX509ReqError, "X509_REQ_add1_attr"); + } } return ary; } @@ -396,7 +402,7 @@ ossl_x509req_add_attribute(VALUE self, VALUE attr) GetX509Req(self, req); if (!X509_REQ_add1_attr(req, GetX509AttrPtr(attr))) { - ossl_raise(eX509ReqError, NULL); + ossl_raise(eX509ReqError, NULL); } return attr; @@ -408,12 +414,6 @@ ossl_x509req_add_attribute(VALUE self, VALUE attr) void Init_ossl_x509req(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509ReqError = rb_define_class_under(mX509, "RequestError", eOSSLError); cX509Req = rb_define_class_under(mX509, "Request", rb_cObject); diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index 5fe6853430..b88c390c72 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509rev_type, 0) #define SetX509Rev(obj, rev) do { \ if (!(rev)) { \ - ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (rev); \ } while (0) #define GetX509Rev(obj, rev) do { \ TypedData_Get_Struct((obj), X509_REVOKED, &ossl_x509rev_type, (rev)); \ if (!(rev)) { \ - ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "REV wasn't initialized!"); \ } \ } while (0) @@ -28,7 +28,7 @@ * Classes */ VALUE cX509Rev; -VALUE eX509RevError; +static VALUE eX509RevError; static void ossl_x509rev_free(void *ptr) @@ -39,9 +39,9 @@ ossl_x509rev_free(void *ptr) static const rb_data_type_t ossl_x509rev_type = { "OpenSSL/X509/REV", { - 0, ossl_x509rev_free, + 0, ossl_x509rev_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -54,14 +54,9 @@ ossl_x509revoked_new(X509_REVOKED *rev) VALUE obj; obj = NewX509Rev(cX509Rev); - if (!rev) { - new = X509_REVOKED_new(); - } else { - new = X509_REVOKED_dup(rev); - } - if (!new) { - ossl_raise(eX509RevError, NULL); - } + new = X509_REVOKED_dup(rev); + if (!new) + ossl_raise(eX509RevError, "X509_REVOKED_dup"); SetX509Rev(obj, new); return obj; @@ -74,7 +69,7 @@ DupX509RevokedPtr(VALUE obj) GetX509Rev(obj, rev); if (!(new = X509_REVOKED_dup(rev))) { - ossl_raise(eX509RevError, NULL); + ossl_raise(eX509RevError, NULL); } return new; @@ -91,7 +86,7 @@ ossl_x509revoked_alloc(VALUE klass) obj = NewX509Rev(klass); if (!(rev = X509_REVOKED_new())) { - ossl_raise(eX509RevError, NULL); + ossl_raise(eX509RevError, NULL); } SetX509Rev(obj, rev); @@ -105,6 +100,7 @@ ossl_x509revoked_initialize(int argc, VALUE *argv, VALUE self) return self; } +/* :nodoc: */ static VALUE ossl_x509revoked_initialize_copy(VALUE self, VALUE other) { @@ -116,7 +112,7 @@ ossl_x509revoked_initialize_copy(VALUE self, VALUE other) rev_new = X509_REVOKED_dup(rev_other); if (!rev_new) - ossl_raise(eX509RevError, "X509_REVOKED_dup"); + ossl_raise(eX509RevError, "X509_REVOKED_dup"); SetX509Rev(self, rev_new); X509_REVOKED_free(rev); @@ -143,8 +139,8 @@ ossl_x509revoked_set_serial(VALUE self, VALUE num) GetX509Rev(self, rev); asn1int = num_to_asn1integer(num, NULL); if (!X509_REVOKED_set_serialNumber(rev, asn1int)) { - ASN1_INTEGER_free(asn1int); - ossl_raise(eX509RevError, "X509_REVOKED_set_serialNumber"); + ASN1_INTEGER_free(asn1int); + ossl_raise(eX509RevError, "X509_REVOKED_set_serialNumber"); } ASN1_INTEGER_free(asn1int); @@ -160,7 +156,7 @@ ossl_x509revoked_get_time(VALUE self) GetX509Rev(self, rev); time = X509_REVOKED_get0_revocationDate(rev); if (!time) - return Qnil; + return Qnil; return asn1time_to_time(time); } @@ -174,8 +170,8 @@ ossl_x509revoked_set_time(VALUE self, VALUE time) GetX509Rev(self, rev); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_REVOKED_set_revocationDate(rev, asn1time)) { - ASN1_TIME_free(asn1time); - ossl_raise(eX509RevError, "X509_REVOKED_set_revocationDate"); + ASN1_TIME_free(asn1time); + ossl_raise(eX509RevError, "X509_REVOKED_set_revocationDate"); } ASN1_TIME_free(asn1time); @@ -194,14 +190,10 @@ ossl_x509revoked_get_extensions(VALUE self) GetX509Rev(self, rev); count = X509_REVOKED_get_ext_count(rev); - if (count < 0) { - OSSL_Debug("count < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(count); + ary = rb_ary_new_capa(count); for (i=0; i<count; i++) { - ext = X509_REVOKED_get_ext(rev, i); - rb_ary_push(ary, ossl_x509ext_new(ext)); + ext = X509_REVOKED_get_ext(rev, i); + rb_ary_push(ary, ossl_x509ext_new(ext)); } return ary; @@ -220,17 +212,17 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary) Check_Type(ary, T_ARRAY); for (i=0; i<RARRAY_LEN(ary); i++) { - OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); + OSSL_Check_Kind(RARRAY_AREF(ary, i), cX509Ext); } GetX509Rev(self, rev); - while ((ext = X509_REVOKED_delete_ext(rev, 0))) - X509_EXTENSION_free(ext); + for (i = X509_REVOKED_get_ext_count(rev); i > 0; i--) + X509_EXTENSION_free(X509_REVOKED_delete_ext(rev, 0)); for (i=0; i<RARRAY_LEN(ary); i++) { - item = RARRAY_AREF(ary, i); - ext = GetX509ExtPtr(item); - if(!X509_REVOKED_add_ext(rev, ext, -1)) { - ossl_raise(eX509RevError, NULL); - } + item = RARRAY_AREF(ary, i); + ext = GetX509ExtPtr(item); + if(!X509_REVOKED_add_ext(rev, ext, -1)) { + ossl_raise(eX509RevError, "X509_REVOKED_add_ext"); + } } return ary; @@ -243,7 +235,7 @@ ossl_x509revoked_add_extension(VALUE self, VALUE ext) GetX509Rev(self, rev); if (!X509_REVOKED_add_ext(rev, GetX509ExtPtr(ext), -1)) { - ossl_raise(eX509RevError, NULL); + ossl_raise(eX509RevError, NULL); } return ext; @@ -260,11 +252,11 @@ ossl_x509revoked_to_der(VALUE self) GetX509Rev(self, rev); len = i2d_X509_REVOKED(rev, NULL); if (len <= 0) - ossl_raise(eX509RevError, "i2d_X509_REVOKED"); + ossl_raise(eX509RevError, "i2d_X509_REVOKED"); str = rb_str_new(NULL, len); p = (unsigned char *)RSTRING_PTR(str); if (i2d_X509_REVOKED(rev, &p) <= 0) - ossl_raise(eX509RevError, "i2d_X509_REVOKED"); + ossl_raise(eX509RevError, "i2d_X509_REVOKED"); ossl_str_adjust(str, p); return str; } @@ -275,12 +267,6 @@ ossl_x509revoked_to_der(VALUE self) void Init_ossl_x509revoked(void) { -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - eX509RevError = rb_define_class_under(mX509, "RevokedError", eOSSLError); cX509Rev = rb_define_class_under(mX509, "Revoked", rb_cObject); diff --git a/ext/openssl/ossl_x509store.c b/ext/openssl/ossl_x509store.c index 2909eeda17..be1458cec5 100644 --- a/ext/openssl/ossl_x509store.c +++ b/ext/openssl/ossl_x509store.c @@ -5,7 +5,7 @@ */ /* * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) + * (See the file 'COPYING'.) */ #include "ossl.h" @@ -13,14 +13,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509store_type, 0) #define SetX509Store(obj, st) do { \ if (!(st)) { \ - ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (st); \ } while (0) #define GetX509Store(obj, st) do { \ TypedData_Get_Struct((obj), X509_STORE, &ossl_x509store_type, (st)); \ if (!(st)) { \ - ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "STORE wasn't initialized!"); \ } \ } while (0) @@ -28,14 +28,14 @@ TypedData_Wrap_Struct((klass), &ossl_x509stctx_type, 0) #define SetX509StCtx(obj, ctx) do { \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \ + ossl_raise(rb_eRuntimeError, "STORE_CTX wasn't initialized!"); \ } \ RTYPEDDATA_DATA(obj) = (ctx); \ } while (0) #define GetX509StCtx(obj, ctx) do { \ TypedData_Get_Struct((obj), X509_STORE_CTX, &ossl_x509stctx_type, (ctx)); \ if (!(ctx)) { \ - ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \ + ossl_raise(rb_eRuntimeError, "STORE_CTX is out of scope!"); \ } \ } while (0) @@ -52,10 +52,17 @@ struct ossl_verify_cb_args { }; static VALUE -call_verify_cb_proc(struct ossl_verify_cb_args *args) +ossl_x509stctx_new_i(VALUE arg) { + return ossl_x509stctx_new((X509_STORE_CTX *)arg); +} + +static VALUE +call_verify_cb_proc(VALUE arg) +{ + struct ossl_verify_cb_args *args = (struct ossl_verify_cb_args *)arg; return rb_funcall(args->proc, rb_intern("call"), 2, - args->preverify_ok, args->store_ctx); + args->preverify_ok, args->store_ctx); } int @@ -66,33 +73,33 @@ ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx) int state; if (NIL_P(proc)) - return ok; + return ok; ret = Qfalse; - rctx = rb_protect((VALUE(*)(VALUE))ossl_x509stctx_new, (VALUE)ctx, &state); + rctx = rb_protect(ossl_x509stctx_new_i, (VALUE)ctx, &state); if (state) { - rb_set_errinfo(Qnil); - rb_warn("StoreContext initialization failure"); + rb_set_errinfo(Qnil); + rb_warn("StoreContext initialization failure"); } else { - args.proc = proc; - args.preverify_ok = ok ? Qtrue : Qfalse; - args.store_ctx = rctx; - ret = rb_protect((VALUE(*)(VALUE))call_verify_cb_proc, (VALUE)&args, &state); - if (state) { - rb_set_errinfo(Qnil); - rb_warn("exception in verify_callback is ignored"); - } - RTYPEDDATA_DATA(rctx) = NULL; + args.proc = proc; + args.preverify_ok = ok ? Qtrue : Qfalse; + args.store_ctx = rctx; + ret = rb_protect(call_verify_cb_proc, (VALUE)&args, &state); + if (state) { + rb_set_errinfo(Qnil); + rb_warn("exception in verify_callback is ignored"); + } + RTYPEDDATA_DATA(rctx) = NULL; } if (ret == Qtrue) { - X509_STORE_CTX_set_error(ctx, X509_V_OK); - ok = 1; + X509_STORE_CTX_set_error(ctx, X509_V_OK); + ok = 1; } else { - if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) - X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); - ok = 0; + if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) + X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); + ok = 0; } return ok; @@ -101,9 +108,19 @@ ossl_verify_cb_call(VALUE proc, int ok, X509_STORE_CTX *ctx) /* * Classes */ -VALUE cX509Store; -VALUE cX509StoreContext; -VALUE eX509StoreError; +static VALUE cX509Store; +static VALUE cX509StoreContext; +static VALUE eX509StoreError; + +static void +ossl_x509store_mark(void *ptr) +{ + X509_STORE *store = ptr; + // Note: this reference is stored as @verify_callback so we don't need to mark it. + // However we do need to ensure GC compaction won't move it, hence why + // we call rb_gc_mark here. + rb_gc_mark((VALUE)X509_STORE_get_ex_data(store, store_ex_verify_cb_idx)); +} static void ossl_x509store_free(void *ptr) @@ -114,9 +131,9 @@ ossl_x509store_free(void *ptr) static const rb_data_type_t ossl_x509store_type = { "OpenSSL/X509/STORE", { - 0, ossl_x509store_free, + ossl_x509store_mark, ossl_x509store_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; /* @@ -142,10 +159,10 @@ x509store_verify_cb(int ok, X509_STORE_CTX *ctx) proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx); if (!proc) - proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx), - store_ex_verify_cb_idx); + proc = (VALUE)X509_STORE_get_ex_data(X509_STORE_CTX_get0_store(ctx), + store_ex_verify_cb_idx); if (!proc) - return ok; + return ok; return ossl_verify_cb_call(proc, ok, ctx); } @@ -157,9 +174,8 @@ ossl_x509store_alloc(VALUE klass) VALUE obj; obj = NewX509Store(klass); - if((store = X509_STORE_new()) == NULL){ - ossl_raise(eX509StoreError, NULL); - } + if ((store = X509_STORE_new()) == NULL) + ossl_raise(eX509StoreError, "X509_STORE_new"); SetX509Store(obj, store); return obj; @@ -174,8 +190,9 @@ ossl_x509store_set_vfy_cb(VALUE self, VALUE cb) X509_STORE *store; GetX509Store(self, store); - X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb); rb_iv_set(self, "@verify_callback", cb); + X509_STORE_set_ex_data(store, store_ex_verify_cb_idx, (void *)cb); + RB_OBJ_WRITTEN(self, Qundef, cb); return cb; } @@ -192,12 +209,9 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) { X509_STORE *store; -/* BUG: This method takes any number of arguments but appears to ignore them. */ GetX509Store(self, store); -#if !defined(HAVE_OPAQUE_OPENSSL) - /* [Bug #405] [Bug #1678] [Bug #3000]; already fixed? */ - store->ex_data.sk = NULL; -#endif + if (argc != 0) + rb_warn("OpenSSL::X509::Store.new does not take any arguments"); X509_STORE_set_verify_cb(store, x509store_verify_cb); ossl_x509store_set_vfy_cb(self, Qnil); @@ -205,7 +219,6 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) rb_iv_set(self, "@error", Qnil); rb_iv_set(self, "@error_string", Qnil); rb_iv_set(self, "@chain", Qnil); - rb_iv_set(self, "@time", Qnil); return self; } @@ -214,8 +227,16 @@ ossl_x509store_initialize(int argc, VALUE *argv, VALUE self) * call-seq: * store.flags = flags * - * Sets _flags_ to the Store. _flags_ consists of zero or more of the constants - * defined in with name V_FLAG_* or'ed together. + * Sets the default flags used by certificate chain verification performed with + * the Store. + * + * _flags_ consists of zero or more of the constants defined in OpenSSL::X509 + * with name V_FLAG_* or'ed together. + * + * OpenSSL::X509::StoreContext#flags= can be used to change the flags for a + * single verification operation. + * + * See also the man page X509_VERIFY_PARAM_set_flags(3). */ static VALUE ossl_x509store_set_flags(VALUE self, VALUE flags) @@ -233,9 +254,9 @@ ossl_x509store_set_flags(VALUE self, VALUE flags) * call-seq: * store.purpose = purpose * - * Sets the store's purpose to _purpose_. If specified, the verifications on - * the store will check every untrusted certificate's extensions are consistent - * with the purpose. The purpose is specified by constants: + * Sets the store's default verification purpose. If specified, + * the verifications on the store will check every certificate's extensions are + * consistent with the purpose. The purpose is specified by constants: * * * X509::PURPOSE_SSL_CLIENT * * X509::PURPOSE_SSL_SERVER @@ -246,6 +267,11 @@ ossl_x509store_set_flags(VALUE self, VALUE flags) * * X509::PURPOSE_ANY * * X509::PURPOSE_OCSP_HELPER * * X509::PURPOSE_TIMESTAMP_SIGN + * + * OpenSSL::X509::StoreContext#purpose= can be used to change the value for a + * single verification operation. + * + * See also the man page X509_VERIFY_PARAM_set_purpose(3). */ static VALUE ossl_x509store_set_purpose(VALUE self, VALUE purpose) @@ -262,6 +288,14 @@ ossl_x509store_set_purpose(VALUE self, VALUE purpose) /* * call-seq: * store.trust = trust + * + * Sets the default trust settings used by the certificate verification with + * the store. + * + * OpenSSL::X509::StoreContext#trust= can be used to change the value for a + * single verification operation. + * + * See also the man page X509_VERIFY_PARAM_set_trust(3). */ static VALUE ossl_x509store_set_trust(VALUE self, VALUE trust) @@ -279,12 +313,23 @@ ossl_x509store_set_trust(VALUE self, VALUE trust) * call-seq: * store.time = time * - * Sets the time to be used in verifications. + * Sets the time to be used in the certificate verifications with the store. + * By default, if not specified, the current system time is used. + * + * OpenSSL::X509::StoreContext#time= can be used to change the value for a + * single verification operation. + * + * See also the man page X509_VERIFY_PARAM_set_time(3). */ static VALUE ossl_x509store_set_time(VALUE self, VALUE time) { - rb_iv_set(self, "@time", time); + X509_STORE *store; + X509_VERIFY_PARAM *param; + + GetX509Store(self, store); + param = X509_STORE_get0_param(store); + X509_VERIFY_PARAM_set_time(param, NUM2LONG(rb_Integer(time))); return time; } @@ -295,33 +340,23 @@ ossl_x509store_set_time(VALUE self, VALUE time) * Adds the certificates in _file_ to the certificate store. _file_ is the path * to the file, and the file contains one or more certificates in PEM format * concatenated together. + * + * See also the man page X509_LOOKUP_file(3). */ static VALUE ossl_x509store_add_file(VALUE self, VALUE file) { X509_STORE *store; X509_LOOKUP *lookup; - char *path = NULL; + const char *path; - if(file != Qnil){ - rb_check_safe_obj(file); - path = StringValueCStr(file); - } GetX509Store(self, store); + path = StringValueCStr(file); lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); - if(lookup == NULL) ossl_raise(eX509StoreError, NULL); - if(X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1){ - ossl_raise(eX509StoreError, NULL); - } -#if OPENSSL_VERSION_NUMBER < 0x10101000 || defined(LIBRESSL_VERSION_NUMBER) - /* - * X509_load_cert_crl_file() which is called from X509_LOOKUP_load_file() - * did not check the return value of X509_STORE_add_{cert,crl}(), leaking - * "cert already in hash table" errors on the error queue, if duplicate - * certificates are found. This will be fixed by OpenSSL 1.1.1. - */ - ossl_clear_error(); -#endif + if (!lookup) + ossl_raise(eX509StoreError, "X509_STORE_add_lookup"); + if (X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM) != 1) + ossl_raise(eX509StoreError, "X509_LOOKUP_load_file"); return self; } @@ -331,24 +366,23 @@ ossl_x509store_add_file(VALUE self, VALUE file) * store.add_path(path) -> self * * Adds _path_ as the hash dir to be looked up by the store. + * + * See also the man page X509_LOOKUP_hash_dir(3). */ static VALUE ossl_x509store_add_path(VALUE self, VALUE dir) { X509_STORE *store; X509_LOOKUP *lookup; - char *path = NULL; + const char *path; - if(dir != Qnil){ - rb_check_safe_obj(dir); - path = StringValueCStr(dir); - } GetX509Store(self, store); + path = StringValueCStr(dir); lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); - if(lookup == NULL) ossl_raise(eX509StoreError, NULL); - if(X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1){ - ossl_raise(eX509StoreError, NULL); - } + if (!lookup) + ossl_raise(eX509StoreError, "X509_STORE_add_lookup"); + if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) + ossl_raise(eX509StoreError, "X509_LOOKUP_add_dir"); return self; } @@ -363,6 +397,8 @@ ossl_x509store_add_path(VALUE self, VALUE dir) * * * OpenSSL::X509::DEFAULT_CERT_FILE * * OpenSSL::X509::DEFAULT_CERT_DIR + * + * See also the man page X509_STORE_set_default_paths(3). */ static VALUE ossl_x509store_set_default_paths(VALUE self) @@ -370,18 +406,19 @@ ossl_x509store_set_default_paths(VALUE self) X509_STORE *store; GetX509Store(self, store); - if (X509_STORE_set_default_paths(store) != 1){ - ossl_raise(eX509StoreError, NULL); - } + if (X509_STORE_set_default_paths(store) != 1) + ossl_raise(eX509StoreError, "X509_STORE_set_default_paths"); return Qnil; } /* * call-seq: - * store.add_cert(cert) + * store.add_cert(cert) -> self * * Adds the OpenSSL::X509::Certificate _cert_ to the certificate store. + * + * See also the man page X509_STORE_add_cert(3). */ static VALUE ossl_x509store_add_cert(VALUE self, VALUE arg) @@ -391,9 +428,8 @@ ossl_x509store_add_cert(VALUE self, VALUE arg) cert = GetX509CertPtr(arg); /* NO NEED TO DUP */ GetX509Store(self, store); - if (X509_STORE_add_cert(store, cert) != 1){ - ossl_raise(eX509StoreError, NULL); - } + if (X509_STORE_add_cert(store, cert) != 1) + ossl_raise(eX509StoreError, "X509_STORE_add_cert"); return self; } @@ -403,6 +439,8 @@ ossl_x509store_add_cert(VALUE self, VALUE arg) * store.add_crl(crl) -> self * * Adds the OpenSSL::X509::CRL _crl_ to the store. + * + * See also the man page X509_STORE_add_crl(3). */ static VALUE ossl_x509store_add_crl(VALUE self, VALUE arg) @@ -412,9 +450,8 @@ ossl_x509store_add_crl(VALUE self, VALUE arg) crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */ GetX509Store(self, store); - if (X509_STORE_add_crl(store, crl) != 1){ - ossl_raise(eX509StoreError, NULL); - } + if (X509_STORE_add_crl(store, crl) != 1) + ossl_raise(eX509StoreError, "X509_STORE_add_crl"); return self; } @@ -447,7 +484,7 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "11", &cert, &chain); ctx = rb_funcall(cX509StoreContext, rb_intern("new"), 3, self, cert, chain); proc = rb_block_given_p() ? rb_block_proc() : - rb_iv_get(self, "@verify_callback"); + rb_iv_get(self, "@verify_callback"); rb_iv_set(ctx, "@verify_callback", proc); result = rb_funcall(ctx, rb_intern("verify"), 0); @@ -459,33 +496,37 @@ ossl_x509store_verify(int argc, VALUE *argv, VALUE self) } /* - * Public Functions - */ -static void ossl_x509stctx_free(void*); - - -static const rb_data_type_t ossl_x509stctx_type = { - "OpenSSL/X509/STORE_CTX", - { - 0, ossl_x509stctx_free, - }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, -}; - -/* * Private functions */ static void +ossl_x509stctx_mark(void *ptr) +{ + X509_STORE_CTX *ctx = ptr; + // Note: this reference is stored as @verify_callback so we don't need to mark it. + // However we do need to ensure GC compaction won't move it, hence why + // we call rb_gc_mark here. + rb_gc_mark((VALUE)X509_STORE_CTX_get_ex_data(ctx, stctx_ex_verify_cb_idx)); +} + +static void ossl_x509stctx_free(void *ptr) { X509_STORE_CTX *ctx = ptr; if (X509_STORE_CTX_get0_untrusted(ctx)) - sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free); + sk_X509_pop_free(X509_STORE_CTX_get0_untrusted(ctx), X509_free); if (X509_STORE_CTX_get0_cert(ctx)) - X509_free(X509_STORE_CTX_get0_cert(ctx)); + X509_free(X509_STORE_CTX_get0_cert(ctx)); X509_STORE_CTX_free(ctx); } +static const rb_data_type_t ossl_x509stctx_type = { + "OpenSSL/X509/STORE_CTX", + { + ossl_x509stctx_mark, ossl_x509stctx_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + static VALUE ossl_x509stctx_alloc(VALUE klass) { @@ -493,9 +534,8 @@ ossl_x509stctx_alloc(VALUE klass) VALUE obj; obj = NewX509StCtx(klass); - if((ctx = X509_STORE_CTX_new()) == NULL){ - ossl_raise(eX509StoreError, NULL); - } + if ((ctx = X509_STORE_CTX_new()) == NULL) + ossl_raise(eX509StoreError, "X509_STORE_CTX_new"); SetX509StCtx(obj, ctx); return obj; @@ -515,32 +555,40 @@ ossl_x509stctx_new(X509_STORE_CTX *ctx) static VALUE ossl_x509stctx_set_flags(VALUE, VALUE); static VALUE ossl_x509stctx_set_purpose(VALUE, VALUE); static VALUE ossl_x509stctx_set_trust(VALUE, VALUE); -static VALUE ossl_x509stctx_set_time(VALUE, VALUE); /* * call-seq: - * StoreContext.new(store, cert = nil, chain = nil) + * StoreContext.new(store, cert = nil, untrusted = nil) + * + * Sets up a StoreContext for a verification of the X.509 certificate _cert_. */ static VALUE ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) { - VALUE store, cert, chain, t; + VALUE store, cert, chain; X509_STORE_CTX *ctx; X509_STORE *x509st; X509 *x509 = NULL; STACK_OF(X509) *x509s = NULL; + int state; rb_scan_args(argc, argv, "12", &store, &cert, &chain); GetX509StCtx(self, ctx); GetX509Store(store, x509st); - if(!NIL_P(cert)) x509 = DupX509CertPtr(cert); /* NEED TO DUP */ - if(!NIL_P(chain)) x509s = ossl_x509_ary2sk(chain); - if(X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){ + if (!NIL_P(cert)) + x509 = DupX509CertPtr(cert); /* NEED TO DUP */ + if (!NIL_P(chain)) { + x509s = ossl_protect_x509_ary2sk(chain, &state); + if (state) { + X509_free(x509); + rb_jump_tag(state); + } + } + if (X509_STORE_CTX_init(ctx, x509st, x509, x509s) != 1){ + X509_free(x509); sk_X509_pop_free(x509s, X509_free); - ossl_raise(eX509StoreError, NULL); + ossl_raise(eX509StoreError, "X509_STORE_CTX_init"); } - if (!NIL_P(t = rb_iv_get(store, "@time"))) - ossl_x509stctx_set_time(self, t); rb_iv_set(self, "@verify_callback", rb_iv_get(store, "@verify_callback")); rb_iv_set(self, "@cert", cert); @@ -550,6 +598,10 @@ ossl_x509stctx_initialize(int argc, VALUE *argv, VALUE self) /* * call-seq: * stctx.verify -> true | false + * + * Performs the certificate verification using the parameters set to _stctx_. + * + * See also the man page X509_verify_cert(3). */ static VALUE ossl_x509stctx_verify(VALUE self) @@ -557,53 +609,51 @@ ossl_x509stctx_verify(VALUE self) X509_STORE_CTX *ctx; GetX509StCtx(self, ctx); - X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx, - (void *)rb_iv_get(self, "@verify_callback")); + VALUE cb = rb_iv_get(self, "@verify_callback"); + X509_STORE_CTX_set_ex_data(ctx, stctx_ex_verify_cb_idx, (void *)cb); + RB_OBJ_WRITTEN(self, Qundef, cb); switch (X509_verify_cert(ctx)) { case 1: - return Qtrue; + return Qtrue; case 0: - ossl_clear_error(); - return Qfalse; + ossl_clear_error(); + return Qfalse; default: - ossl_raise(eX509CertError, NULL); + ossl_raise(eX509StoreError, "X509_verify_cert"); } } /* * call-seq: - * stctx.chain -> Array of X509::Certificate + * stctx.chain -> nil | Array of X509::Certificate + * + * Returns the verified chain. + * + * See also the man page X509_STORE_CTX_set0_verified_chain(3). */ static VALUE ossl_x509stctx_get_chain(VALUE self) { X509_STORE_CTX *ctx; - STACK_OF(X509) *chain; - X509 *x509; - int i, num; - VALUE ary; + const STACK_OF(X509) *chain; GetX509StCtx(self, ctx); - if((chain = X509_STORE_CTX_get0_chain(ctx)) == NULL){ - return Qnil; - } - if((num = sk_X509_num(chain)) < 0){ - OSSL_Debug("certs in chain < 0???"); - return rb_ary_new(); - } - ary = rb_ary_new2(num); - for(i = 0; i < num; i++) { - x509 = sk_X509_value(chain, i); - rb_ary_push(ary, ossl_x509_new(x509)); - } - - return ary; + chain = X509_STORE_CTX_get0_chain(ctx); + if (!chain) + return Qnil; /* Could be an empty array instead? */ + return ossl_x509_sk2ary(chain); } /* * call-seq: * stctx.error -> Integer + * + * Returns the error code of _stctx_. This is typically called after #verify + * is done, or from the verification callback set to + * OpenSSL::X509::Store#verify_callback=. + * + * See also the man page X509_STORE_CTX_get_error(3). */ static VALUE ossl_x509stctx_get_err(VALUE self) @@ -618,6 +668,11 @@ ossl_x509stctx_get_err(VALUE self) /* * call-seq: * stctx.error = error_code + * + * Sets the error code of _stctx_. This is used by the verification callback + * set to OpenSSL::X509::Store#verify_callback=. + * + * See also the man page X509_STORE_CTX_set_error(3). */ static VALUE ossl_x509stctx_set_error(VALUE self, VALUE err) @@ -634,7 +689,10 @@ ossl_x509stctx_set_error(VALUE self, VALUE err) * call-seq: * stctx.error_string -> String * - * Returns the error string corresponding to the error code retrieved by #error. + * Returns the human readable error string corresponding to the error code + * retrieved by #error. + * + * See also the man page X509_verify_cert_error_string(3). */ static VALUE ossl_x509stctx_get_err_string(VALUE self) @@ -651,6 +709,10 @@ ossl_x509stctx_get_err_string(VALUE self) /* * call-seq: * stctx.error_depth -> Integer + * + * Returns the depth of the chain. This is used in combination with #error. + * + * See also the man page X509_STORE_CTX_get_error_depth(3). */ static VALUE ossl_x509stctx_get_err_depth(VALUE self) @@ -665,20 +727,32 @@ ossl_x509stctx_get_err_depth(VALUE self) /* * call-seq: * stctx.current_cert -> X509::Certificate + * + * Returns the certificate which caused the error. + * + * See also the man page X509_STORE_CTX_get_current_cert(3). */ static VALUE ossl_x509stctx_get_curr_cert(VALUE self) { X509_STORE_CTX *ctx; + X509 *x509; GetX509StCtx(self, ctx); + x509 = X509_STORE_CTX_get_current_cert(ctx); + if (!x509) + return Qnil; - return ossl_x509_new(X509_STORE_CTX_get_current_cert(ctx)); + return ossl_x509_new(x509); } /* * call-seq: * stctx.current_crl -> X509::CRL + * + * Returns the CRL which caused the error. + * + * See also the man page X509_STORE_CTX_get_current_crl(3). */ static VALUE ossl_x509stctx_get_curr_crl(VALUE self) @@ -689,7 +763,7 @@ ossl_x509stctx_get_curr_crl(VALUE self) GetX509StCtx(self, ctx); crl = X509_STORE_CTX_get0_current_crl(ctx); if (!crl) - return Qnil; + return Qnil; return ossl_x509crl_new(crl); } @@ -698,7 +772,10 @@ ossl_x509stctx_get_curr_crl(VALUE self) * call-seq: * stctx.flags = flags * - * Sets the verification flags to the context. See Store#flags=. + * Sets the verification flags to the context. This overrides the default value + * set by Store#flags=. + * + * See also the man page X509_VERIFY_PARAM_set_flags(3). */ static VALUE ossl_x509stctx_set_flags(VALUE self, VALUE flags) @@ -716,7 +793,10 @@ ossl_x509stctx_set_flags(VALUE self, VALUE flags) * call-seq: * stctx.purpose = purpose * - * Sets the purpose of the context. See Store#purpose=. + * Sets the purpose of the context. This overrides the default value set by + * Store#purpose=. + * + * See also the man page X509_VERIFY_PARAM_set_purpose(3). */ static VALUE ossl_x509stctx_set_purpose(VALUE self, VALUE purpose) @@ -733,6 +813,11 @@ ossl_x509stctx_set_purpose(VALUE self, VALUE purpose) /* * call-seq: * stctx.trust = trust + * + * Sets the trust settings of the context. This overrides the default value set + * by Store#trust=. + * + * See also the man page X509_VERIFY_PARAM_set_trust(3). */ static VALUE ossl_x509stctx_set_trust(VALUE self, VALUE trust) @@ -751,6 +836,8 @@ ossl_x509stctx_set_trust(VALUE self, VALUE trust) * stctx.time = time * * Sets the time used in the verification. If not set, the current time is used. + * + * See also the man page X509_VERIFY_PARAM_set_time(3). */ static VALUE ossl_x509stctx_set_time(VALUE self, VALUE time) @@ -772,19 +859,13 @@ void Init_ossl_x509store(void) { #undef rb_intern -#if 0 - mOSSL = rb_define_module("OpenSSL"); - eOSSLError = rb_define_class_under(mOSSL, "OpenSSLError", rb_eStandardError); - mX509 = rb_define_module_under(mOSSL, "X509"); -#endif - /* Register ext_data slot for verify callback Proc */ stctx_ex_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"stctx_ex_verify_cb_idx", 0, 0, 0); if (stctx_ex_verify_cb_idx < 0) - ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index"); + ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index"); store_ex_verify_cb_idx = X509_STORE_get_ex_new_index(0, (void *)"store_ex_verify_cb_idx", 0, 0, 0); if (store_ex_verify_cb_idx < 0) - ossl_raise(eOSSLError, "X509_STORE_get_ex_new_index"); + ossl_raise(eOSSLError, "X509_STORE_get_ex_new_index"); eX509StoreError = rb_define_class_under(mX509, "StoreError", eOSSLError); @@ -826,23 +907,37 @@ Init_ossl_x509store(void) cX509Store = rb_define_class_under(mX509, "Store", rb_cObject); /* * The callback for additional certificate verification. It is invoked for - * each untrusted certificate in the chain. + * each certificate in the chain and can be used to implement custom + * certificate verification conditions. * * The callback is invoked with two values, a boolean that indicates if the * pre-verification by OpenSSL has succeeded or not, and the StoreContext in - * use. The callback must return either true or false. + * use. + * + * The callback can use StoreContext#error= to change the error code as + * needed. The callback must return either true or false. + * + * NOTE: any exception raised within the callback will be ignored. + * + * See also the man page X509_STORE_CTX_set_verify_cb(3). */ rb_attr(cX509Store, rb_intern("verify_callback"), 1, 0, Qfalse); /* * The error code set by the last call of #verify. + * + * See also StoreContext#error. */ rb_attr(cX509Store, rb_intern("error"), 1, 0, Qfalse); /* * The description for the error code set by the last call of #verify. + * + * See also StoreContext#error_string. */ rb_attr(cX509Store, rb_intern("error_string"), 1, 0, Qfalse); /* * The certificate chain constructed by the last call of #verify. + * + * See also StoreContext#chain. */ rb_attr(cX509Store, rb_intern("chain"), 1, 0, Qfalse); rb_define_alloc_func(cX509Store, ossl_x509store_alloc); diff --git a/ext/openssl/ruby_missing.h b/ext/openssl/ruby_missing.h deleted file mode 100644 index 069acc8b14..0000000000 --- a/ext/openssl/ruby_missing.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 'OpenSSL for Ruby' project - * Copyright (C) 2001-2003 Michal Rokos <m.rokos@sh.cvut.cz> - * All rights reserved. - */ -/* - * This program is licensed under the same licence as Ruby. - * (See the file 'LICENCE'.) - */ -#if !defined(_OSSL_RUBY_MISSING_H_) -#define _OSSL_RUBY_MISSING_H_ - -/* Ruby 2.4 */ -#ifndef RB_INTEGER_TYPE_P -# define RB_INTEGER_TYPE_P(obj) (RB_FIXNUM_P(obj) || RB_TYPE_P(obj, T_BIGNUM)) -#endif - -/* Ruby 2.5 */ -#ifndef ST2FIX -# define RB_ST2FIX(h) LONG2FIX((long)(h)) -# define ST2FIX(h) RB_ST2FIX(h) -#endif - -#endif /* _OSSL_RUBY_MISSING_H_ */ |
