Remove unneeded Go code, update dependencies

main
Jan Dittberner 7 months ago
parent 30c7ddba80
commit 4ecdedadf7

2
.gitignore vendored

@ -1,7 +1,5 @@
*.pem
.*.swp
/translate.*.toml
/.idea/
/example_ca/
/node_modules/
/public/

@ -1,71 +0,0 @@
[CSRButtonLabel]
hash = "sha1-7f7bcb57602a96a49c8df4868fad7b81992e0734"
other = "Zertifikats-Signier-Anfrage erzeugen"
[CSRGenTitle]
hash = "sha1-f1a8f21b12fe51250da4a11f1c6ab28eab69b69d"
other = "CSR-Erzeugung im Browser"
[DownloadDescription]
hash = "sha1-f4a7826398e5c57c7feb4709ee939ea655f05469"
other = "Dein Schlüsselmaterial ist bereit zum Herunterladen. Die herunterladbare Datei enthält deinen privaten Schlüssel und dein Zertifikat verschlüsselt mit deinem Passwort. Du kannst die Datei jetzt verwenden, um dein Zertifikat in deinem Browser oder anderen Anwendungen zu installieren."
[DownloadLabel]
hash = "sha1-a479c9c34e878d07b4d67a73a48f432ad7dc53c8"
other = "Herunterladen"
["JavaScript.Certificate.Received"]
hash = "sha1-217622c21b50fcfb864802155080be482c285456"
other = "Zertifikat von der CA erhalten"
["JavaScript.Certificate.Waiting"]
hash = "sha1-0a528daa78d850d2c9360cdec82f6f849ffb6bcf"
other = "Warte auf Zertifikat ..."
["JavaScript.KeyGen.Generated"]
hash = "sha1-34cdfcdc837e3fc052733a3588cc3923b793103e"
other = "Schlüssel in __seconds__ Sekunden erzeugt"
["JavaScript.KeyGen.Running"]
hash = "sha1-fd272f37118fe10395f6238a3eae94685b5f8cf1"
other = "Schlüsselerzeugung läuft seit __seconds__ Sekunden"
["JavaScript.KeyGen.Started"]
hash = "sha1-e68739d705d5eb16317984a95a486fb9ff9bae6d"
other = "Schlüsselerzeugung gestartet"
[NameHelpText]
hash = "sha1-52b81217549e37d161090a04b7f84223a270928e"
other = "Gib deinen Namen so ein, wie er im Zertifikat erscheinen soll"
[NameLabel]
hash = "sha1-ab42293e29e1ffb306c1403dd95144d664853a60"
other = "Dein Name"
[PasswordLabel]
hash = "sha1-2b5e8edbf45819afdfa973c224b6b02d699e60de"
other = "Passwort für dein Client-Zertifikat"
[RSA2048Label]
hash = "sha1-2b1e7b638c31426d30d7e4bdebadbaa07d7521b0"
other = "2048 Bit (nicht empfohlen)"
[RSA3072Label]
hash = "sha1-97d1a8f9e8c5cf1f473b4a6fa0b5c39905f0f747"
other = "3072 Bit"
[RSA4096Label]
hash = "sha1-b14d7490195ac7f2d649f3b75dd2fe0daea53967"
other = "4096 Bit"
[RSAHelpText]
hash = "sha1-82511ecf2909ba189d7b16a828fce97c9359fad1"
other = "In Deinem Browser wird ein RSA-Schlüsselpaar erzeugt. Größere Schlüssellängen bieten eine erhöhte Sicherheit, benötigen aber bei der Erzeugung mehr Zeit."
[RSAKeySizeLabel]
hash = "sha1-bd446df78ad62000d6516a95594a24b98688e1fa"
other = "RSA-Schlüssellänge"
[StatusLoading]
hash = "sha1-530afa5bce434b05e3a10e83ff2567f7f8622af9"
other = "Lade ..."

