diff --git a/config/db.go b/config/db.go index 5f66473e..f2e12e49 100644 --- a/config/db.go +++ b/config/db.go @@ -5,11 +5,11 @@ import ( "context" "crypto/tls" "crypto/x509" - "encoding/asn1" "encoding/pem" "fmt" "github.com/boltdb/bolt" + "github.com/micromdm/micromdm/crypto" "github.com/micromdm/micromdm/pubsub" "github.com/pkg/errors" ) @@ -118,21 +118,10 @@ func (db *DB) PushTopic() (string, error) { if err != nil { return "", errors.Wrap(err, "get push certificate for topic") } - topic, err := topicFromCert(cert.Leaf) + topic, err := crypto.TopicFromCert(cert.Leaf) return topic, errors.Wrap(err, "get topic from push certificate") } -func topicFromCert(cert *x509.Certificate) (string, error) { - var oidASN1UserID = asn1.ObjectIdentifier{0, 9, 2342, 19200300, 100, 1, 1} - for _, v := range cert.Subject.Names { - if v.Type.Equal(oidASN1UserID) { - return v.Value.(string), nil - } - } - - return "", errors.New("could not find Push Topic (UserID OID) in certificate") -} - func isNotFound(err error) bool { if _, ok := err.(*notFound); ok { return true diff --git a/crypto/helpers.go b/crypto/helpers.go index 27271eac..bb5fd4b7 100644 --- a/crypto/helpers.go +++ b/crypto/helpers.go @@ -5,6 +5,7 @@ import ( "crypto/rsa" "crypto/x509" "crypto/x509/pkix" + "encoding/asn1" "encoding/pem" "errors" "io/ioutil" @@ -114,3 +115,15 @@ func WritePEMRSAKeyFile(key *rsa.PrivateKey, path string) error { Bytes: x509.MarshalPKCS1PrivateKey(key), }) } + +// TopicFromCert extracts the push certificate topic from the provided certificate. +func TopicFromCert(cert *x509.Certificate) (string, error) { + var oidASN1UserID = asn1.ObjectIdentifier{0, 9, 2342, 19200300, 100, 1, 1} + for _, v := range cert.Subject.Names { + if v.Type.Equal(oidASN1UserID) { + return v.Value.(string), nil + } + } + + return "", errors.New("could not find Push Topic (UserID OID) in certificate") +} diff --git a/serve.go b/serve.go index 6841b2f2..f25c7117 100644 --- a/serve.go +++ b/serve.go @@ -674,11 +674,23 @@ func (c *config) setupEnrollmentService() { return } + var topicProvider enroll.TopicProvider + if c.pushCert.Certificate != nil { + pushTopic, err := crypto.TopicFromCert(c.pushCert.Certificate) + if err != nil { + c.err = errors.Wrap(err, "get apns topic from certificate") + return + } + topicProvider = staticTopicProvider{topic: pushTopic} + } else { + topicProvider = c.configDB + } + var SCEPCertificateSubject string // TODO: clean up order of inputs. Maybe pass *SCEPConfig as an arg? // but if you do, the packages are coupled, better not. c.enrollService, c.err = enroll.NewService( - c.configDB, + topicProvider, c.pubclient, c.scepCACertPath, c.ServerPublicURL+"/scep", @@ -690,6 +702,13 @@ func (c *config) setupEnrollmentService() { ) } +// if the apns-cert flags are specified this provider will be used in the enroll service. +type staticTopicProvider struct{ topic string } + +func (p staticTopicProvider) PushTopic() (string, error) { + return p.topic, nil +} + func (c *config) depClient() (dep.Client, error) { if c.err != nil { return nil, c.err