Last active
August 29, 2015 14:07
-
-
Save bnagy/7a81e5387beeeea866c1 to your computer and use it in GitHub Desktop.
openssl issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'openssl' | |
require 'socket' | |
# client.rb - minimal SSL client | |
# require 'openssl' | |
# require 'socket' | |
# include OpenSSL::SSL | |
# HOST = '::1' | |
# PORT = 8000 | |
# socket = TCPSocket.new(HOST, PORT) | |
# ssl = SSLSocket.new(socket) | |
# ssl.sync_close = true | |
# ssl.connect | |
# puts ssl.readline | |
KEY = OpenSSL::PKey::RSA.new <<-_end_of_pem_ | |
-----BEGIN RSA PRIVATE KEY----- | |
MIICXgIBAAKBgQDLwsSw1ECnPtT+PkOgHhcGA71nwC2/nL85VBGnRqDxOqjVh7Cx | |
aKPERYHsk4BPCkE3brtThPWc9kjHEQQ7uf9Y1rbCz0layNqHyywQEVLFmp1cpIt/ | |
Q3geLv8ZD9pihowKJDyMDiN6ArYUmZczvW4976MU3+l54E6lF/JfFEU5hwIDAQAB | |
AoGBAKSl/MQarye1yOysqX6P8fDFQt68VvtXkNmlSiKOGuzyho0M+UVSFcs6k1L0 | |
maDE25AMZUiGzuWHyaU55d7RXDgeskDMakD1v6ZejYtxJkSXbETOTLDwUWTn618T | |
gnb17tU1jktUtU67xK/08i/XodlgnQhs6VoHTuCh3Hu77O6RAkEA7+gxqBuZR572 | |
74/akiW/SuXm0SXPEviyO1MuSRwtI87B02D0qgV8D1UHRm4AhMnJ8MCs1809kMQE | |
JiQUCrp9mQJBANlt2ngBO14us6NnhuAseFDTBzCHXwUUu1YKHpMMmxpnGqaldGgX | |
sOZB3lgJsT9VlGf3YGYdkLTNVbogQKlKpB8CQQDiSwkb4vyQfDe8/NpU5Not0fII | |
8jsDUCb+opWUTMmfbxWRR3FBNu8wnym/m19N4fFj8LqYzHX4KY0oVPu6qvJxAkEA | |
wa5snNekFcqONLIE4G5cosrIrb74sqL8GbGb+KuTAprzj5z1K8Bm0UW9lTjVDjDi | |
qRYgZfZSL+x1P/54+xTFSwJAY1FxA/N3QPCXCjPh5YqFxAMQs2VVYTfg+t0MEcJD | |
dPMQD5JX6g5HKnHFg2mZtoXQrWmJSn7p8GJK8yNTopEErA== | |
-----END RSA PRIVATE KEY----- | |
_end_of_pem_ | |
# openssl x509 output of an example cert generated by issue_cert: | |
# Certificate: | |
# Data: | |
# Version: 3 (0x2) | |
# Serial Number: 1 (0x1) | |
# Signature Algorithm: sha1WithRSAEncryption | |
# Issuer: DC=org, DC=ruby-lang, CN=localhost | |
# Validity | |
# Not Before: Oct 2 03:35:33 2014 GMT | |
# Not After : Oct 2 04:35:33 2014 GMT | |
# Subject: DC=org, DC=ruby-lang, CN=localhost | |
# Subject Public Key Info: | |
# Public Key Algorithm: rsaEncryption | |
# Public-Key: (1024 bit) | |
# Modulus: | |
# 00:cb:c2:c4:b0:d4:40:a7:3e:d4:fe:3e:43:a0:1e: | |
# 17:06:03:bd:67:c0:2d:bf:9c:bf:39:54:11:a7:46: | |
# a0:f1:3a:a8:d5:87:b0:b1:68:a3:c4:45:81:ec:93: | |
# 80:4f:0a:41:37:6e:bb:53:84:f5:9c:f6:48:c7:11: | |
# 04:3b:b9:ff:58:d6:b6:c2:cf:49:5a:c8:da:87:cb: | |
# 2c:10:11:52:c5:9a:9d:5c:a4:8b:7f:43:78:1e:2e: | |
# ff:19:0f:da:62:86:8c:0a:24:3c:8c:0e:23:7a:02: | |
# b6:14:99:97:33:bd:6e:3d:ef:a3:14:df:e9:79:e0: | |
# 4e:a5:17:f2:5f:14:45:39:87 | |
# Exponent: 65537 (0x10001) | |
# X509v3 extensions: | |
# X509v3 Key Usage: critical | |
# Digital Signature, Key Encipherment | |
# Signature Algorithm: sha1WithRSAEncryption | |
# b5:de:5a:02:b4:87:fe:86:9f:cc:48:87:ae:8d:1f:34:39:10: | |
# 21:23:05:3e:1f:4c:92:f6:02:d1:fe:bf:c8:35:30:d6:5c:13: | |
# c3:21:c4:05:62:7e:29:d3:69:da:74:66:e9:af:c7:a0:80:c0: | |
# e9:a0:76:23:cf:d7:1d:f9:de:03:3a:05:82:e1:25:b6:31:86: | |
# 84:3d:0c:b9:8a:af:2e:76:d1:7d:e6:67:3d:2c:f3:8a:0f:72: | |
# 4e:3d:2c:4c:f0:98:7b:b1:af:b3:bf:67:20:75:9a:dd:62:23: | |
# 0f:92:2c:7e:74:8e:a8:21:14:3d:e7:2a:56:2f:34:7b:1d:01: | |
# 72:b5 | |
KEY2 = OpenSSL::PKey::EC.new " | |
-----BEGIN EC PRIVATE KEY----- | |
MHcCAQEEIFvuDl4S9lyJaRoCzSVQs22C0BATvcH3u6Zzu3i7+wGAoAoGCCqGSM49 | |
AwEHoUQDQgAEqt9mISb4W5KWMts/bXvvxM8Iye/V7WTyMeAgYhYLYPEsEKRda7jf | |
lWb40vsSSggLb3q+RCLxE1nA0R+8WVxTFw== | |
-----END EC PRIVATE KEY----- | |
" | |
class << KEY2 | |
def private? | |
private_key? | |
end | |
def public? | |
public_key? | |
end | |
end | |
def issue_cert(dn, key, serial, not_before, not_after, extensions, | |
issuer, issuer_key, digest) | |
cert = OpenSSL::X509::Certificate.new | |
issuer = cert unless issuer | |
issuer_key = key unless issuer_key | |
cert.version = 2 | |
cert.serial = serial | |
cert.subject = dn | |
cert.issuer = issuer.subject | |
cert.public_key = key | |
cert.not_before = not_before | |
cert.not_after = not_after | |
ef = OpenSSL::X509::ExtensionFactory.new | |
ef.subject_certificate = cert | |
ef.issuer_certificate = issuer | |
extensions.each{|oid, value, critical| | |
cert.add_extension(ef.create_extension(oid, value, critical)) | |
} | |
cert.sign(issuer_key, digest) | |
puts cert.to_pem | |
cert | |
end | |
def server_cert | |
svr = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=localhost") | |
now = Time.at(Time.now.to_i) | |
ee_exts = [ | |
["keyUsage","keyEncipherment,digitalSignature",true], | |
] | |
issue_cert(svr, KEY2, 1, now, now+3600, ee_exts, nil, nil, OpenSSL::Digest::SHA1.new) | |
end | |
CERT = server_cert | |
HOST = '127.0.0.1' | |
PORT = 8000 | |
CERT2 = OpenSSL::X509::Certificate.new " | |
-----BEGIN CERTIFICATE----- | |
MIIBizCCATCgAwIBAgIQRscrDbJn2bLiEYKuFxrrijAKBggqhkjOPQQDAjAtMRQw | |
EgYDVQQKEwtKdXN0IEVub3VnaDEVMBMGA1UEAxMMVGVzdENlcnRzIENBMB4XDTE0 | |
MTAwMjAzMDczMVoXDTI0MTAwMjAzMDczMVowKjEUMBIGA1UEChMLSnVzdCBFbm91 | |
Z2gxEjAQBgNVBAMTCVRlc3RDZXJ0czBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA | |
BKrfZiEm+FuSljLbP21778TPCMnv1e1k8jHgIGIWC2DxLBCkXWu435Vm+NL7EkoI | |
C296vkQi8RNZwNEfvFlcUxejNTAzMA4GA1UdDwEB/wQEAwIAoDATBgNVHSUEDDAK | |
BggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMAoGCCqGSM49BAMCA0kAMEYCIQCXUtZG | |
0vHdZLrEkmQYtyVe63LOpDJiEKd3sa8Awxqz7gIhAOZ5Rjd61zF16nvJnlCblnzT | |
xsSPM9P4vD8zcG5+gpoR | |
-----END CERTIFICATE----- | |
" | |
# openssl -x509 output of the ECDSA cert: | |
# | |
# This cert validates with openssl, and can be used successfully with openssl | |
# s_server / s_client | |
# | |
# Certificate: | |
# Data: | |
# Version: 3 (0x2) | |
# Serial Number: | |
# 46:c7:2b:0d:b2:67:d9:b2:e2:11:82:ae:17:1a:eb:8a | |
# Signature Algorithm: ecdsa-with-SHA256 | |
# Issuer: O=Just Enough, CN=TestCerts CA | |
# Validity | |
# Not Before: Oct 2 03:07:31 2014 GMT | |
# Not After : Oct 2 03:07:31 2024 GMT | |
# Subject: O=Just Enough, CN=TestCerts | |
# Subject Public Key Info: | |
# Public Key Algorithm: id-ecPublicKey | |
# Public-Key: (256 bit) | |
# pub: | |
# 04:aa:df:66:21:26:f8:5b:92:96:32:db:3f:6d:7b: | |
# ef:c4:cf:08:c9:ef:d5:ed:64:f2:31:e0:20:62:16: | |
# 0b:60:f1:2c:10:a4:5d:6b:b8:df:95:66:f8:d2:fb: | |
# 12:4a:08:0b:6f:7a:be:44:22:f1:13:59:c0:d1:1f: | |
# bc:59:5c:53:17 | |
# ASN1 OID: prime256v1 | |
# X509v3 extensions: | |
# X509v3 Key Usage: critical | |
# Digital Signature, Key Encipherment | |
# X509v3 Extended Key Usage: | |
# TLS Web Server Authentication | |
# X509v3 Basic Constraints: critical | |
# CA:FALSE | |
# Signature Algorithm: ecdsa-with-SHA256 | |
# 30:46:02:21:00:97:52:d6:46:d2:f1:dd:64:ba:c4:92:64:18: | |
# b7:25:5e:eb:72:ce:a4:32:62:10:a7:77:b1:af:00:c3:1a:b3: | |
# ee:02:21:00:e6:79:46:37:7a:d7:31:75:ea:7b:c9:9e:50:9b: | |
# 96:7c:d3:c6:c4:8f:33:d3:f8:bc:3f:33:70:6e:7e:82:9a:11 | |
def start_server | |
ctx = OpenSSL::SSL::SSLContext.new | |
# these ones work | |
# ctx.cert = CERT | |
# ctx.key = KEY | |
# Uncomment below to demonstrate bug | |
ctx.cert = CERT | |
ctx.key = KEY2 | |
ctx.options = OpenSSL::SSL::OP_SINGLE_ECDH_USE # didn't | |
num_handshakes = 0 | |
ctx.renegotiation_cb = lambda do |ssl| | |
puts "Negotiating..." | |
num_handshakes += 1 | |
raise RuntimeError.new("No client renegotiation allowed") if num_handshakes > 1 | |
end | |
tcps = TCPServer.new(HOST, PORT) | |
ssls = OpenSSL::SSL::SSLServer.new(tcps, ctx) | |
ssls.start_immediately = true | |
begin | |
done = false | |
loop do | |
ssl = ssls.accept | |
puts "Connected" | |
begin | |
ssl.write "ACK\n" | |
ensure | |
ssl.close | |
end | |
puts "Disconnected" | |
end | |
rescue | |
puts $! | |
puts [email protected]("\n") | |
ensure | |
tcps.close if (tcps) | |
end | |
end | |
start_server |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment