docs: private FormValidation checkSpecificSignature(JSONObject json, JSONObject signatureJson, MessageDigest digest, String digestEntry, Signature signature, String signatureEntry, String digestName) throws IOException {
          // this is for computing a digest to check sanity
          DigestOutputStream dos = new DigestOutputStream(new NullOutputStream(), digest);
          SignatureOutputStream sos = new SignatureOutputStream(signature);
  
          String providedDigest = signatureJson.optString(digestEntry, null);
          if (providedDigest == null) {
              return FormValidation.warning("No '" + digestEntry + "' found");
          }
  
          String providedSignature = signatureJson.optString(signatureEntry, null);
          if (providedSignature == null) {
              return FormValidation.warning("No '" + signatureEntry + "' found");
          }
  
          // until JENKINS-11110 fix, UC used to serve invalid digest (and therefore unverifiable signature)
          // that only covers the earlier portion of the file. This was caused by the lack of close() call
          // in the canonical writing, which apparently leave some bytes somewhere that's not flushed to
          // the digest output stream. This affects Jenkins [1.424,1,431].
          // Jenkins 1.432 shipped with the "fix" (1eb0c64abb3794edce29cbb1de50c93fa03a8229) that made it
          // compute the correct digest, but it breaks all the existing UC json metadata out there. We then
          // quickly discovered ourselves in the catch-22 situation. If we generate UC with the correct signature,
          // it'll cut off [1.424,1.431] from the UC. But if we don't, we'll cut off [1.432,*).
          //
          // In 1.433, we revisited 1eb0c64abb3794edce29cbb1de50c93fa03a8229 so that the original "digest"/"signature"
          // pair continues to be generated in a buggy form, while "correct_digest"/"correct_signature" are generated
          // correctly.
          //
          // Jenkins should ignore "digest"/"signature" pair. Accepting it creates a vulnerability that allows
          // the attacker to inject a fragment at the end of the json.
          json.writeCanonical(new OutputStreamWriter(new TeeOutputStream(dos,sos), Charsets.UTF_8)).close();
  
          // did the digest match? this is not a part of the signature validation, but if we have a bug in the c14n
          // (which is more likely than someone tampering with update center), we can tell
  
          if (!digestMatches(digest.digest(), providedDigest)) {
              String msg = digestName + " digest mismatch: expected=" + providedDigest + " in '" + name + "'";
              if (LOGGER.isLoggable(Level.SEVERE)) {
                  LOGGER.severe(msg);
                  LOGGER.severe(json.toString(2));
              }
              return FormValidation.error(msg);
          }
  
          if (!verifySignature(signature, providedSignature)) {
              return FormValidation.error(digestName + " based signature in the update center doesn't match with the certificate in '"+name + "'");
          }
  
          return FormValidation.ok();
      }