@ -1,71 +0,0 @@
[CSRButtonLabel]
hash = "sha1-7f7bcb57602a96a49c8df4868fad7b81992e0734"
other = "Generate signing request"
[CSRGenTitle]
hash = "sha1-f1a8f21b12fe51250da4a11f1c6ab28eab69b69d"
other = "CSR generation in browser"
[DownloadDescription]
hash = "sha1-f4a7826398e5c57c7feb4709ee939ea655f05469"
other = "Your key material is ready for download. The downloadable file contains your private key and your certificate encrypted with your password. You can now use the file to install your certificate in your browser or other applications."
[DownloadLabel]
hash = "sha1-a479c9c34e878d07b4d67a73a48f432ad7dc53c8"
other = "Download"
["JavaScript.Certificate.Received"]
hash = "sha1-217622c21b50fcfb864802155080be482c285456"
other = "received certificate from CA"
["JavaScript.Certificate.Waiting"]
hash = "sha1-0a528daa78d850d2c9360cdec82f6f849ffb6bcf"
other = "waiting for certificate ..."
["JavaScript.KeyGen.Generated"]
hash = "sha1-34cdfcdc837e3fc052733a3588cc3923b793103e"
other = "key generated in __seconds__ seconds"
["JavaScript.KeyGen.Running"]
hash = "sha1-fd272f37118fe10395f6238a3eae94685b5f8cf1"
other = "key generation running for __seconds__ seconds"
["JavaScript.KeyGen.Started"]
hash = "sha1-e68739d705d5eb16317984a95a486fb9ff9bae6d"
other = "started key generation"
[NameHelpText]
hash = "sha1-52b81217549e37d161090a04b7f84223a270928e"
other = "Please input your name as it should be added to your certificate"
[NameLabel]
hash = "sha1-ab42293e29e1ffb306c1403dd95144d664853a60"
other = "Your name"
[PasswordLabel]
hash = "sha1-2b5e8edbf45819afdfa973c224b6b02d699e60de"
other = "Password for your client certificate"
[RSA2048Label]
hash = "sha1-2b1e7b638c31426d30d7e4bdebadbaa07d7521b0"
other = "2048 Bit (not recommended)"
[RSA3072Label]
hash = "sha1-97d1a8f9e8c5cf1f473b4a6fa0b5c39905f0f747"
other = "3072 Bit"
[RSA4096Label]
hash = "sha1-b14d7490195ac7f2d649f3b75dd2fe0daea53967"
other = "4096 Bit"
[RSAHelpText]
hash = "sha1-82511ecf2909ba189d7b16a828fce97c9359fad1"
other = "An RSA key pair will be generated in your browser. Longer key sizes provide better security but take longer to generate."
[RSAKeySizeLabel]
hash = "sha1-bd446df78ad62000d6516a95594a24b98688e1fa"
other = "RSA Key Size"
[StatusLoading]
hash = "sha1-530afa5bce434b05e3a10e83ff2567f7f8622af9"
other = "Loading ..."

@ -1,18 +0,0 @@
CSRButtonLabel = "Generate signing request"
CSRGenTitle = "CSR generation in browser"
DownloadDescription = "Your key material is ready for download. The downloadable file contains your private key and your certificate encrypted with your password. You can now use the file to install your certificate in your browser or other applications."
DownloadLabel = "Download"
"JavaScript.Certificate.Received" = "received certificate from CA"
"JavaScript.Certificate.Waiting" = "waiting for certificate ..."
"JavaScript.KeyGen.Generated" = "key generated in __seconds__ seconds"
"JavaScript.KeyGen.Running" = "key generation running for __seconds__ seconds"
"JavaScript.KeyGen.Started" = "started key generation"
NameHelpText = "Please input your name as it should be added to your certificate"
NameLabel = "Your name"
PasswordLabel = "Password for your client certificate"
RSA2048Label = "2048 Bit (not recommended)"
RSA3072Label = "3072 Bit"
RSA4096Label = "4096 Bit"
RSAHelpText = "An RSA key pair will be generated in your browser. Longer key sizes provide better security but take longer to generate."
RSAKeySizeLabel = "RSA Key Size"
StatusLoading = "Loading ..."

140
ca.cnf

@ -1,140 +0,0 @@
extensions = v3_ext
[ca]
default_ca = sub_ca
[rootca]
dir = ./example_ca/root
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
serial = $dir/serial
new_certs_dir = $dir/newcerts
crl = $dir/crl.pem
certificate = $dir/ca.crt.pem
private_key = $dir/private/ca.key.pem
RANDFILE = $dir/private/.rand
policy = policy_any
unique_subject = no
email_in_dn = no
copy_extensions = none
default_md = sha256
default_days = 1825
default_crl_days = 30
[sub_ca]
dir = ./example_ca/sub
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
serial = $dir/serial
new_certs_dir = $dir/newcerts
crl = $dir/crl.pem
certificate = $dir/ca.crt.pem
private_key = $dir/private/ca.key.pem
RANDFILE = $dir/private/.rand
unique_subject = no
email_in_dn = no
default_md = sha256
default_days = 365
default_crl_days = 30
[email_ca]
dir = ./example_ca/email
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
serial = $dir/serial
new_certs_dir = $dir/newcerts
crl = $dir/crl.pem
certificate = $dir/ca.crt.pem
private_key = $dir/private/ca.key.pem
RANDFILE = $dir/private/.rand
unique_subject = no
email_in_dn = no
default_md = sha256
default_days = 365
default_crl_days = 30
[policy_any]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[policy_match]
commonName = supplied
[email_ext]
basicConstraints = critical,CA:false
keyUsage = keyEncipherment,digitalSignature,nonRepudiation
extendedKeyUsage = clientAuth,emailProtection
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
authorityInfoAccess = 1.3.6.1.5.5.7.48.2;URI:http://example.org/ca/root/ca.crt,OCSP;URI:http://ocsp.example.org/
crlDistributionPoints = URI:http://crl.example.org/email.crl
[req]
default_bits = 3072
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = root_ca
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = CH
countryName_min = 2
countryName_max = 2
localityName = Locality Name (eg, city)
organizationName = Organization Name (eg, company)
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
[req_attributes]
[root_ca]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
[ext_sub_ca]
basicConstraints = critical,CA:true,pathlen:0
keyUsage = critical,keyCertSign,cRLSign
extendedKeyUsage = serverAuth,clientAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
authorityInfoAccess = 1.3.6.1.5.5.7.48.2;URI:http://example.org/ca/root/ca.crt,OCSP;URI:http://ocsp.example.org/
crlDistributionPoints = URI:http://crl.example.org/sub.crl
certificatePolicies = @policy_sub_ca
[ext_email_ca]
basicConstraints = critical,CA:true,pathlen:0
keyUsage = critical,keyCertSign,cRLSign
extendedKeyUsage = clientAuth,emailProtection
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
authorityInfoAccess = 1.3.6.1.5.5.7.48.2;URI:http://example.org/ca/root/ca.crt,OCSP;URI:http://ocsp.example.org/
crlDistributionPoints = URI:http://crl.example.org/email.crl
certificatePolicies = @policy_email_ca
[policy_sub_ca]
policyIdentifier = 1.3.6.1.5.5.7.2.1
CPS = http://example.org/ca/sub/cps.html
[policy_email_ca]
policyIdentifier = 1.3.6.1.5.5.7.2.1
CPS = http://example.org/ca/email/cps.html

