src/share/classes/org/openjdk/jigsaw/cli/Signer.java

Print this page

        

*** 30,39 **** --- 30,40 ---- import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.StandardCopyOption; import java.security.*; import java.security.cert.X509Certificate; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.security.auth.DestroyFailedException; import static java.lang.System.err;
*** 41,51 **** import static java.lang.System.out; import static java.security.KeyStore.PasswordProtection; import static java.security.KeyStore.PrivateKeyEntry; import org.openjdk.jigsaw.*; ! import org.openjdk.jigsaw.ModuleFile.Reader; import org.openjdk.internal.joptsimple.OptionException; import org.openjdk.internal.joptsimple.OptionParser; import org.openjdk.internal.joptsimple.OptionSet; import org.openjdk.internal.joptsimple.OptionSpec; --- 42,54 ---- import static java.lang.System.out; import static java.security.KeyStore.PasswordProtection; import static java.security.KeyStore.PrivateKeyEntry; import org.openjdk.jigsaw.*; ! import org.openjdk.jigsaw.ModuleFileParser; ! import org.openjdk.jigsaw.ModuleFileParserException; ! import org.openjdk.jigsaw.ModuleFileParser.Event; import org.openjdk.internal.joptsimple.OptionException; import org.openjdk.internal.joptsimple.OptionParser; import org.openjdk.internal.joptsimple.OptionSet; import org.openjdk.internal.joptsimple.OptionSpec;
*** 213,233 **** throw new Command.Exception("unable to extract private key " + "entry from keystore", x); } // First, read in module file and calculate hashes ! List<byte[]> hashes = null; ! byte[] moduleInfoBytes = null; ! try (FileInputStream mfis = new FileInputStream(moduleFile); ! Reader reader = new Reader(new DataInputStream(mfis))) ! { ! moduleInfoBytes = reader.readStart(); ! if (reader.hasSignature()) throw new Command.Exception("module file is already signed"); ! reader.readRest(); ! hashes = reader.getCalculatedHashes(); ! } catch (IOException x) { throw new Command.Exception("unable to read module file", x); } // Next, generate signature and insert into signed module file File tmpFile = (signedModuleFile == null) --- 216,246 ---- throw new Command.Exception("unable to extract private key " + "entry from keystore", x); } // First, read in module file and calculate hashes ! List<byte[]> hashes = new ArrayList<>(); ! int moduleInfoLength = 0; ! try (FileInputStream mfis = new FileInputStream(moduleFile)) { ! ModuleFileParser parser = ModuleFile.newParser(mfis); ! hashes.add(parser.getHash()); ! while (parser.hasNext()) { ! Event event = parser.next(); ! if (event == Event.END_SECTION) { ! SectionHeader header = parser.getSectionHeader(); ! if (header.getType() == SectionType.SIGNATURE) throw new Command.Exception("module file is already signed"); ! if (header.getType() == SectionType.MODULE_INFO) ! moduleInfoLength = header.getCSize(); ! checkHashMatch(header.getHash(), parser.getHash()); ! hashes.add(parser.getHash()); ! } else if (event == Event.END_FILE) { ! checkHashMatch(parser.fileHeader().getHash(), parser.getHash()); ! hashes.add(parser.getHash()); ! } ! } ! } catch (IOException | ModuleFileParserException x) { throw new Command.Exception("unable to read module file", x); } // Next, generate signature and insert into signed module file File tmpFile = (signedModuleFile == null)
*** 239,249 **** // Transfer header and module-info from module file // to signed module file. long remainderStart = ModuleFileHeader.LENGTH + SectionHeader.LENGTH ! + moduleInfoBytes.length; FileChannel source = mraf.getChannel(); FileChannel dest = raf.getChannel(); for (long pos = 0; pos < remainderStart;) { pos += source.transferTo(pos, remainderStart - pos, dest); } --- 252,262 ---- // Transfer header and module-info from module file // to signed module file. long remainderStart = ModuleFileHeader.LENGTH + SectionHeader.LENGTH ! + moduleInfoLength; FileChannel source = mraf.getChannel(); FileChannel dest = raf.getChannel(); for (long pos = 0; pos < remainderStart;) { pos += source.transferTo(pos, remainderStart - pos, dest); }
*** 273,282 **** --- 286,314 ---- throw new Command.Exception("unable to sign module", ioe); } } } + private void checkHashMatch(byte[] expected, byte[] computed) { + if (!MessageDigest.isEqual(expected, computed)) + throw new ModuleFileParserException("Expected hash " + + hashHexString(expected) + + " instead of " + + hashHexString(computed)); + } + + private String hashHexString(byte[] hash) { + StringBuilder hex = new StringBuilder("0x"); + for (int i = 0; i < hash.length; i++) { + int val = (hash[i] & 0xFF); + if (val <= 16) + hex.append("0"); + hex.append(Integer.toHexString(val)); + } + return hex.toString(); + } + private PrivateKeyEntry getPrivateKeyEntry(String signer) throws GeneralSecurityException, IOException { PasswordProtection storePassword = null; PasswordProtection keyPassword = null;