diff --git a/changelog.html b/changelog.html
index 53e36398877fc0cc502a56bc0cab24595ce2eb1e..2125e824d9023feab974c768fb7a31125872d888 100644
--- a/changelog.html
+++ b/changelog.html
@@ -63,6 +63,8 @@ Upcoming changes
GET request to configSubmit wipes some configuration
(issue 11397, issue 7847)
+
+ Allow update center CA certificates to be placed in $JENKINS_HOME/update-center-rootCAs
diff --git a/core/src/main/java/hudson/model/UpdateSite.java b/core/src/main/java/hudson/model/UpdateSite.java
index c6ac33b71979630791e546c432528b177e78649c..8389fcbffb475018866211c308e41c991f84dc94 100644
--- a/core/src/main/java/hudson/model/UpdateSite.java
+++ b/core/src/main/java/hudson/model/UpdateSite.java
@@ -51,6 +51,7 @@ import org.kohsuke.stapler.StaplerResponse;
import javax.servlet.ServletContext;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
@@ -196,12 +197,25 @@ public class UpdateSite {
certs.add(c);
}
- // all default root CAs in JVM are trusted, plus certs bundled in Jenkins
+ // if we trust default root CAs, we end up trusting anyone who has a valid certificate,
+ // which isn't useful at all
Set anchors = new HashSet(); // CertificateUtil.getDefaultRootCAs();
- ServletContext context = Jenkins.getInstance().servletContext;
- for (String cert : (Set) context.getResourcePaths("/WEB-INF/update-center-rootCAs")) {
+ Jenkins j = Jenkins.getInstance();
+ for (String cert : (Set) j.servletContext.getResourcePaths("/WEB-INF/update-center-rootCAs")) {
if (cert.endsWith(".txt")) continue; // skip text files that are meant to be documentation
- anchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(context.getResourceAsStream(cert)),null));
+ anchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(j.servletContext.getResourceAsStream(cert)),null));
+ }
+ File[] cas = new File(j.root, "update-center-rootCAs").listFiles();
+ if (cas!=null) {
+ for (File cert : cas) {
+ if (cert.getName().endsWith(".txt")) continue; // skip text files that are meant to be documentation
+ FileInputStream in = new FileInputStream(cert);
+ try {
+ anchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(in),null));
+ } finally {
+ in.close();
+ }
+ }
}
CertificateUtil.validatePath(certs,anchors);
}