diff --git a/build.gradle b/build.gradle index 43963b30cc6..21a9fc3289e 100644 --- a/build.gradle +++ b/build.gradle @@ -21,10 +21,9 @@ sourceCompatibility = 1.8 mainClassName = 'bisq.desktop.app.BisqAppMain' -jar { - manifest.attributes( - 'Class-Path': 'bcpg-jdk15on-1.56.jar bcprov-jdk15on-1.56.jar' - ) +tasks.withType(AbstractArchiveTask) { + preserveFileTimestamps = false + reproducibleFileOrder = true } tasks.withType(JavaCompile) { diff --git a/package/linux/32bitBuild.sh b/package/linux/32bitBuild.sh index 4bd665b34ef..4fd962c6ac6 100644 --- a/package/linux/32bitBuild.sh +++ b/package/linux/32bitBuild.sh @@ -26,21 +26,11 @@ $JAVA_HOME/bin/javapackager \ -vendor Bisq \ -outdir deploy \ -srcfiles "$dir/Bisq-$version.jar" \ - -srcfiles "$dir/bcpg-jdk15on-1.56.jar" \ - -srcfiles "$dir/bcprov-jdk15on-1.56.jar" \ -srcfiles package/linux/LICENSE \ -appclass bisq.desktop.app.BisqAppMain \ -BjvmOptions=-Xss1280k \ -outfile Bisq -# when we have support for security manager we use that -# \ -# -BjvmOptions=-Djava.security.manager \ -# -BjvmOptions=-Djava.security.debug=failure \ -# -BjvmOptions=-Djava.security.policy=file:bisq.policy -# -srcfiles "core/src/main/resources/bisq.policy" \ - - # sudo alien -r -c -k deploy/bundles/bisq-$version.deb diff --git a/package/linux/64bitBuild.sh b/package/linux/64bitBuild.sh index 553332701c2..d987527e747 100644 --- a/package/linux/64bitBuild.sh +++ b/package/linux/64bitBuild.sh @@ -26,21 +26,11 @@ $JAVA_HOME/bin/javapackager \ -vendor Bisq \ -outdir deploy \ -srcfiles "$dir/Bisq-$version.jar" \ - -srcfiles "$dir/bcpg-jdk15on-1.56.jar" \ - -srcfiles "$dir/bcprov-jdk15on-1.56.jar" \ -srcfiles package/linux/LICENSE \ -appclass bisq.desktop.app.BisqAppMain \ -BjvmOptions=-Xss1280k \ -outfile Bisq -# when we have support for security manager we use that -# \ -# -BjvmOptions=-Djava.security.manager \ -# -BjvmOptions=-Djava.security.debug=failure \ -# -BjvmOptions=-Djava.security.policy=file:bisq.policy -# -srcfiles "core/src/main/resources/bisq.policy" \ - - # uncomment because the build VM does not support alien #sudo alien -r -c -k deploy/bundles/bisq-$version.deb diff --git a/package/osx/create_app.sh b/package/osx/create_app.sh index f839ea9ef7a..f3d121abc03 100755 --- a/package/osx/create_app.sh +++ b/package/osx/create_app.sh @@ -12,6 +12,16 @@ version="0.7.0" EXE_JAR=build/libs/bisq-desktop-0.7.0-all.jar +echo SHA 256 before stripping jar file: +shasum -a256 $EXE_JAR | awk '{print $1}' + +# We make a deterministic jar by stripping out comments with date, etc. +java -jar ./package/osx/tools-1.0.jar $EXE_JAR + +echo SHA 256 after stripping jar file to get a deterministic jar: +shasum -a256 $EXE_JAR | awk '{print $1}' | tee deploy/Bisq-$version.jar.txt + + linux32=build/vm/vm_shared_ubuntu14_32bit linux64=build/vm/vm_shared_ubuntu win32=build/vm/vm_shared_windows_32bit @@ -76,20 +86,9 @@ $JAVA_HOME/bin/javapackager \ -vendor Bisq \ -outdir deploy \ -srcfiles "deploy/Bisq-$version.jar" \ - -srcfiles "build/app/lib//$bc_lib1" \ - -srcfiles "build/app/lib//$bc_lib2" \ -appclass bisq.desktop.app.BisqAppMain \ -outfile Bisq - -# TODO lib/bcpg-jdk15on.jar lib/bcprov-jdk15on.jar not included in build -# when we have support for security manager we use that -# \ -# -BjvmOptions=-Djava.security.manager \ -# -BjvmOptions=-Djava.security.debug=failure \ -# -BjvmOptions=-Djava.security.policy=file:bisq.policy -# -srcfiles "core/src/main/resources/bisq.policy" \ - rm "deploy/Bisq.html" rm "deploy/Bisq.jnlp" diff --git a/package/osx/finalize.sh b/package/osx/finalize.sh index 7b23afa3539..98c0fe9a27d 100755 --- a/package/osx/finalize.sh +++ b/package/osx/finalize.sh @@ -28,6 +28,8 @@ cp "$target_dir/../../package/5BC5ED73.asc" "$target_dir/" cp "$target_dir/../../package/29CDFD3B.asc" "$target_dir/" # signing key cp "$target_dir/../../package/signingkey.asc" "$target_dir/" +# hash of jar file +cp "deploy/Bisq-$version.jar.txt" "$target_dir/" dmg="Bisq-$version.dmg" cp "$macOS/$dmg" "$target_dir/" @@ -54,13 +56,14 @@ cp "$win64/bundles/$exe" "$target_dir/$exe64" cd "$target_dir" - +echo Create signatures gpg --digest-algo SHA256 --local-user $BISQ_GPG_USER --output $dmg.asc --detach-sig --armor $dmg gpg --digest-algo SHA256 --local-user $BISQ_GPG_USER --output $deb64.asc --detach-sig --armor $deb64 gpg --digest-algo SHA256 --local-user $BISQ_GPG_USER --output $deb32.asc --detach-sig --armor $deb32 gpg --digest-algo SHA256 --local-user $BISQ_GPG_USER --output $exe64.asc --detach-sig --armor $exe64 gpg --digest-algo SHA256 --local-user $BISQ_GPG_USER --output $exe32.asc --detach-sig --armor $exe32 +echo Verify signatures gpg --digest-algo SHA256 --verify $dmg{.asc*,} gpg --digest-algo SHA256 --verify $deb64{.asc*,} gpg --digest-algo SHA256 --verify $deb32{.asc*,} diff --git a/package/osx/tools-1.0.jar b/package/osx/tools-1.0.jar new file mode 100644 index 00000000000..69abf5498a3 Binary files /dev/null and b/package/osx/tools-1.0.jar differ diff --git a/package/windows/32bitBuild.bat b/package/windows/32bitBuild.bat index 045a2cbb438..0b56ac0d429 100644 --- a/package/windows/32bitBuild.bat +++ b/package/windows/32bitBuild.bat @@ -21,15 +21,5 @@ call "%JAVA_HOME%\bin\javapackager.exe" -deploy ^ -outdir %outdir% ^ -appclass bisq.desktop.app.BisqAppMain ^ -srcfiles %outdir%\Bisq.jar ^ --srcfiles %outdir%\bcpg-jdk15on-1.56.jar ^ --srcfiles %outdir%\bcprov-jdk15on-1.56.jar ^ -outfile Bisq ^ -Bruntime="%JAVA_HOME%\jre" - -:: when we have support for security manager we use that -:: -BjvmOptions=-Djava.security.manager ^ -:: -BjvmOptions=-Djava.security.debug=failure ^ -:: -BjvmOptions=-Djava.security.policy=file:bisq.policy ^ - -:: -srcfiles "core/src/main/resources/bisq.policy" ^ - diff --git a/package/windows/64bitBuild.bat b/package/windows/64bitBuild.bat index 13f391deec1..986d3a1ed5b 100644 --- a/package/windows/64bitBuild.bat +++ b/package/windows/64bitBuild.bat @@ -21,14 +21,5 @@ call "%JAVA_HOME%\bin\javapackager.exe" -deploy ^ -outdir %outdir% ^ -appclass bisq.desktop.app.BisqAppMain ^ -srcfiles %outdir%\Bisq.jar ^ --srcfiles %outdir%\bcpg-jdk15on-1.56.jar ^ --srcfiles %outdir%\bcprov-jdk15on-1.56.jar ^ -outfile Bisq ^ -Bruntime="%JAVA_HOME%\jre" - -:: when we have support for security manager we use that -:: -BjvmOptions=-Djava.security.manager ^ -:: -BjvmOptions=-Djava.security.debug=failure ^ -:: -BjvmOptions=-Djava.security.policy=file:bisq.policy ^ - -:: -srcfiles "core/src/main/resources/bisq.policy" ^ diff --git a/src/main/java/bisq/desktop/main/MainViewModel.java b/src/main/java/bisq/desktop/main/MainViewModel.java index 6c43fd513f9..e47a6173d51 100644 --- a/src/main/java/bisq/desktop/main/MainViewModel.java +++ b/src/main/java/bisq/desktop/main/MainViewModel.java @@ -48,7 +48,7 @@ import bisq.core.dao.DaoSetup; import bisq.core.filter.FilterManager; import bisq.core.locale.CurrencyUtil; -import bisq.core.locale.GlobalSettings; +import bisq.core.locale.FiatCurrency; import bisq.core.locale.Res; import bisq.core.locale.TradeCurrency; import bisq.core.offer.OpenOffer; @@ -1294,7 +1294,7 @@ private void setupDevDummyPaymentAccounts() { perfectMoneyAccount.init(); perfectMoneyAccount.setAccountNr("dummy_" + new Random().nextInt(100)); perfectMoneyAccount.setAccountName("PerfectMoney dummy");// Don't translate only for dev - perfectMoneyAccount.setSelectedTradeCurrency(GlobalSettings.getDefaultTradeCurrency()); + perfectMoneyAccount.setSelectedTradeCurrency(new FiatCurrency("USD")); user.addPaymentAccount(perfectMoneyAccount); if (p2PService.isBootstrapped()) { diff --git a/src/main/java/bisq/desktop/main/account/arbitratorregistration/ArbitratorRegistrationViewModel.java b/src/main/java/bisq/desktop/main/account/arbitratorregistration/ArbitratorRegistrationViewModel.java index e219967851c..1ffa41fddf0 100644 --- a/src/main/java/bisq/desktop/main/account/arbitratorregistration/ArbitratorRegistrationViewModel.java +++ b/src/main/java/bisq/desktop/main/account/arbitratorregistration/ArbitratorRegistrationViewModel.java @@ -155,7 +155,7 @@ boolean setPrivKeyAndCheckPubKey(String privKeyString) { void onRegister(ResultHandler resultHandler, ErrorMessageHandler errorMessageHandler) { updateDisableStates(); if (allDataValid) { - AddressEntry arbitratorDepositAddressEntry = walletService.getOrCreateAddressEntry(AddressEntry.Context.ARBITRATOR); + AddressEntry arbitratorDepositAddressEntry = walletService.getArbitratorAddressEntry(); String registrationSignature = arbitratorManager.signStorageSignaturePubKey(registrationKey); // TODO not impl in UI String emailAddress = null; diff --git a/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java b/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java index 798f2bffae7..1ed5784c924 100644 --- a/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java +++ b/src/main/java/bisq/desktop/main/funds/deposit/DepositView.java @@ -144,7 +144,7 @@ public void initialize() { usageColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.usage"))); // trigger creation of at least 1 savings address - walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE); + walletService.getFreshAddressEntry(); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); tableView.setPlaceholder(new AutoTooltipLabel(Res.get("funds.deposit.noAddresses"))); @@ -217,7 +217,7 @@ public void initialize() { if (hasUnUsedAddress) { new Popup<>().warning(Res.get("funds.deposit.selectUnused")).show(); } else { - AddressEntry newSavingsAddressEntry = walletService.getOrCreateUnusedAddressEntry(AddressEntry.Context.AVAILABLE); + AddressEntry newSavingsAddressEntry = walletService.getFreshAddressEntry(); updateList(); observableList.stream() .filter(depositListItem -> depositListItem.getAddressString().equals(newSavingsAddressEntry.getAddressString())) diff --git a/src/main/java/bisq/desktop/main/offer/EditableOfferDataModel.java b/src/main/java/bisq/desktop/main/offer/EditableOfferDataModel.java index 34f2c23f08d..f581e65b111 100644 --- a/src/main/java/bisq/desktop/main/offer/EditableOfferDataModel.java +++ b/src/main/java/bisq/desktop/main/offer/EditableOfferDataModel.java @@ -411,12 +411,12 @@ Offer createAndGetOffer() { return offer; } - // This works only if have already funds in the wallet + // This works only if we have already funds in the wallet public void estimateTxSize() { txFeeFromFeeService = feeService.getTxFee(feeTxSize); - Address fundingAddress = btcWalletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); + Address fundingAddress = btcWalletService.getFreshAddressEntry().getAddress(); Address reservedForTradeAddress = btcWalletService.getOrCreateAddressEntry(offerId, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); - Address changeAddress = btcWalletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); + Address changeAddress = btcWalletService.getFreshAddressEntry().getAddress(); Coin reservedFundsForOffer = getSecurityDeposit(); if (!isBuyOffer()) diff --git a/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferDataModel.java b/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferDataModel.java index 7260ce86502..15b93bb79b2 100644 --- a/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferDataModel.java +++ b/src/main/java/bisq/desktop/main/offer/takeoffer/TakeOfferDataModel.java @@ -327,13 +327,13 @@ void onTakeOffer(TradeResultHandler tradeResultHandler) { // and if funds get higher (if tx get larger) the user would get confused (adding small inputs would increase total required funds). // So that would require more thoughts how to deal with all those cases. public void estimateTxSize() { - Address fundingAddress = btcWalletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); + Address fundingAddress = btcWalletService.getFreshAddressEntry().getAddress(); int txSize = 0; if (btcWalletService.getBalance(Wallet.BalanceType.AVAILABLE).isPositive()) { txFeeFromFeeService = getTxFeeBySize(feeTxSize); Address reservedForTradeAddress = btcWalletService.getOrCreateAddressEntry(offer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); - Address changeAddress = btcWalletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); + Address changeAddress = btcWalletService.getFreshAddressEntry().getAddress(); Coin reservedFundsForOffer = getSecurityDeposit().add(txFeeFromFeeService).add(txFeeFromFeeService); if (isBuyOffer()) diff --git a/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java b/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java index a2b39b30371..1073c85c302 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/DisputeSummaryWindow.java @@ -516,8 +516,8 @@ private void addButtons(Contract contract) { closeTicketButton.setOnAction(e -> { if (dispute.getDepositTxSerialized() != null) { try { - AddressEntry arbitratorAddressEntry = walletService.getOrCreateAddressEntry(AddressEntry.Context.ARBITRATOR); - disputeResult.setArbitratorPubKey(walletService.getOrCreateAddressEntry(AddressEntry.Context.ARBITRATOR).getPubKey()); + AddressEntry arbitratorAddressEntry = walletService.getArbitratorAddressEntry(); + disputeResult.setArbitratorPubKey(walletService.getArbitratorAddressEntry().getPubKey()); /* byte[] depositTxSerialized, Coin buyerPayoutAmount, diff --git a/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/BisqInstaller.java b/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/BisqInstaller.java index 412d96cbbac..62d03e7f9bc 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/BisqInstaller.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/BisqInstaller.java @@ -71,14 +71,20 @@ public Optional download(String version) { // Get installer filename on all platforms FileDescriptor installerFileDescriptor = getInstallerDescriptor(version, partialUrl); + // tells us which key was used for signing FileDescriptor signingKeyDescriptor = getSigningKeyDescriptor(partialUrl); + + // Hash of jar file inside of the binary + FileDescriptor jarHashDescriptor = getJarHashDescriptor(version, partialUrl); + List keyFileDescriptors = getKeyFileDescriptors(); List sigFileDescriptors = getSigFileDescriptors(installerFileDescriptor, keyFileDescriptors); List allFiles = Lists.newArrayList(); - allFiles.addAll(Lists.newArrayList(installerFileDescriptor)); - allFiles.addAll(Lists.newArrayList(signingKeyDescriptor)); + allFiles.add(installerFileDescriptor); + allFiles.add(signingKeyDescriptor); + allFiles.add(jarHashDescriptor); allFiles.addAll(keyFileDescriptors); allFiles.addAll(sigFileDescriptors); @@ -229,6 +235,16 @@ private FileDescriptor getSigningKeyDescriptor(String url) { .build(); } + @NotNull + private FileDescriptor getJarHashDescriptor(String version, String partialUrl) { + String fileName = "Bisq-" + version + ".jar.txt"; + return FileDescriptor.builder() + .type(DownloadType.JAR_HASH) + .fileName(fileName) + .id(fileName) + .loadUrl(partialUrl.concat(fileName)) + .build(); + } /** * The files containing the gpg keys of the bisq signers. @@ -330,7 +346,8 @@ public enum DownloadType { KEY, SIG, SIGNING_KEY, - MISC + MISC, + JAR_HASH } } diff --git a/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/DisplayUpdateDownloadWindow.java b/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/DisplayUpdateDownloadWindow.java index 3e2c9c8f86e..c0e8cfca1bc 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/DisplayUpdateDownloadWindow.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/DisplayUpdateDownloadWindow.java @@ -24,6 +24,7 @@ import bisq.desktop.main.overlays.popups.Popup; import bisq.core.alert.Alert; +import bisq.core.app.BisqEnvironment; import bisq.core.locale.Res; import bisq.common.util.Utilities; @@ -46,12 +47,18 @@ import javafx.beans.value.ChangeListener; +import java.nio.file.Path; +import java.nio.file.Paths; + import java.io.File; +import java.io.FileReader; import java.io.IOException; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Scanner; import lombok.extern.slf4j.Slf4j; @@ -73,8 +80,9 @@ public class DisplayUpdateDownloadWindow extends Overlay downloadResults = downloadTask.getValue(); Optional downloadFailed = downloadResults.stream() - .filter(fileDescriptor -> !BisqInstaller.DownloadStatusEnum.OK.equals(fileDescriptor.getDownloadStatus())).findFirst(); + .filter(fileDescriptor -> !BisqInstaller.DownloadStatusEnum.OK.equals(fileDescriptor.getDownloadStatus())) + .findFirst(); downloadedFilesLabel.getStyleClass().removeAll("error-text", "success-text"); if (downloadResults == null || downloadResults.isEmpty() || downloadFailed.isPresent()) { showErrorMessage(downloadButton, statusLabel, downloadFailedString); @@ -222,6 +231,11 @@ private void addContent() { log.debug("Download completed successfully."); downloadedFilesLabel.getStyleClass().add("success-text"); + downloadTask.getFileDescriptors().stream() + .filter(fileDescriptor -> fileDescriptor.getType() == BisqInstaller.DownloadType.JAR_HASH) + .findFirst() + .ifPresent(this::copyJarHashToDataDir); + verifyTask = installer.verify(downloadResults); verifiedSigLabel.setOpacity(1); @@ -271,6 +285,32 @@ private void addContent() { }); } + private void copyJarHashToDataDir(BisqInstaller.FileDescriptor fileDescriptor) { + StringBuilder sb = new StringBuilder(); + final File sourceFile = fileDescriptor.getSaveFile(); + try (Scanner scanner = new Scanner(new FileReader(sourceFile))) { + while (scanner.hasNext()) { + sb.append(scanner.next()); + } + scanner.close(); + final String hashOfJar = sb.toString(); + + Path path = Paths.get(BisqEnvironment.getStaticAppDataDir(), fileDescriptor.getFileName()); + final String target = path.toString(); + try (PrintWriter writer = new PrintWriter(target, "UTF-8")) { + writer.println(hashOfJar); + writer.close(); + log.info("Copied hash of jar from {} to {}", sourceFile.getAbsolutePath(), target); + } catch (Exception e) { + log.error(e.toString()); + e.printStackTrace(); + } + } catch (Exception e) { + log.error(e.toString()); + e.printStackTrace(); + } + } + @Override protected void addCloseButton() { closeButton = new AutoTooltipButton(Res.get("displayUpdateDownloadWindow.button.ignoreDownload")); diff --git a/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/VerifyTask.java b/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/VerifyTask.java index 5aca15fee2a..5499ebd04f7 100644 --- a/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/VerifyTask.java +++ b/src/main/java/bisq/desktop/main/overlays/windows/downloadupdate/VerifyTask.java @@ -61,7 +61,7 @@ public VerifyTask(final List fileDescriptors) { * @throws IOException Forwarded exceotions from HttpURLConnection and file handling methods */ @Override - protected List call() throws IOException { + protected List call() { log.debug("VerifyTask started..."); Optional installer = fileDescriptors.stream() .filter(fileDescriptor -> BisqInstaller.DownloadType.INSTALLER.equals(fileDescriptor.getType()))