Skip to content

Commit

Permalink
(PE-37345) Create new bulk signing endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
artlawson committed Dec 20, 2023
1 parent 83f6be3 commit c0cfe90
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
-----BEGIN X509 CRL-----
MIICnDCBhQIBATANBgkqhkiG9w0BAQUFADAfMR0wGwYDVQQDDBRQdXBwZXQgQ0E6
IGxvY2FsaG9zdBcNMTQwNDI5MjExNTI3WhcNMTkwNDI4MjExNTI4WjAiMCACAQQX
DTE0MDQyOTIxMTUyOFowDDAKBgNVHRUEAwoBAaAOMAwwCgYDVR0UBAMCAQEwDQYJ
KoZIhvcNAQEFBQADggIBAEHP3m5UA+lz1mjF2K+2jZ9bgZE15POftI9peXNILia3
AHE7OQtyxju/Mt/o5OpPW+0RJso9OrXhEE6T65BgOovBi1VkfxXILIui8n1oF1UK
9npunKXwgjP6Y8QbuaLv584QdwjfEFlFp/nJW5IQRKVIgsLsSGIBlZvmELiosR/W
er3Ba7Cy/Y8cfMx0t/4QCU63l/Sr/8mgvp3P5RwhljN9ekp5Y3Yz4jdRycJsrq8J
aQss8N4BrE/ppbvCdmf5UdkXgivd6cl04aSg1f25yYtEY12fyD8C8VySGOfZrnlh
aOhJapWTuKVU/PxdCZfeL+RVufrRWBo4iJCRARKddDeqDWtI62pysjy/2PRvzMRW
qudj9gJC3JnsWzvZqTGK6LNwDyH65Uc7cXjq+xxMgDpCYKZrpSmwlKUmpfnzZK/o
ckJKFaQzXvF/RJF2Ai5W3HEl4CjRp5y2yqpORsl+FDVBl2hi5n7rCqJ4RibbdtTC
pFFUP+na3zv0Z49uFLGQ/a/WHI2KuryMlDTkqltr9xncSpKafyT1UCciRdct3Q01
EWmuRcsawSg+nLB7VcLRgcnbbRuHJS2Pn2AZxYAg0SshGeZpl0zIiVzadb1/IY1d
MlXJjO6RAj87/yUMC7/xC6IJh3sQymC1Yw8nYOGjnGiMCV68e5izd3eQTj8arTZj
MIICvTCBpgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRQdXBwZXQgQ0E6
IGxvY2FsaG9zdBcNMjMxMjIwMjMyMzMwWhcNMjgxMjIwMjMyMzMxWjAiMCACAQQX
DTIzMTIyMDIzMjMzMVowDDAKBgNVHRUEAwoBAaAvMC0wCgYDVR0UBAMCAQIwHwYD
VR0jBBgwFoAUWctw9L0Bogbt5p4IKvI4hGREaF8wDQYJKoZIhvcNAQELBQADggIB
ADHj9EkJbCP/6qhKrRRRB3Er7vfJz/D3tHCswTSeny1uddReDH542NiVjPRXW2xv
eafDnqI93K/NTbdDvCypoeG+GRW+d/1fwhqXM1uHgZaweFBsiElEEFryU76Vvc1K
dW0tsixDQo1re7P1VEJ/kxzd64Y2bpDnfDGTH9L//kNdkeM8zaWIKTvMBl6tHXoS
JHEqYtSSk7cqQ/P8ZMmAMFNmM1Cb+zNFsVrlLgaLyLA4LVHqRHKvFw17xs5EK1m8
OCihLBP7gcN2gCeFwXpU3SbsRKgJFo8pEk/4LNoTHJblYs+IcmYzRmledGLaKES8
oq57qfOofEVbpOvKi0lZ+BTtRr+8YiPn9DK6YK+RFmRktG+7lPAvYOWwei1x6EQe
2fUVN8SqpNo7GVkwSwQyUlw9fp3SvfqVpfrfRhgGh3iihheJ0OUP+tyX7flBTk2v
466J7oqUwnb0L0LfLLhxdAq8paZdUt4EoQAMb2btLgaE/AlTPbCenqUpuukGHNmM
NDoK698wqmthTEhRwFoyIsCFKUeuJFzuyPQzbCxSXpt1XHcNAjTtr6ldQ3K6oti1
bFHrC+qLZc1S4moXIBn21lBDZDOPvMnAzuWWQZAwKJ0A85EjDxZid3WsWY5NaRp9
sLxuL0ArduisaEwbXXxIxHeA3wEEvHOc8omFym3lFP1Y
-----END X509 CRL-----
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
-----BEGIN X509 CRL-----
MIICnDCBhQIBATANBgkqhkiG9w0BAQUFADAfMR0wGwYDVQQDDBRQdXBwZXQgQ0E6
IGxvY2FsaG9zdBcNMTQwNDI5MjExNTI3WhcNMTkwNDI4MjExNTI4WjAiMCACAQQX
DTE0MDQyOTIxMTUyOFowDDAKBgNVHRUEAwoBAaAOMAwwCgYDVR0UBAMCAQEwDQYJ
KoZIhvcNAQEFBQADggIBAEHP3m5UA+lz1mjF2K+2jZ9bgZE15POftI9peXNILia3
AHE7OQtyxju/Mt/o5OpPW+0RJso9OrXhEE6T65BgOovBi1VkfxXILIui8n1oF1UK
9npunKXwgjP6Y8QbuaLv584QdwjfEFlFp/nJW5IQRKVIgsLsSGIBlZvmELiosR/W
er3Ba7Cy/Y8cfMx0t/4QCU63l/Sr/8mgvp3P5RwhljN9ekp5Y3Yz4jdRycJsrq8J
aQss8N4BrE/ppbvCdmf5UdkXgivd6cl04aSg1f25yYtEY12fyD8C8VySGOfZrnlh
aOhJapWTuKVU/PxdCZfeL+RVufrRWBo4iJCRARKddDeqDWtI62pysjy/2PRvzMRW
qudj9gJC3JnsWzvZqTGK6LNwDyH65Uc7cXjq+xxMgDpCYKZrpSmwlKUmpfnzZK/o
ckJKFaQzXvF/RJF2Ai5W3HEl4CjRp5y2yqpORsl+FDVBl2hi5n7rCqJ4RibbdtTC
pFFUP+na3zv0Z49uFLGQ/a/WHI2KuryMlDTkqltr9xncSpKafyT1UCciRdct3Q01
EWmuRcsawSg+nLB7VcLRgcnbbRuHJS2Pn2AZxYAg0SshGeZpl0zIiVzadb1/IY1d
MlXJjO6RAj87/yUMC7/xC6IJh3sQymC1Yw8nYOGjnGiMCV68e5izd3eQTj8arTZj
MIICvTCBpgIBATANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQDDBRQdXBwZXQgQ0E6
IGxvY2FsaG9zdBcNMjMxMjIwMjMyMzMwWhcNMjgxMjIwMjMyMzMxWjAiMCACAQQX
DTIzMTIyMDIzMjMzMVowDDAKBgNVHRUEAwoBAaAvMC0wCgYDVR0UBAMCAQIwHwYD
VR0jBBgwFoAUWctw9L0Bogbt5p4IKvI4hGREaF8wDQYJKoZIhvcNAQELBQADggIB
ADHj9EkJbCP/6qhKrRRRB3Er7vfJz/D3tHCswTSeny1uddReDH542NiVjPRXW2xv
eafDnqI93K/NTbdDvCypoeG+GRW+d/1fwhqXM1uHgZaweFBsiElEEFryU76Vvc1K
dW0tsixDQo1re7P1VEJ/kxzd64Y2bpDnfDGTH9L//kNdkeM8zaWIKTvMBl6tHXoS
JHEqYtSSk7cqQ/P8ZMmAMFNmM1Cb+zNFsVrlLgaLyLA4LVHqRHKvFw17xs5EK1m8
OCihLBP7gcN2gCeFwXpU3SbsRKgJFo8pEk/4LNoTHJblYs+IcmYzRmledGLaKES8
oq57qfOofEVbpOvKi0lZ+BTtRr+8YiPn9DK6YK+RFmRktG+7lPAvYOWwei1x6EQe
2fUVN8SqpNo7GVkwSwQyUlw9fp3SvfqVpfrfRhgGh3iihheJ0OUP+tyX7flBTk2v
466J7oqUwnb0L0LfLLhxdAq8paZdUt4EoQAMb2btLgaE/AlTPbCenqUpuukGHNmM
NDoK698wqmthTEhRwFoyIsCFKUeuJFzuyPQzbCxSXpt1XHcNAjTtr6ldQ3K6oti1
bFHrC+qLZc1S4moXIBn21lBDZDOPvMnAzuWWQZAwKJ0A85EjDxZid3WsWY5NaRp9
sLxuL0ArduisaEwbXXxIxHeA3wEEvHOc8omFym3lFP1Y
-----END X509 CRL-----
34 changes: 31 additions & 3 deletions src/clj/puppetlabs/services/ca/certificate_authority_core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
[ring.util.request :as request]
[ring.util.response :as rr]
[schema.core :as schema]
[slingshot.slingshot :as sling])
[slingshot.slingshot :refer [try+]])
(:import (clojure.lang IFn)
(java.io ByteArrayInputStream InputStream StringWriter)
(java.security.cert X509Certificate)
Expand Down Expand Up @@ -77,7 +77,7 @@
[ca-settings :- ca/CaSettings
report-activity
{:keys [body] {:keys [subject]} :route-params :as request}]
(sling/try+
(try+
(let [report-activity-fn (ca/create-report-activity-fn report-activity request)]
(ca/process-csr-submission! subject body ca-settings report-activity-fn)
(rr/content-type (rr/response nil) "text/plain"))
Expand Down Expand Up @@ -257,6 +257,30 @@
request-cert)
(log/warn (i18n/trs "Request is missing a certificate for an endpoint that requires a certificate."))))))

