aboutsummaryrefslogtreecommitdiffstats
path: root/ext/openssl/ossl_pkey.c
Commit message (Collapse)AuthorAgeFilesLines
* Add support for raw private/public keys (#646)Ryo Kajiwara2023-07-121-0/+132
| | | | | | | | | | | Add OpenSSL::PKey.new_raw_private_key, #raw_private_key and public equivalents. These methods are useful for importing and exporting keys that support "raw private/public key". Currently, OpenSSL implements X25519/X448 and Ed25519/Ed448 keys. [rhe: rewrote commit message] Co-authored-by: Bart de Water <bartdewater@gmail.com>
* pkey: use unsigned type for bit fieldsky/pkey-fix-warning-single-bit-bitfield-constant-conversionKazuki Yamaguchi2023-06-071-3/+3
| | | | | | | | | clang generates a warning: ../../../../ext/openssl/ossl_pkey.c:326:22: error: implicit truncation from 'int' to a one-bit wide bit-field changes value from 1 to -1 [-Werror,-Wsingle-bit-bitfield-constant-conversion] arg->interrupted = 1; ^ ~ 1 error generated.
* Merge pull request #604 from casperisfine/ssl-write-barrierKazuki Yamaguchi2023-06-021-1/+1
|\ | | | | Implement Write Barrier for all OpenSSL types
| * Implement Write Barrier for all OpenSSL typesJean Boussier2023-06-011-1/+1
| | | | | | | | | | | | | | The vast majority have no reference so it's just a matter of setting the flags. For the couple exception, they have very little references so it's easy.
* | Workaround: Fix OpenSSL::PKey.read that cannot parse PKey in the FIPS mode.Jun Aruga2023-06-011-5/+21
|/ | | | | | | | | | | | | | | | | | | | | This commit is a workaround to avoid the error below that the `OpenSSL::PKey.read` fails with the OpenSSL 3.0 FIPS mode. ``` $ openssl genrsa -out key.pem 4096 $ ruby -e "require 'openssl'; OpenSSL::PKey.read(File.read('key.pem'))" -e:1:in `read': Could not parse PKey (OpenSSL::PKey::PKeyError) from -e:1:in `<main>' ``` The root cause is on the OpenSSL side. The `OSSL_DECODER_CTX_set_selection` doesn't apply the selection value properly if there are multiple providers, and a provider (e.g. "base" provider) handles the decoder implementation, and another provider (e.g. "fips" provider) handles the keys. The workaround is to create `OSSL_DECODER_CTX` variable each time without using the `OSSL_DECODER_CTX_set_selection`.
* Use EVP_Digest{Sign,Verify} when availableTheo Buehler2022-11-231-2/+2
| | | | | | LibreSSL 3.4 added EVP_DigestSign() and EVP_DigestVerify(). Use them when available to prepare for the addition of Ed25519 support in LibreSSL 3.7.
* Merge branch 'maint-3.0'Kazuki Yamaguchi2022-09-081-3/+43
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * maint-3.0: Ruby/OpenSSL 3.0.1 Ruby/OpenSSL 2.2.2 Ruby/OpenSSL 2.1.4 Make GitHub Actions happy on 2.1/2.2 branches test/openssl/test_cipher: skip AES-CCM tests on OpenSSL <= 1.1.1b pkey/ec: check existence of public key component before exporting pkey: restore support for decoding "openssl ecparam -genkey" output pkey: clear error queue before each OSSL_DECODER_from_bio() call pkey/dsa: let PKey::DSA.generate choose appropriate q size hmac: use EVP_PKEY_new_raw_private_key() if available x509*: fix error queue leak in #extensions= and #attributes= methods Check if the option is an Hash in `pkey_ctx_apply_options0()`
| * Merge pull request #540 from rhenium/ky/pkey-read-prefer-keysKazuki Yamaguchi2022-09-081-3/+42
| |\ | | | | | | pkey: restore support for decoding "openssl ecparam -genkey" output
| | * pkey: restore support for decoding "openssl ecparam -genkey" outputky/pkey-read-prefer-keysKazuki Yamaguchi2022-09-021-0/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Scan through the input for a private key, then fallback to generic decoder. OpenSSL 3.0's OSSL_DECODER supports encoded key parameters. The PEM header "-----BEGIN EC PARAMETERS-----" is used by one of such encoding formats. While this is useful for OpenSSL::PKey::PKey, an edge case has been discovered. The openssl CLI command line "openssl ecparam -genkey" prints two PEM blocks in a row, one for EC parameters and another for the private key. Feeding the whole output into OSSL_DECODER results in only the first PEM block, the key parameters, being decoded. Previously, ruby/openssl did not support decoding key parameters and it would decode the private key PEM block instead. While the new behavior is technically correct, "openssl ecparam -genkey" is so widely used that ruby/openssl does not want to break existing applications. Fixes https://github.com/ruby/openssl/pull/535
| | * pkey: clear error queue before each OSSL_DECODER_from_bio() callKazuki Yamaguchi2022-09-021-4/+7
| | | | | | | | | | | | Fix potential error queue leak.
| * | Check if the option is an Hash in `pkey_ctx_apply_options0()`Nobuhiro IMAI2022-08-081-0/+1
| |/ | | | | | | causes SEGV if it is an Array or something like that.
* / Fix build with LibreSSL 3.5Jeremy Evans2022-04-011-1/+1
|/
* pkey: use EVP_PKEY_CTX_new_from_name() on OpenSSL 3.0Kazuki Yamaguchi2021-12-201-0/+6
| | | | | Replace EVP_PKEY_CTX_new_id() with the new EVP_PKEY_CTX_new_from_name() which takes the algorithm name in a string instead of in an NID.
* pkey: assume a pkey always has public key components on OpenSSL 3.0Kazuki Yamaguchi2021-12-201-0/+11
| | | | | | | | | OpenSSL 3.0's EVP_PKEY_get0() returns NULL for provider-backed pkeys. This causes segfault because it was supposed to never return NULL before. We can't check the existence of public key components in this way on OpenSSL 3.0. Let's just skip it for now.
* engine: disable OpenSSL::Engine on OpenSSL 3.0Kazuki Yamaguchi2021-12-201-0/+4
| | | | | | | | | | The entire ENGINE API is deprecated in OpenSSL 3.0 in favor of the new "Provider" concept. OpenSSL::Engine will not be defined when compiled with OpenSSL 3.0. We would need a way to interact with providers from Ruby programs, but since the concept is completely different from the ENGINE API, it will not be through the current OpenSSL::Engine interface.
* Merge pull request #478 from rhenium/ky/pkey-base-dupKazuki Yamaguchi2021-12-121-17/+29
|\ | | | | pkey: allocate EVP_PKEY on #initialize
| * pkey: use EVP_PKEY_dup() if availableky/pkey-base-dupKazuki Yamaguchi2021-12-121-0/+25
| | | | | | | | | | We can use it to implement OpenSSL::PKey::PKey#initialize_copy. This should work on all key types, not just DH/DSA/EC/RSA types.
| * pkey: allocate EVP_PKEY on #initializeKazuki Yamaguchi2021-12-121-12/+3
| | | | | | | | | | | | | | Allocate an EVP_PKEY when the content is ready: when #initialize or #initialize_copy is called, rather than when a T_DATA is allocated. This is more natural because the lower level API has been deprecated and an EVP_PKEY is becoming the minimum unit of handling keys.
| * pkey: do not check NULL argument in ossl_pkey_new()Kazuki Yamaguchi2021-12-121-5/+1
| | | | | | | | | | Passing NULL to ossl_pkey_new() makes no sense in the first place, and in fact it is ensured not to be NULL in all cases.
* | pkey: use OSSL_DECODER to load encrypted PEM on OpenSSL 3.0ky/pkey-ossl-decoderKazuki Yamaguchi2021-12-121-0/+40
|/ | | | | | | | | | | | | | OpenSSL 3.0 has rewritten routines to load pkeys (PEM_read_bio_* and d2i_* functions) around the newly introduced OSSL_DECODER API. This comes with a slight behavior change. They now decrypt and parse each encountered PEM block, then check the kind of the block. This used to be the reverse: they checked the PEM header to see the kind, and then decrypted the content. This means that the password callback may now be called repeatedly. Let's use the OSSL_DECODER API directly on OpenSSL 3.0 so that the return value from the password callback will be reused automatically.
* pkey, ssl: use EVP_PKEY_eq() instead of EVP_PKEY_cmp()Kazuki Yamaguchi2021-10-241-2/+2
| | | | | OpenSSL 3.0 renamed EVP_PKEY_cmp() to EVP_PKEY_eq() because that was a confusing name.
* Suppress cast-function-type warningsNobuyoshi Nakada2021-09-121-2/+3
|
* pkey: implement PKey#sign_raw, #verify_raw, and #verify_recoverKazuki Yamaguchi2021-05-251-0/+232
| | | | | | | | | | | | | Add a variant of PKey#sign and #verify that do not hash the data automatically. Sometimes the caller has the hashed data only, but not the plaintext to be signed. In that case, users would have to use the low-level API such as RSA#private_encrypt or #public_decrypt directly. OpenSSL 1.0.0 and later supports EVP_PKEY_sign() and EVP_PKEY_verify() which provide the same functionality as part of the EVP API. This patch adds wrappers for them.
* pkey: update version reference in #sign and #verify documentationKazuki Yamaguchi2021-05-251-2/+2
| | | | The next release is decided to be 3.0 rather than 2.3.
* pkey: implement PKey#encrypt and #decryptKazuki Yamaguchi2021-05-251-0/+141
| | | | | Support public key encryption and decryption operations using the EVP API.
* pkey: implement #to_text using EVP APIKazuki Yamaguchi2021-04-151-0/+38
| | | | | | | | | | | | | | | | Use EVP_PKEY_print_private() instead of the low-level API *_print() functions, such as RSA_print(). EVP_PKEY_print_*() family was added in OpenSSL 1.0.0. Note that it falls back to EVP_PKEY_print_public() and EVP_PKEY_print_params() as necessary. This is required for EVP_PKEY_DH type for which _private() fails if the private component is not set in the pkey object. Since the new API works in the same way for all key types, we now implement #to_text in the base class OpenSSL::PKey::PKey rather than in each subclass.
* Merge pull request #397 from rhenium/ky/pkey-refactor-generateKazuki Yamaguchi2021-04-051-63/+28
|\ | | | | pkey: use high level EVP interface to generate parameters and keys
| * pkey: remove unused ossl_generate_cb_2() helper functionky/pkey-refactor-generateKazuki Yamaguchi2021-04-051-58/+15
| | | | | | | | | | | | The previous series of commits re-implemented key generation with the low level API with the EVP API. The BN_GENCB-based callback function is no longer used.
| * pkey: fix interrupt handling in OpenSSL::PKey.generate_keyKazuki Yamaguchi2021-04-051-5/+13
| | | | | | | | | | | | rb_thread_call_without_gvl() can be interrupted, but it may be able to resume the operation. Call rb_thread_check_ints() to see if it raises an exception or not.
* | pkey: allow setting algorithm-specific options in #sign and #verifyky/pkey-sign-verify-optionsKazuki Yamaguchi2021-04-041-38/+75
| | | | | | | | | | | | Similarly to OpenSSL::PKey.generate_key and .generate_parameters, let OpenSSL::PKey::PKey#sign and #verify take an optional parameter for specifying control strings for EVP_PKEY_CTX_ctrl_str().
* | pkey: prepare pkey_ctx_apply_options() for usage by other operationsKazuki Yamaguchi2021-04-041-8/+14
| | | | | | | | | | | | The routine to apply Hash to EVP_PKEY_CTX_ctrl_str() is currently used by key generation, but it is useful for other operations too. Let's change it to a slightly more generic name.
* | pkey: fix potential memory leak in PKey#signKazuki Yamaguchi2021-04-041-2/+6
|/ | | | | | Fix potential leak of EVP_MD_CTX object in an error path. This path is normally unreachable, since the size of a signature generated by any supported algorithms would not be larger than LONG_MAX.
* [DOC] Fix RDoc markupNobuhiro IMAI2020-07-291-1/+1
|
* Add compare? method to OpenSSL::PKey that wraps EVP_PKEY_cmp.Colton Jenkins2020-07-141-0/+39
| | | | | | Explicitly check for type given some conflicting statements within openssl's documentation around EVP_PKEY_cmp and EVP_PKEY_ASN1_METHOD(3). Add documentation with an example for compare?
* Merge pull request #329 from rhenium/ky/pkey-generic-operationsKazuki Yamaguchi2020-05-131-43/+366
|\ | | | | pkey: add more support for 'generic' pkey types
| * pkey: add PKey::PKey#deriveKazuki Yamaguchi2020-05-131-0/+52
| | | | | | | | | | | | Add OpenSSL::PKey::PKey#derive as the wrapper for EVP_PKEY_CTX_derive(). This is useful for pkey types that we don't have dedicated classes, such as X25519.
| * pkey: support 'one-shot' signing and verificationKazuki Yamaguchi2020-05-131-0/+30
| | | | | | | | | | | | OpenSSL 1.1.1 added EVP_DigestSign() and EVP_DigestVerify() functions to the interface. Some EVP_PKEY methods such as PureEdDSA algorithms do not support the streaming mechanism and require us to use them.
| * pkey: port PKey::PKey#sign and #verify to the EVP_Digest* interfaceKazuki Yamaguchi2020-05-131-39/+51
| | | | | | | | | | | | | | | | | | Use EVP_DigestSign*() and EVP_DigestVerify*() interface instead of the old EVP_Sign*() and EVP_Verify*() functions. They were added in OpenSSL 1.0.0. Also, allow the digest to be specified as nil, as certain EVP_PKEY types don't expect a digest algorithm.
| * pkey: add PKey.generate_parameters and .generate_keyKazuki Yamaguchi2020-05-131-0/+222
| | | | | | | | | | Add two methods to create a PKey using the generic EVP interface. This is useful for the PKey types we don't have a dedicated class.
| * pkey: assume generic PKeys contain private componentsKazuki Yamaguchi2020-05-131-4/+11
| | | | | | | | | | | | The EVP interface cannot tell whether if a pkey contains the private components or not. Assume it does if it does not respond to #private?. This fixes the NoMethodError on calling #sign on a generic PKey.
* | pkey: refactor #export/#to_pem and #to_derky/pkey-refactor-serializationKazuki Yamaguchi2020-05-131-4/+50
| | | | | | | | | | Add ossl_pkey_export_traditional() and ossl_pkey_export_spki() helper functions, and use them. This reduces code duplication.
* | pkey: refactor DER/PEM-encoded string parsing codeKazuki Yamaguchi2020-05-131-25/+32
| | | | | | | | | | Export the flow used by OpenSSL::PKey.read and let the subclasses call it before attempting other formats.
* | pkey: have PKey.read parse PEM-encoded DHParameterKazuki Yamaguchi2020-05-131-0/+3
| | | | | | | | | | Try PEM_read_bio_Parameters(). Only PEM format is supported at the moment since corresponding d2i_* functions are not provided by OpenSSL.
* | pkey: simplify ossl_pkey_new()Kazuki Yamaguchi2020-05-131-13/+9
|/ | | | | | ossl_{rsa,dsa,dh,ec}_new() called from this function are not used anywhere else. Inline them into pkey_new0() and reduce code duplication.
* pkey: add PKey#inspect and #oidKazuki Yamaguchi2020-04-211-0/+38
| | | | | | | | | | | Implement OpenSSL::PKey::PKey#oid as a wrapper around EVP_PKEY_id(). This allows user code to check the type of a PKey object. EVP_PKEY can have a pkey type for which we do not provide a dedicated subclass. In other words, an EVP_PKEY that is not any of {RSA,DSA,DH,EC} can exist. It is currently not possible to distinguish such a pkey. Also, implement PKey#inspect to include the key type for convenience.
* Look up digest by name instead of constantBart de Water2020-04-211-2/+2
|
* pkey: add support for PKCS #8 key serializationKazuki Yamaguchi2019-11-251-12/+140
| | | | | | | | | | | | OpenSSL::PKey::PKey#private_to_der, #private_to_pem are added to the generic PKey class. They serialize the private key to PKCS #8 {Encrypted,}PrivateKeyInfo format, in DER- and PEM- encoding, respectively. For symmetry, also add #public_to_der and #public_to_pem that serialize the public key into X.509 SubjectPublicKeyInfo format. OpenSSL::PKey.read now reads DER-encoded PKCS #8 keys as well as the "raw" private keys. PEM-encoded PKCS #8 keys have been already handled by PEM_read_bio_PrivateKey().
* Merge branch 'maint-2.0' into maintKazuki Yamaguchi2018-08-081-3/+26
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | The fix made in 6fcc6c0efc42 ("test/test_ssl: fix test failure with TLS 1.3", 2018-08-06) is applied to the new test cases. * maint-2.0: reduce LibreSSL warnings openssl_missing.h: constified openssl: search winsock search winsock libraries explicitly no ID cache in Init functions test/test_ssl: fix test failure with TLS 1.3 tool/ruby-openssl-docker: update to latest versions pkey: resume key generation after interrupt
| * Merge pull request #205 from rhenium/ky/pkey-generate-interrupt-resumeKazuki Yamaguchi2018-08-081-3/+25
| |\ | | | | | | pkey: resume key generation after interrupt [Bug #14882]
| | * pkey: resume key generation after interruptky/pkey-generate-interrupt-resumeKazuki Yamaguchi2018-07-271-3/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Key/parameter generation (OpenSSL::PKey::*.{new,generate}) immediately aborts when it is done with GVL released (in other words, no block is given) and the thread is interrupted (e.g., by a signal) during the operation. Have ossl_generate_cb_2() acquire GVL and call rb_thread_check_ints() if needed to process the pending interrupt rather than abort the operation completely by returning 0. Reference: https://bugs.ruby-lang.org/issues/14882