- Because Crystal language is missing most OpenSSL bindings (libCrypto, libSSL).
- Of course, Crystal official is always busy, it will not help you solve these problems.
- In despair, I came across 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 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 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.
-
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.
- Lib (libCrypto, libSSL)
-
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.
- This repository contains OpenSSL and Network components.
- Crystal HTTP::Client components are highly integrated with OpenSSL.
- More specification tests.
- Troubleshooting Deep Memory Errors / Memory Leaks (More stress tests?)
- ...
- Simple Mitm Server (Need to be used with Carton.cr)
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
- ...
Add this to your application's shard.yml:
dependencies:
cherry:
github: 636f7374/cherry.cr
$ git clone https://github.com/636f7374/cherry.cr.git
$ make test
- Official | Ruby OpenSSL::X509::Certificate
- Official | OpenSSL Documentation
- Official | OpenSSL x509v3_config
- Official | PEM_read_bio_PrivateKey
- Official | X509V3_get_d2i
- Official | Secure programming with the OpenSSL API
- Github | Golang Nid.go
- Github | Rust OpenSSL Password callbacks
- Github | OpenSSL SSL_Rsa.c
- Blogs | The Most Common OpenSSL Commands
- Blogs | OpenSSL – Convert RSA Key to private key
- Blogs | problem with d2i_X509?
- Blogs | Parsing X.509 Certificates with OpenSSL and C
- Blogs | Using the OpenSSL library with macOS Sierra
- StackOverflow | Read certificate files from memory instead of a file using OpenSSL
- StackOverflow | Programmatically Create X509 Certificate using OpenSSL
- StackOverflow | OpenSSL Command to check if a server is presenting a certificate
- StackOverflow | C++ OpenSSL export private key
- StackOverflow | Why is openssl key length different from specified bytes
- StackOverflow | Reading PEM-formatted RSA keyfile with the OpenSSL C API
- StackOverflow | OpenSSL certificate lacks key identifiers
- StackOverflow | OpenSSL CA keyUsage extension
- ...
- #7897 | Need to enhance the OpenSSL::SSL::Context loads Certificate / PrivateKey from Memory
- #7896 | Need to enhance the OpenSSL::X509 more features
- #8108 | openssl ssl_accept sometimes does not return, causes server to hang permanently
- #7291 | Get SNI for OpenSSL
- ...
Name | Creator | Maintainer | Contributor |
---|---|---|---|
636f7374 | √ | √ | |
datanoise | √ |
- MIT License