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: Added deallocate functions #36

Merged
merged 11 commits into from
Feb 27, 2019
Merged

fix: Added deallocate functions #36

merged 11 commits into from
Feb 27, 2019

Conversation

Andrew-Lees11
Copy link
Contributor

We had reports of a memory leak when using this repo on Linux.
I have tracked down places where we allocate memory and added deallocate functions to fix the leaks.

@Andrew-Lees11
Copy link
Contributor Author

This PR also fixes issue #8 to store the EVP key instead of the RSA key.

defer {
RSA_free(rsaKey)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This additional block exists now because we are storing the envelope key rather than the RSA key.

Changing the key to store the envelope key rather than the RSA key it contains is beneficial because the sign, verify and CBC decrypt functions no longer need to construct a new one (and copy the RSA key in), which should shorten their pathlength. (caveat: we did not benchmark this)

}

EVP_CIPHER_CTX_set_padding(rsaEncryptCtx, padding)

// Initialize the AES encryption key array (of size 1)
typealias UInt8Ptr = UnsafeMutablePointer<UInt8>?
var ek: UInt8Ptr
ek = UnsafeMutablePointer<UInt8>.allocate(capacity: Int(EVP_PKEY_size(evp_key)))
ek = UnsafeMutablePointer<UInt8>.allocate(capacity: Int(EVP_PKEY_size(.make(optional: key.reference))))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why this change is correct / necessary?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, I get it - key is (now) a pointer to an envelope key, so this is equivalent to what we had before


// Now that Init has initialized pkey_ctx, set the padding option
EVP_PKEY_CTX_ctrl(pkey_ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, padding, nil)
EVP_DigestSignInit(md_ctx, nil, .make(optional: md), nil, .make(optional: key.reference))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, as a note to other readers, we discovered through experimentation that the attempt to set the padding algorithm (that is being removed here) 1. fails to actually alter the padding used, and 2. causes the memory allocated by other openssl routines to be leaked.

The default padding algorithm is already RSA_PKCS1_PADDING, so there's no need to set it. Ideally we would be explicit about it (in case the default changes in the future) but for now, this achieves the same as the existing code and does not leak.

@Andrew-Lees11
Copy link
Contributor Author

We tested the leak by running signing,verifying encryption and decryption of a JWT. This produced the following memory report: leaks.txt which highlights leaks at:

evp_key = .init(PEM_read_bio_PUBKEY(bio, nil, nil, nil))

This was due to the evp_key not being properly freed after it was referenced by:

var pkey_ctx = EVP_PKEY_CTX_new(evp_key, nil)

(Mirrored for private key).

There were also minor leaks in encrypt and decrypt where allocated memory from pointers wasn't being deallocated.

The same tests now show no memory leaks with the changes from this PR.

@djones6
Copy link
Contributor

djones6 commented Feb 26, 2019

@billabt Would you be able to take a look at this and merge/tag if you are happy?

@Andrew-Lees11
Copy link
Contributor Author

Please squash and merge though since there are a fair amount of commits.

@billabt
Copy link
Collaborator

billabt commented Feb 26, 2019

I’ll take a look.

Copy link
Collaborator

@billabt billabt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes look good to me... I'm not going to worry about squashing them tho'...

@billabt billabt merged commit f2e3705 into master Feb 27, 2019
@djones6
Copy link
Contributor

djones6 commented Feb 27, 2019

@billabt The problem with not squash-merging is that the master branch history now has a bunch of intermediate commits in it. Github has a drop-down which lets you squash-merge rather than creating a merge commit (so it's trivial to do when merging). You don't lose the individual commits for the PR either - they are immortalised in the PR.

@billabt
Copy link
Collaborator

billabt commented Feb 27, 2019

Ok. I'll keep that in mind for future changes. Too late for this one.

@ianpartridge ianpartridge deleted the deallocate branch February 27, 2019 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants