Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configure identity verification from CLI #122

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions cmd/nanomdm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"crypto/x509"
"flag"
"fmt"
"io/ioutil"
stdlog "log"
"math/rand"
"net/http"
Expand Down Expand Up @@ -72,6 +71,7 @@ func main() {
flDMURLPfx = flag.String("dm", "", "URL to send Declarative Management requests to")
flAuthProxy = flag.String("auth-proxy-url", "", "Reverse proxy URL target for MDM-authenticated HTTP requests")
flUAZLChal = flag.Bool("ua-zl-dc", false, "reply with zero-length DigestChallenge for UserAuthenticate")
flVerify = flag.String("verify", "pool", "device identity verification type")
)
flag.Parse()

Expand All @@ -89,20 +89,40 @@ func main() {
if *flRootsPath == "" {
stdlog.Fatal("must supply CA cert path flag")
}
caPEM, err := ioutil.ReadFile(*flRootsPath)
caPEM, err := os.ReadFile(*flRootsPath)
if err != nil {
stdlog.Fatal(err)
stdlog.Fatal(fmt.Errorf("reading root CA: %w", err))
}
var intsPEM []byte
if *flIntsPath != "" {
intsPEM, err = os.ReadFile(*flIntsPath)

var verifier certverify.CertVerifier
switch *flVerify {
case "pool":
var intsPEM []byte
if *flIntsPath != "" {
intsPEM, err = os.ReadFile(*flIntsPath)
if err != nil {
stdlog.Fatal(fmt.Errorf("reading intermediate CA: %w", err))
}
}
verifier, err = certverify.NewPoolVerifier(caPEM, intsPEM, x509.ExtKeyUsageClientAuth)
if err != nil {
stdlog.Fatal(err)
}
}
verifier, err := certverify.NewPoolVerifier(caPEM, intsPEM, x509.ExtKeyUsageClientAuth)
if err != nil {
stdlog.Fatal(err)
case "signature-only":
if *flIntsPath != "" {
stdlog.Fatal("intermediate cannot be used with signature-only verification")
}
verifier, err = certverify.NewSignatureVerifier(caPEM)
if err != nil {
stdlog.Fatal(err)
}
logger.Info(
"msg", "reduced security: signature-only verifier",
// double up and use a err in case that key is used for reporting
"err", "reduced security: signature-only verifier",
)
default:
stdlog.Fatal(fmt.Errorf("invalid verify flag: %s", *flVerify))
}

mdmStorage, err := cliStorage.Parse(logger)
Expand Down
11 changes: 11 additions & 0 deletions docs/operations-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ By default NanoMDM will respond to a `UserAuthenticate` message with an HTTP 410

Note that the `UserAuthenticate` message is only for "directory" MDM users and not the "primary" MDM user enrollment. See also [Apple's discussion of UserAthenticate](https://developer.apple.com/documentation/devicemanagement/userauthenticate#discussion) for more information.

### -verify string

* device identity verification type (default "pool")

Selects which verifier to use to verify the device identity certificate:

* `pool`: uses the "pool" verifier which can configure multiple CAs and intermediate certificates.
* `signature-only`: uses the "signature" verifier which only verifies a device identity certificate was signed by a single CA. Notably it does not check identity certificate validity (expiry). **WARNING**: this *reduces security* of the signature checking.

*Example:* `-verify pool`

## HTTP endpoints & APIs

### MDM
Expand Down