(schema/def Certnames [schema/Str])

(schema/defn handle-bulk-cert-signing
[request
_ca-settings :- ca/CaSettings]
(let [json-body (try-to-parse (:body request))
certnames (:certnames json-body)]
(if-let [schema-error (schema/check Certnames certnames)]
(-> (rr/response (cheshire/generate-string {:kind :schema-violation
:submitted certnames
:error (str schema-error)}))
(rr/status 422)
(rr/content-type "application/json"))
(-> (rr/response (cheshire/generate-string {}))
(rr/status 200)
(rr/content-type "application/json")))))

(schema/defn handle-bulk-cert-signing-all
[_request
_ca-settings :- ca/CaSettings]
(-> (rr/response (cheshire/generate-string {}))
(rr/status 200)
(rr/content-type "application/json")))

(schema/defn ^:always-validate
handle-cert-renewal
"Given a request and the CA settings, if there is a cert present in the request
Expand Down Expand Up @@ -540,7 +564,11 @@
(PUT ["/clean"] request
(handle-cert-clean request ca-settings report-activity))
(POST ["/certificate_renewal"] request
(handle-cert-renewal request ca-settings report-activity)))
(handle-cert-renewal request ca-settings report-activity))
(POST ["/sign"] request
(handle-bulk-cert-signing request ca-settings))
(POST ["/sign/all"] request
(handle-bulk-cert-signing-all request ca-settings)))
(comidi/not-found "Not Found")))

