cherry
Version, currently 0.1.34 versions
- 0.1.3latestJan 27, 2021
- 0.1.2not indexedFeb 1, 2021
- 0.1.1not indexedFeb 1, 2021
- 0.1.0not indexedFeb 1, 2021
github.com/636f7374/cherry.cr
⛵️ Available - Crystal Man-in-the-middle Toolkit
9 stars
1 dependent
License: MIT
Installation
# Add this to your shard.yml
dependencies:
cherry:
github: 636f7374/cherry.cr
version: ~> 0.1.3Then run:
shards installshard.yml
- Crystal
- no constraint declared
- License
- MIT
- Author
- 636f7374
Dependencies
This version declares no dependencies.
README
<div align = "center"><img src="images/icon.png" width="256" height="256" /></div>
<div align = "center">
<h1>Cherry.cr - Man-in-the-middle Toolkit</h1>
</div>
<p align="center">
<a href="https://crystal-lang.org">
<img src="https://img.shields.io/badge/built%20with-crystal-000000.svg" /></a>
<a href="https://github.com/636f7374/cherry.cr/actions">
<img src="https://github.com/636f7374/cherry.cr/workflows/Continuous%20Integration/badge.svg" /></a>
<a href="https://github.com/636f7374/cherry.cr/releases">
<img src="https://img.shields.io/github/release/636f7374/cherry.cr.svg" /></a>
<a href="https://github.com/636f7374/cherry.cr/blob/master/license">
<img src="https://img.shields.io/github/license/636f7374/cherry.cr.svg"></a>
</p>
## Description
* Because Crystal language is missing most OpenSSL bindings ([libCrypto](https://github.com/crystal-lang/crystal/blob/master/src/openssl/lib_crypto.cr), libSSL).
* [It doesn't even support loading certificate / private key files from memory](https://github.com/crystal-lang/crystal/issues/7897).
* Of course, Crystal official is [always busy](#related), it will not help you solve these problems.
* In despair, I came across [openssl.cr](https://github.com/datanoise/openssl.cr), which is a shabby OpenSSL binding.
* This OpenSSL repository was last updated 5 years ago, Fortunately, most of its features are not completely broken.
* So I started to test slowly and repair the broken things, And refer to [Ruby prototype](https://ruby-doc.org/stdlib-2.4.0/libdoc/openssl/rdoc/OpenSSL/X509/Certificate.html) for redesign.
* It took one month to fix most of the problems, and finally it was available after three months.
* I think if I was using [Rust](https://github.com/sfackler/rust-openssl) then I would n’t have encountered these problems.
* But this allows me to learn a lot, I hope it can help more people.
* That's it, Thanks for using, If you encounter any problems, please let me know.
* After a period of testing, thread safety is now supported.
## Features
* OpenSSL
* Lib (libCrypto, libSSL)
* There are many bindings in it, many related to loading / reading certificates.
* libCrypto: (I.e. `bio_*`, `evp_*`, `rsa_*`, `dsa_*`, `pem_*`, `asn1_*`, `x509_*`).
* libSSL: (I.e. `ssl_ctx_use_certificate`, `ssl_ctx_use_privatekey`).
* Asn1 (Integer, Time)
* Integer: Certificate serial number, very useful.
* Time: Certificate validity period, very useful.
* Bio (MemBIO)
* MemBIO: OpenSSL memory buffer, Essential when making Certificate / (Private / Public) keys.
* Nid
* Certificate subject id flag, Essential when making Certificate.
* NID: (I.e. `subject_alt_name`, `ext_usage`, `usage`).
* Pkey (PKey, DSA, RSA)
* Essential when (create / read) Public / Private Key.
* I encountered a memory leak problem here, it has been fixed.
* SSL (Context)
* Context: Support loading certificate / private key files from memory.
* X509 (ExtensionFactory, Request, SuperCertificate, SuperName).
* ExtensionFactory: Certificate Subject Add / Remove, very important.
* Request: I don't seem to use it, but I also made.
* SuperCertificate: Generate certificate requires it.
* SuperName: `issuer_name`, `subject_name`, Generate certificate requires it.
* MITM
* Mitm Slightly complicated but worth it, low memory usage.
* Client: Wrapper for `OpenSSL::SSL::Socket::Client`.
* Server: Wrapper for `OpenSSL::SSL::Socket::Server`.
* Context: Convenient and fast certificate generation, for Man-in-the-middle.
## Tips
* This repository contains OpenSSL and Network components.
* Crystal HTTP::Client components are highly integrated with OpenSSL.
## Next
* [ ] More specification tests.
* [ ] Troubleshooting Deep Memory Errors / Memory Leaks (More stress tests?)
* [ ] ...
## Usage
* Simple Mitm Server (Need to be used with [Carton.cr](https://github.com/636f7374/carton.cr))
```crystal
require "base64"
require "carton"
require "cherry"
# This is a simple design, please do not use it directly.
def handle_client(context, client : Carton::Socket)
return client.close unless request = client.request_payload
STDOUT.puts [client]
case {client.tunnel_mode, client.traffic_type}
when {true, Carton::Traffic::HTTPS}
client = MITM::Server.upgrade client, request, context
buffer = uninitialized UInt8[4096_i32]
length = client.read buffer.to_slice
puts String.new buffer.to_slice[0_i32, length]
end
client.close
end
# Durian
servers = [] of Tuple(Socket::IPAddress, Durian::Protocol)
servers << Tuple.new Socket::IPAddress.new("8.8.8.8", 53_i32), Durian::Protocol::UDP
servers << Tuple.new Socket::IPAddress.new("1.1.1.1", 53_i32), Durian::Protocol::UDP
resolver = Durian::Resolver.new servers
resolver.ip_cache = Durian::Resolver::Cache::IPAddress.new
# Carton
tcp_server = TCPServer.new "0.0.0.0", 1234_i32
carton = Carton::Server.new tcp_server, resolver
carton.authentication = Carton::Authentication::None
carton.client_timeout = Carton::TimeOut.new
carton.remote_timeout = Carton::TimeOut.new
certificate = Base64.decode_string "Something..."
private_key = Base64.decode_string "Something..."
context = MITM::Context.new certificate, private_key
# Authentication (Optional)
# carton.authentication = Carton::Authentication::Basic
# carton.on_auth = ->(user_name : String, password : String) do
# STDOUT.puts [user_name, password]
# Carton::Verify::Pass
# end
loop do
socket = carton.accept?
spawn do
next unless client = socket
next unless client = carton.process client
handle_client context, client
end
end
```
* Simple HTTP Client
* ...
### Used as Shard
Add this to your application's shard.yml:
```yaml
dependencies:
cherry:
github: 636f7374/cherry.cr
```
### Installation
```bash
$ git clone https://github.com/636f7374/cherry.cr.git
```
## Development
```bash
$ make test
```
## References
* [Official | Ruby OpenSSL::X509::Certificate](https://ruby-doc.org/stdlib-2.4.0/libdoc/openssl/rdoc/OpenSSL/X509/Certificate.html)
* [Official | OpenSSL Documentation](https://www.openssl.org/docs/)
* [Official | OpenSSL x509v3_config](https://www.openssl.org/docs/manmaster/man5/x509v3_config.html)
* [Official | PEM_read_bio_PrivateKey](https://www.openssl.org/docs/man1.1.0/man3/PEM_write_bio_RSA_PUBKEY.html)
* [Official | X509V3_get_d2i](https://www.openssl.org/docs/man1.1.0/man3/X509_add1_ext_i2d.html)
* [Official | Secure programming with the OpenSSL API](https://developer.ibm.com/tutorials/l-openssl/)
* [Github | Golang Nid.go](https://github.com/spacemonkeygo/openssl/blob/master/nid.go)
* [Github | Rust OpenSSL Password callbacks](https://github.com/sfackler/rust-openssl/pull/410)
* [Github | OpenSSL SSL_Rsa.c](https://github.com/openssl/openssl/blob/master/ssl/ssl_rsa.c)
* [Blogs | The Most Common OpenSSL Commands](https://www.sslshopper.com/article-most-common-openssl-commands.html)
* [Blogs | OpenSSL – Convert RSA Key to private key](https://rafpe.ninja/2016/08/17/openssl-convert-rsa-key-to-private-key/)
* [Blogs | problem with d2i_X509?](http://openssl.6102.n7.nabble.com/problem-with-d2i-X509-td1537.html)
* [Blogs | Parsing X.509 Certificates with OpenSSL and C](https://zakird.com/2013/10/13/certificate-parsing-with-openssl)
* [Blogs | Using the OpenSSL library with macOS Sierra](https://medium.com/@timmykko/using-openssl-library-with-macos-sierra-7807cfd47892)
* [StackOverflow | Read certificate files from memory instead of a file using OpenSSL](https://stackoverflow.com/questions/3810058/read-certificate-files-from-memory-instead-of-a-file-using-openssl)
* [StackOverflow | Programmatically Create X509 Certificate using OpenSSL](https://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openssl)
* [StackOverflow | OpenSSL Command to check if a server is presenting a certificate](https://stackoverflow.com/questions/24457408/openssl-command-to-check-if-a-server-is-presenting-a-certificate)
* [StackOverflow | C++ OpenSSL export private key](https://stackoverflow.com/questions/5367991/c-openssl-export-private-key)
* [StackOverflow | Why is openssl key length different from specified bytes](https://security.stackexchange.com/questions/102508/why-is-openssl-key-length-different-from-specified-bytes)
* [StackOverflow | Reading PEM-formatted RSA keyfile with the OpenSSL C API](https://stackoverflow.com/questions/16675147/reading-pem-formatted-rsa-keyfile-with-the-openssl-c-api)
* [StackOverflow | OpenSSL certificate lacks key identifiers](https://stackoverflow.com/questions/2883164/openssl-certificate-lacks-key-identifiers)
* [StackOverflow | OpenSSL CA keyUsage extension](https://superuser.com/questions/738612/openssl-ca-keyusage-extension)
* ...
## Related
* [#7897 | Need to enhance the OpenSSL::SSL::Context loads Certificate / PrivateKey from Memory](https://github.com/crystal-lang/crystal/issues/7897)
* [#7896 | Need to enhance the OpenSSL::X509 more features](https://github.com/crystal-lang/crystal/issues/7896)
* [#8108 | openssl ssl_accept sometimes does not return, causes server to hang permanently](https://github.com/crystal-lang/crystal/issues/8108)
* [#7291 | Get SNI for OpenSSL](https://github.com/crystal-lang/crystal/pull/7291)
* ...
## Credit
* [\_Icon::Wanicon/Fruits](https://www.flaticon.com/packs/fruits-and-vegetables-48)
* [\_Icon::Freepik/GraphicDesign](https://www.flaticon.com/packs/graphic-design-125)
## Contributors
|Name|Creator|Maintainer|Contributor|
|:---:|:---:|:---:|:---:|
|**[636f7374](https://github.com/636f7374)**|√|√||
|**[datanoise](https://github.com/datanoise)**|||√|
## License
* MIT License
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.1.3- Tagged
- Jan 27, 2021
- Commit
423578daa8b3- Indexed
- yes
Dependents
Repository
github.com/636f7374/cherry.cr
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 12, 2026
- Synced
- Aug 12, 2026
- Versions
- 4