HTTPS

816 views
Skip to first unread message

Hans Stimer

unread,
Nov 14, 2009, 8:23:04 PM11/14/09
to golang-nuts
Does the HTTP library support HTTPS?

Russ Cox

unread,
Nov 14, 2009, 8:47:52 PM11/14/09
to Hans Stimer, golang-nuts
On Sat, Nov 14, 2009 at 17:23, Hans Stimer <hans....@gmail.com> wrote:
> Does the HTTP library support HTTPS?

No, not yet, but soon. There is a preliminary
TLS server code in crypto/tls, and I think the
client code is close.

Russ

Adam Langley

unread,
Nov 14, 2009, 8:50:19 PM11/14/09
to Hans Stimer, golang-nuts
On Sat, Nov 14, 2009 at 5:23 PM, Hans Stimer <hans....@gmail.com> wrote:
> Does the HTTP library support HTTPS?

(repost since the first didn't seem to go through:)


There's basic support for TLS serving in crypto/tls.

There's basic support for TLS as a client in my local working directory.

You could try something like this (you'll need to move it out of
package tls by importing crypto/tls and putting tls. in front of the
local names).

If you're not on amd64, it'll be very slow.



// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package tls

import (
"net";
"os";
"io";
"encoding/pem";
"crypto/x509";
"testing";
"time";
"http";
)

func currentTime() uint32 {
return uint32(time.Seconds());
}

func readFile(name string) ([]byte, os.Error) {
file, err := os.Open(name, os.O_RDONLY, 0);
if err != nil {
return nil, err;
}
stat, err := file.Stat();
if err != nil {
return nil, err;
}
contents := make([]byte, stat.Size);
_, err = io.ReadFull(file, contents);
if err != nil {
return nil, err;
}
file.Close();
return contents, nil;
}

func TestServer(t *testing.T) {
urandom, err := os.Open("/dev/urandom", os.O_RDONLY, 0);
if err != nil {
t.Errorf("Failed to open urandom: %s\n", err);
return;
}

pemBytes, err := readFile("server.crt");
if err != nil {
t.Errorf("Failed to read server.crt: %s", err);
return;
}
cert, _ := pem.Decode(pemBytes);
if cert == nil {
t.Error("Failed to parse server.crt");
return;
}

keyBytes, err := readFile("server.key.insecure");
if err != nil {
t.Errorf("Failed to read server.key.insecure: %s", err);
return;
}
pkPEM, _ := pem.Decode(keyBytes);
if pkPEM == nil {
t.Errorf("Failed to parse server.key.insecure: %s", err);
return;
}
if pkPEM.Type != "RSA PRIVATE KEY" {
t.Errorf("server.key.insecure is not an RSA private key. Found '%s'",
pkPEM.Type);
return;
}
if len(pkPEM.Headers) != 0 {
t.Error("server.key.insecure has headers and is probably encrypted.");
return;
}
priv, err := x509.ParsePKCS1PrivateKey(pkPEM.Bytes);
if err != nil {
t.Errorf("Invalid key in server.key.insecure: %s", err);
return;
}

config := new(Config);
config.Rand = urandom;
config.Time = time.Seconds;
config.Certificates = make([]Certificate, 1);
config.Certificates[0].Certificate = [][]byte{cert.Bytes};
config.Certificates[0].PrivateKey = priv;

l, err := net.ListenTCP("tcp",
&net.TCPAddr{net.ParseIP("0.0.0.0"), 8555});
if err != nil {
t.Errorf("Cannot bind: %s\n", err);
return;
}

tls := NewTLSListener(l, config);

http.Serve(tls, http.NotFoundHandler());
}

Hans Stimer

unread,
Nov 14, 2009, 9:04:07 PM11/14/09
to golang-nuts
Thank you. When is the client going to be checked in?

On Nov 14, 5:50 pm, Adam Langley <a...@golang.org> wrote:

Adam Langley

unread,
Nov 14, 2009, 9:08:25 PM11/14/09
to Hans Stimer, golang-nuts
On Sat, Nov 14, 2009 at 6:04 PM, Hans Stimer <hans....@gmail.com> wrote:
> Thank you. When is the client going to be checked in?

Probably not for a few weeks given the number of entries on the bug
tracker I'm afraid.


AGL

Greg

unread,
Nov 29, 2009, 6:51:10 PM11/29/09
to golang-nuts
So, I tried the code above and modified it to this:
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main


import (
"net";
"crypto/tls";
config := new(tls.Config);
config.Rand = urandom;
config.Time = time.Seconds;
config.Certificates = make([]tls.Certificate, 1);
config.Certificates[0].Certificate = [][]byte{cert.Bytes};
config.Certificates[0].PrivateKey = priv;

l, err := net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP
("0.0.0.0"), 8555});
if err != nil {
t.Errorf("Cannot bind: %s\n", err);
return;
}

ptls := tls.NewListener(l, config);

http.Serve(ptls, http.NotFoundHandler());

}
--------

I end up with this as a compile time error:
server.go:102: implicit assignment of tls.Listener field 'listener' in
function argument

I'm new to "go" and still getting my head around an object matching an
interface as a side-effect of published methods. It seems that
tls.Listener object should "match" a net.Listener interface. I think
that is the intent, but don't understand why it wouldn't work.

Ian Lance Taylor

unread,
Nov 29, 2009, 8:10:34 PM11/29/09
to Greg, golang-nuts
Greg <galt...@austin.rr.com> writes:

> ptls := tls.NewListener(l, config);
>
> http.Serve(ptls, http.NotFoundHandler());

> I end up with this as a compile time error:
> server.go:102: implicit assignment of tls.Listener field 'listener' in
> function argument

This is a confusing error message in this context. The problem is
that ptls has type tls.Listener. tls.Listener is a struct which has a
field named 'listener'. Because 'listener' starts with a lower case
letter, it is not visible outside of the tls package. When you try to
use ptls as a net.Listener interface value, you are implicitly asking
the compiler to copy the value. That is invalid, and that is what the
compiler is warning you about.

The fix is simple:
http.Serve(&ptls, http.NotFoundHandler());
&ptl also matches the net.Listener interface, and it does not require
copying the hidden field.

Ian

Greg Althaus

unread,
Nov 29, 2009, 8:28:03 PM11/29/09
to Ian Lance Taylor, golang-nuts
Thank you!
Reply all
Reply to author
Forward
0 new messages