Discussion:
Using the SSL module.
Trilok Tourani
2015-06-21 14:34:29 UTC
Permalink
Can someone please tell me as to how to make a connection between a server
and a client, SSL protected?

I have tried using SSL.sslfile(Stdio.File demo, SSL.context ctx) function
but still don't understand how to make the data going through the
connection encrypted/decrypted.

Regards
Trilok Tourani
Chris Angelico
2015-06-21 14:42:47 UTC
Permalink
On Mon, Jun 22, 2015 at 12:34 AM, Trilok Tourani
Post by Trilok Tourani
Can someone please tell me as to how to make a connection between a server
and a client, SSL protected?
I have tried using SSL.sslfile(Stdio.File demo, SSL.context ctx) function
but still don't understand how to make the data going through the connection
encrypted/decrypted.
Once you've done that, you don't read or write anything on the
underlying Stdio.File, you just use the SSL file. Anything you write
gets encrypted and then sent to the other end; everything you read has
first been decrypted. Generally, you can pretend that it's exactly the
same as a regular Stdio.File, although the abstraction leaks sometimes
(certain operations involve both reading and writing, even though you
wouldn't expect them to).

If you're building the server in Pike, you'll need to set up a key and
certificate. Otherwise, it's fairly easy:

int main()
{
Stdio.File sock = Stdio.File();
sock->connect("gideon.rosuav.com", 443);
SSL.File ssl = SSL.File(sock, SSL.Context());
ssl->write("GET / HTTP/1.0\r\n\r\n");
write("Response:\n%s\n", ssl->read(1024,1));
}

Although you seem to be using a version of Pike that has SSL.sslfile
rather than SSL.File, but translate as appropriate.

ChrisA
Chris Angelico
2015-06-22 01:56:05 UTC
Permalink
On Mon, Jun 22, 2015 at 6:11 AM, Trilok Tourani
Thanks a lot Chris. Can you also please elaborate when the server is built
with pike, in my case, it is the localhost(127.0.0.1).
and also, does SSL.context() generate its own random keys for us?
Let's keep this on the list - I'm not the greatest expert on all this,
and I'd rather have the chance that someone else might catch my
errors!

From what I understand, yes, the SSL module will generate all the
session keys and things. But it doesn't generate keys or certificates.
You have two basic options: Firstly, go through the usual commercial
signing route - search the web for SSL certificates, pick a nice cheap
one, go with that. Or alternatively, create a self-signed certificate
(again, search the web; you'll find instructions for doing that on
various platforms), and then have a copy of the certificate embedded
in the client. The latter is more secure if you control both ends,
plus it doesn't cost money. Commercial certs are great if you want to
work with the broader internet, particularly web browsers.

Once you have those generated, all you need to do is parse them
(they're conventionally stored in an ASCII format, base-64 encoded
with some framing) and hand them on to the SSL port. It's been a while
since I did that, but I could probably dig up some example code to
show you.

ChrisA
Trilok Tourani
2015-06-22 06:34:27 UTC
Permalink
Thanks Chris. Any example would be great.



Regards
Trilok Tourani
Post by Chris Angelico
On Mon, Jun 22, 2015 at 6:11 AM, Trilok Tourani
Thanks a lot Chris. Can you also please elaborate when the server is
built
with pike, in my case, it is the localhost(127.0.0.1).
and also, does SSL.context() generate its own random keys for us?
Let's keep this on the list - I'm not the greatest expert on all this,
and I'd rather have the chance that someone else might catch my
errors!
From what I understand, yes, the SSL module will generate all the
session keys and things. But it doesn't generate keys or certificates.
You have two basic options: Firstly, go through the usual commercial
signing route - search the web for SSL certificates, pick a nice cheap
one, go with that. Or alternatively, create a self-signed certificate
(again, search the web; you'll find instructions for doing that on
various platforms), and then have a copy of the certificate embedded
in the client. The latter is more secure if you control both ends,
plus it doesn't cost money. Commercial certs are great if you want to
work with the broader internet, particularly web browsers.
Once you have those generated, all you need to do is parse them
(they're conventionally stored in an ASCII format, base-64 encoded
with some framing) and hand them on to the SSL port. It's been a while
since I did that, but I could probably dig up some example code to
show you.
ChrisA
Chris Angelico
2015-06-22 14:47:42 UTC
Permalink
On Mon, Jun 22, 2015 at 4:34 PM, Trilok Tourani
Post by Trilok Tourani
Thanks Chris. Any example would be great.
Okay. Got around to dusting off some old code and making sure it
actually, yaknow, works. This is written for Pike 8.1, so you may need
to make some changes for 7.8.



void http_query(Protocols.HTTP.Server.Request r)
{
write("Request for %s\n",r->not_query);
r->response_and_finish((["data":"You requested:
"+r->not_query,"type":"text/plain"]));
}

void sockread(object sock,string data)
{
write("[%d] Data received: %O\n",hash_value(sock),data);
if (String.trim_all_whites(data)=="quit") {sock->write("Bye!\n");
sock->close();}
else sock->write("Uh huh.\n");
}

void sockgone(object sock)
{
write("[%d] Disconnected.\n",hash_value(sock));
}

object mainsock;
void accept(object sock)
{
mainsock->accept(); //Will return sock, same as the argument.
Dunno why we get it both ways.
write("[%d] New connection from
%s\n",hash_value(sock),sock->query_address());
sock->set_read_callback(sockread);
sock->set_close_callback(sockgone);
sock->set_id(sock);
sock->write("Hello, world!\n");
}

int main()
{
//Load up three files...
//1) Certificate chain from the CSA
sscanf(Stdio.read_file("gd_bundle.crt"),"%{%*s-----BEGIN
CERTIFICATE-----%s-----END CERTIFICATE-----%}",array certs);
certs=MIME.decode_base64(certs[*][0][*]);
//2) Our certificate
sscanf(Stdio.read_file("demo.crt"),"%*s-----BEGIN
CERTIFICATE-----%s-----END CERTIFICATE-----",string crt);
certs=({MIME.decode_base64(crt)})+certs; //Ours first, chain following it
//3) Our private key
sscanf(Stdio.read_file("demo.key"),"%*s-----BEGIN RSA PRIVATE
KEY-----%s-----END RSA PRIVATE KEY-----",string key);
key=MIME.decode_base64(key);
write("Keys loaded successfully.\n");

Protocols.HTTP.Server.SSLPort(http_query,443,"::",key,certs);

object ctx=SSL.Context();
ctx->add_cert(Standards.PKCS.RSA.parse_private_key(key),certs,({"*"}));
mainsock=SSL.Port(ctx); mainsock->bind(1234,accept,"::");
write("Listening on ports 443 and 1234.\n");
return -1;
}



This is a dual server - HTTPS and a TLS-enabled telnet-like
connection. For this, I used a certificate that I bought from GoDaddy,
so the authority chain comes from the GoDaddy certificate bundle
(gd_bundle.crt). Using a self-signed cert would also work, and as
Grubba pointed out, Pike is quite capable of generating those.

It's pretty simple, and might even be simpler than I've shown here.
Note the one liner to set up HTTPS hosting... a simple reactive
function to handle requests, and you can completely ignore SSL and
just work with the requests themselves.

ChrisA
Henrik Grubbström
2015-06-22 15:16:52 UTC
Permalink
Post by Chris Angelico
On Mon, Jun 22, 2015 at 4:34 PM, Trilok Tourani
Post by Trilok Tourani
Thanks Chris. Any example would be great.
Okay. Got around to dusting off some old code and making sure it
actually, yaknow, works. This is written for Pike 8.1, so you may need
to make some changes for 7.8.
void http_query(Protocols.HTTP.Server.Request r)
{
write("Request for %s\n",r->not_query);
"+r->not_query,"type":"text/plain"]));
}
void sockread(object sock,string data)
{
write("[%d] Data received: %O\n",hash_value(sock),data);
if (String.trim_all_whites(data)=="quit") {sock->write("Bye!\n");
sock->close();}
else sock->write("Uh huh.\n");
}
void sockgone(object sock)
{
write("[%d] Disconnected.\n",hash_value(sock));
}
object mainsock;
void accept(object sock)
{
mainsock->accept(); //Will return sock, same as the argument.
Dunno why we get it both ways.
write("[%d] New connection from
%s\n",hash_value(sock),sock->query_address());
sock->set_read_callback(sockread);
sock->set_close_callback(sockgone);
sock->set_id(sock);
sock->write("Hello, world!\n");
}
int main()
{
//Load up three files...
//1) Certificate chain from the CSA
sscanf(Stdio.read_file("gd_bundle.crt"),"%{%*s-----BEGIN
CERTIFICATE-----%s-----END CERTIFICATE-----%}",array certs);
[Parsing of a PEM-file by hand removed]

You might want to have a look at Standards.PEM.
Post by Chris Angelico
write("Keys loaded successfully.\n");
Protocols.HTTP.Server.SSLPort(http_query,443,"::",key,certs);
object ctx=SSL.Context();
ctx->add_cert(Standards.PKCS.RSA.parse_private_key(key),certs,({"*"}));

Note that the add_cert() function is new in Pike 8.0.
Post by Chris Angelico
mainsock=SSL.Port(ctx); mainsock->bind(1234,accept,"::");
write("Listening on ports 443 and 1234.\n");
return -1;
}
This is a dual server - HTTPS and a TLS-enabled telnet-like
connection. For this, I used a certificate that I bought from GoDaddy,
so the authority chain comes from the GoDaddy certificate bundle
(gd_bundle.crt). Using a self-signed cert would also work, and as
Grubba pointed out, Pike is quite capable of generating those.
It's pretty simple, and might even be simpler than I've shown here.
Note the one liner to set up HTTPS hosting... a simple reactive
function to handle requests, and you can completely ignore SSL and
just work with the requests themselves.
/grubba
Chris Angelico
2015-06-22 15:34:23 UTC
Permalink
Post by Henrik Grubbström
[Parsing of a PEM-file by hand removed]
You might want to have a look at Standards.PEM.
Oh, cool, thanks! Hadn't spotted that one.

That saves me a small amount of trouble, but there's one thing that
still doesn't gel with me. In a program that uses keypairs generated
by ssh-keygen(1), I can parse a private key nice and easily, but the
public key is a bit different. Here's mine, straight from
.ssh/id_rsa.pub:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDk7uBGern7ntWxWqyYnSGmZykktC/sb7or9AY4UKM8/zwAWwLhubmnr9SysEaMayc4R7WSbdRaD4g2ZTn/F46awdgLS4uybDIfChSUUnwNUAuxmlPS+9mGbs3ajQZ3svt1h1/Xr6tuyI4BSwScJlTgRKE+il4zYiGFteqdWUjGSLshm4CBCL5QaCtebtKsVIut8uIHEQH0uepSqMs4vvZUS+xsUYyVjDSjJ4RfNDs23CnVGHaEp3WNnOnn/r9341ksiUtc2+MofMUUycrPVewh0YnxSMpK8YcQ/i0b/EpiB0poe4JOm/bIa50C5Y9FV7buVc9TqS+BueJkO9XBRkxp
***@sikorsky

But trying to parse that invariably fails. Currently, here's how I do it:

object load_public_key(string fn) {return
decode_public_key((Stdio.read_file(fn)/" ")[1]);}
object decode_public_key(string key)
{
key=MIME.decode_base64(key);
//I have no idea how this rewrapping works, but it appears to. There's some
//signature data at the beginning of the MIME-encoded file, but we need some
//different signature data for parse_public_key().
return Standards.PKCS.RSA.parse_public_key("0\202\1\n\2\202"+key[20..]+"\2\3\1\0\1");
}

Stripping off the leading "ssh-rsa" and the trailing identifier, that
makes reasonable sense. But I have no idea what the rewrapping means -
I have to strip off the first twenty bytes, which seem always to be
"\0\0\0\assh-rsa\0\0\0\3\1\0\1\0\0", and then patch on a replacement
set of framing bytes, including some at the end. Is there a standard
way to parse these keys? Or is it ssh-keygen that's doing something
unusual here (maybe something SSH-specific)?

Other than that rewrapping, the keys seem to be perfectly compatible,
which means I can make use of the key exchanges that I've already done
around the network. But it does seem weird.

ChrisA
Henrik Grubbström
2015-06-29 16:36:57 UTC
Permalink
Post by Chris Angelico
Post by Henrik Grubbström
[Parsing of a PEM-file by hand removed]
You might want to have a look at Standards.PEM.
Oh, cool, thanks! Hadn't spotted that one.
That saves me a small amount of trouble, but there's one thing that
still doesn't gel with me. In a program that uses keypairs generated
by ssh-keygen(1), I can parse a private key nice and easily, but the
public key is a bit different. Here's mine, straight from
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDk7uBGern7ntWxWqyYnSGmZykktC/sb7or9AY4UKM8/zwAWwLhubmnr9SysEaMayc4R7WSbdRaD4g2ZTn/F46awdgLS4uybDIfChSUUnwNUAuxmlPS+9mGbs3ajQZ3svt1h1/Xr6tuyI4BSwScJlTgRKE+il4zYiGFteqdWUjGSLshm4CBCL5QaCtebtKsVIut8uIHEQH0uepSqMs4vvZUS+xsUYyVjDSjJ4RfNDs23CnVGHaEp3WNnOnn/r9341ksiUtc2+MofMUUycrPVewh0YnxSMpK8YcQ/i0b/EpiB0poe4JOm/bIa50C5Y9FV7buVc9TqS+BueJkO9XBRkxp
[...]
Post by Chris Angelico
Stripping off the leading "ssh-rsa" and the trailing identifier, that
makes reasonable sense. But I have no idea what the rewrapping means -
I have to strip off the first twenty bytes, which seem always to be
"\0\0\0\assh-rsa\0\0\0\3\1\0\1\0\0", and then patch on a replacement
set of framing bytes, including some at the end. Is there a standard
way to parse these keys? Or is it ssh-keygen that's doing something
unusual here (maybe something SSH-specific)?
It looks like a simple SSH-specific encoding. From looking at your
example, I believe that something like the following might work:

Stdio.Buffer buf = Stdio.Buffer(MIME.decode_base64(encoded_key));

string tag = buf->read_hstring(4);

if (tag == "ssh-rsa") {
int modulo = buf->read_hint(4);

int pub = buf->read_hint(4);

Crypto.RSA rsa = Crypto.RSA();

rsa->set_public_key(modulo, pub);

return rsa;
}
Post by Chris Angelico
Other than that rewrapping, the keys seem to be perfectly compatible,
which means I can make use of the key exchanges that I've already done
around the network. But it does seem weird.
/grubba
--
Henrik Grubbström ***@roxen.com
Roxen Internet Software AB
Chris Angelico
2015-06-29 17:01:04 UTC
Permalink
It looks like a simple SSH-specific encoding. From looking at your example,
Stdio.Buffer buf = Stdio.Buffer(MIME.decode_base64(encoded_key));
string tag = buf->read_hstring(4);
if (tag == "ssh-rsa") {
int modulo = buf->read_hint(4);
int pub = buf->read_hint(4);
Crypto.RSA rsa = Crypto.RSA();
rsa->set_public_key(modulo, pub);
return rsa;
}
Thanks! I don't know much about crypto, so all I can do is try it out.
It seems that the public exponent comes first in the encoded version,
so I switched those two read_hint() lines, and then it appears to work
- the key can successfully verify signatures created with the
corresponding private key. This looks a lot better than "rip these
bytes off, shove those bytes on, and see how it goes".

ChrisA
Trilok Tourani
2015-06-29 17:31:20 UTC
Permalink
I have used the https.pike in pike 8 which is a example of a client/server
connection. Some of the websites its working, but for some it says bad
certificate chain. Does that mean, the websites certificate chain needs to
be fixed? or is there any other way one can do it?

Thanks.

Regards
Trilok Tourani
Post by Henrik Grubbström
Post by Henrik Grubbström
It looks like a simple SSH-specific encoding. From looking at your
example,
Post by Henrik Grubbström
Stdio.Buffer buf = Stdio.Buffer(MIME.decode_base64(encoded_key));
string tag = buf->read_hstring(4);
if (tag == "ssh-rsa") {
int modulo = buf->read_hint(4);
int pub = buf->read_hint(4);
Crypto.RSA rsa = Crypto.RSA();
rsa->set_public_key(modulo, pub);
return rsa;
}
Thanks! I don't know much about crypto, so all I can do is try it out.
It seems that the public exponent comes first in the encoded version,
so I switched those two read_hint() lines, and then it appears to work
- the key can successfully verify signatures created with the
corresponding private key. This looks a lot better than "rip these
bytes off, shove those bytes on, and see how it goes".
ChrisA
Trilok Tourani
2015-06-23 06:21:43 UTC
Permalink
The code that you have written in your previous mail, starts listening for
the ports, but when I connect a sock to 127.0.0.1:1234, it doesn't seem to
be calling the accept or http_query functions. It just hangs there.
(sock->connect("127.0.0.1",1234);)

Regards
Trilok Tourani
Post by Chris Angelico
On Mon, Jun 22, 2015 at 4:34 PM, Trilok Tourani
Post by Trilok Tourani
Thanks Chris. Any example would be great.
Okay. Got around to dusting off some old code and making sure it
actually, yaknow, works. This is written for Pike 8.1, so you may need
to make some changes for 7.8.
void http_query(Protocols.HTTP.Server.Request r)
{
write("Request for %s\n",r->not_query);
"+r->not_query,"type":"text/plain"]));
}
void sockread(object sock,string data)
{
write("[%d] Data received: %O\n",hash_value(sock),data);
if (String.trim_all_whites(data)=="quit") {sock->write("Bye!\n");
sock->close();}
else sock->write("Uh huh.\n");
}
void sockgone(object sock)
{
write("[%d] Disconnected.\n",hash_value(sock));
}
object mainsock;
void accept(object sock)
{
mainsock->accept(); //Will return sock, same as the argument.
Dunno why we get it both ways.
write("[%d] New connection from
%s\n",hash_value(sock),sock->query_address());
sock->set_read_callback(sockread);
sock->set_close_callback(sockgone);
sock->set_id(sock);
sock->write("Hello, world!\n");
}
int main()
{
//Load up three files...
//1) Certificate chain from the CSA
sscanf(Stdio.read_file("gd_bundle.crt"),"%{%*s-----BEGIN
CERTIFICATE-----%s-----END CERTIFICATE-----%}",array certs);
certs=MIME.decode_base64(certs[*][0][*]);
//2) Our certificate
sscanf(Stdio.read_file("demo.crt"),"%*s-----BEGIN
CERTIFICATE-----%s-----END CERTIFICATE-----",string crt);
certs=({MIME.decode_base64(crt)})+certs; //Ours first, chain following it
//3) Our private key
sscanf(Stdio.read_file("demo.key"),"%*s-----BEGIN RSA PRIVATE
KEY-----%s-----END RSA PRIVATE KEY-----",string key);
key=MIME.decode_base64(key);
write("Keys loaded successfully.\n");
Protocols.HTTP.Server.SSLPort(http_query,443,"::",key,certs);
object ctx=SSL.Context();
ctx->add_cert(Standards.PKCS.RSA.parse_private_key(key),certs,({"*"}));
mainsock=SSL.Port(ctx); mainsock->bind(1234,accept,"::");
write("Listening on ports 443 and 1234.\n");
return -1;
}
This is a dual server - HTTPS and a TLS-enabled telnet-like
connection. For this, I used a certificate that I bought from GoDaddy,
so the authority chain comes from the GoDaddy certificate bundle
(gd_bundle.crt). Using a self-signed cert would also work, and as
Grubba pointed out, Pike is quite capable of generating those.
It's pretty simple, and might even be simpler than I've shown here.
Note the one liner to set up HTTPS hosting... a simple reactive
function to handle requests, and you can completely ignore SSL and
just work with the requests themselves.
ChrisA
Chris Angelico
2015-06-23 06:31:51 UTC
Permalink
On Tue, Jun 23, 2015 at 4:21 PM, Trilok Tourani
Post by Trilok Tourani
The code that you have written in your previous mail, starts listening for
the ports, but when I connect a sock to 127.0.0.1:1234, it doesn't seem to
be calling the accept or http_query functions. It just hangs there.
(sock->connect("127.0.0.1",1234);)
Yep. It doesn't call those until key exchange etc is completed. Try
pulling up a terminal and running:

openssl s_client -connect 127.0.0.1:1234

That should show a quick dump of the certificate, and then give you a
telnet-like connection.

ChrisA
Trilok Tourani
2015-06-23 06:43:37 UTC
Permalink
okay got the certificate information. How do I proceed in connecting to
this port with pike? The tried it the same way you mentioned in your first
mail. But when I do ssl->write("....."); it just returns 0 every time. but
when I run sock->write("...."); it gives me some data.

Regards
Trilok Tourani
okay got the certificate information. How do I proceed in connecting to
this port with pike? The tried it the same way you mentioned in your first
mail. But when I do ssl->write("....."); it just returns 0 every time. but
when I run sock->write("...."); it gives me some data.
Regards
Trilok Tourani
Post by Chris Angelico
On Tue, Jun 23, 2015 at 4:21 PM, Trilok Tourani
Post by Trilok Tourani
The code that you have written in your previous mail, starts listening
for
Post by Trilok Tourani
the ports, but when I connect a sock to 127.0.0.1:1234, it doesn't
seem to
Post by Trilok Tourani
be calling the accept or http_query functions. It just hangs there.
(sock->connect("127.0.0.1",1234);)
Yep. It doesn't call those until key exchange etc is completed. Try
openssl s_client -connect 127.0.0.1:1234
That should show a quick dump of the certificate, and then give you a
telnet-like connection.
ChrisA
Chris Angelico
2015-06-23 06:51:39 UTC
Permalink
On Tue, Jun 23, 2015 at 4:43 PM, Trilok Tourani
okay got the certificate information. How do I proceed in connecting to this
port with pike? The tried it the same way you mentioned in your first mail.
But when I do ssl->write("....."); it just returns 0 every time. but when I
run sock->write("...."); it gives me some data.
You'll want to connect, then establish an SSL.File (or SSL.sslfile)
around that socket. Once you have that, it should all work. See the
earlier emails for examples, or you may have one already.

ChrisA
Trilok Tourani
2015-06-26 10:27:52 UTC
Permalink
The ssl->write("...") keeps returning 0 (ie. it is in the handshake phase),
and when I wait for it, the sock's fd becomes -1 and I am unable to write
again.

Also, my server on 127.0.0.1:1999, when i connect to it using openssl,
wireshark shows normal TCP packets, while when I openssl to gideon.rosuav,
it shows TLSv1.2 packets. But in both, I can see the master-key,
certificates, etc. Does this mean that there is some fault with my SSL port?

Regards
Trilok Tourani
Post by Chris Angelico
On Tue, Jun 23, 2015 at 4:43 PM, Trilok Tourani
Post by Trilok Tourani
okay got the certificate information. How do I proceed in connecting to
this
Post by Trilok Tourani
port with pike? The tried it the same way you mentioned in your first
mail.
Post by Trilok Tourani
But when I do ssl->write("....."); it just returns 0 every time. but
when I
Post by Trilok Tourani
run sock->write("...."); it gives me some data.
You'll want to connect, then establish an SSL.File (or SSL.sslfile)
around that socket. Once you have that, it should all work. See the
earlier emails for examples, or you may have one already.
ChrisA
Trilok Tourani
2015-06-26 15:20:06 UTC
Permalink
Also, In pike 8, my ssl object keeps showing SSL.File(Stdio.File("socket", "
runescape.com:443", 777 /* fd=10 */), SSL.ClientConnection(handshaking))
Like it is stuck on the handshaking phase.

any ideas on how to overcome it?

Regards
Trilok Tourani
Post by Trilok Tourani
The ssl->write("...") keeps returning 0 (ie. it is in the handshake
phase), and when I wait for it, the sock's fd becomes -1 and I am unable to
write again.
Also, my server on 127.0.0.1:1999, when i connect to it using openssl,
wireshark shows normal TCP packets, while when I openssl to gideon.rosuav,
it shows TLSv1.2 packets. But in both, I can see the master-key,
certificates, etc. Does this mean that there is some fault with my SSL port?
Regards
Trilok Tourani
Post by Chris Angelico
On Tue, Jun 23, 2015 at 4:43 PM, Trilok Tourani
Post by Trilok Tourani
okay got the certificate information. How do I proceed in connecting to
this
Post by Trilok Tourani
port with pike? The tried it the same way you mentioned in your first
mail.
Post by Trilok Tourani
But when I do ssl->write("....."); it just returns 0 every time. but
when I
Post by Trilok Tourani
run sock->write("...."); it gives me some data.
You'll want to connect, then establish an SSL.File (or SSL.sslfile)
around that socket. Once you have that, it should all work. See the
earlier emails for examples, or you may have one already.
ChrisA
Henrik Grubbström
2015-06-22 10:08:38 UTC
Permalink
Post by Chris Angelico
On Mon, Jun 22, 2015 at 6:11 AM, Trilok Tourani
Thanks a lot Chris. Can you also please elaborate when the server is built
with pike, in my case, it is the localhost(127.0.0.1).
and also, does SSL.context() generate its own random keys for us?
Let's keep this on the list - I'm not the greatest expert on all this,
and I'd rather have the chance that someone else might catch my
errors!
From what I understand, yes, the SSL module will generate all the
session keys and things. But it doesn't generate keys or certificates.
You have two basic options: Firstly, go through the usual commercial
signing route - search the web for SSL certificates, pick a nice cheap
one, go with that. Or alternatively, create a self-signed certificate
(again, search the web; you'll find instructions for doing that on
various platforms), and then have a copy of the certificate embedded
in the client. The latter is more secure if you control both ends,
plus it doesn't cost money.
Note that it's reasonably simple to generate self-signed certificates in
Pike; take a look at SSL.https for an example.
Post by Chris Angelico
Commercial certs are great if you want to
work with the broader internet, particularly web browsers.
Once you have those generated, all you need to do is parse them
(they're conventionally stored in an ASCII format, base-64 encoded
with some framing) and hand them on to the SSL port. It's been a while
since I did that, but I could probably dig up some example code to
show you.
/grubba
Henrik Grubbström
2015-06-22 10:03:43 UTC
Permalink
Post by Chris Angelico
On Mon, Jun 22, 2015 at 12:34 AM, Trilok Tourani
Post by Trilok Tourani
Can someone please tell me as to how to make a connection between a server
and a client, SSL protected?
I have tried using SSL.sslfile(Stdio.File demo, SSL.context ctx) function
but still don't understand how to make the data going through the connection
encrypted/decrypted.
Once you've done that, you don't read or write anything on the
underlying Stdio.File, you just use the SSL file. Anything you write
gets encrypted and then sent to the other end; everything you read has
first been decrypted. Generally, you can pretend that it's exactly the
same as a regular Stdio.File, although the abstraction leaks sometimes
(certain operations involve both reading and writing, even though you
wouldn't expect them to).
If you're building the server in Pike, you'll need to set up a key and
int main()
{
Stdio.File sock = Stdio.File();
sock->connect("gideon.rosuav.com", 443);
SSL.File ssl = SSL.File(sock, SSL.Context());
Note that with Pike 8.0 and later I believe that you need to also call
ssl->connect("gideon.rosuav.com") here.
Post by Chris Angelico
ssl->write("GET / HTTP/1.0\r\n\r\n");
write("Response:\n%s\n", ssl->read(1024,1));
}
Although you seem to be using a version of Pike that has SSL.sslfile
rather than SSL.File, but translate as appropriate.
Caveat emptor.

/grubba
Chris Angelico
2015-06-22 14:06:39 UTC
Permalink
Post by Henrik Grubbström
Post by Chris Angelico
int main()
{
Stdio.File sock = Stdio.File();
sock->connect("gideon.rosuav.com", 443);
SSL.File ssl = SSL.File(sock, SSL.Context());
Note that with Pike 8.0 and later I believe that you need to also call
ssl->connect("gideon.rosuav.com") here.
Post by Chris Angelico
ssl->write("GET / HTTP/1.0\r\n\r\n");
write("Response:\n%s\n", ssl->read(1024,1));
}
Interesting. I just tried with and without that on 8.1.2ish (latest
from git as of a few days ago), and it didn't fail, but it didn't
change anything. Is that to do with the SNI extension?

ChrisA
Henrik Grubbström
2015-06-29 15:46:13 UTC
Permalink
Post by Chris Angelico
Post by Henrik Grubbström
Post by Chris Angelico
int main()
{
Stdio.File sock = Stdio.File();
sock->connect("gideon.rosuav.com", 443);
SSL.File ssl = SSL.File(sock, SSL.Context());
Note that with Pike 8.0 and later I believe that you need to also call
ssl->connect("gideon.rosuav.com") here.
Post by Chris Angelico
ssl->write("GET / HTTP/1.0\r\n\r\n");
write("Response:\n%s\n", ssl->read(1024,1));
}
Interesting. I just tried with and without that on 8.1.2ish (latest
from git as of a few days ago), and it didn't fail, but it didn't
change anything. Is that to do with the SNI extension?
Yes, the argument is passed along to the SNI extension, but it also
sets up the low-level SSL state for operation as a client, which
includes queueing the initial client hello message for sending, so
I don't see how you could have it work without the call.

/grubba
--
Henrik Grubbström ***@roxen.com
Roxen Internet Software AB
Loading...