Initial import.

This commit is contained in:
Kyle Isom
2015-06-10 16:29:52 -07:00
commit 7391da8567
12 changed files with 365 additions and 0 deletions

19
cmd/certchain/README Normal file
View File

@@ -0,0 +1,19 @@
certchain
This is a utility for printing the X.509 certificate chain from a TLS
connection.
Note: while this will accept more than one server, it will print all
of the chains without any indication where one chain ends and the next
begins. This was the intended behaviour for the use case, but it may
not be applicable in other cases.
There are no knobs.
Examples:
$ certchain www.kyleisom.net
-----BEGIN CERTIFICATE-----
MIIFUTCCBDmgAwIBAgIQaaTVw0yZFGAYvFDKAIo4BzANBgkqhkiG9w0BAQsFADCB
kDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxNjA0BgNV
...

View File

@@ -0,0 +1,39 @@
package main
import (
"crypto/tls"
"encoding/pem"
"flag"
"fmt"
"regexp"
"github.com/kisom/goutils/die"
)
var hasPort = regexp.MustCompile(`:\d+$`)
func main() {
flag.Parse()
for _, server := range flag.Args() {
if !hasPort.MatchString(server) {
server += ":443"
}
var chain string
conn, err := tls.Dial("tcp", server, nil)
die.If(err)
details := conn.ConnectionState()
for _, cert := range details.PeerCertificates {
p := pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
}
chain += string(pem.EncodeToMemory(&p))
}
fmt.Println(chain)
}
}

18
cmd/csrpubdump/README Normal file
View File

@@ -0,0 +1,18 @@
csrpubdump
This is a small utility to dump the public key from an X.509 certificate
signature request (CSR) to a standard RFC 5280 PKIX public key format.
There are no command line flags; it accepts a number of PEM- or
DER-enoded CSRs and outputs a public key of the same name as the CSR
with the suffix ".pub" appended.
Example:
$ csrpubdump cert.csr
[+] wrote cert.csr.pub.
$ openssl req -text -in cert.csr -modulus | grep ^Modulus
Modulus=C7021819792D3ADE906156868B6475B67E475325A1AAD6C50BFD8CFE007A4B7C50E89CCA91EF14EEB13AD4B01E8FABDF6884AA74B9CAFFF4D4FD8C26ECAA9DD9DC4D232C3A54FFEE7EBB4CCD34BB4D4AFFD73FB2880A10A8E5CA99533FBC85746FDC3AEFFDA8A6FF25A95DDB010B15813AC6AD910C5CB1CA264E07783B67B1716B977A69D7C647067336D50BE3FF2CF8BCA2A9DC3D2357E441DEB4E29A1914DD30AD0B3895F8564D47E0D2B1EE879C2018A3F75736696EDF056F5BCD8DF6C7B688711B63C253A272F837356D27D4CD67109DE9E9F39F16E05F33EE9179C9B767151DF5DC78E8B2A5E71B6F33213ACE69D3131DA27ACCE86011A7D43965CECE33687C50456B622E0804FE213458D6D0BF82AA711B01FFCAE54DD7D046F14A67D3E1C089EDA62821DF48100A4FF5DEE2E98F79AC526C8A96B16F1C93E7776F8A2BF5166FE5C651713DE88A426DF92406EBDA56E0E01B6FE001B2CFCD22EAE2EB3D1EEC311E20BE739B2489A9DB581DD35837BFBEBFDC4136C2F822C53A204CB7F9
$ openssl rsa -pubin -text -in cert.csr.pub -modulus | grep ^Modulus
Modulus=C7021819792D3ADE906156868B6475B67E475325A1AAD6C50BFD8CFE007A4B7C50E89CCA91EF14EEB13AD4B01E8FABDF6884AA74B9CAFFF4D4FD8C26ECAA9DD9DC4D232C3A54FFEE7EBB4CCD34BB4D4AFFD73FB2880A10A8E5CA99533FBC85746FDC3AEFFDA8A6FF25A95DDB010B15813AC6AD910C5CB1CA264E07783B67B1716B977A69D7C647067336D50BE3FF2CF8BCA2A9DC3D2357E441DEB4E29A1914DD30AD0B3895F8564D47E0D2B1EE879C2018A3F75736696EDF056F5BCD8DF6C7B688711B63C253A272F837356D27D4CD67109DE9E9F39F16E05F33EE9179C9B767151DF5DC78E8B2A5E71B6F33213ACE69D3131DA27ACCE86011A7D43965CECE33687C50456B622E0804FE213458D6D0BF82AA711B01FFCAE54DD7D046F14A67D3E1C089EDA62821DF48100A4FF5DEE2E98F79AC526C8A96B16F1C93E7776F8A2BF5166FE5C651713DE88A426DF92406EBDA56E0E01B6FE001B2CFCD22EAE2EB3D1EEC311E20BE739B2489A9DB581DD35837BFBEBFDC4136C2F822C53A204CB7F9

55
cmd/csrpubdump/pubdump.go Normal file
View File