@ -1,8 +0,0 @@
package main
import (
_ "code.cacert.org/jandd/poc-browser-csr-generation/migrations"
)
func main() {
}

@ -1,17 +0,0 @@
module code.cacert.org/jandd/poc-browser-csr-generation
go 1.13
require (
github.com/BurntSushi/toml v0.3.1
github.com/go-sql-driver/mysql v1.5.0
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.0.4
github.com/gorilla/csrf v1.7.0
github.com/nicksnyder/go-i18n/v2 v2.1.1
github.com/pressly/goose v2.6.0+incompatible
github.com/sirupsen/logrus v1.7.0
golang.org/x/text v0.3.4
gopkg.in/yaml.v2 v2.4.0 // indirect
)

@ -1,40 +0,0 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.4 h1:5eXU1CZhpQdq5kXbKb+sECH5Ia5KiO6CYzIzdlVx6Bs=
github.com/gobwas/ws v1.0.4/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/gorilla/csrf v1.7.0 h1:mMPjV5/3Zd460xCavIkppUdvnl5fPXMpv2uz2Zyg7/Y=
github.com/gorilla/csrf v1.7.0/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/nicksnyder/go-i18n/v2 v2.1.1 h1:ATCOanRDlrfKVB4WHAdJnLEqZtDmKYsweqsOUYflnBU=
github.com/nicksnyder/go-i18n/v2 v2.1.1/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pressly/goose v2.6.0+incompatible h1:3f8zIQ8rfgP9tyI0Hmcs2YNAqUCL1c+diLe3iU8Qd/k=
github.com/pressly/goose v2.6.0+incompatible/go.mod h1:m+QHWCqxR3k8D9l7qfzuC/djtlfzxr34mozWDYEu1z8=
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

@ -36,12 +36,8 @@ function jsMinify() {
function publishAssets() {
return src([
'node_modules/popper.js/dist/*.js',
'node_modules/popper.js/dist/*.map',
'node_modules/jquery/dist/*.*',
'node_modules/bootstrap/dist/js/*.*',
'node_modules/node-forge/dist/*.*',
'node_modules/i18next-client/i18next.min.js',
'node_modules/bootstrap/dist/js/bootstrap.bundle.*',
'node_modules/node-forge/dist/forge.min.js',
]).pipe(dest('public/js'));
}

@ -1,107 +0,0 @@
package handlers
import (
"html/template"
"net/http"
"github.com/gorilla/csrf"
"github.com/nicksnyder/go-i18n/v2/i18n"
log "github.com/sirupsen/logrus"
)
type IndexHandler struct {
bundle *i18n.Bundle
}
func NewIndexHandler(bundle *i18n.Bundle) *IndexHandler {
return &IndexHandler{bundle: bundle}
}
func (i *IndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {
http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
return
}
if r.URL.Path != "/" {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
localizer := i18n.NewLocalizer(i.bundle, r.Header.Get("Accept-Language"))
csrGenTitle := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "CSRGenTitle",
Other: "CSR generation in browser",
}})
nameLabel := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "NameLabel",
Other: "Your name",
}})
nameHelpText := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "NameHelpText",
Other: "Please input your name as it should be added to your certificate",
}})
passwordLabel := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "PasswordLabel",
Other: "Password for your client certificate",
}})
rsaKeySizeLegend := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "RSAKeySizeLabel",
Other: "RSA Key Size",
}})
rsa3072Label := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "RSA3072Label",
Other: "3072 Bit",
}})
rsa2048Label := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "RSA2048Label",
Other: "2048 Bit (not recommended)",
}})
rsa4096Label := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "RSA4096Label",
Other: "4096 Bit",
}})
rsaHelpText := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "RSAHelpText",
Other: "An RSA key pair will be generated in your browser. Longer key" +
" sizes provide better security but take longer to generate.",
}})
csrButtonLabel := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "CSRButtonLabel",
Other: "Generate signing request",
}})
statusLoading := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "StatusLoading",
Other: "Loading ...",
}})
downloadLabel := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "DownloadLabel",
Other: "Download",
}})
downloadDescription := localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "DownloadDescription",
Other: "Your key material is ready for download. The downloadable file contains your private key and your" +
" certificate encrypted with your password. You can now use the file to install your certificate in your" +
" browser or other applications.",
}})
t := template.Must(template.ParseFiles("templates/index.html"))
err := t.Execute(w, map[string]interface{}{
"Title": csrGenTitle,
"NameLabel": nameLabel,
"NameHelpText": nameHelpText,
"PasswordLabel": passwordLabel,
"RSAKeySizeLegend": rsaKeySizeLegend,
"RSA3072Label": rsa3072Label,
"RSA2048Label": rsa2048Label,
"RSA4096Label": rsa4096Label,
"RSAHelpText": rsaHelpText,
"CSRButtonLabel": csrButtonLabel,
"StatusLoading": statusLoading,
"DownloadDescription": downloadDescription,
"DownloadLabel": downloadLabel,
csrf.TemplateTag: csrf.TemplateField(r),
})
if err != nil {
log.Panic(err)
}
}

