#pike __REAL_VERSION__ |
#require constant(SSL.Cipher) |
|
|
|
#ifndef PORT |
#define PORT 25678 |
#endif |
|
#ifdef SSL3_DEBUG |
#define SSL3_DEBUG_MSG(X ...) werror(X) |
#else /*! SSL3_DEBUG */ |
#define SSL3_DEBUG_MSG(X ...) |
#endif /* SSL3_DEBUG */ |
|
import Stdio; |
|
#ifndef HTTPS_CLIENT |
inherit SSL.sslport; |
|
protected void create() |
{ |
SSL3_DEBUG_MSG("https->create\n"); |
sslport::create(); |
} |
|
void my_accept_callback(object f) |
{ |
werror("Accept!\n"); |
conn(accept()); |
} |
#endif |
|
string my_certificate = MIME.decode_base64( |
"MIIBxDCCAW4CAQAwDQYJKoZIhvcNAQEEBQAwbTELMAkGA1UEBhMCREUxEzARBgNV\n" |
"BAgTClRodWVyaW5nZW4xEDAOBgNVBAcTB0lsbWVuYXUxEzARBgNVBAoTClRVIEls\n" |
"bWVuYXUxDDAKBgNVBAsTA1BNSTEUMBIGA1UEAxMLZGVtbyBzZXJ2ZXIwHhcNOTYw\n" |
"NDMwMDUzNjU4WhcNOTYwNTMwMDUzNjU5WjBtMQswCQYDVQQGEwJERTETMBEGA1UE\n" |
"CBMKVGh1ZXJpbmdlbjEQMA4GA1UEBxMHSWxtZW5hdTETMBEGA1UEChMKVFUgSWxt\n" |
"ZW5hdTEMMAoGA1UECxMDUE1JMRQwEgYDVQQDEwtkZW1vIHNlcnZlcjBcMA0GCSqG\n" |
"SIb3DQEBAQUAA0sAMEgCQQDBB6T7bGJhRhRSpDESxk6FKh3iKKrpn4KcDtFM0W6s\n" |
"16QSPz6J0Z2a00lDxudwhJfQFkarJ2w44Gdl/8b+de37AgMBAAEwDQYJKoZIhvcN\n" |
"AQEEBQADQQB5O9VOLqt28vjLBuSP1De92uAiLURwg41idH8qXxmylD39UE/YtHnf\n" |
"bC6QS0pqetnZpQj1yEsjRTeVfuRfANGw\n"); |
|
string my_key = MIME.decode_base64( |
"MIIBOwIBAAJBAMEHpPtsYmFGFFKkMRLGToUqHeIoqumfgpwO0UzRbqzXpBI/PonR\n" |
"nZrTSUPG53CEl9AWRqsnbDjgZ2X/xv517fsCAwEAAQJBALzUbJmkQm1kL9dUVclH\n" |
"A2MTe15VaDTY3N0rRaZ/LmSXb3laiOgBnrFBCz+VRIi88go3wQ3PKLD8eQ5to+SB\n" |
"oWECIQDrmq//unoW1+/+D3JQMGC1KT4HJprhfxBsEoNrmyIhSwIhANG9c0bdpJse\n" |
"VJA0y6nxLeB9pyoGWNZrAB4636jTOigRAiBhLQlAqhJnT6N+H7LfnkSVFDCwVFz3\n" |
"eygz2yL3hCH8pwIhAKE6vEHuodmoYCMWorT5tGWM0hLpHCN/z3Btm38BGQSxAiAz\n" |
"jwsOclu4b+H8zopfzpAaoB8xMcbs0heN+GNNI0h/dQ==\n"); |
|
class conn { |
import Stdio; |
|
object sslfile; |
|
string message = |
"HTTP/1.0 200 Ok\r\n" |
"Connection: close\r\n" |
"Content-Length: 132\r\n" |
"Content-Type: text/html; charset=ISO-8859-1\r\n" |
"Date: Thu, 01 Jan 1970 00:00:01 GMT\r\n" |
"Server: Bare-Bones\r\n" |
"\r\n" |
"<html><head><title>SSL-3 server</title></head>\n" |
"<body><h1>This is a minimal SSL-3 http server</h1>\n" |
"<hr><it>/nisse</it></body></html>\n"; |
int index = 0; |
|
void write_callback() |
{ |
if (index < sizeof(message)) |
{ |
int written = sslfile->write(message[index..]); |
if (written > 0) |
index += written; |
else |
sslfile->close(); |
} |
if (index == sizeof(message)) |
sslfile->close(); |
} |
|
void read_callback(mixed id, string data) |
{ |
SSL3_DEBUG_MSG("Received: '" + data + "'\n"); |
sslfile->set_write_callback(write_callback); |
} |
|
protected void create(object f) |
{ |
sslfile = f; |
sslfile->set_nonblocking(read_callback, 0, 0); |
} |
} |
|
class no_random { |
object arcfour = Crypto.Arcfour(); |
|
protected void create(string|void secret) |
{ |
if (!secret) |
secret = sprintf("Foo!%4c", time()); |
arcfour->set_encrypt_key(Crypto.SHA1->hash(secret)); |
} |
|
string read(int size) |
{ |
return arcfour->crypt(replace(allocate(size), 0, "\021") * ""); |
} |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class client |
{ |
constant request = |
"HEAD / HTTP/1.0\r\n" |
"Host: localhost:" + PORT + "\r\n" |
"\r\n"; |
|
SSL.sslfile ssl; |
int sent; |
void write_cb() |
{ |
int bytes = ssl->write(request[sent..]); |
if (bytes > 0) { |
sent += bytes; |
} else if (sent < 0) { |
werror("Failed to write data: %s\n", strerror(ssl->errno())); |
exit(17); |
} |
if (sent == sizeof(request)) { |
ssl->set_write_callback(UNDEFINED); |
} |
} |
void got_data(mixed ignored, string data) |
{ |
werror("Data: %O\n", data); |
} |
void con_closed() |
{ |
werror("Connection closed.\n"); |
exit(0); |
} |
|
protected void create(Stdio.File con) |
{ |
SSL.context ctx = SSL.context(); |
ctx->random = no_random()->read; |
|
ctx->preferred_suites = ctx->get_suites(-1, 2); |
werror("Starting\n"); |
ssl = SSL.sslfile(con, ctx, 1); |
ssl->set_nonblocking(got_data, write_cb, con_closed); |
} |
} |
|
int main() |
{ |
#ifdef HTTPS_CLIENT |
Stdio.File con = Stdio.File(); |
if (!con->connect("127.0.0.1", PORT)) { |
werror("Failed to connect to server: %s\n", strerror(con->errno())); |
return 17; |
} |
client(con); |
return -17; |
#else |
Crypto.Sign key; |
|
#if 0 |
SSL3_DEBUG_MSG("Cert: '%s'\n", String.string2hex(my_certificate)); |
SSL3_DEBUG_MSG("Key: '%s'\n", String.string2hex(my_key)); |
#if 0 |
array raw_key = SSL.asn1.ber_decode(my_key)->get_asn1()[1]; |
SSL3_DEBUG_MSG("Decoded key: %O\n", key); |
object n = raw_key[1][1]; |
object e = raw_key[2][1]; |
object d = raw_key[3][1]; |
object p = raw_key[4][1]; |
object q = raw_key[5][1]; |
|
werror("n = %s\np = %s\nq = %s\npq = %s\n", |
n->digits(), p->digits(), q->digits(), (p*q)->digits()); |
|
key = Crypto.RSA(); |
key->set_public_key(n, e); |
key->set_private_key(d); |
#else /* !0 */ |
|
key = Standards.PKCS.RSA.parse_private_key(my_key); |
#endif /* 0 */ |
#else |
key = Crypto.RSA()-> |
set_random(Crypto.Random.random_string)->generate_key(1024); |
my_certificate = |
Standards.X509.make_selfsigned_certificate(key, 3600*4, ([ |
"organizationName" : "Test", |
"commonName" : "*", |
])); |
#endif |
add_cert(key, ({ my_certificate }), ({ "*" })); |
|
key = Crypto.DSA()-> |
set_random(Crypto.Random.random_string)->generate_key(1024, 160); |
my_certificate = |
Standards.X509.make_selfsigned_certificate(key, 3600*4, ([ |
"organizationName" : "Test", |
"commonName" : "*", |
])); |
add_cert(key, ({ my_certificate })); |
|
#if constant(Crypto.ECC.Curve) |
key = Crypto.ECC.SECP_521R1.ECDSA()-> |
set_random(Crypto.Random.random_string)->generate_key(); |
my_certificate = |
Standards.X509.make_selfsigned_certificate(key, 3600*4, ([ |
"organizationName" : "Test", |
"commonName" : "*", |
])); |
add_cert(key, ({ my_certificate })); |
#endif |
|
|
preferred_suites = get_suites(-1, 2); |
SSL3_DEBUG_MSG("Cipher suites:\n%s", |
.Constants.fmt_cipher_suites(preferred_suites)); |
|
SSL3_DEBUG_MSG("Certs:\n%O\n", cert_pairs); |
|
random = no_random()->read; |
werror("Starting\n"); |
if (!bind(PORT, my_accept_callback)) |
{ |
perror(""); |
return 17; |
} |
else { |
werror("Listening on port %d.\n", PORT); |
return -17; |
} |
#endif |
} |
|
|