aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorRasmus Dahlberg <rasmus.dahlberg@kau.se>2020-10-23 18:01:10 +0200
committerRasmus Dahlberg <rasmus.dahlberg@kau.se>2020-10-23 18:01:10 +0200
commit9b38f5a034486c27eaf81062ecdd86a72667e2b0 (patch)
treef2c7a4e4c485214f81aa66882ea69f93c1aa85d1 /server
parent7d62710808a38102c09c4f18b1309bf63051db5e (diff)
added basic trust-anchor code path
Pretty much the bare minimum to load trust anchors from file and check that the submitter's certificate chains back to something valid.
Diffstat (limited to 'server')
-rw-r--r--server/main.go22
-rw-r--r--server/testdata/anchors.pem32
-rw-r--r--server/testdata/end-entity.key51
-rw-r--r--server/testdata/end-entity.pem30
-rw-r--r--server/testdata/root.key51
-rw-r--r--server/testdata/root.pem32
6 files changed, 212 insertions, 6 deletions
diff --git a/server/main.go b/server/main.go
index 53ac8e6..f52433b 100644
--- a/server/main.go
+++ b/server/main.go
@@ -12,15 +12,18 @@ import (
"github.com/system-transparency/stfe"
"google.golang.org/grpc"
+ "github.com/google/certificate-transparency-go/trillian/ctfe"
ctutil "github.com/google/certificate-transparency-go/trillian/util"
+ "github.com/google/certificate-transparency-go/x509"
)
var (
- httpEndpoint = flag.String("http_endpoint", "localhost:6965", "host:port specification of where stfe serves clients")
- rpcBackend = flag.String("log_rpc_server", "localhost:6962", "host:port specification of where Trillian serves clients")
- prefix = flag.String("prefix", "/st/v1", "a prefix that proceeds each endpoint path")
- trillianID = flag.Int64("trillianID", 5991359069696313945, "log identifier in the Trillian database")
- rpcDeadline = flag.Duration("rpc_deadline", time.Second*10, "deadline for backend RPC requests")
+ httpEndpoint = flag.String("http_endpoint", "localhost:6965", "host:port specification of where stfe serves clients")
+ rpcBackend = flag.String("log_rpc_server", "localhost:6962", "host:port specification of where Trillian serves clients")
+ prefix = flag.String("prefix", "/st/v1", "a prefix that proceeds each endpoint path")
+ trillianID = flag.Int64("trillian_id", 5991359069696313945, "log identifier in the Trillian database")
+ rpcDeadline = flag.Duration("rpc_deadline", time.Second*10, "deadline for backend RPC requests")
+ anchorsPemFile = flag.String("anchors_file", "testdata/anchors.pem", "path to a file containing PEM-encoded X.509 root certificates")
)
func main() {
@@ -37,8 +40,15 @@ func main() {
mux := http.NewServeMux()
http.Handle("/", mux)
+ // TODO: proper setup
+ glog.Info("Loading trust anchors")
+ cert_pool := ctfe.NewPEMCertPool()
+ cert_pool.AppendCertsFromPEMFile(*anchorsPemFile)
+ anchors := ctfe.NewCertValidationOpts(cert_pool, time.Now(), true, false, nil, nil, false, []x509.ExtKeyUsage{})
+ glog.Infof("%v", cert_pool.Subjects())
+
glog.Info("Creating STFE server instance")
- stfe_server := stfe.NewInstance(*prefix, *trillianID, trillian.NewTrillianLogClient(conn), *rpcDeadline, new(ctutil.SystemTimeSource))
+ stfe_server := stfe.NewInstance(*prefix, *trillianID, trillian.NewTrillianLogClient(conn), *rpcDeadline, new(ctutil.SystemTimeSource), anchors)
stfe_server.AddEndpoints(mux)
glog.Infof("Serving on %v%v", *httpEndpoint, *prefix)
diff --git a/server/testdata/anchors.pem b/server/testdata/anchors.pem
new file mode 100644
index 0000000..6a96054
--- /dev/null
+++ b/server/testdata/anchors.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFiTCCA3GgAwIBAgIUCpdSpYgFV7bmPzdIAcesg5ZJxe4wDQYJKoZIhvcNAQEL
+BQAwVDELMAkGA1UEBhMCU0UxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDENMAsGA1UEAwwEcmdkZDAeFw0yMDEw
+MjMxNDI4MzFaFw0yMzA4MTMxNDI4MzFaMFQxCzAJBgNVBAYTAlNFMRMwEQYDVQQI
+DApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQx
+DTALBgNVBAMMBHJnZGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2
+zbx/W/DBBUOtd94vzI0Qqx/909oJAMyqxF5evFmeoyORI/rIeXzvCu2YOQa7Y1Ku
+wKuY65oafIDLY+FMxHKBhJ7vaY3wQJQxj4e0nXjcnFHCIBWwcrP2bb1aGwog2WyI
+kKjEUdFshFcUuGNFrEzlLyW0wOh3Enm7mt30U+a7LsUUBfhrgK/CMnrthc35rFVJ
+DiIBcEzl2F+n4k7BY+d4MqgCqPJmA9+f30F19JMTPcrjSEevNUNoH7+Vrzl8bgWr
+5i2VezE/gMVeFjHFebzBjGKxxRtSPt2In/I2vALvPUuZ5Lw29Ire0Wy/AhYB1ngx
+/L3nSHvMzlmlGC5H7FHMqg8T9g9VOaUWyiO8Ck73dF8JHxIOKwCJWZgIr4qAwSvK
+O8PpHIoFOhpLFLhP+zH3B2w4QFbk/HfuQ2Ww78+AXEHoP2JTiAyH89xD/g+6366W
+5dcutQw+rb1S9DGc4yXIPTew/24Hzmu1YkhcRemwebZ6s6y7H9muz0T4Ax2eYb0Z
+NtaTR7+1TEcC/3R2YWuK1H8kY2kwEl0ize77QRZPii4cLCvIT9Ug7xpzVLYlJvly
+WswZed1R8rncUE4fqWYOu0V0LzC/PBUv2cmFk0i6UjpCbFH70hK58AvZccpH+onF
+RZNdqM5q+jjaySLzZFiqezgGX1k25p8H76EqaC59xQIDAQABo1MwUTAdBgNVHQ4E
+FgQUrcBnUTJSmhmdJdn+HA/aBSQ1VYQwHwYDVR0jBBgwFoAUrcBnUTJSmhmdJdn+
+HA/aBSQ1VYQwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAVivn
+9T+M8rsWaP9PPsBTJbcgbfL1gmKMDh7xki14don5b3aJytzsrFowDDCQodtq6kPw
+r3iv5M55pftQxwT3s+buFSX0ck57PSif1u/TfVMT1tq+YQuFeQLoo7Kr8bk5kUCG
+GVqHBwllPaRbQQ4y2Lx4/i8J4hj8//IYR0lEnDNEpOkMM1pZYU5bsB7aUfJOaHVD
+QnUyAiudZtSTWNT0rB2vYYef8yBFQoSi2Uj5CCdoM4ubi/pEvnbtT8rKseaycjBA
+2lw+fO4B6s3haRWY+U8BAEqTUq9GesH++SM9t1VDAlcoRZx2s6JeZrvSYMs6NyVQ
+JilrhOmRg6Dghkt9UJQWpCkslxsEze1Crz1KQgFyRwtqkaeDGlwRGhySlHCMg4vu
+aXGDdSTUv2m9Ss31ktwEmMNcPI7vyehHyhFnt6wi3FzCnQu/I5D4MtOerrUljLiU
+qXQkFGditrKuZQnRwx6mOAy5hIrtJVqlBi+bzmNAoUHdkcID8YEpbx47eBEIwyct
+Wi2x19FOI+aECutO/OjzkfOkig3cZg0qwAm/JJsve4nc8d5D2HewH99EFGtuz1jn
+4mimMAjebW17Uf484w4wI3IeQ/F+nDvk14xkD+Hc90tq6KH7z0DplhXVIvx8SPs3
+9109jghVzFwjxF+FS9QkvUQaqdoyVCw5SI0c3hA=
+-----END CERTIFICATE-----
diff --git a/server/testdata/end-entity.key b/server/testdata/end-entity.key
new file mode 100644
index 0000000..f232f2e
--- /dev/null
+++ b/server/testdata/end-entity.key
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/server/testdata/end-entity.pem b/server/testdata/end-entity.pem
new file mode 100644
index 0000000..ab5154f
--- /dev/null
+++ b/server/testdata/end-entity.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFMjCCAxoCFFdE6AyXlAd3tmoTZXRkLElTp6d1MA0GCSqGSIb3DQEBCwUAMFQx
+CzAJBgNVBAYTAlNFMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
+cm5ldCBXaWRnaXRzIFB0eSBMdGQxDTALBgNVBAMMBHJnZGQwHhcNMjAxMDIzMTQz
+NTQ2WhcNMjIwMzE5MTQzNTQ2WjBXMQswCQYDVQQGEwJTRTETMBEGA1UECAwKU29t
+ZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRAwDgYD
+VQQDDAdyZ2RkLWVlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAx42J
++xiAYTGGJL0w6KHXV6in9IuHOBiyKvavVog8qWh1dh3I3nIUA3i0CdbeuLRubovC
+pOIFk2HjKo1qxpdh/Iab3RtTBEYghz8bkdIi3PhNdsgKUh2Pi7GCE/+0NdzMKUxL
+LSqJAIF+WymbfnnRYsxPjPBusnNdTunLWuvjS2AcpaLFcF+LojdlaFBUDvDYGWpP
+h60/z9IjUE7JbxluAl4GZYIx2bSlhQZ96bse/HoEjeJumv74JZ4GI1SH/TjFJCQS
+KRMPimm7PXsTDoaZrw/8Bc+FfVbLyp7u3ML28WGfABzPjvzXScKPTRjjoVdX2BWp
+kOV7T5zVYsJAs6cGbIgJ6UWPsOafSrIPTSCz17sNDCaN1PtkNKemosMFt8aZvnYX
+eypvMC0SPFKQr3+uFuxRIjRIrRrVfLfIb9iHBo20vSbunnRt9jwmHq5UvXxLSMoB
+dFKMp8RmnV22e40gpWppZ3C4e8HaDrGsGV0LB04PFkFaa/iqyAh8NxG7c4AFzkD7
+efDg+XQ1ujSLtnX0Mr+C/HGVpoJVRdMxnRGnUIdGt6tXrCMGGWkxjVObMaxdPe/7
+PccjxoN5wKa6Nxcv0T0dZFntKkizBJGw2VuBEAFfQCvz7a18YvQV70mr4FU5gQ4Q
+4M6pshrerM+4laIVheEJWvWi5Nh8l2NI9R0x3R0CAwEAATANBgkqhkiG9w0BAQsF
+AAOCAgEAEr0mnYtQx1WBSEVsRd4q0F8dmwEFaaIoC25RaOlbUiWUSp1S7vZpa/KJ
+ds7dh5xSNgssjoCuTFAWezgCQmEmI4JBuki4Bc5iJvVctRa/b4p0Dm6YxEYz2c2j
+0IaD32N4xZXQb+1Rf0RxEmExADZbAdmso7B0W/aCIMKwJID0FRt443ZWmu7fsLH1
+0xCr4ZQusX8eQ29jKNaMAS67uNz71z1FqffzwdtzGziE25sHgLqiyMGZzoJm1hw+
+mS5E21XAdgPu9JWoYzS+G/uqw7ZjjHEv+GPyjKhgXzgu3AxMZbQx0wTnSWHTsj57
+qgUGI1sOaxhRWkPouXztvSMOkW3zYSrNc740YxoDvYYYPveAnQ15ThqgPCon9/SE
+mqwjQzjoRVTfQz4AQgj3v2RBRYgHHu51L6VMkpanNRuUnPXvs9MqNgIhAoFENd+C
+5c/K92ntTXgYTGigPbW+a4IUVj0Ry8ctg45JZ40YBGSrReDcap9lct8X/pREY1Af
+jBpd5QPBszBaozcuTAVmakiD+YL3/JOCKNbdAYQeSXYi1A0v8n+pNvgEJRQIbbyX
+0mQugmo6EEwzRGXcc8NnBgA3knkpT/PyDgzS1uTGoDYh1iPSkkVtXNxrNgmA7jem
+Kls6XILMjQzGWAo2R/8aVnlTCF0rDBV3I12wcSQ/MsjMVXwag1k=
+-----END CERTIFICATE-----
diff --git a/server/testdata/root.key b/server/testdata/root.key
new file mode 100644
index 0000000..97effe3
--- /dev/null
+++ b/server/testdata/root.key
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/server/testdata/root.pem b/server/testdata/root.pem
new file mode 100644
index 0000000..6a96054
--- /dev/null
+++ b/server/testdata/root.pem
@@ -0,0 +1,32 @@
+-----BEGIN CERTIFICATE-----
+MIIFiTCCA3GgAwIBAgIUCpdSpYgFV7bmPzdIAcesg5ZJxe4wDQYJKoZIhvcNAQEL
+BQAwVDELMAkGA1UEBhMCU0UxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
+GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDENMAsGA1UEAwwEcmdkZDAeFw0yMDEw
+MjMxNDI4MzFaFw0yMzA4MTMxNDI4MzFaMFQxCzAJBgNVBAYTAlNFMRMwEQYDVQQI
+DApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQx
+DTALBgNVBAMMBHJnZGQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2
+zbx/W/DBBUOtd94vzI0Qqx/909oJAMyqxF5evFmeoyORI/rIeXzvCu2YOQa7Y1Ku
+wKuY65oafIDLY+FMxHKBhJ7vaY3wQJQxj4e0nXjcnFHCIBWwcrP2bb1aGwog2WyI
+kKjEUdFshFcUuGNFrEzlLyW0wOh3Enm7mt30U+a7LsUUBfhrgK/CMnrthc35rFVJ
+DiIBcEzl2F+n4k7BY+d4MqgCqPJmA9+f30F19JMTPcrjSEevNUNoH7+Vrzl8bgWr
+5i2VezE/gMVeFjHFebzBjGKxxRtSPt2In/I2vALvPUuZ5Lw29Ire0Wy/AhYB1ngx
+/L3nSHvMzlmlGC5H7FHMqg8T9g9VOaUWyiO8Ck73dF8JHxIOKwCJWZgIr4qAwSvK
+O8PpHIoFOhpLFLhP+zH3B2w4QFbk/HfuQ2Ww78+AXEHoP2JTiAyH89xD/g+6366W
+5dcutQw+rb1S9DGc4yXIPTew/24Hzmu1YkhcRemwebZ6s6y7H9muz0T4Ax2eYb0Z
+NtaTR7+1TEcC/3R2YWuK1H8kY2kwEl0ize77QRZPii4cLCvIT9Ug7xpzVLYlJvly
+WswZed1R8rncUE4fqWYOu0V0LzC/PBUv2cmFk0i6UjpCbFH70hK58AvZccpH+onF
+RZNdqM5q+jjaySLzZFiqezgGX1k25p8H76EqaC59xQIDAQABo1MwUTAdBgNVHQ4E
+FgQUrcBnUTJSmhmdJdn+HA/aBSQ1VYQwHwYDVR0jBBgwFoAUrcBnUTJSmhmdJdn+
+HA/aBSQ1VYQwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAVivn
+9T+M8rsWaP9PPsBTJbcgbfL1gmKMDh7xki14don5b3aJytzsrFowDDCQodtq6kPw
+r3iv5M55pftQxwT3s+buFSX0ck57PSif1u/TfVMT1tq+YQuFeQLoo7Kr8bk5kUCG
+GVqHBwllPaRbQQ4y2Lx4/i8J4hj8//IYR0lEnDNEpOkMM1pZYU5bsB7aUfJOaHVD
+QnUyAiudZtSTWNT0rB2vYYef8yBFQoSi2Uj5CCdoM4ubi/pEvnbtT8rKseaycjBA
+2lw+fO4B6s3haRWY+U8BAEqTUq9GesH++SM9t1VDAlcoRZx2s6JeZrvSYMs6NyVQ
+JilrhOmRg6Dghkt9UJQWpCkslxsEze1Crz1KQgFyRwtqkaeDGlwRGhySlHCMg4vu
+aXGDdSTUv2m9Ss31ktwEmMNcPI7vyehHyhFnt6wi3FzCnQu/I5D4MtOerrUljLiU
+qXQkFGditrKuZQnRwx6mOAy5hIrtJVqlBi+bzmNAoUHdkcID8YEpbx47eBEIwyct
+Wi2x19FOI+aECutO/OjzkfOkig3cZg0qwAm/JJsve4nc8d5D2HewH99EFGtuz1jn
+4mimMAjebW17Uf484w4wI3IeQ/F+nDvk14xkD+Hc90tq6KH7z0DplhXVIvx8SPs3
+9109jghVzFwjxF+FS9QkvUQaqdoyVCw5SI0c3hA=
+-----END CERTIFICATE-----