@ -1,67 +0,0 @@
package handlers
import (
"encoding/json"
"net/http"
"strings"
"github.com/nicksnyder/go-i18n/v2/i18n"
)
type JSLocalesHandler struct {
bundle *i18n.Bundle
}
func NewJSLocalesHandler(bundle *i18n.Bundle) *JSLocalesHandler {
return &JSLocalesHandler{bundle: bundle}
}
func (j *JSLocalesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) != 4 {
http.Error(w, "Not found", http.StatusNotFound)
return
}
lang := parts[2]
localizer := i18n.NewLocalizer(j.bundle, lang)
type translationData struct {
Keygen struct {
Started string `json:"started"`
Running string `json:"running"`
Generated string `json:"generated"`
} `json:"keygen"`
Certificate struct {
Waiting string `json:"waiting"`
Received string `json:"received"`
} `json:"certificate"`
}
translations := &translationData{}
translations.Keygen.Started = localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "JavaScript.KeyGen.Started",
Other: "started key generation",
}})
translations.Keygen.Running = localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "JavaScript.KeyGen.Running",
Other: "key generation running for __seconds__ seconds",
}})
translations.Keygen.Generated = localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "JavaScript.KeyGen.Generated",
Other: "key generated in __seconds__ seconds",
}})
translations.Certificate.Waiting = localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "JavaScript.Certificate.Waiting",
Other: "waiting for certificate ...",
}})
translations.Certificate.Received = localizer.MustLocalize(&i18n.LocalizeConfig{DefaultMessage: &i18n.Message{
ID: "JavaScript.Certificate.Received",
Other: "received certificate from CA",
}})
encoder := json.NewEncoder(w)
if err := encoder.Encode(translations); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

