[6380] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[1023] | 2 | package org.openstreetmap.josm.tools;
|
---|
| 3 |
|
---|
[4998] | 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 |
|
---|
[6682] | 6 | import java.awt.Desktop;
|
---|
[1023] | 7 | import java.awt.event.KeyEvent;
|
---|
[5850] | 8 | import java.io.BufferedReader;
|
---|
[4153] | 9 | import java.io.File;
|
---|
[12241] | 10 | import java.io.FileInputStream;
|
---|
[1023] | 11 | import java.io.IOException;
|
---|
[6682] | 12 | import java.net.URI;
|
---|
| 13 | import java.net.URISyntaxException;
|
---|
[7082] | 14 | import java.nio.charset.StandardCharsets;
|
---|
[7314] | 15 | import java.nio.file.Files;
|
---|
[7315] | 16 | import java.nio.file.Path;
|
---|
[7314] | 17 | import java.nio.file.Paths;
|
---|
[12241] | 18 | import java.security.KeyStoreException;
|
---|
| 19 | import java.security.NoSuchAlgorithmException;
|
---|
| 20 | import java.security.cert.CertificateException;
|
---|
| 21 | import java.security.cert.CertificateFactory;
|
---|
| 22 | import java.security.cert.X509Certificate;
|
---|
[6103] | 23 | import java.util.Arrays;
|
---|
[11162] | 24 | import java.util.Locale;
|
---|
[12830] | 25 | import java.util.concurrent.ExecutionException;
|
---|
[1023] | 26 |
|
---|
[6310] | 27 | import org.openstreetmap.josm.Main;
|
---|
[12241] | 28 | import org.openstreetmap.josm.io.CertificateAmendment.CertAmend;
|
---|
[6310] | 29 |
|
---|
[1023] | 30 | /**
|
---|
[12219] | 31 | * {@code PlatformHook} implementation for Unix systems.
|
---|
| 32 | * @since 1023
|
---|
[2376] | 33 | */
|
---|
[1023] | 34 | public class PlatformHookUnixoid implements PlatformHook {
|
---|
[6070] | 35 |
|
---|
[5994] | 36 | private String osDescription;
|
---|
[6070] | 37 |
|
---|
[4897] | 38 | @Override
|
---|
[12776] | 39 | public Platform getPlatform() {
|
---|
| 40 | return Platform.UNIXOID;
|
---|
| 41 | }
|
---|
| 42 |
|
---|
| 43 | @Override
|
---|
[6443] | 44 | public void preStartupHook() {
|
---|
[9750] | 45 | // See #12022 - Disable GNOME ATK Java wrapper as it causes a lot of serious trouble
|
---|
| 46 | if ("org.GNOME.Accessibility.AtkWrapper".equals(System.getProperty("assistive_technologies"))) {
|
---|
| 47 | System.clearProperty("assistive_technologies");
|
---|
| 48 | }
|
---|
[1169] | 49 | }
|
---|
[4897] | 50 |
|
---|
| 51 | @Override
|
---|
[1169] | 52 | public void openUrl(String url) throws IOException {
|
---|
[6682] | 53 | for (String program : Main.pref.getCollection("browser.unix",
|
---|
| 54 | Arrays.asList("xdg-open", "#DESKTOP#", "$BROWSER", "gnome-open", "kfmclient openURL", "firefox"))) {
|
---|
[1169] | 55 | try {
|
---|
[6682] | 56 | if ("#DESKTOP#".equals(program)) {
|
---|
| 57 | Desktop.getDesktop().browse(new URI(url));
|
---|
| 58 | } else if (program.startsWith("$")) {
|
---|
| 59 | program = System.getenv().get(program.substring(1));
|
---|
| 60 | Runtime.getRuntime().exec(new String[]{program, url});
|
---|
| 61 | } else {
|
---|
| 62 | Runtime.getRuntime().exec(new String[]{program, url});
|
---|
| 63 | }
|
---|
[1169] | 64 | return;
|
---|
[7004] | 65 | } catch (IOException | URISyntaxException e) {
|
---|
[12620] | 66 | Logging.warn(e);
|
---|
[1169] | 67 | }
|
---|
| 68 | }
|
---|
| 69 | }
|
---|
[1023] | 70 |
|
---|
[4897] | 71 | @Override
|
---|
[1169] | 72 | public void initSystemShortcuts() {
|
---|
[8518] | 73 | // CHECKSTYLE.OFF: LineLength
|
---|
[4897] | 74 | // TODO: Insert system shortcuts here. See Windows and especially OSX to see how to.
|
---|
[8513] | 75 | for (int i = KeyEvent.VK_F1; i <= KeyEvent.VK_F12; ++i) {
|
---|
[8518] | 76 | Shortcut.registerSystemShortcut("screen:toogle"+i, tr("reserved"), i, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 77 | .setAutomatic();
|
---|
[8513] | 78 | }
|
---|
[8518] | 79 | Shortcut.registerSystemShortcut("system:reset", tr("reserved"), KeyEvent.VK_DELETE, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 80 | .setAutomatic();
|
---|
| 81 | Shortcut.registerSystemShortcut("system:resetX", tr("reserved"), KeyEvent.VK_BACK_SPACE, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK)
|
---|
| 82 | .setAutomatic();
|
---|
| 83 | // CHECKSTYLE.ON: LineLength
|
---|
[1169] | 84 | }
|
---|
[6920] | 85 |
|
---|
[4897] | 86 | @Override
|
---|
[2376] | 87 | public String getDefaultStyle() {
|
---|
[2371] | 88 | return "javax.swing.plaf.metal.MetalLookAndFeel";
|
---|
| 89 | }
|
---|
[4153] | 90 |
|
---|
[6103] | 91 | /**
|
---|
[10166] | 92 | * Determines if the distribution is Debian or Ubuntu, or a derivative.
|
---|
| 93 | * @return {@code true} if the distribution is Debian, Ubuntu or Mint, {@code false} otherwise
|
---|
| 94 | */
|
---|
| 95 | public static boolean isDebianOrUbuntu() {
|
---|
| 96 | try {
|
---|
| 97 | String dist = Utils.execOutput(Arrays.asList("lsb_release", "-i", "-s"));
|
---|
| 98 | return "Debian".equalsIgnoreCase(dist) || "Ubuntu".equalsIgnoreCase(dist) || "Mint".equalsIgnoreCase(dist);
|
---|
[12830] | 99 | } catch (IOException | ExecutionException | InterruptedException e) {
|
---|
[10627] | 100 | // lsb_release is not available on all Linux systems, so don't log at warning level
|
---|
[12620] | 101 | Logging.debug(e);
|
---|
[10166] | 102 | return false;
|
---|
| 103 | }
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | /**
|
---|
[6850] | 107 | * Get the package name including detailed version.
|
---|
[7314] | 108 | * @param packageNames The possible package names (when a package can have different names on different distributions)
|
---|
[6850] | 109 | * @return The package name and package version if it can be identified, null otherwise
|
---|
[7314] | 110 | * @since 7314
|
---|
[6850] | 111 | */
|
---|
[11747] | 112 | public static String getPackageDetails(String... packageNames) {
|
---|
[6850] | 113 | try {
|
---|
[10378] | 114 | // CHECKSTYLE.OFF: SingleSpaceSeparator
|
---|
[11096] | 115 | boolean dpkg = Paths.get("/usr/bin/dpkg-query").toFile().exists();
|
---|
| 116 | boolean eque = Paths.get("/usr/bin/equery").toFile().exists();
|
---|
| 117 | boolean rpm = Paths.get("/bin/rpm").toFile().exists();
|
---|
[10378] | 118 | // CHECKSTYLE.ON: SingleSpaceSeparator
|
---|
[7349] | 119 | if (dpkg || rpm || eque) {
|
---|
[7314] | 120 | for (String packageName : packageNames) {
|
---|
[10308] | 121 | String[] args;
|
---|
[7314] | 122 | if (dpkg) {
|
---|
| 123 | args = new String[] {"dpkg-query", "--show", "--showformat", "${Architecture}-${Version}", packageName};
|
---|
[7349] | 124 | } else if (eque) {
|
---|
| 125 | args = new String[] {"equery", "-q", "list", "-e", "--format=$fullversion", packageName};
|
---|
[7314] | 126 | } else {
|
---|
| 127 | args = new String[] {"rpm", "-q", "--qf", "%{arch}-%{version}", packageName};
|
---|
| 128 | }
|
---|
[12830] | 129 | try {
|
---|
| 130 | String version = Utils.execOutput(Arrays.asList(args));
|
---|
| 131 | if (version != null && !version.isEmpty()) {
|
---|
| 132 | return packageName + ':' + version;
|
---|
[12239] | 133 | }
|
---|
[12830] | 134 | } catch (ExecutionException e) {
|
---|
| 135 | // Package does not exist, continue
|
---|
| 136 | Logging.trace(e);
|
---|
[7314] | 137 | }
|
---|
| 138 | }
|
---|
[6962] | 139 | }
|
---|
[12830] | 140 | } catch (IOException | InterruptedException e) {
|
---|
[12620] | 141 | Logging.warn(e);
|
---|
[6850] | 142 | }
|
---|
[6962] | 143 | return null;
|
---|
[6850] | 144 | }
|
---|
[6920] | 145 |
|
---|
[6850] | 146 | /**
|
---|
[6103] | 147 | * Get the Java package name including detailed version.
|
---|
| 148 | *
|
---|
| 149 | * Some Java bugs are specific to a certain security update, so in addition
|
---|
| 150 | * to the Java version, we also need the exact package version.
|
---|
| 151 | *
|
---|
[7314] | 152 | * @return The package name and package version if it can be identified, null otherwise
|
---|
[6103] | 153 | */
|
---|
| 154 | public String getJavaPackageDetails() {
|
---|
[7318] | 155 | String home = System.getProperty("java.home");
|
---|
[10580] | 156 | if (home.contains("java-8-openjdk") || home.contains("java-1.8.0-openjdk")) {
|
---|
| 157 | return getPackageDetails("openjdk-8-jre", "java-1_8_0-openjdk", "java-1.8.0-openjdk");
|
---|
| 158 | } else if (home.contains("java-9-openjdk") || home.contains("java-1.9.0-openjdk")) {
|
---|
[12830] | 159 | return getPackageDetails("openjdk-9-jre", "java-1_9_0-openjdk", "java-1.9.0-openjdk", "java-9-openjdk");
|
---|
[7349] | 160 | } else if (home.contains("icedtea")) {
|
---|
| 161 | return getPackageDetails("icedtea-bin");
|
---|
| 162 | } else if (home.contains("oracle")) {
|
---|
| 163 | return getPackageDetails("oracle-jdk-bin", "oracle-jre-bin");
|
---|
[6103] | 164 | }
|
---|
| 165 | return null;
|
---|
| 166 | }
|
---|
[6920] | 167 |
|
---|
[6850] | 168 | /**
|
---|
| 169 | * Get the Web Start package name including detailed version.
|
---|
| 170 | *
|
---|
[7314] | 171 | * OpenJDK packages are shipped with icedtea-web package,
|
---|
| 172 | * but its version generally does not match main java package version.
|
---|
[6920] | 173 | *
|
---|
[6850] | 174 | * Simply return {@code null} if there's no separate package for Java WebStart.
|
---|
| 175 | *
|
---|
| 176 | * @return The package name and package version if it can be identified, null otherwise
|
---|
| 177 | */
|
---|
| 178 | public String getWebStartPackageDetails() {
|
---|
[7314] | 179 | if (isOpenJDK()) {
|
---|
| 180 | return getPackageDetails("icedtea-netx", "icedtea-web");
|
---|
[6850] | 181 | }
|
---|
| 182 | return null;
|
---|
| 183 | }
|
---|
[6103] | 184 |
|
---|
[10734] | 185 | /**
|
---|
| 186 | * Get the Gnome ATK wrapper package name including detailed version.
|
---|
| 187 | *
|
---|
| 188 | * Debian and Ubuntu derivatives come with a pre-enabled accessibility software
|
---|
| 189 | * completely buggy that makes Swing crash in a lot of different ways.
|
---|
| 190 | *
|
---|
| 191 | * Simply return {@code null} if it's not found.
|
---|
| 192 | *
|
---|
| 193 | * @return The package name and package version if it can be identified, null otherwise
|
---|
| 194 | */
|
---|
| 195 | public String getAtkWrapperPackageDetails() {
|
---|
| 196 | if (isOpenJDK() && isDebianOrUbuntu()) {
|
---|
| 197 | return getPackageDetails("libatk-wrapper-java");
|
---|
| 198 | }
|
---|
| 199 | return null;
|
---|
| 200 | }
|
---|
| 201 |
|
---|
[12219] | 202 | private String buildOSDescription() {
|
---|
[5850] | 203 | String osName = System.getProperty("os.name");
|
---|
| 204 | if ("Linux".equalsIgnoreCase(osName)) {
|
---|
| 205 | try {
|
---|
[8540] | 206 | // Try lsb_release (only available on LSB-compliant Linux systems,
|
---|
| 207 | // see https://www.linuxbase.org/lsb-cert/productdir.php?by_prod )
|
---|
[12411] | 208 | String line = exec("lsb_release", "-ds");
|
---|
[12217] | 209 | if (line != null && !line.isEmpty()) {
|
---|
| 210 | line = line.replaceAll("\"+", "");
|
---|
| 211 | line = line.replaceAll("NAME=", ""); // strange code for some Gentoo's
|
---|
| 212 | if (line.startsWith("Linux ")) // e.g. Linux Mint
|
---|
| 213 | return line;
|
---|
| 214 | else if (!line.isEmpty())
|
---|
| 215 | return "Linux " + line;
|
---|
[5850] | 216 | }
|
---|
| 217 | } catch (IOException e) {
|
---|
[12620] | 218 | Logging.debug(e);
|
---|
[5877] | 219 | // Non LSB-compliant Linux system. List of common fallback release files: http://linuxmafia.com/faq/Admin/release-files.html
|
---|
| 220 | for (LinuxReleaseInfo info : new LinuxReleaseInfo[]{
|
---|
| 221 | new LinuxReleaseInfo("/etc/lsb-release", "DISTRIB_DESCRIPTION", "DISTRIB_ID", "DISTRIB_RELEASE"),
|
---|
| 222 | new LinuxReleaseInfo("/etc/os-release", "PRETTY_NAME", "NAME", "VERSION"),
|
---|
| 223 | new LinuxReleaseInfo("/etc/arch-release"),
|
---|
| 224 | new LinuxReleaseInfo("/etc/debian_version", "Debian GNU/Linux "),
|
---|
| 225 | new LinuxReleaseInfo("/etc/fedora-release"),
|
---|
| 226 | new LinuxReleaseInfo("/etc/gentoo-release"),
|
---|
[7314] | 227 | new LinuxReleaseInfo("/etc/redhat-release"),
|
---|
| 228 | new LinuxReleaseInfo("/etc/SuSE-release")
|
---|
[5877] | 229 | }) {
|
---|
| 230 | String description = info.extractDescription();
|
---|
| 231 | if (description != null && !description.isEmpty()) {
|
---|
| 232 | return "Linux " + description;
|
---|
| 233 | }
|
---|
| 234 | }
|
---|
[5850] | 235 | }
|
---|
| 236 | }
|
---|
| 237 | return osName;
|
---|
| 238 | }
|
---|
[6070] | 239 |
|
---|
[5994] | 240 | @Override
|
---|
| 241 | public String getOSDescription() {
|
---|
| 242 | if (osDescription == null) {
|
---|
| 243 | osDescription = buildOSDescription();
|
---|
| 244 | }
|
---|
| 245 | return osDescription;
|
---|
| 246 | }
|
---|
[6070] | 247 |
|
---|
[12219] | 248 | private static class LinuxReleaseInfo {
|
---|
[5877] | 249 | private final String path;
|
---|
| 250 | private final String descriptionField;
|
---|
| 251 | private final String idField;
|
---|
| 252 | private final String releaseField;
|
---|
| 253 | private final boolean plainText;
|
---|
| 254 | private final String prefix;
|
---|
[6070] | 255 |
|
---|
[12219] | 256 | LinuxReleaseInfo(String path, String descriptionField, String idField, String releaseField) {
|
---|
[5877] | 257 | this(path, descriptionField, idField, releaseField, false, null);
|
---|
| 258 | }
|
---|
| 259 |
|
---|
[12219] | 260 | LinuxReleaseInfo(String path) {
|
---|
[5877] | 261 | this(path, null, null, null, true, null);
|
---|
| 262 | }
|
---|
| 263 |
|
---|
[12219] | 264 | LinuxReleaseInfo(String path, String prefix) {
|
---|
[5877] | 265 | this(path, null, null, null, true, prefix);
|
---|
| 266 | }
|
---|
[6070] | 267 |
|
---|
[5877] | 268 | private LinuxReleaseInfo(String path, String descriptionField, String idField, String releaseField, boolean plainText, String prefix) {
|
---|
| 269 | this.path = path;
|
---|
| 270 | this.descriptionField = descriptionField;
|
---|
| 271 | this.idField = idField;
|
---|
| 272 | this.releaseField = releaseField;
|
---|
| 273 | this.plainText = plainText;
|
---|
| 274 | this.prefix = prefix;
|
---|
| 275 | }
|
---|
| 276 |
|
---|
[12219] | 277 | @Override
|
---|
| 278 | public String toString() {
|
---|
[6070] | 279 | return "ReleaseInfo [path=" + path + ", descriptionField=" + descriptionField +
|
---|
[8846] | 280 | ", idField=" + idField + ", releaseField=" + releaseField + ']';
|
---|
[5877] | 281 | }
|
---|
[6070] | 282 |
|
---|
[5877] | 283 | /**
|
---|
| 284 | * Extracts OS detailed information from a Linux release file (/etc/xxx-release)
|
---|
| 285 | * @return The OS detailed information, or {@code null}
|
---|
| 286 | */
|
---|
| 287 | public String extractDescription() {
|
---|
| 288 | String result = null;
|
---|
| 289 | if (path != null) {
|
---|
[7315] | 290 | Path p = Paths.get(path);
|
---|
[11096] | 291 | if (p.toFile().exists()) {
|
---|
[7315] | 292 | try (BufferedReader reader = Files.newBufferedReader(p, StandardCharsets.UTF_8)) {
|
---|
[5877] | 293 | String id = null;
|
---|
| 294 | String release = null;
|
---|
| 295 | String line;
|
---|
| 296 | while (result == null && (line = reader.readLine()) != null) {
|
---|
| 297 | if (line.contains("=")) {
|
---|
| 298 | String[] tokens = line.split("=");
|
---|
| 299 | if (tokens.length >= 2) {
|
---|
| 300 | // Description, if available, contains exactly what we need
|
---|
| 301 | if (descriptionField != null && descriptionField.equalsIgnoreCase(tokens[0])) {
|
---|
| 302 | result = Utils.strip(tokens[1]);
|
---|
| 303 | } else if (idField != null && idField.equalsIgnoreCase(tokens[0])) {
|
---|
| 304 | id = Utils.strip(tokens[1]);
|
---|
| 305 | } else if (releaseField != null && releaseField.equalsIgnoreCase(tokens[0])) {
|
---|
| 306 | release = Utils.strip(tokens[1]);
|
---|
| 307 | }
|
---|
| 308 | }
|
---|
| 309 | } else if (plainText && !line.isEmpty()) {
|
---|
| 310 | // Files composed of a single line
|
---|
| 311 | result = Utils.strip(line);
|
---|
| 312 | }
|
---|
| 313 | }
|
---|
| 314 | // If no description has been found, try to rebuild it with "id" + "release" (i.e. "name" + "version")
|
---|
| 315 | if (result == null && id != null && release != null) {
|
---|
[8846] | 316 | result = id + ' ' + release;
|
---|
[5877] | 317 | }
|
---|
| 318 | } catch (IOException e) {
|
---|
| 319 | // Ignore
|
---|
[12620] | 320 | Logging.trace(e);
|
---|
[5877] | 321 | }
|
---|
| 322 | }
|
---|
| 323 | }
|
---|
| 324 | // Append prefix if any
|
---|
| 325 | if (result != null && !result.isEmpty() && prefix != null && !prefix.isEmpty()) {
|
---|
| 326 | result = prefix + result;
|
---|
| 327 | }
|
---|
[8510] | 328 | if (result != null)
|
---|
| 329 | result = result.replaceAll("\"+", "");
|
---|
[5877] | 330 | return result;
|
---|
| 331 | }
|
---|
| 332 | }
|
---|
[6920] | 333 |
|
---|
[11162] | 334 | /**
|
---|
| 335 | * Get the dot directory <code>~/.josm</code>.
|
---|
| 336 | * @return the dot directory
|
---|
| 337 | */
|
---|
[11218] | 338 | private static File getDotDirectory() {
|
---|
[11162] | 339 | String dirName = "." + Main.pref.getJOSMDirectoryBaseName().toLowerCase(Locale.ENGLISH);
|
---|
| 340 | return new File(System.getProperty("user.home"), dirName);
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | /**
|
---|
| 344 | * Returns true if the dot directory should be used for storing preferences,
|
---|
| 345 | * cache and user data.
|
---|
| 346 | * Currently this is the case, if the dot directory already exists.
|
---|
| 347 | * @return true if the dot directory should be used
|
---|
| 348 | */
|
---|
[11613] | 349 | private static boolean useDotDirectory() {
|
---|
[11162] | 350 | return getDotDirectory().exists();
|
---|
| 351 | }
|
---|
| 352 |
|
---|
[7206] | 353 | @Override
|
---|
[7829] | 354 | public File getDefaultCacheDirectory() {
|
---|
[11162] | 355 | if (useDotDirectory()) {
|
---|
| 356 | return new File(getDotDirectory(), "cache");
|
---|
| 357 | } else {
|
---|
| 358 | String xdgCacheDir = System.getenv("XDG_CACHE_HOME");
|
---|
| 359 | if (xdgCacheDir != null && !xdgCacheDir.isEmpty()) {
|
---|
| 360 | return new File(xdgCacheDir, Main.pref.getJOSMDirectoryBaseName());
|
---|
| 361 | } else {
|
---|
| 362 | return new File(System.getProperty("user.home") + File.separator +
|
---|
| 363 | ".cache" + File.separator + Main.pref.getJOSMDirectoryBaseName());
|
---|
| 364 | }
|
---|
| 365 | }
|
---|
[7829] | 366 | }
|
---|
[7831] | 367 |
|
---|
| 368 | @Override
|
---|
| 369 | public File getDefaultPrefDirectory() {
|
---|
[11162] | 370 | if (useDotDirectory()) {
|
---|
| 371 | return getDotDirectory();
|
---|
| 372 | } else {
|
---|
| 373 | String xdgConfigDir = System.getenv("XDG_CONFIG_HOME");
|
---|
| 374 | if (xdgConfigDir != null && !xdgConfigDir.isEmpty()) {
|
---|
| 375 | return new File(xdgConfigDir, Main.pref.getJOSMDirectoryBaseName());
|
---|
| 376 | } else {
|
---|
| 377 | return new File(System.getProperty("user.home") + File.separator +
|
---|
| 378 | ".config" + File.separator + Main.pref.getJOSMDirectoryBaseName());
|
---|
| 379 | }
|
---|
| 380 | }
|
---|
[7831] | 381 | }
|
---|
[7834] | 382 |
|
---|
| 383 | @Override
|
---|
| 384 | public File getDefaultUserDataDirectory() {
|
---|
[11162] | 385 | if (useDotDirectory()) {
|
---|
| 386 | return getDotDirectory();
|
---|
| 387 | } else {
|
---|
| 388 | String xdgDataDir = System.getenv("XDG_DATA_HOME");
|
---|
| 389 | if (xdgDataDir != null && !xdgDataDir.isEmpty()) {
|
---|
| 390 | return new File(xdgDataDir, Main.pref.getJOSMDirectoryBaseName());
|
---|
| 391 | } else {
|
---|
| 392 | return new File(System.getProperty("user.home") + File.separator +
|
---|
| 393 | ".local" + File.separator + "share" + File.separator + Main.pref.getJOSMDirectoryBaseName());
|
---|
| 394 | }
|
---|
| 395 | }
|
---|
[7834] | 396 | }
|
---|
[8015] | 397 |
|
---|
[11642] | 398 | @Override
|
---|
[12241] | 399 | public X509Certificate getX509Certificate(CertAmend certAmend)
|
---|
| 400 | throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
|
---|
| 401 | File f = new File("/usr/share/ca-certificates/mozilla", certAmend.getFilename());
|
---|
| 402 | if (f.exists()) {
|
---|
| 403 | CertificateFactory fact = CertificateFactory.getInstance("X.509");
|
---|
| 404 | try (FileInputStream is = new FileInputStream(f)) {
|
---|
| 405 | return (X509Certificate) fact.generateCertificate(is);
|
---|
| 406 | }
|
---|
| 407 | }
|
---|
| 408 | return null;
|
---|
| 409 | }
|
---|
[1023] | 410 | }
|
---|