Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix memory leak in OpenSSL.crypto.dump_privatekey #496

Merged
merged 3 commits into from
Jul 3, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Deprecations:
Changes:
^^^^^^^^

- Fix memory leak in ``OpenSSL.crypto.dump_privatekey()`` with ``FILETYPE_TEXT``.
`#496 <https://github.com/pyca/pyopenssl/pull/496>`_
- Enable use of CRL (and more) in verify context.
`#483 <https://github.com/pyca/pyopenssl/pull/483>`_

Expand Down
9 changes: 1 addition & 8 deletions doc/api/crypto.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,7 @@ Certificate signing requests
Private keys
~~~~~~~~~~~~

.. py:function:: dump_privatekey(type, pkey[, cipher, passphrase])

Dump the private key *pkey* into a buffer string encoded with the type
*type*, optionally (if *type* is :py:const:`FILETYPE_PEM`) encrypting it
using *cipher* and *passphrase*.

*passphrase* must be either a string or a callback for providing the
pass phrase.
.. autofunction:: dump_privatekey

.. py:function:: load_privatekey(type, buffer[, passphrase])

Expand Down
28 changes: 15 additions & 13 deletions src/OpenSSL/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -1698,16 +1698,17 @@ def dump_publickey(type, pkey):

def dump_privatekey(type, pkey, cipher=None, passphrase=None):
"""
Dump a private key to a buffer

:param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1, or
FILETYPE_TEXT)
:param pkey: The PKey to dump
:param cipher: (optional) if encrypted PEM format, the cipher to
use
Dump the private key *pkey* into a buffer string encoded with the type
*type*. Optionally (if *type* is :const:`FILETYPE_PEM`) encrypting it
using *cipher* and *passphrase*.

:param type: The file type (one of :const:`FILETYPE_PEM`,
:const:`FILETYPE_ASN1`, or :const:`FILETYPE_TEXT`)
:param PKey pkey: The PKey to dump
:param cipher: (optional) if encrypted PEM format, the cipher to use
:param passphrase: (optional) if encrypted PEM format, this can be either
the passphrase to use, or a callback for providing the
passphrase.
the passphrase to use, or a callback for providing the passphrase.

:return: The buffer with the dumped key in
:rtype: bytes
"""
Expand All @@ -1733,16 +1734,17 @@ def dump_privatekey(type, pkey, cipher=None, passphrase=None):
elif type == FILETYPE_ASN1:
result_code = _lib.i2d_PrivateKey_bio(bio, pkey._pkey)
elif type == FILETYPE_TEXT:
rsa = _lib.EVP_PKEY_get1_RSA(pkey._pkey)
rsa = _ffi.gc(
_lib.EVP_PKEY_get1_RSA(pkey._pkey),
_lib.RSA_free
)
result_code = _lib.RSA_print(bio, rsa, 0)
# TODO RSA_free(rsa)?
else:
raise ValueError(
"type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
"FILETYPE_TEXT")

if result_code == 0:
_raise_current_error()
_openssl_assert(result_code != 0)

return _bio_to_string(bio)

Expand Down