@ -1,215 +0,0 @@
package handlers
import (
"bytes"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"os"
"os/exec"
"time"
log "github.com/sirupsen/logrus"
)
type SigningRequestRegistry struct {
caCertificates []*x509.Certificate
caChainMap map[string][]string
requests map[string]chan *responseData
}
func NewSigningRequestRegistry(caCertificates []*x509.Certificate) *SigningRequestRegistry {
return &SigningRequestRegistry{
caCertificates: caCertificates,
caChainMap: make(map[string][]string),
requests: make(map[string]chan *responseData),
}
}
type SigningRequestAttributes struct {
CommonName string
CSRBytes []byte
RequestToken string
}
func (registry *SigningRequestRegistry) AddSigningRequest(request *requestData) (string, error) {
requestToken, csrBytes, err := validateCsr(request.Csr)
if err != nil {
return "", err
}
requestAttributes := &SigningRequestAttributes{
CommonName: request.CommonName,
CSRBytes: csrBytes,
RequestToken: requestToken,
}
go func() {
responseChannel := make(chan *responseData, 1)
registry.requests[requestToken] = responseChannel
registry.signCertificate(responseChannel, requestAttributes)
}()
return requestToken, nil
}
func validateCsr(csr string) (string, []byte, error) {
csrBlock, _ := pem.Decode([]byte(csr))
if csrBlock == nil {
return "", nil, errors.New("request data did not contain valid PEM data")
}
if csrBlock.Type != "CERTIFICATE REQUEST" {
return "", nil, fmt.Errorf("request is not valid, type in PEM data is %s", csrBlock.Type)
}
var err error
var csrContent *x509.CertificateRequest
csrContent, err = x509.ParseCertificateRequest(csrBlock.Bytes)
if err != nil {
return "", nil, err
}
if err = csrContent.CheckSignature(); err != nil {
log.Errorf("invalid CSR signature %v", err)
return "", nil, err
}
// generate request token as defined in CAB Baseline Requirements 1.7.3 Request Token definition
requestToken := fmt.Sprintf(
"%s%x", time.Now().UTC().Format("200601021504"), sha256.Sum256(csrContent.Raw),
)
log.Debugf("generated request token %s", requestToken)
return requestToken, csrContent.Raw, nil
}
func (registry *SigningRequestRegistry) signCertificate(channel chan *responseData, request *SigningRequestAttributes) {
responseData, err := registry.sign(request)
if err != nil {
log.Error(err)
close(channel)
return
}
channel <- responseData
}
func (registry *SigningRequestRegistry) sign(request *SigningRequestAttributes) (*responseData, error) {
log.Infof("handling signing request %s", request.RequestToken)
subjectDN := fmt.Sprintf("/CN=%s", request.CommonName)
var err error
var csrFile *os.File
if csrFile, err = ioutil.TempFile("", "*.csr.pem"); err != nil {
log.Errorf("could not open temporary file: %s", err)
return nil, err
}
if err = pem.Encode(csrFile, &pem.Block{
Type: "CERTIFICATE REQUEST",
Bytes: request.CSRBytes,
}); err != nil {
log.Errorf("could not write CSR to file: %s", err)
return nil, err
}
if err = csrFile.Close(); err != nil {
log.Errorf("could not close CSR file: %s", err)
return nil, err
}
defer func(file *os.File) {
err = os.Remove(file.Name())
if err != nil {
log.Errorf("could not remove temporary file: %s", err)
}
}(csrFile)
// simulate a delay during certificate creation
time.Sleep(5 * time.Second)
opensslCommand := exec.Command(
"openssl", "ca", "-config", "ca.cnf", "-name", "email_ca",
"-policy", "policy_match", "-extensions", "email_ext",
"-batch", "-subj", subjectDN, "-utf8", "-rand_serial", "-in", csrFile.Name())
var out, cmdErr bytes.Buffer
opensslCommand.Stdout = &out
opensslCommand.Stderr = &cmdErr
err = opensslCommand.Run()
if err != nil {
log.Error(err)
log.Error(cmdErr.String())
return nil, err
}
var block *pem.Block
if block, _ = pem.Decode(out.Bytes()); block == nil {
err = fmt.Errorf("could not decode pem")
return nil, err
}
var certificate *x509.Certificate
if certificate, err = x509.ParseCertificate(block.Bytes); err != nil {
return nil, err
}
var caChain []string
if caChain, err = registry.getCAChain(certificate); err != nil {
return nil, err
}
response := &responseData{
Certificate: string(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: certificate.Raw,
})),
CAChain: caChain,
}
return response, nil
}
func (registry *SigningRequestRegistry) GetResponseChannel(requestUuid string) (chan *responseData, error) {
if responseChannel, exists := registry.requests[requestUuid]; exists {
delete(registry.requests, requestUuid)
return responseChannel, nil
} else {
return nil, errors.New("no request found")
}
}
func (registry *SigningRequestRegistry) getCAChain(certificate *x509.Certificate) ([]string, error) {
issuerString := string(certificate.RawIssuer)
if value, exists := registry.caChainMap[issuerString]; exists {
return value, nil
}
result := make([]string, 0)
appendCert := func(cert *x509.Certificate) {
result = append(
result,
string(pem.EncodeToMemory(&pem.Block{Bytes: cert.Raw, Type: "CERTIFICATE"})))
log.Debugf("added %s to cachain", result[len(result)-1])
}
var previous *x509.Certificate
var count = 0
for {
if len(registry.caCertificates) == 0 {
return nil, errors.New("no CA certificates loaded")
}
if count > len(registry.caCertificates) {
return nil, errors.New("could not construct certificate chain")
}
for _, caCert := range registry.caCertificates {
if previous == nil {
if bytes.Equal(caCert.RawSubject, certificate.RawIssuer) {
previous = caCert
appendCert(caCert)
}
} else if bytes.Equal(previous.RawSubject, previous.RawIssuer) {
registry.caChainMap[issuerString] = result
return result, nil
} else if bytes.Equal(caCert.RawSubject, previous.RawIssuer) {
previous = caCert
appendCert(caCert)
} else {
log.Debugf("skipped certificate %s", caCert.Subject)
}
}
count++
}
}

