diff --git a/authority/provisioner/scep.go b/authority/provisioner/scep.go
index 5d67762c..05802ffb 100644
--- a/authority/provisioner/scep.go
+++ b/authority/provisioner/scep.go
@@ -26,10 +26,18 @@ type SCEP struct {
// Numerical identifier for the ContentEncryptionAlgorithm as defined in github.com/mozilla-services/pkcs7
// at https://github.com/mozilla-services/pkcs7/blob/33d05740a3526e382af6395d3513e73d4e66d1cb/encrypt.go#L63
// Defaults to 0, being DES-CBC
- EncryptionAlgorithmIdentifier int `json:"encryptionAlgorithmIdentifier,omitempty"`
- Options *Options `json:"options,omitempty"`
- Claims *Claims `json:"claims,omitempty"`
- claimer *Claimer
+ EncryptionAlgorithmIdentifier int `json:"encryptionAlgorithmIdentifier,omitempty"`
+ // CustomPath is used to specify a custom path on which the SCEP provisioner will be made
+ // available. By default a SCEP provisioner is available at
+ // https://
:/scep/ and requests performed looking similar
+ // to https://:/scep/?operations=GetCACert. When CustomPath
+ // is set, the SCEP URL will be https://:/scep//,
+ // resulting in SCEP clients that expect a specific path, such as "/pkiclient.exe", to be
+ // able to interact with the SCEP provisioner.
+ CustomPath string `json:"customPath,omitempty"`
+ Options *Options `json:"options,omitempty"`
+ Claims *Claims `json:"claims,omitempty"`
+ claimer *Claimer
secretChallengePassword string
encryptionAlgorithm int
diff --git a/scep/api/api.go b/scep/api/api.go
index 4f8d897b..9b48187a 100644
--- a/scep/api/api.go
+++ b/scep/api/api.go
@@ -66,7 +66,9 @@ func New(scepAuth scep.Interface) api.RouterHandler {
// Route traffic and implement the Router interface.
func (h *Handler) Route(r api.Router) {
getLink := h.Auth.GetLinkExplicit
+ r.MethodFunc(http.MethodGet, getLink("{provisionerName}/{customPath}*", false, nil), h.lookupProvisioner(h.Get))
r.MethodFunc(http.MethodGet, getLink("{provisionerName}", false, nil), h.lookupProvisioner(h.Get))
+ r.MethodFunc(http.MethodPost, getLink("{provisionerName}/{customPath}*", false, nil), h.lookupProvisioner(h.Post))
r.MethodFunc(http.MethodPost, getLink("{provisionerName}", false, nil), h.lookupProvisioner(h.Post))
}
@@ -191,6 +193,13 @@ func (h *Handler) lookupProvisioner(next nextHTTP) nextHTTP {
return
}
+ customPathParam := chi.URLParam(r, "customPath")
+ customPath, err := url.PathUnescape(customPathParam)
+ if err != nil {
+ api.WriteError(w, err)
+ return
+ }
+
p, err := h.Auth.LoadProvisionerByName(provisionerName)
if err != nil {
api.WriteError(w, err)
@@ -203,6 +212,12 @@ func (h *Handler) lookupProvisioner(next nextHTTP) nextHTTP {
return
}
+ configuredCustomPath := strings.Trim(prov.CustomPath, "/")
+ if customPath != configuredCustomPath {
+ api.WriteError(w, errors.Errorf("custom path requested '%s' is not the expected path '%s'", customPath, configuredCustomPath))
+ return
+ }
+
ctx := r.Context()
ctx = context.WithValue(ctx, scep.ProvisionerContextKey, scep.Provisioner(prov))
next(w, r.WithContext(ctx))