1 /* 2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jpackage.internal; 27 28 import java.io.BufferedOutputStream; 29 import java.io.BufferedReader; 30 import java.io.ByteArrayInputStream; 31 import java.io.ByteArrayOutputStream; 32 import java.io.File; 33 import java.io.FileOutputStream; 34 import java.io.IOException; 35 import java.io.InputStreamReader; 36 import java.io.PrintStream; 37 import java.nio.file.StandardCopyOption; 38 import java.nio.file.Files; 39 import java.text.DateFormat; 40 import java.text.ParseException; 41 import java.text.SimpleDateFormat; 42 import java.util.ArrayList; 43 import java.util.Calendar; 44 import java.util.Date; 45 import java.util.List; 46 import java.util.Locale; 47 48 final class MacCertificate { 49 private final String certificate; 50 private final boolean verbose; 51 52 MacCertificate(String certificate) { 53 this.certificate = certificate; 54 this.verbose = false; 55 } 56 57 MacCertificate(String certificate, boolean verbose) { 58 this.certificate = certificate; 59 this.verbose = verbose; 60 } 61 62 boolean isValid() { 63 return verifyCertificate(this.certificate, verbose); 64 } 65 66 private static File findCertificate(String certificate, boolean verbose) { 67 File result = null; 68 69 List<String> args = new ArrayList<>(); 70 args.add("security"); 71 args.add("find-certificate"); 72 args.add("-c"); 73 args.add(certificate); 74 args.add("-a"); 75 args.add("-p"); 76 77 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); 78 PrintStream ps = new PrintStream(baos)) { 79 ProcessBuilder security = new ProcessBuilder(args); 80 IOUtils.exec(security, false, ps); 81 82 File output = File.createTempFile("tempfile", ".tmp"); 83 84 Files.copy(new ByteArrayInputStream(baos.toByteArray()), 85 output.toPath(), StandardCopyOption.REPLACE_EXISTING); 86 87 result = output; 88 } 89 catch (IOException ignored) {} 90 91 return result; 92 } 93 94 private static Date findCertificateDate(String filename, boolean verbose) { 95 Date result = null; 96 97 List<String> args = new ArrayList<>(); 98 args.add("/usr/bin/openssl"); 99 args.add("x509"); 100 args.add("-noout"); 101 args.add("-enddate"); 102 args.add("-in"); 103 args.add(filename); 104 105 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); 106 PrintStream ps = new PrintStream(baos)) { 107 ProcessBuilder security = new ProcessBuilder(args); 108 IOUtils.exec(security, false, ps); 109 String output = baos.toString(); 110 output = output.substring(output.indexOf("=") + 1); 111 DateFormat df = new SimpleDateFormat( 112 "MMM dd kk:mm:ss yyyy z", Locale.ENGLISH); 113 result = df.parse(output); 114 } catch (IOException | ParseException ex) { 115 Log.debug(ex); 116 } 117 118 return result; 119 } 120 121 private static boolean verifyCertificate( 122 String certificate, boolean verbose) { 123 boolean result = false; 124 125 try { 126 File file = null; 127 Date certificateDate = null; 128 129 try { 130 file = findCertificate(certificate, verbose); 131 132 if (file != null) { 133 certificateDate = findCertificateDate( 134 file.getCanonicalPath(), verbose); 135 } 136 } 137 finally { 138 if (file != null) { 139 file.delete(); 140 } 141 } 142 143 if (certificateDate != null) { 144 Calendar c = Calendar.getInstance(); 145 Date today = c.getTime(); 146 147 if (certificateDate.after(today)) { 148 result = true; 149 } 150 } 151 } 152 catch (IOException ignored) {} 153 154 return result; 155 } 156 }