@ -1,62 +0,0 @@
package handlers
import (
"encoding/json"
"net/http"
log "github.com/sirupsen/logrus"
)
type CertificateSigningHandler struct {
requestRegistry *SigningRequestRegistry
}
func NewCertificateSigningHandler(requestRegistry *SigningRequestRegistry) *CertificateSigningHandler {
return &CertificateSigningHandler{requestRegistry: requestRegistry}
}
func (h *CertificateSigningHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Only POST requests support", http.StatusMethodNotAllowed)
return
}
if r.Header.Get("content-type") != "application/json" {
http.Error(w, "Only JSON content is accepted", http.StatusNotAcceptable)
return
}
var err error
var requestBody requestData
if err = json.NewDecoder(r.Body).Decode(&requestBody); err != nil {
log.Error(err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
type acceptedResponse struct {
RequestId string `json:"request_id"`
}
taskUuid, err := h.requestRegistry.AddSigningRequest(&requestBody)
if err != nil {
log.Error(err)
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusAccepted)
response := &acceptedResponse{RequestId: taskUuid}
if err = json.NewEncoder(w).Encode(response); err != nil {
log.Print(err)
}
}
type requestData struct {
Csr string `json:"csr"`
CommonName string `json:"common_name"`
}
type responseData struct {
Certificate string `json:"certificate"`
CAChain []string `json:"ca_chain"`
}

@ -1,79 +0,0 @@
package handlers
import (
"encoding/json"
"net/http"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
log "github.com/sirupsen/logrus"
)
type WebSocketHandler struct {
requestRegistry *SigningRequestRegistry
}
func NewWebSocketHandler(registry *SigningRequestRegistry) *WebSocketHandler {
return &WebSocketHandler{requestRegistry: registry}
}
func (w *WebSocketHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
conn, _, _, err := ws.UpgradeHTTP(request, writer)
if err != nil {
http.Error(writer, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
go func() {
defer func() { _ = conn.Close() }()
var (
reader = wsutil.NewReader(conn, ws.StateServerSide)
writer = wsutil.NewWriter(conn, ws.StateServerSide, ws.OpText)
jsonDecoder = json.NewDecoder(reader)
jsonEncoder = json.NewEncoder(writer)
)
for {
header, err := reader.NextFrame()
if err != nil {
log.Error(err)
break
}
if header.OpCode == ws.OpClose {
log.Debug("channel closed")
break
}
type requestType struct {
RequestId string `json:"request_id"`
}
request := &requestType{}
err = jsonDecoder.Decode(request)
if err != nil {
log.Error(err)
break
}
channel, err := w.requestRegistry.GetResponseChannel(request.RequestId)
if err != nil {
log.Error(err)
break
}
var response *responseData
response = <-channel
if err = jsonEncoder.Encode(response); err != nil {
log.Error(err)
break
}
close(channel)
if err = writer.Flush(); err != nil {
log.Error(err)
break
}
}
}()
}

@ -1,148 +0,0 @@
package main
import (
"crypto/rand"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/signal"
"path/filepath"
"strings"
"syscall"
"time"
"github.com/BurntSushi/toml"
"github.com/gorilla/csrf"
"github.com/nicksnyder/go-i18n/v2/i18n"
log "github.com/sirupsen/logrus"
"golang.org/x/text/language"
"code.cacert.org/jandd/poc-browser-csr-generation/handlers"
)
func main() {
log.SetFormatter(&log.TextFormatter{
FullTimestamp: true,
})
bundle := loadI18nBundle()
mux := http.NewServeMux()
csrfKey := initCSRFKey()
signingRequestRegistry := handlers.NewSigningRequestRegistry(loadCACertificates())
mux.Handle("/sign/", handlers.NewCertificateSigningHandler(signingRequestRegistry))
mux.Handle("/", handlers.NewIndexHandler(bundle))
fileServer := http.FileServer(http.Dir("./public"))
mux.Handle("/css/", fileServer)
mux.Handle("/js/", fileServer)
mux.Handle("/locales/", handlers.NewJSLocalesHandler(bundle))
mux.Handle("/ws/", handlers.NewWebSocketHandler(signingRequestRegistry))
tlsConfig := &tls.Config{
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
},
NextProtos: []string{"h2"},
PreferServerCipherSuites: true,
MinVersion: tls.VersionTLS12,
}
server := http.Server{
Addr: ":8000",
Handler: csrf.Protect(csrfKey, csrf.FieldName("csrfToken"), csrf.RequestHeader("X-CSRF-Token"))(mux),
TLSConfig: tlsConfig,
ReadTimeout: 20 * time.Second,
ReadHeaderTimeout: 5 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 30 * time.Second,
}
go func() {
err := server.ListenAndServeTLS("server.crt.pem", "server.key.pem")
if err != nil {
log.Fatal(err)
}
}()
var hostPort string
if strings.HasPrefix(server.Addr, ":") {
hostPort = fmt.Sprintf("localhost%s", server.Addr)
} else {
hostPort = server.Addr
}
log.Infof("started web server on https://%s/", hostPort)
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
s := <-c
log.Infof("received %s, shutting down", s)
_ = server.Close()
}
func loadI18nBundle() *i18n.Bundle {
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
for _, lang := range []string{"en-US", "de-DE"} {
if _, err := bundle.LoadMessageFile(fmt.Sprintf("active.%s.toml", lang)); err != nil {
log.Panic(err)
}
}
return bundle
}
func initCSRFKey() []byte {
var csrfKey []byte = nil
if csrfB64, exists := os.LookupEnv("CSRF_KEY"); exists {
csrfKey, _ = base64.RawStdEncoding.DecodeString(csrfB64)
log.Info("read CSRF key from environment variable")
}
if csrfKey == nil {
csrfKey = generateRandomBytes(32)
log.Infof(
"generated new random CSRF key, set environment variable CSRF_KEY to %s to "+
"keep the same key for new sessions",
base64.RawStdEncoding.EncodeToString(csrfKey))
}
return csrfKey
}
func generateRandomBytes(count int) []byte {
randomBytes := make([]byte, count)
_, err := rand.Read(randomBytes)
if err != nil {
log.Fatalf("could not read random bytes: %v", err)
return nil
}
return randomBytes
}
func loadCACertificates() (caCertificates []*x509.Certificate) {
var err error
caFiles, err := filepath.Glob("example_ca/*/ca.crt.pem")
if err != nil {
log.Panic(err)
}
caCertificates = make([]*x509.Certificate, len(caFiles))
for index, certFile := range caFiles {
var certBytes []byte
if certBytes, err = ioutil.ReadFile(certFile); err != nil {
log.Panic(err)
}
var block *pem.Block
if block, _ = pem.Decode(certBytes); block == nil {
log.Panicf("no PEM data found in %s", certFile)
return
}
if caCertificates[index], err = x509.ParseCertificate(block.Bytes); err != nil {
log.Panic(err)
}
}
log.Infof("read %d CA certificates", len(caCertificates))
return
}

@ -1,615 +0,0 @@
-- +goose Up
-- LibreSSL - CAcert web application
-- Copyright (C) 2004-2020 CAcert Inc.
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; version 2 of the License.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-- Initial database schema
CREATE TABLE `abusereports` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`when` datetime NOT NULL,
`IP` int(11) DEFAULT NULL,
`url` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`comment` varchar(255) NOT NULL,
`reason` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `addlang` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userid` int(11) NOT NULL,
`lang` varchar(5) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `userid` (`userid`, `lang`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `adminlog` (
`when` datetime NOT NULL,
`uid` int(11) NOT NULL,
`adminid` int(11) NOT NULL,
`actiontypeid` int(11) DEFAULT NULL,
`old-lname` varchar(255),
`old-dob` varchar(255),
`new-lname` varchar(255),
`new-dob` varchar(255)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `advertising` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`replaceid` int(10) UNSIGNED NOT NULL,
`replaced` tinyint(3) UNSIGNED NOT NULL,
`orderid` tinyint(3) UNSIGNED NOT NULL,
`link` varchar(255) NOT NULL,
`title` varchar(255) NOT NULL,
`months` tinyint(3) UNSIGNED NOT NULL,
`who` int(10) UNSIGNED NOT NULL,
`when` datetime NOT NULL,
`active` tinyint(3) UNSIGNED NOT NULL,
`approvedby` int(10) UNSIGNED NOT NULL,
`expires` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `alerts` (
`memid` int(11) NOT NULL DEFAULT 0,
`general` tinyint(1) NOT NULL DEFAULT 0,
`country` tinyint(1) NOT NULL DEFAULT 0,
`regional` tinyint(1) NOT NULL DEFAULT 0,
`radius` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`memid`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `baddomains` (
`domain` varchar(255) NOT NULL DEFAULT ''
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `cats_passed` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`variant_id` int(11) NOT NULL,
`pass_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP(),
PRIMARY KEY (`id`),
UNIQUE KEY `test_passed` (`user_id`, `variant_id`, `pass_date`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `cats_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type_text` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `type_text` (`type_text`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `cats_variant` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type_id` int(11) NOT NULL,
`test_text` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `test_text` (`test_text`, `type_id`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `countries` (
`id` int(3) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '',
`acount` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `disputedomain` (
`id` int(11) NOT NULL DEFAULT 0,
`memid` int(11) NOT NULL DEFAULT 0,
`oldmemid` int(11) NOT NULL DEFAULT 0,
`domain` varchar(255) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`hash` varchar(50) NOT NULL DEFAULT '',
`attempts` int(1) NOT NULL DEFAULT 0,
`action` enum ('accept','reject','failed') NOT NULL DEFAULT 'accept'
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `disputeemail` (
`id` int(11) NOT NULL DEFAULT 0,
`memid` int(11) NOT NULL DEFAULT 0,
`oldmemid` int(11) NOT NULL DEFAULT 0,
`email` varchar(255) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`hash` varchar(50) NOT NULL DEFAULT '',
`attempts` int(1) NOT NULL DEFAULT 0,
`action` enum ('accept','reject','failed') NOT NULL DEFAULT 'accept',
`IP` varchar(20) NOT NULL DEFAULT ''
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `domaincerts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`domid` int(11) NOT NULL DEFAULT 0,
`serial` varchar(50) NOT NULL DEFAULT '',
`CN` varchar(255) NOT NULL DEFAULT '',
`subject` text NOT NULL,
`csr_name` varchar(255) NOT NULL DEFAULT '',
`crt_name` varchar(255) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`revoked` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`expire` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`warning` tinyint(1) NOT NULL DEFAULT 0,
`renewed` tinyint(1) NOT NULL DEFAULT 0,
`rootcert` int(2) NOT NULL DEFAULT 1,
`md` enum ('md5','sha1','sha256','sha512') NOT NULL DEFAULT 'sha512',
`type` tinyint(4) DEFAULT NULL,
`pkhash` char(40) DEFAULT NULL,
`certhash` char(40) DEFAULT NULL,
`coll_found` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `domaincerts_pkhash` (`pkhash`),
KEY `revoked` (`revoked`),
KEY `created` (`created`),
KEY `domid` (`domid`),
KEY `serial` (`serial`),
KEY `stats_domaincerts_expire` (`expire`),
KEY `domaincrt` (`crt_name`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `domains` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`memid` int(11) NOT NULL DEFAULT 0,
`domain` varchar(255) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`deleted` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`hash` varchar(50) NOT NULL DEFAULT '',
`attempts` int(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `memid` (`memid`),
KEY `domain` (`domain`),
KEY `memid_2` (`memid`),
KEY `stats_domains_hash` (`hash`),
KEY `stats_domains_deleted` (`deleted`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `domlink` (
`certid` int(11) NOT NULL DEFAULT 0,
`domid` int(11) NOT NULL DEFAULT 0,
UNIQUE KEY `index` (`certid`, `domid`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `email` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`memid` int(11) NOT NULL DEFAULT 0,
`email` varchar(255) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`deleted` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`hash` varchar(50) NOT NULL DEFAULT '',
`attempts` int(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `memid` (`memid`),
KEY `stats_email_hash` (`hash`),
KEY `stats_email_deleted` (`deleted`),
KEY `email` (`email`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `emailcerts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`memid` int(11) NOT NULL DEFAULT 0,
`serial` varchar(50) NOT NULL DEFAULT '',
`CN` varchar(255) NOT NULL DEFAULT '',
`subject` text NOT NULL,
`keytype` char(2) NOT NULL DEFAULT 'NS',
`codesign` tinyint(1) NOT NULL DEFAULT 0,
`csr_name` varchar(255) NOT NULL DEFAULT '',
`crt_name` varchar(255) NOT NULL DEFAULT '',
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`revoked` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`expire` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`warning` tinyint(1) NOT NULL DEFAULT 0,
`renewed` tinyint(1) NOT NULL DEFAULT 0,
`rootcert` int(2) NOT NULL DEFAULT 1,
`md` enum ('md5','sha1','sha256','sha512') NOT NULL DEFAULT 'sha512',
`type` tinyint(4) DEFAULT NULL,
`disablelogin` int(1) NOT NULL DEFAULT 0,
`pkhash` char(40) DEFAULT NULL,
`certhash` char(40) DEFAULT NULL,
`coll_found` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
KEY `emailcerts_pkhash` (`pkhash`),
KEY `revoked` (`revoked`),
KEY `created` (`created`),
KEY `memid` (`memid`),
KEY `serial` (`serial`),
KEY `stats_emailcerts_expire` (`expire`),
KEY `emailcrt` (`crt_name`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `emaillink` (
`emailcertsid` int(11) NOT NULL DEFAULT 0,
`emailid` int(11) NOT NULL DEFAULT 0,
KEY `index` (`emailcertsid`, `emailid`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `gpg` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`memid` int(11) NOT NULL DEFAULT 0,
`email` varchar(255) NOT NULL DEFAULT '',
`level` int(1) NOT NULL DEFAULT 0,
`multiple` tinyint(1) NOT NULL DEFAULT 0,
`expires` tinyint(1) NOT NULL DEFAULT 0,
`csr` varchar(255) NOT NULL DEFAULT '',
`crt` varchar(255) NOT NULL DEFAULT '',
`issued` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`expire` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`keyid` char(18) DEFAULT NULL,
`warning` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `stats_gpg_expire` (`expire`),
KEY `stats_gpg_issued` (`issued`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `languages` (
`locale` varchar(5) NOT NULL,
`en_co` varchar(255) NOT NULL,
`en_lang` varchar(255) NOT NULL,
`country` varchar(255) NOT NULL,
`lang` varchar(255) NOT NULL
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `localias` (
`locid` int(11) NOT NULL DEFAULT 0,
`name` varchar(255) NOT NULL DEFAULT '',
KEY `locid` (`locid`),
KEY `name` (`name`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `locations` (
`id` int(7) NOT NULL AUTO_INCREMENT,
`regid` int(4) NOT NULL DEFAULT 0,
`ccid` int(3) NOT NULL DEFAULT 0,
`name` varchar(50) NOT NULL DEFAULT '',
`lat` double(6, 3) NOT NULL DEFAULT 0.000,
`long` double(6, 3) NOT NULL DEFAULT 0.000,
`acount` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `ccid` (`ccid`),
KEY `regid` (`regid`),
KEY `name` (`name`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `news` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`when` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`who` varchar(255) NOT NULL DEFAULT '',
`short` varchar(255) NOT NULL DEFAULT '',
`story` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE = MyISAM
DEFAULT CHARSET = latin1;
CREATE TABLE `notary` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`from` int(11) NOT NULL DEFAULT 0,
`to` int(11) NOT NULL DEFAULT 0,
`awarded` int(3) NOT NULL DEFAULT 0,
`points` int(3) NOT NULL DEFAULT 0,
`method` enum ('Face to Face Meeting','Trusted Third Parties','Thawte Points Transfer','Administrative Increase','CT Magazine - Germany','Temporary Increase','Unknown') NOT NULL DEFAULT 'Face to Face Meeting',
`location` varchar(255) NOT NULL DEFAULT '',
`date` varchar(255) NOT NULL DEFAULT '',
`when` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`expire` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`sponsor` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `from` (`from`),
KEY `to` (`to`),
KEY `from_2` (`from`),
KEY `to_2` (`to`),
KEY `stats_notary_when` (`when`),