@@ -0,0 +1,55 @@
package main
import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"flag"
"fmt"
"io/ioutil"
"log"
"github.com/kisom/die"
)
func main() {
flag.Parse()
for _, fileName := range flag.Args() {
in, err := ioutil.ReadFile(fileName)
die.If(err)
if p, _ := pem.Decode(in); p != nil {
if p.Type != "CERTIFICATE REQUEST" {
log.Fatal("INVALID FILE TYPE")
}
in = p.Bytes
}
csr, err := x509.ParseCertificateRequest(in)
die.If(err)
out, err := x509.MarshalPKIXPublicKey(csr.PublicKey)
die.If(err)
var t string
switch pub := csr.PublicKey.(type) {
case *rsa.PublicKey:
t = "RSA PUBLIC KEY"
case *ecdsa.PublicKey:
t = "EC PUBLIC KEY"
default:
die.With("unrecognised public key type %T", pub)
}
p := &pem.Block{
Type: t,
Bytes: out,
}
err = ioutil.WriteFile(fileName+".pub", pem.EncodeToMemory(p), 0644)
die.If(err)
fmt.Printf("[+] wrote %s.\n", fileName+".pub")
}
}

20
cmd/readchain/README Normal file
View File

@@ -0,0 +1,20 @@
readchain
This is a small utility to read a chain of PEM-encoded X.509 certificates
and print their common names. It was written to quickly see what certificates
were in a bundle.
It is called with the files containing chains to read passed in as an
argument. The program has no knobs or widgets to adjust.
Examples:
$ readchain google.com.pem microsoft.com.pem
[+] google.com.pem:
*.google.com
Google Internet Authority G2
GeoTrust Global CA
[+] microsoft.com.pem:
microsoft.com
MSIT Machine Auth CA 2
Microsoft Internet Authority

40
cmd/readchain/chain.go Normal file
View File

@@ -0,0 +1,40 @@
package main
import (
"crypto/x509"
"encoding/pem"
"flag"
"fmt"
"io/ioutil"
"os"
)
func main() {
flag.Parse()
for _, fileName := range flag.Args() {
data, err := ioutil.ReadFile(fileName)
if err != nil {
fmt.Fprintf(os.Stderr, "[!] %s: %v\n", fileName, err)
continue
}
fmt.Printf("[+] %s:\n", fileName)
rest := data[:]
for {
var p *pem.Block
p, rest = pem.Decode(rest)
if p == nil {
break
}
cert, err := x509.ParseCertificate(p.Bytes)
if err != nil {
fmt.Fprintf(os.Stderr, "[!] %s: %v\n", fileName, err)
break
}
fmt.Printf("\t%+v\n", cert.Subject.CommonName)
}
}
}

42
cmd/stealchain/README Normal file
View File

@@ -0,0 +1,42 @@
stealchain
This is a utility to extract the verified X.509 chain from a TLS
connection. It takes a list of sites on the command line; for each
site that it can connect to, 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:
-ca allows the trusted CA roots to be specified via a PEM bundle of
root certificates.
-sni specifies the server name for SNI. This applies to all hosts in
the run; if this is run as
$ stealchain -sni foo.com foo.com bar.com
it will attempt to use "foo.com" as the server name for both hosts.
-noverify skips certificate verification. This might be useful for seeing
what certificates a server is actually sending.
Examples:
$ stealchain kyleisom.net
[+] wrote kyleisom.net.pem.
$ readchain kyleisom.net.pem
[+] kyleisom.net.pem:
*.kyleisom.net
COMODO RSA Domain Validation Secure Server CA
$ stealchain google.com microsoft.com apple.com amazon.com
[+] wrote google.com.pem.
[+] wrote microsoft.com.pem.
[+] wrote apple.com.pem.
[+] wrote amazon.com.pem.

63
cmd/stealchain/thief.go Normal file
View File

@@ -0,0 +1,63 @@
package main
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"flag"
"fmt"
"io/ioutil"
"os"
"github.com/kisom/goutils/die"
)
func main() {
var cfg = &tls.Config{}
var sysRoot, serverName string
flag.StringVar(&sysRoot, "ca", "", "provide an alternate CA bundle")
flag.StringVar(&cfg.ServerName, "sni", cfg.ServerName, "provide an SNI name")
flag.BoolVar(&cfg.InsecureSkipVerify, "noverify", false, "don't verify certificates")
flag.Parse()
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
}
if serverName != "" {
cfg.ServerName = serverName
}
for _, site := range flag.Args() {
conn, err := tls.Dial("tcp", site+":443", cfg)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
cs := conn.ConnectionState()
var chain []byte
for _, cert := range cs.PeerCertificates {
p := &pem.Block{
Type: "CERTIFICATE",
Bytes: cert.Raw,
}
chain = append(chain, pem.EncodeToMemory(p)...)
}
err = ioutil.WriteFile(site+".pem", chain, 0644)
die.If(err)
fmt.Printf("[+] wrote %s.pem.\n", site)
}
}