From 0ca17b44f62f39ec25677311bb9885ee459025e8 Mon Sep 17 00:00:00 2001 From: Jesse Peterson Date: Wed, 24 Aug 2022 16:11:39 -0700 Subject: [PATCH] Add -intermediate switch for device verification --- certverify/pool.go | 8 +++++++- cmd/nanomdm/main.go | 9 +++++++-- docs/operations-guide.md | 10 ++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/certverify/pool.go b/certverify/pool.go index 244c22a..04fcb5c 100644 --- a/certverify/pool.go +++ b/certverify/pool.go @@ -11,7 +11,7 @@ type PoolVerifier struct { } // NewPoolVerifier creates a new Verifier -func NewPoolVerifier(rootsPEM []byte, keyUsages ...x509.ExtKeyUsage) (*PoolVerifier, error) { +func NewPoolVerifier(rootsPEM []byte, intsPEM []byte, keyUsages ...x509.ExtKeyUsage) (*PoolVerifier, error) { opts := x509.VerifyOptions{ KeyUsages: keyUsages, Roots: x509.NewCertPool(), @@ -19,6 +19,12 @@ func NewPoolVerifier(rootsPEM []byte, keyUsages ...x509.ExtKeyUsage) (*PoolVerif if len(rootsPEM) == 0 || !opts.Roots.AppendCertsFromPEM(rootsPEM) { return nil, errors.New("could not append root CA(s)") } + if len(intsPEM) > 0 { + opts.Intermediates = x509.NewCertPool() + if !opts.Intermediates.AppendCertsFromPEM(intsPEM) { + return nil, errors.New("could not append intermediate CA(s)") + } + } return &PoolVerifier{ verifyOpts: opts, }, nil diff --git a/cmd/nanomdm/main.go b/cmd/nanomdm/main.go index 033b491..e583508 100644 --- a/cmd/nanomdm/main.go +++ b/cmd/nanomdm/main.go @@ -50,7 +50,8 @@ func main() { flListen = flag.String("listen", ":9000", "HTTP listen address") flAPIKey = flag.String("api", "", "API key for API endpoints") flVersion = flag.Bool("version", false, "print version") - flRootsPath = flag.String("ca", "", "path to CA cert for verification") + flRootsPath = flag.String("ca", "", "path to PEM CA cert(s)") + flIntsPath = flag.String("intermediate", "", "path to PEM intermediate cert(s)") flWebhook = flag.String("webhook-url", "", "URL to send requests to") flCertHeader = flag.String("cert-header", "", "HTTP header containing URL-escaped TLS client certificate") flDebug = flag.Bool("debug", false, "log debug messages") @@ -81,7 +82,11 @@ func main() { if err != nil { stdlog.Fatal(err) } - verifier, err := certverify.NewPoolVerifier(caPEM, x509.ExtKeyUsageClientAuth) + intsPEM, err := os.ReadFile(*flIntsPath) + if err != nil { + stdlog.Fatal(err) + } + verifier, err := certverify.NewPoolVerifier(caPEM, intsPEM, x509.ExtKeyUsageClientAuth) if err != nil { stdlog.Fatal(err) } diff --git a/docs/operations-guide.md b/docs/operations-guide.md index 112af8f..82e4d3e 100644 --- a/docs/operations-guide.md +++ b/docs/operations-guide.md @@ -28,9 +28,15 @@ API authorization in NanoMDM is simply HTTP Basic authentication using "nanomdm" ### -ca string -* Path to CA cert for verification +* path to PEM CA cert(s) -NanoMDM validates that the device identity certificate is issued from specific CAs. This switch is the path to a file of PEM-encoded CAs to validate against. +NanoMDM validates that the device identity certificate is issued from specific CAs. This switch is the path to a file of PEM-encoded CAs to validate enrollments against. + +### -intermediate string + +* path to PEM intermediate cert(s) + +NanoMDM validates that the device identity certificate is issued from specific CAs. This switch is the path to a file of PEM-encoded intermediate certificates that can be used to build a chain of trust to the CAs to validate enrollments against. ### -cert-header string