Closed bararchy closed 6 years ago
There's this but it's outdated. I've been upgrading it every Crystal release on my computer because I need it for a project of mine but I don't have enough knowledge on the subject to keep a public updated fork.
@Exilor we had this open: https://github.com/crystal-lang/crystal/issues/1710 And it seemed that it just fizzled.
Maybe we should fork it and PR it to the main Crystal repo, as in addition to OpenSSL and not as an external shard
@bararchy I agree but as I said I'm not knowledgeable with this so I can't be of much help :/
For instance, OpenSSL::MemBIO is a struct defining a #finalize
which is not currently allowed. I changed it to a class and it does the job but that's just me fiddling with the code until it works. But I don't know why it was a struct in the first place or if memory will leak if it's a class.
If you feel able then by all means go ahead (if asterite is ok with it).
@Exilor If @datanoise was still around we could ask him technical details, TBH , I , like you , am not that knowledgeable in regards to the small details of C-Crystal bindings and structures of types, I guess we need someone to "keep an eye" on those commits\PR's and make sure that if we change stuff it's not bad.
You may look at the Ruby API (not the implementation) but also the OpenSSL C API, see how they are different or similar, then try to implement the features. Keep in mind that macOS still ships with OpenSSL v0.9.8 and many Linux LTS releases ship OpenSSL v1.0.x; some features may not always be available.
Linking to C isn't complex. You may use crystal_lib to generate the initial bindings for example. Constants, enums, structs and functions will be generated automatically from C headers. You'll may want to clean them up, thought, because C uses so much aliases and defines that the generated bindings are usually not pretty.
Once you have them, you merely call the lib functions. If you receive a pointer to a C struct, you most likely will have to free it, using a special OpenSSL function to achieve so. You need a class
and a #finalize
method for that, because Crystal struct
are allocated on the stack and the GC won't collect them (i.e. memory leak) and thus will never call #finalize
—hence why it's now forbidden on struct
.
Make sure to never expose raw C pointers, except through #to_unsafe
. Always verify that a returned pointer isn't a null
pointer, then either raise
or return nil
depending on the situation.
If you need to allocate a C struct on the stack (unlikely) you may x = uninitialized LibSSL::MyStruct
or x = LibSSL::MyStruct
; if you must allocate a struct and return it, allocate heap memory, you may ptr = Pointer(LibSSL::MyStruct).allocate
.
And that's about it. If you're unsure about what API to create, you may open an issue first.
If it's enough pain to support multiple OpenSSL versions, possibly crystal could just bundle "a good version" and require its compilation and use if the local installed one is out of date or what not? Just thinking out loud :)
No. OpenSSL is big and flawed. We must let official packagers deal with that.
@ysbaddaden Good idea about using the crystal_lib, sadly it seems not to work (crashes on the exmaples) , I opened a ticket.
@ysbaddaden your answer should be put in C bindings section
Please feel free to copy-paste, rephrase a bit and open a pull request :-)
Hey, I'm completely new to Crystal but really need RSA support in the stdlib. I've written this using the Ruby API (minus all the aliases) and the datanoise library mentioned above as inspiration.
There is only one flaw I can find so far and that is that I can't seem to write out the RSA priv/pub key to a .pem file when using a passphrase. Reading in seems fine - if anyone is able to help with that at all that would be greatly appreciated as openssl doesn't throw any errors on my machine for this.
Since I'm completely new, I am not 100% sure about the naming conventions, presentation etc when contributing to the stdlib. Is anyone able to skim over my fork before I submit a PR?
https://github.com/crystal-lang/crystal/compare/master...randomstate:feature/openssl-rsa?expand=1
Thanks 👍
@CImrie It's probably best if you open a PR anyway (tagged as [WIP]
) so it's easier for others to review your code and comment on it.
@straight-shoota Thanks, I've opened one 👍
Closing this as it was discussed it would be handled in an outside shard
I think that a big part missing in the OpenSSL lib is the RSA and Private\Public key bindings. I can try to add some, but looking at Ruby sources they built there own C wrappers around those parts.
How should I proceed with this ? does someone working on that ?