Skip to content

Commit

Permalink
Merge pull request #645 from rhenium/ky/pkey-document-traditional-pem
Browse files Browse the repository at this point in the history
[DOC] enhance RDoc for exporting pkeys
  • Loading branch information
rhenium authored Aug 16, 2023
2 parents 8ac40ba + d22769a commit 6588fad
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 52 deletions.
30 changes: 14 additions & 16 deletions ext/openssl/ossl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -674,23 +674,21 @@ 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
*
* 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.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.
*
Expand All @@ -710,13 +708,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
*
Expand Down Expand Up @@ -909,12 +907,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'
* 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
Expand Down
2 changes: 1 addition & 1 deletion ext/openssl/ossl_kdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
18 changes: 18 additions & 0 deletions ext/openssl/ossl_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,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)
Expand Down Expand Up @@ -953,6 +965,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)
Expand Down
29 changes: 22 additions & 7 deletions ext/openssl/ossl_pkey_dh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
65 changes: 57 additions & 8 deletions ext/openssl/ossl_pkey_dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
* <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_export(int argc, VALUE *argv, VALUE self)
Expand All @@ -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.
*
* <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_to_der(VALUE self)
Expand Down
70 changes: 63 additions & 7 deletions ext/openssl/ossl_pkey_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
* <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)
Expand All @@ -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.
*
* <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_der or #private_to_der instead.
*/
static VALUE
ossl_ec_key_to_der(VALUE self)
Expand Down
Loading

0 comments on commit 6588fad

Please sign in to comment.