(schema/defn ^:always-validate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,67 @@
:body "Bad data"})]
(is (= 400 (:status response)))))))

(deftest ca-bulk-signing-endpoint-test
(testing "ca bulk signing endpoint "
(bootstrap/with-puppetserver-running-with-mock-jrubies
"JRuby mocking is safe here because all of the requests are to the CA
endpoints, which are implemented in Clojure."
app
{:jruby-puppet
{:gem-path [(ks/absolute-path jruby-testutils/gem-path)]}
:webserver
{:ssl-cert (str bootstrap/server-conf-dir "/ssl/certs/localhost.pem")
:ssl-key (str bootstrap/server-conf-dir "/ssl/private_keys/localhost.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-crl-path (str bootstrap/server-conf-dir "/ssl/crl.pem")}}

(testing "returns 200 with valid payload"
(let [random-certname (ks/rand-str :alpha-lower 16)
response (http-client/post
"https://localhost:8140/puppet-ca/v1/sign"
{:body (json/encode {:certnames [random-certname]})
:ssl-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-key (str bootstrap/server-conf-dir "/ca/ca_key.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:as :text
:headers {"Accept" "application/json"}})]
(is (= 200 (:status response)))))
(testing "throws schema violation for invalid certname"
(let [error-msg "{\"kind\":\"schema-violation\""
response (http-client/post
"https://localhost:8140/puppet-ca/v1/sign"
{:body (json/encode {:certnames [1 2 3]})
:ssl-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-key (str bootstrap/server-conf-dir "/ca/ca_key.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:as :text
:headers {"Accept" "application/json"}})
body (:body response)]
(is (= 422 (:status response)))
(is (.contains body error-msg)))))))

(deftest ca-bulk-signing-all-endpoint-test
(testing "returns 200 response"
(bootstrap/with-puppetserver-running-with-mock-jrubies
"JRuby mocking is safe here because all of the requests are to the CA
endpoints, which are implemented in Clojure."
app
{:jruby-puppet
{:gem-path [(ks/absolute-path jruby-testutils/gem-path)]}
:webserver
{:ssl-cert (str bootstrap/server-conf-dir "/ssl/certs/localhost.pem")
:ssl-key (str bootstrap/server-conf-dir "/ssl/private_keys/localhost.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-crl-path (str bootstrap/server-conf-dir "/ssl/crl.pem")}}
(let [response (http-client/post
"https://localhost:8140/puppet-ca/v1/sign/all"
{:ssl-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:ssl-key (str bootstrap/server-conf-dir "/ca/ca_key.pem")
:ssl-ca-cert (str bootstrap/server-conf-dir "/ca/ca_crt.pem")
:as :text
:headers {"Accept" "application/json"}})]
(is (= 200 (:status response)))))))

(deftest ca-certificate-renew-endpoint-test
(testing "with the feature enabled"
(testing "with allow-header-cert-info = false (default)"
Expand Down

0 comments on commit c0cfe90

Please sign in to comment.