From 06d67640e95b753be8ca7984cf1ecbdf598b2e75 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Thu, 29 Jun 2023 20:26:06 +0900 Subject: [DOC] prefer "password" to "passphrase" Let's consistently use the word "password". Although they are considered synonymous, the mixed usage in the rdoc can cause confusion. OpenSSL::KDF.scrypt is an exception. This is because RFC 7914 refers to the input parameter as "passphrase". --- ext/openssl/ossl.c | 20 ++++++++++---------- ext/openssl/ossl_kdf.c | 2 +- ext/openssl/ossl_pkey_rsa.c | 20 ++++++++++---------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 0ffb817f..08e1d57b 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -207,7 +207,7 @@ ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd_) while (1) { /* - * when the flag is nonzero, this passphrase + * when the flag is nonzero, this password * will be used to perform encryption; otherwise it will * be used to perform decryption. */ @@ -676,12 +676,12 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * * 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-256-cbc' - * pass_phrase = 'my secure pass phrase goes here' + * password = 'my secure password goes here' * - * key_secure = key.export cipher, pass_phrase + * key_secure = key.export cipher, password * * open 'private.secure.pem', 'w' do |io| * io.write key_secure @@ -705,13 +705,13 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * * === 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.read key4_pem, pass_phrase + * password = 'my secure password goes here' + * key4 = OpenSSL::PKey.read key4_pem, password * * == RSA Encryption * @@ -943,12 +943,12 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * 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-256-cbc' * * open 'ca_key.pem', 'w', 0400 do |io| - * io.write ca_key.export(cipher, pass_phrase) + * io.write ca_key.export(cipher, password) * end * * === CA Certificate diff --git a/ext/openssl/ossl_kdf.c b/ext/openssl/ossl_kdf.c index 0d25a730..48b161d4 100644 --- a/ext/openssl/ossl_kdf.c +++ b/ext/openssl/ossl_kdf.c @@ -21,7 +21,7 @@ static VALUE mKDF, eKDF; * (https://tools.ietf.org/html/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. diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index 072adabe..a9dce0d8 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -50,8 +50,8 @@ VALUE eRSAError; /* * call-seq: * RSA.new -> rsa - * RSA.new(encoded_key [, passphrase]) -> rsa - * RSA.new(encoded_key) { passphrase } -> rsa + * RSA.new(encoded_key [, password ]) -> rsa + * RSA.new(encoded_key) { password } -> rsa * RSA.new(size [, exponent]) -> rsa * * Generates or loads an \RSA keypair. @@ -61,9 +61,9 @@ VALUE eRSAError; * #set_crt_params. * * If called with a String, tries to parse as DER or PEM encoding of an \RSA key. - * Note that, if _passphrase_ is not specified but the key is encrypted with a - * passphrase, \OpenSSL will prompt for it. - * See also OpenSSL::PKey.read which can parse keys of any kinds. + * 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. * * If called with a number, generates a new key pair. This form works as an * alias of RSA.generate. @@ -71,7 +71,7 @@ VALUE eRSAError; * 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) @@ -217,11 +217,11 @@ can_export_rsaprivatekey(VALUE self) /* * 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 + * rsa.export([cipher, password]) => PEM-format String + * rsa.to_pem([cipher, password]) => PEM-format String + * rsa.to_s([cipher, password]) => PEM-format String * - * Outputs this keypair in PEM encoding. If _cipher_ and _pass_phrase_ are + * Outputs this keypair in PEM encoding. If _cipher_ and _password_ are * given they will be used to encrypt the key. _cipher_ must be an * OpenSSL::Cipher instance. */ -- cgit v1.2.3 From 56312038d66d3d94514891e69c7d1344a50f5852 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Wed, 28 Jun 2023 12:10:50 +0900 Subject: [DOC] prefer PKey#private_to_pem and #public_to_pem in RDoc Suggest the use of OpenSSL::PKey::PKey#private_to_pem and #public_to_pem in the top-level documentation. For new programs, these are recommended over OpenSSL::PKey::RSA#export (also aliased as #to_s and #to_pem) unless there is a specific reason to use it, i.e., unless the PKCS#1 output format specifically is required. The output format of OpenSSL::PKey::RSA#export depends on whether the key is a public key or a private key, which is very counter-intuitive. Additionally, when called with arguments to encrypt a private key, as in this example, OpenSSL's own, non-standard format is used. The man page of PEM_write_bio_PrivateKey_traditional(3) in OpenSSL 1.1.1 or later states that it "should only be used for compatibility with legacy programs". --- ext/openssl/ossl.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 08e1d57b..1b98d91e 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -669,8 +669,8 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * * 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 * @@ -681,11 +681,9 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * cipher = OpenSSL::Cipher.new 'aes-256-cbc' * password = 'my secure password goes here' * - * key_secure = key.export cipher, password + * 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. * @@ -945,10 +943,10 @@ ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2) * ca_key = OpenSSL::PKey::RSA.new 2048 * password = 'my secure password goes here' * - * cipher = OpenSSL::Cipher.new 'aes-256-cbc' + * cipher = 'aes-256-cbc' * * open 'ca_key.pem', 'w', 0400 do |io| - * io.write ca_key.export(cipher, password) + * io.write ca_key.private_to_pem(cipher, password) * end * * === CA Certificate -- cgit v1.2.3 From d22769af8f88a78dc2903c114e2010cfbf3d5b88 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Wed, 28 Jun 2023 12:09:27 +0900 Subject: [DOC] enhance RDoc for exporting pkeys Describe the behavior of OpenSSL::PKey::{DH,DSA,EC,RSA}#to_pem and #to_der more clearly. They return a different result depending on whether the pkey is a public or private key. This was not documented adequately. Also, suggest the use of OpenSSL::PKey::PKey#private_to_pem and #public_to_pem instead, if possible. --- ext/openssl/ossl_pkey.c | 18 ++++++++++++ ext/openssl/ossl_pkey_dh.c | 29 ++++++++++++++----- ext/openssl/ossl_pkey_dsa.c | 65 +++++++++++++++++++++++++++++++++++------ ext/openssl/ossl_pkey_ec.c | 70 ++++++++++++++++++++++++++++++++++++++++----- ext/openssl/ossl_pkey_rsa.c | 63 +++++++++++++++++++++++++++++++++++++--- 5 files changed, 219 insertions(+), 26 deletions(-) diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c index 9caeb562..1a0fbe69 100644 --- a/ext/openssl/ossl_pkey.c +++ b/ext/openssl/ossl_pkey.c @@ -809,6 +809,18 @@ ossl_pkey_private_to_der(int argc, VALUE *argv, VALUE self) * * 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) @@ -858,6 +870,12 @@ ossl_pkey_public_to_der(VALUE self) * 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) diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c index 83c41378..a231814a 100644 --- a/ext/openssl/ossl_pkey_dh.c +++ b/ext/openssl/ossl_pkey_dh.c @@ -216,9 +216,20 @@ 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) @@ -244,10 +255,14 @@ 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) diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c index b097f8c9..058ce738 100644 --- a/ext/openssl/ossl_pkey_dsa.c +++ b/ext/openssl/ossl_pkey_dsa.c @@ -211,16 +211,58 @@ 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. * + * 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 traditional \OpenSSL DSAPrivateKey. + * + * A PEM-encoded key will look like: + * + * -----BEGIN DSA PRIVATE KEY----- + * [...] + * -----END DSA PRIVATE KEY----- + * + * [When the key contains private components, and _cipher_ and _password_ are given] + * + * 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: + * + * -----BEGIN DSA PRIVATE KEY----- + * Proc-Type: 4,ENCRYPTED + * DEK-Info: AES-128-CBC,733F5302505B34701FC41F5C0746E4C0 + * + * [...] + * -----END DSA PRIVATE KEY----- + * + * Note that this format uses MD5 to derive the encryption key, and hence + * will not be available on FIPS-compliant systems. + * + * This method is kept for compatibility. + * 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_export(int argc, VALUE *argv, VALUE self) @@ -238,8 +280,15 @@ ossl_dsa_export(int argc, VALUE *argv, VALUE self) * call-seq: * dsa.to_der -> aString * - * Encodes this DSA to its DER encoding. + * Serializes a private or public key to a DER-encoding. + * + * See #to_pem for details. + * + * This method is kept for compatibility. + * 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_to_der(VALUE self) diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index 329c12d9..4b3a1fd0 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -400,13 +400,61 @@ static VALUE ossl_ec_key_is_private(VALUE self) /* * 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 * - * 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. + * 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 + * + * [...] + * -----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. + * + * This method is kept for compatibility. + * 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) @@ -426,7 +474,15 @@ ossl_ec_key_export(int argc, VALUE *argv, VALUE self) * call-seq: * key.to_der => String * - * See the OpenSSL documentation for i2d_ECPrivateKey_bio() + * Serializes a private or public key to a DER-encoding. + * + * See #to_pem for details. + * + * This method is kept for compatibility. + * This should only be used when the SEC 1/RFC 5915 ECPrivateKey format is + * required. + * + * Consider using #public_to_der or #private_to_der instead. */ static VALUE ossl_ec_key_to_der(VALUE self) diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c index a9dce0d8..389f76f3 100644 --- a/ext/openssl/ossl_pkey_rsa.c +++ b/ext/openssl/ossl_pkey_rsa.c @@ -221,9 +221,57 @@ can_export_rsaprivatekey(VALUE self) * rsa.to_pem([cipher, password]) => PEM-format String * rsa.to_s([cipher, password]) => PEM-format String * - * Outputs this keypair in PEM encoding. If _cipher_ and _password_ are - * given they will be used to encrypt the key. _cipher_ must be an - * OpenSSL::Cipher instance. + * 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 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. + * + * This method is kept for compatibility. + * 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_export(int argc, VALUE *argv, VALUE self) @@ -238,7 +286,14 @@ ossl_rsa_export(int argc, VALUE *argv, VALUE self) * call-seq: * rsa.to_der => DER-format String * - * Outputs this keypair in DER encoding. + * Serializes a private or public key to a DER-encoding. + * + * See #to_pem for details. + * + * This method is kept for compatibility. + * This should only be used when the PKCS #1 RSAPrivateKey format is required. + * + * Consider using #public_to_der or #private_to_der instead. */ static VALUE ossl_rsa_to_der(VALUE self) -- cgit v1.2.3