diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index cbd466c4f9..40504c0495 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -938,8 +938,11 @@ foobar require.NoError(t, err) require.Equal(t, originalAssets, assets) - // Upload an APNS cert - s.uploadAPNSCert("apns.pem", http.StatusAccepted) + // Invalid APNS cert upload attempt + s.uploadAPNSCert("apns_invalid.pem", http.StatusUnprocessableEntity, "Invalid certificate. Please provide a valid certificate from Apple Push Certificate Portal.") + + // Successfully upload an APNS cert + s.uploadAPNSCert("apns.pem", http.StatusAccepted, "") assets, err = s.ds.GetMDMConfigAssetsByName(ctx, []fleet.MDMAssetName{fleet.MDMAssetCACert, fleet.MDMAssetCAKey, fleet.MDMAssetAPNSKey, fleet.MDMAssetAPNSCert}) require.NoError(t, err) @@ -953,7 +956,7 @@ foobar require.Len(t, assets, 0) } -func (s *integrationMDMTestSuite) uploadAPNSCert(pemFileName string, expectedStatus int) { +func (s *integrationMDMTestSuite) uploadAPNSCert(pemFileName string, expectedStatus int, wantErr string) { t := s.T() read := func(name string) []byte { b, err := os.ReadFile(filepath.Join("testdata", name)) @@ -980,7 +983,11 @@ func (s *integrationMDMTestSuite) uploadAPNSCert(pemFileName string, expectedSta "Authorization": fmt.Sprintf("Bearer %s", s.token), } - s.DoRawWithHeaders("POST", "/api/latest/fleet/mdm/apple/apns_certificate", b.Bytes(), expectedStatus, headers) + res := s.DoRawWithHeaders("POST", "/api/latest/fleet/mdm/apple/apns_certificate", b.Bytes(), expectedStatus, headers) + if wantErr != "" { + errMsg := extractServerErrorText(res.Body) + assert.Contains(t, errMsg, wantErr) + } } func (s *integrationMDMTestSuite) TestMDMAppleUnenroll() { diff --git a/server/service/mdm.go b/server/service/mdm.go index 4291e6e55d..ebdb0e7696 100644 --- a/server/service/mdm.go +++ b/server/service/mdm.go @@ -2287,6 +2287,12 @@ func (svc *Service) UploadMDMAppleAPNSCert(ctx context.Context, cert io.ReadSeek return ctxerr.Wrap(ctx, err, "reading apns certificate") } + // Validate cert TODO(JVE): is there more to do here for validation? + block, _ := pem.Decode(certBytes) + if block == nil { + return fleet.NewInvalidArgumentError("certificate", "Invalid certificate. Please provide a valid certificate from Apple Push Certificate Portal.") + } + // Save to DB if err := svc.ds.InsertMDMConfigAssets(ctx, []fleet.MDMConfigAsset{ {Name: fleet.MDMAssetAPNSCert, Value: certBytes}, diff --git a/server/service/testdata/apns_invalid.pem b/server/service/testdata/apns_invalid.pem new file mode 100644 index 0000000000..9fdf5e8ec7 --- /dev/null +++ b/server/service/testdata/apns_invalid.pem @@ -0,0 +1 @@ +an invalid pem