Merge pull request #1 from joshlf/stealchain-server

Add stealchain-server utility
This commit is contained in:
Kyle Isom 2017-08-28 17:39:30 -07:00 committed by GitHub
commit 70d7ff505b
2 changed files with 100 additions and 0 deletions

View File

@ -0,0 +1,17 @@
stealchain-server
This is a utility to extract the verified X.509 chain from a TLS
connection initiated by another client. It listens on a port, and
for each connection, it will dump the certificates that the peer
actually sent (and not the verified chain that is built from this).
It was written to assist in debugging issues with certificate chains.
There are a few knobs:
-listen specifies the address to listen on.
-ca allows the trusted CA roots to be specified via a PEM bundle of
root certificates.
-verify requires that the client present a valid certificate chain.

View File

@ -0,0 +1,83 @@
package main
import (
"crypto/rand"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"flag"
"fmt"
"io/ioutil"
"net"
"os"
"github.com/kisom/goutils/die"
)
func main() {
cfg := &tls.Config{}
var sysRoot, listenAddr string
var verify bool
flag.StringVar(&sysRoot, "ca", "", "provide an alternate CA bundle")
flag.StringVar(&listenAddr, "listen", ":443", "address to listen on")
flag.BoolVar(&verify, "verify", false, "verify client certificates")
flag.Parse()
if verify {
cfg.ClientAuth = tls.RequireAndVerifyClientCert
}
if sysRoot != "" {
pemList, err := ioutil.ReadFile(sysRoot)
die.If(err)
roots := x509.NewCertPool()
if !roots.AppendCertsFromPEM(pemList) {
fmt.Printf("[!] no valid roots found")
roots = nil
}
cfg.RootCAs = roots
}
l, err := net.Listen("tcp", listenAddr)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
for {
conn, err := l.Accept()
if err != nil {
fmt.Println(err.Error())
}
raddr := conn.RemoteAddr()
tconn := tls.Server(conn, cfg)
cs := tconn.ConnectionState()
if len(cs.PeerCertificates) == 0 {
fmt.Printf("[+] %v: no chain presented\n", raddr)
continue
}
var chain []byte
for _, cert := range cs.PeerCertificates {
p := &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
}
chain = append(chain, pem.EncodeToMemory(p)...)
}
var nonce [16]byte
_, err = rand.Read(nonce[:])
if err != nil {
panic(err)
}
fname := fmt.Sprintf("%v-%v.pem", raddr, hex.EncodeToString(nonce[:]))
err = ioutil.WriteFile(fname, chain, 0644)
die.If(err)
fmt.Printf("%v: [+] wrote %v.\n", raddr, fname)
}
}