diff --git a/apps/routerconsole/jsp/verifyupdate.jsp b/apps/routerconsole/jsp/verifyupdate.jsp new file mode 100644 index 000000000..2d13d3508 --- /dev/null +++ b/apps/routerconsole/jsp/verifyupdate.jsp @@ -0,0 +1,12 @@ +<%@page contentType="text/html" %> + + +
+0h
characters if necessary), the next 40 bytes are the
+ * resulting DSA signature, and the remaining bytes are the input file.
+ *
+ * @param inputFile The file to be signed.
+ * @param outputFile The signed file to write.
+ * @param privateKeyFile The name of the file containing the private key to
+ * sign inputFile
with.
+ * @param updateVersion The version number of the I2P update. If this
+ * string is longer than 16 characters it will be
+ * truncated.
+ *
+ * @return An instance of {@link net.i2p.data.Signature}.
+ */
+ public Signature sign(String inputFile, String outputFile, String privateKeyFile, String updateVersion) {
+ byte[] headerUpdateVersion = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00 };
+ byte[] updateVersionBytes = {};
+ if (updateVersion.length() > 16)
+ updateVersion = updateVersion.substring(0, 16);
+ try {
+ updateVersionBytes = updateVersion.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // If this ever gets called, you need a new JVM.
+ }
+ for (int i = 0; i < updateVersionBytes.length; i++)
+ headerUpdateVersion[i] = updateVersionBytes[i];
+ byte[] data = readFileBytes(inputFile, 0, (int) new File(inputFile).length());
+ Signature signature = DSAEngine.getInstance().sign(data, new SigningPrivateKey(readFileBytes(privateKeyFile, 0, (int) new File(privateKeyFile).length()-1)));
+ FileOutputStream fileOutputStream = null;
+ try {
+ fileOutputStream = new FileOutputStream(outputFile);
+ fileOutputStream.write(headerUpdateVersion);
+ fileOutputStream.write(signature.getData());
+ fileOutputStream.write(data);
+ fileOutputStream.close();
+ } catch (IOException ioe) {
+ if (_log.shouldLog(Log.WARN))
+ _log.log(Log.WARN, "Error writing signed I2P update file " + outputFile, ioe);
+ }
+
+ return signature;
+ }
+
+ /**
+ * Verifies the DSA signature of a signed I2P update.
+ *
+ * @param inputFile The signed update file to check.
+ *
+ * @return true
if the file has a valid signature.
+ */
+ public boolean verify(String inputFile) {
+ DSAEngine.getInstance().verifySignature(new Signature(readFileBytes(inputFile, 16, 55)),
+ readFileBytes(inputFile, 56, (int) new File(inputFile).length()-57),
+ new SigningPublicKey(I2P_PUBLICKEY));
+ return false;
+ }
+
+ /**
+ * Verifies the DSA signature of a signed I2P update.
+ *
+ * @param inputFile The signed update file to check.
+ * @param publicKeyFile The public key to use for verification.
+ *
+ * @return true
if the file has a valid signature.
+ */
+ public boolean verify(String inputFile, String publicKeyFile) {
+ DSAEngine.getInstance().verifySignature(new Signature(readFileBytes(inputFile, 16, 55)),
+ readFileBytes(inputFile, 56, (int) new File(inputFile).length()-57),
+ new SigningPublicKey(readFileBytes(publicKeyFile, 0, (int) new File(publicKeyFile).length()-1)));
+ return false;
+ }
+
+ private byte[] readFileBytes(String inputFile, int offset, int length) {
+ byte[] bytes = new byte[length];
+ FileInputStream fileInputStream = null;
+
+ try {
+ fileInputStream = new FileInputStream(inputFile);
+ fileInputStream.read(bytes, offset, length);
+ fileInputStream.close();
+ } catch (FileNotFoundException fnfe) {
+ if (_log.shouldLog(Log.WARN))
+ _log.log(Log.WARN, "File " + inputFile + " not found", fnfe);
+ } catch (IOException ioe) {
+ if (_log.shouldLog(Log.WARN))
+ _log.log(Log.WARN, "Error reading file " + inputFile, ioe);
+ }
+
+ return bytes;
+ }
+}