crypto/tls, http: Make HTTPS servers easier.

R=r, adg, rsc
CC=golang-dev
https://golang.org/cl/1684051
diff --git a/src/pkg/crypto/tls/tls.go b/src/pkg/crypto/tls/tls.go
index 1a5da3a..874f944 100644
--- a/src/pkg/crypto/tls/tls.go
+++ b/src/pkg/crypto/tls/tls.go
@@ -6,8 +6,12 @@
 package tls
 
 import (
-	"os"
+	"io/ioutil"
 	"net"
+	"os"
+	"encoding/pem"
+	"crypto/rsa"
+	"crypto/x509"
 )
 
 func Server(conn net.Conn, config *Config) *Conn {
@@ -65,3 +69,52 @@
 	}
 	return Client(c, nil), nil
 }
+
+// LoadX509KeyPair
+func LoadX509KeyPair(certFile string, keyFile string) (cert Certificate, err os.Error) {
+	certPEMBlock, err := ioutil.ReadFile(certFile)
+	if err != nil {
+		return
+	}
+
+	certDERBlock, _ := pem.Decode(certPEMBlock)
+	if certDERBlock == nil {
+		err = os.ErrorString("failed to parse certificate PEM data")
+		return
+	}
+
+	cert.Certificate = [][]byte{certDERBlock.Bytes}
+
+	keyPEMBlock, err := ioutil.ReadFile(keyFile)
+	if err != nil {
+		return
+	}
+
+	keyDERBlock, _ := pem.Decode(keyPEMBlock)
+	if keyDERBlock == nil {
+		err = os.ErrorString("failed to parse key PEM data")
+		return
+	}
+
+	key, err := x509.ParsePKCS1PrivateKey(keyDERBlock.Bytes)
+	if err != nil {
+		err = os.ErrorString("failed to parse key")
+		return
+	}
+
+	cert.PrivateKey = key
+
+	// We don't need to parse the public key for TLS, but we so do anyway
+	// to check that it looks sane and matches the private key.
+	x509Cert, err := x509.ParseCertificate(certDERBlock.Bytes)
+	if err != nil {
+		return
+	}
+
+	if x509Cert.PublicKeyAlgorithm != x509.RSA || x509Cert.PublicKey.(*rsa.PublicKey).N.Cmp(key.PublicKey.N) != 0 {
+		err = os.ErrorString("Private key does not match public key")
+		return
+	}
+
+	return
+}