Commit d05728a8 authored by Heiko Reese's avatar Heiko Reese
Browse files

parent b6632e61
......@@ -5,7 +5,6 @@ import (
_ "encoding/gob"
_ "log"
"sync"
//"git.scc.kit.edu/heiko.reese/CertificateStats"
)
type CertCache struct {
......@@ -36,6 +35,13 @@ func (cc *CertCache) Delete(serial string) {
cc.Unlock()
}
func (cc *CertCache) Len() int {
cc.RLock()
l := len(cc.certs)
cc.RUnlock()
return l
}
func (cc *CertCache) Get(serial string) *SearchableCert {
cc.RLock()
cert, present := cc.certs[serial]
......
......@@ -4,81 +4,11 @@ import (
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"reflect"
"strings"
"time"
)
/*
type pkixelement struct {
OID asn1.ObjectIdentifier
Prefix string
Name string
}
var (
oidNames = map[string]pkixelement{
"2.5.4.3": pkixelement{asn1.ObjectIdentifier{2, 5, 4, 3}, "CN", "CommonName"},
"1.2.840.113549.1.9.1": pkixelement{asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, "email", "email"},
"2.5.4.11": pkixelement{asn1.ObjectIdentifier{2, 5, 4, 11}, "OU", "OrganizationalUnit"},
"2.5.4.10": pkixelement{asn1.ObjectIdentifier{2, 5, 4, 10}, "O", "Organization"},
"2.5.4.7": pkixelement{asn1.ObjectIdentifier{2, 5, 4, 7}, "L", "Locality"},
"2.5.4.8": pkixelement{asn1.ObjectIdentifier{2, 5, 4, 8}, "ST", "Province"},
"2.5.4.6": pkixelement{asn1.ObjectIdentifier{2, 5, 4, 6}, "C", "Country"},
}
)
*/
var (
// C=DE, ST=Baden-Wuerttemberg, L=Karlsruhe, O=Karlsruhe Institute of Technology, OU=Steinbuch Centre for Computing, CN=KIT-CA/emailAddress=ca@kit.edu
RawIssuerG1 = []byte{
0x30, 0x81, 0xbf, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45,
0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x42, 0x61, 0x64, 0x65, 0x6e,
0x2d, 0x57, 0x75, 0x65, 0x72, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x67, 0x31, 0x12, 0x30,
0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x4b, 0x61, 0x72, 0x6c, 0x73, 0x72, 0x75, 0x68,
0x65, 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x21, 0x4b, 0x61, 0x72, 0x6c,
0x73, 0x72, 0x75, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x20,
0x6f, 0x66, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x31, 0x27, 0x30,
0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1e, 0x53, 0x74, 0x65, 0x69, 0x6e, 0x62, 0x75, 0x63,
0x68, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x43, 0x6f, 0x6d,
0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
0x06, 0x4b, 0x49, 0x54, 0x2d, 0x43, 0x41, 0x31, 0x19, 0x30, 0x17, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0a, 0x63, 0x61, 0x40, 0x6b, 0x69, 0x74, 0x2e, 0x65,
0x64, 0x75,
}
// C=DE, ST=Baden-Wuerttemberg, L=Karlsruhe, O=Karlsruhe Institute of Technology, CN=KIT-CA
RawIssuerG2 = []uint8{
0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31,
0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x12, 0x42, 0x61, 0x64, 0x65, 0x6e, 0x2d,
0x57, 0x75, 0x65, 0x72, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x67, 0x31, 0x12, 0x30, 0x10,
0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x4b, 0x61, 0x72, 0x6c, 0x73, 0x72, 0x75, 0x68, 0x65,
0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x21, 0x4b, 0x61, 0x72, 0x6c, 0x73,
0x72, 0x75, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x20, 0x6f,
0x66, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x31, 0x0f, 0x30, 0x0d,
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x06, 0x4b, 0x49, 0x54, 0x2d, 0x43, 0x41,
}
)
var (
SignatureAlgorithmNames = map[x509.SignatureAlgorithm]string{
x509.UnknownSignatureAlgorithm: "UnknownSignatureAlgorithm",
x509.MD2WithRSA: "MD2WithRSA",
x509.MD5WithRSA: "MD5WithRSA",
x509.SHA1WithRSA: "SHA1WithRSA",
x509.SHA256WithRSA: "SHA256WithRSA",
x509.SHA384WithRSA: "SHA384WithRSA",
x509.SHA512WithRSA: "SHA512WithRSA",
x509.DSAWithSHA1: "DSAWithSHA1",
x509.DSAWithSHA256: "DSAWithSHA256",
x509.ECDSAWithSHA1: "ECDSAWithSHA1",
x509.ECDSAWithSHA256: "ECDSAWithSHA256",
x509.ECDSAWithSHA384: "ECDSAWithSHA384",
x509.ECDSAWithSHA512: "ECDSAWithSHA512",
}
oidEmail = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}
)
type SearchableCert struct {
Serial string `json:serial`
HexSerial string `json:hexserial`
......
package websearch
import (
"crypto/x509"
"encoding/pem"
"io/ioutil"
"log"
)
func ReadCertificates(filenames ...string) []*x509.Certificate {
var (
allcerts []*x509.Certificate = make([]*x509.Certificate, 0, len(filenames))
block *pem.Block
)
for _, filename := range filenames {
// read certificate
content, err := ioutil.ReadFile(filename)
if err == nil {
// extract all certificates
for {
block, content = pem.Decode(content)
if block == nil {
break
}
// process only certificates
if block.Type == "CERTIFICATE" {
certs, err := x509.ParseCertificates(block.Bytes)
if err != nil {
log.Println(err.Error())
continue
}
for _, cert := range certs {
allcerts = append(allcerts, cert)
}
}
}
} else {
log.Println(err)
}
}
return allcerts
}
......@@ -9,7 +9,7 @@ import (
)
func main() {
f, _ := ioutil.ReadFile("net-dashboard-1.tmn.scc.kit.edu-2019-07-09-8854737385717428272297305380.pem")
f, _ := ioutil.ReadFile("cmd_dumpcert/net-dashboard-1.tmn.scc.kit.edu-2019-07-09-8854737385717428272297305380.pem")
block, _ := pem.Decode(f)
certs, _ := x509.ParseCertificates(block.Bytes)
//pkey := certs[0].PublicKey.(*rsa.PublicKey).N.BitLen()
......
package main
import (
"errors"
"flag"
"fmt"
"fmt"
"path/filepath"
. "git.scc.kit.edu/KIT-CA/websearch"
"github.com/gorilla/mux"
"io"
"io/ioutil"
"log"
"math/big"
"net"
"net/http"
"net/http/fcgi"
"strings"
"sync"
"time"
_ "github.com/k0kubun/pp"
)
const (
......@@ -23,19 +23,20 @@ const (
)
var (
localaddr string
modeArg string
mode int
serialG2Start big.Int
serialG1Cutoff big.Int
localaddr string
modeArg string
mode int
ccache CertCache
allCertDir string
watcherDone chan bool
newFileChan chan string
)
func init() {
serialG2Start.SetString("8926168349745120614054526923", 10)
serialG1Cutoff.SetString("9000000000000000000000000000", 10) // TODO: anpassen sobald bekannt
// flag parsing
flag.StringVar(&modeArg, "mode", "local", "Mode of operation: local (local webserver), tcp (FCGI via localaddr) or unix (FCGI via UNIX socket at localaddr)")
flag.StringVar(&localaddr, "localaddr", "localhost:8000", "Local bind address (local, tcp) oder filename of UNIX socket (unix)")
flag.StringVar(&allCertDir, "certdir", "Certificates/.archive/", "Location of certificate files")
flag.Parse()
modeArg = strings.TrimSpace(strings.ToLower(modeArg))
switch modeArg {
......@@ -48,9 +49,12 @@ func init() {
default:
log.Fatalln("Unknown mode:", modeArg)
}
// initialize CertCache
ccache = NewCertCache()
}
func getcert(w http.ResponseWriter, r *http.Request) {
func getcertHandler(w http.ResponseWriter, r *http.Request) {
headers := w.Header()
headers.Add("Content-Type", "text/html")
serial := mux.Vars(r)["serial"]
......@@ -58,71 +62,44 @@ func getcert(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, whichca)
}
const (
kitcag1 = "kit-ca"
kitcag2 = "kit-ca-g2"
getcertTempl = "https://pki.pca.dfn.de/%s/cgi-bin/pub/pki?cmd=send_email_cert&type=email&dataType=CERTIFICATE&key=%s"
installcertTempl = "https://pki.pca.dfn.de/%s/cgi-bin/pub/pki?cmd=getcert&type=CERTIFICATE&key=%s"
testCertURL = getcertTempl
)
func main() {
var err error
func BuildCertificateLink(serial string) (string, error) {
// convert to integer
var sernum big.Int
_, ok := sernum.SetString(serial, 10)
if !ok {
return "", errors.New("Unable to convert serial number to bigint")
}
// alte CA (kurze nummern, serial kleiner als erstes g2)
if len(serial) == 8 || len(serial) == 14 || sernum.Cmp(&serialG2Start) < 1 {
return kitcag1, nil
}
// neue CA (seriennummer größer als letztes g1)
if sernum.Cmp(&serialG1Cutoff) == 1 {
return kitcag2, nil
}
// ab hier callout
var wg sync.WaitGroup
calloutResults := make(chan string, 2)
// call both CAs in parallel
for _, ca := range [...]string{kitcag1, kitcag2} {
wg.Add(1)
go func(c string) {
defer wg.Done()
// timeout after 15 secs
var netClient = &http.Client{
Timeout: time.Second * 15,
}
// ask
resp, err := netClient.Head(fmt.Sprintf(testCertURL, ca, serial))
if err != nil {
return
// create watcher for new certificates
NewDirectoryWatcher(allCertDir, watcherDone, newFileChan)
go func(newFileChan chan string) {
select {
case newcert := <-newFileChan:
for _, c := range ReadCertificates(newcert) {
log.Println("Adding new certificate", newcert)
ccache.Add(c)
}
if resp.Header.Get("Content-Type") == "application/x-x509-email-cert" {
calloutResults <- ca
}
}(ca)
}
// wait for callouts to return
wg.Wait()
close(calloutResults)
// take first success and roll with it
for thisCA := range calloutResults {
return thisCA, nil
}
}(newFileChan)
// read initial batch of certificates
files, err := ioutil.ReadDir(allCertDir)
if err != nil {
log.Fatal(err)
}
// TODO: what now? both callouts failed
return "", errors.New("both callouts failed")
}
allfiles := make([]string, len(files))
for _, file := range files {
if !file.IsDir() {
fmt.Println(allCertDir, file.Name(), filepath.Join(allCertDir, file.Name()))
allfiles = append(allfiles, filepath.Join(allCertDir, file.Name()))
}
}
for _, c := range ReadCertificates(allfiles...) {
ccache.Add(c)
}
func main() {
// create http interface
r := mux.NewRouter()
r.HandleFunc("/p/getcert/{serial}", getcert)
r.HandleFunc("/p/getcert/{serial}", getcertHandler)
// TODO: was tun bei anderen anfragen?
//r.NotFoundHandler = http.HandlerFunc
var err error
log.Printf("Serving %s via %s", modeArg, localaddr)
switch mode {
case local:
......
package websearch
import (
"encoding/asn1"
"crypto/x509"
)
const (
kitcag1 = "kit-ca-g1"
kitcag2 = "kit-ca-g2"
)
var (
// C=DE, ST=Baden-Wuerttemberg, L=Karlsruhe, O=Karlsruhe Institute of Technology, OU=Steinbuch Centre for Computing, CN=KIT-CA/emailAddress=ca@kit.edu
RawIssuerG1 = []byte{
0x30, 0x81, 0xbf, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45,
0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x42, 0x61, 0x64, 0x65, 0x6e,
0x2d, 0x57, 0x75, 0x65, 0x72, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x67, 0x31, 0x12, 0x30,
0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x4b, 0x61, 0x72, 0x6c, 0x73, 0x72, 0x75, 0x68,
0x65, 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x21, 0x4b, 0x61, 0x72, 0x6c,
0x73, 0x72, 0x75, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x20,
0x6f, 0x66, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x31, 0x27, 0x30,
0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1e, 0x53, 0x74, 0x65, 0x69, 0x6e, 0x62, 0x75, 0x63,
0x68, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x43, 0x6f, 0x6d,
0x70, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
0x06, 0x4b, 0x49, 0x54, 0x2d, 0x43, 0x41, 0x31, 0x19, 0x30, 0x17, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0a, 0x63, 0x61, 0x40, 0x6b, 0x69, 0x74, 0x2e, 0x65,
0x64, 0x75,
}
// C=DE, ST=Baden-Wuerttemberg, L=Karlsruhe, O=Karlsruhe Institute of Technology, CN=KIT-CA
RawIssuerG2 = []byte{
0x30, 0x7b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31,
0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x12, 0x42, 0x61, 0x64, 0x65, 0x6e, 0x2d,
0x57, 0x75, 0x65, 0x72, 0x74, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x67, 0x31, 0x12, 0x30, 0x10,
0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x4b, 0x61, 0x72, 0x6c, 0x73, 0x72, 0x75, 0x68, 0x65,
0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x21, 0x4b, 0x61, 0x72, 0x6c, 0x73,
0x72, 0x75, 0x68, 0x65, 0x20, 0x49, 0x6e, 0x73, 0x74, 0x69, 0x74, 0x75, 0x74, 0x65, 0x20, 0x6f,
0x66, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x31, 0x0f, 0x30, 0x0d,
0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x06, 0x4b, 0x49, 0x54, 0x2d, 0x43, 0x41,
}
RawIssuers = map[string][]byte{
kitcag1 : RawIssuerG1,
kitcag2 : RawIssuerG2,
}
)
var (
SignatureAlgorithmNames = map[x509.SignatureAlgorithm]string{
x509.UnknownSignatureAlgorithm: "UnknownSignatureAlgorithm",
x509.MD2WithRSA: "MD2WithRSA",
x509.MD5WithRSA: "MD5WithRSA",
x509.SHA1WithRSA: "SHA1WithRSA",
x509.SHA256WithRSA: "SHA256WithRSA",
x509.SHA384WithRSA: "SHA384WithRSA",
x509.SHA512WithRSA: "SHA512WithRSA",
x509.DSAWithSHA1: "DSAWithSHA1",
x509.DSAWithSHA256: "DSAWithSHA256",
x509.ECDSAWithSHA1: "ECDSAWithSHA1",
x509.ECDSAWithSHA256: "ECDSAWithSHA256",
x509.ECDSAWithSHA384: "ECDSAWithSHA384",
x509.ECDSAWithSHA512: "ECDSAWithSHA512",
}
oidEmail = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}
)
package websearch
import (
"math/big"
"errors"
)
var (
serialG2Start big.Int
serialG1Cutoff big.Int
)
func init() {
serialG2Start.SetString("8926168349745120614054526923", 10)
serialG1Cutoff.SetString("99000000000000000000000000000", 10) // TODO: anpassen sobald bekannt
}
const (
getcertTempl = "https://pki.pca.dfn.de/%s/cgi-bin/pub/pki?cmd=send_email_cert&type=email&dataType=CERTIFICATE&key=%s"
installcertTempl = "https://pki.pca.dfn.de/%s/cgi-bin/pub/pki?cmd=getcert&type=CERTIFICATE&key=%s"
testCertURL = getcertTempl
)
func BuildCertificateLink(serial string) (string, error) {
// convert to integer
var sernum big.Int
_, ok := sernum.SetString(serial, 10)
if !ok {
return "", errors.New("Unable to convert serial number to bigint")
}
// alte CA (kurze nummern, serial kleiner als erstes g2)
if len(serial) == 8 || len(serial) == 14 || sernum.Cmp(&serialG2Start) < 1 {
return kitcag1, nil
}
// neue CA (seriennummer größer als letztes g1)
if sernum.Cmp(&serialG1Cutoff) == 1 {
return kitcag2, nil
}
// TODO: memdb befragen
return "", errors.New("both callouts failed")
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment