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.text.DateFormat; 38 import java.text.ParseException; 39 import java.text.SimpleDateFormat; 40 import java.util.ArrayList; 41 import java.util.Calendar; 42 import java.util.Date; 43 import java.util.List; 44 import java.util.Locale; 45 46 final class MacCertificate { 47 private final String certificate; 48 private final boolean verbose; 49 50 MacCertificate(String certificate) { 51 this.certificate = certificate; 52 this.verbose = false; 53 } 54 55 MacCertificate(String certificate, boolean verbose) { 56 this.certificate = certificate; 57 this.verbose = verbose; 58 } 59 60 boolean isValid() { 61 return verifyCertificate(this.certificate, verbose); 62 } 63 64 private static File findCertificate(String certificate, boolean verbose) { 65 File result = null; 66 67 List<String> args = new ArrayList<>(); 68 args.add("security"); 69 args.add("find-certificate"); 70 args.add("-c"); 71 args.add(certificate); 72 args.add("-a"); 73 args.add("-p"); 74 75 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); 76 PrintStream ps = new PrintStream(baos)) { 77 ProcessBuilder security = new ProcessBuilder(args); 78 IOUtils.exec(security, verbose, false, ps); 79 80 File output = File.createTempFile("tempfile", ".tmp"); 81 PrintStream p = new PrintStream( 82 new BufferedOutputStream( 83 new FileOutputStream(output, true))); 84 BufferedReader bfReader = new BufferedReader( 85 new InputStreamReader( 86 new ByteArrayInputStream(baos.toByteArray()))); 87 String line = null; 88 89 while((line = bfReader.readLine()) != null){ 90 p.println(line); 91 } 92 93 p.close(); 94 result = output; 95 } 96 catch (IOException ignored) {} 97 98 return result; 99 } 100 101 private static Date findCertificateDate(String filename, boolean verbose) { 102 Date result = null; 103 104 List<String> args = new ArrayList<>(); 105 args.add("/usr/bin/openssl"); 106 args.add("x509"); 107 args.add("-noout"); 108 args.add("-enddate"); 109 args.add("-in"); 110 args.add(filename); 111 112 try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); 113 PrintStream ps = new PrintStream(baos)) { 114 ProcessBuilder security = new ProcessBuilder(args); 115 IOUtils.exec(security, verbose, false, ps); 116 String output = baos.toString(); 117 output = output.substring(output.indexOf("=") + 1); 118 DateFormat df = new SimpleDateFormat( 119 "MMM dd kk:mm:ss yyyy z", Locale.ENGLISH); 120 result = df.parse(output); 121 } catch (IOException | ParseException ex) { 122 Log.debug(ex); 123 } 124 125 return result; 126 } 127 128 private static boolean verifyCertificate( 129 String certificate, boolean verbose) { 130 boolean result = false; 131 132 try { 133 File file = null; 134 Date certificateDate = null; 135 136 try { 137 file = findCertificate(certificate, verbose); 138 139 if (file != null) { 140 certificateDate = findCertificateDate( 141 file.getCanonicalPath(), verbose); 142 } 143 } 144 finally { 145 if (file != null) { 146 file.delete(); 147 } 148 } 149 150 if (certificateDate != null) { 151 Calendar c = Calendar.getInstance(); 152 Date today = c.getTime(); 153 154 if (certificateDate.after(today)) { 155 result = true; 156 } 157 } 158 } 159 catch (IOException ignored) {} 160 161 return result; 162 } 163 }