Skip to content

Instantly share code, notes, and snippets.

@bnagy
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bnagy/7a81e5387beeeea866c1 to your computer and use it in GitHub Desktop.
Save bnagy/7a81e5387beeeea866c1 to your computer and use it in GitHub Desktop.
openssl issue
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 $@.join("\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