Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Merks2022-02-12 16:00:13 +0000
committerEd Merks2022-02-13 05:41:41 +0000
commitf149fd1be884ae15e951f9e447f0ce5b89315c20 (patch)
tree590fcf672c6acdc9794df34e050bcb2150d82eb4
parentebb22636c086e0cc23c1263303840ac5fc17a54b (diff)
downloadrt.equinox.p2-f149fd1be884ae15e951f9e447f0ce5b89315c20.tar.gz
rt.equinox.p2-f149fd1be884ae15e951f9e447f0ce5b89315c20.tar.xz
rt.equinox.p2-f149fd1be884ae15e951f9e447f0ce5b89315c20.zip
Bug 578166 - Signing information apparent in the Plug-ins tab of the
About dialog Introduce org.eclipse.equinox.internal.p2.ui.KeySigningInfoFactory to provide the adapter for the AboutBundleData.ExtendedSigningInfo interface. The signature and key information is gathered from the artifact metadata of the bundle pool repository of the installation. Change-Id: I578b62cb0a20d4141d38c2b587e39ae8bc0dfd4d Signed-off-by: Ed Merks <ed.merks@gmail.com> Reviewed-on: https://git.eclipse.org/r/c/equinox/rt.equinox.p2/+/190744
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java7
-rw-r--r--bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF4
-rw-r--r--bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF1
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/plugin.xml7
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/KeySigningInfoFactory.java184
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java4
-rw-r--r--bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties4
9 files changed, 211 insertions, 4 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java
index c5f9d0196..383fd74b8 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPPublicKeyStore.java
@@ -25,7 +25,7 @@ import org.eclipse.equinox.internal.p2.core.helpers.LogHelper;
import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
public class PGPPublicKeyStore {
- private Map<String, PGPPublicKey> keys = new HashMap<>();
+ private Map<String, PGPPublicKey> keys = new LinkedHashMap<>();
public PGPPublicKey addKey(PGPPublicKey key) {
if (key == null) {
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java
index 6fc1dc597..740e06c2b 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/processors/pgp/PGPSignatureVerifier.java
@@ -88,6 +88,13 @@ public final class PGPSignatureVerifier extends ProcessingStep {
return res;
}
+ public static PGPPublicKeyStore getKeys(IArtifactDescriptor artifact) {
+ PGPPublicKeyStore keyStore = new PGPPublicKeyStore();
+ String keyText = artifact.getProperty(PGPSignatureVerifier.PGP_SIGNER_KEYS_PROPERTY_NAME);
+ PGPPublicKeyStore.readPublicKeys(keyText).stream().forEach(keyStore::addKey);
+ return keyStore;
+ }
+
@Override
public void initialize(IProvisioningAgent agent, IProcessingStepDescriptor descriptor,
IArtifactDescriptor context) {
diff --git a/bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF
index 76a2520ae..290732d27 100644
--- a/bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.extensionlocation/META-INF/MANIFEST.MF
@@ -2,11 +2,11 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.extensionlocation;singleton:=true
-Bundle-Version: 1.4.0.qualifier
+Bundle-Version: 1.4.100.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.extensionlocation.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
-Export-Package: org.eclipse.equinox.internal.p2.extensionlocation;x-friends:="org.eclipse.equinox.p2.reconciler.dropins,org.eclipse.equinox.p2.ui.importexport"
+Export-Package: org.eclipse.equinox.internal.p2.extensionlocation;x-friends:="org.eclipse.equinox.p2.reconciler.dropins,org.eclipse.equinox.p2.ui,org.eclipse.equinox.p2.ui.importexport"
Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.5.0,4.0.0)",
org.eclipse.equinox.p2.metadata
Bundle-RequiredExecutionEnvironment: JavaSE-11
diff --git a/bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml b/bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml
index 474ce108b..d6352193a 100644
--- a/bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.extensionlocation/pom.xml
@@ -9,6 +9,6 @@
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.extensionlocation</artifactId>
- <version>1.4.0-SNAPSHOT</version>
+ <version>1.4.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF
index f4c597204..b66eb2ce6 100644
--- a/bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ui/META-INF/MANIFEST.MF
@@ -43,6 +43,7 @@ Import-Package: javax.xml.parsers,
org.eclipse.equinox.internal.p2.artifact.repository,
org.eclipse.equinox.internal.p2.core.helpers,
org.eclipse.equinox.internal.p2.director,
+ org.eclipse.equinox.internal.p2.extensionlocation,
org.eclipse.equinox.internal.p2.metadata,
org.eclipse.equinox.internal.p2.metadata.repository,
org.eclipse.equinox.internal.p2.operations,
diff --git a/bundles/org.eclipse.equinox.p2.ui/plugin.xml b/bundles/org.eclipse.equinox.p2.ui/plugin.xml
index 6f6031e2e..87e8645fd 100644
--- a/bundles/org.eclipse.equinox.p2.ui/plugin.xml
+++ b/bundles/org.eclipse.equinox.p2.ui/plugin.xml
@@ -12,6 +12,13 @@
<adapter type="org.eclipse.equinox.p2.repository.metadata.IMetadataRepository"/>
<adapter type="org.eclipse.equinox.p2.repository.artifact.IArtifactRepository"/>
</factory>
+ <factory
+ adaptableType="org.eclipse.ui.internal.about.AboutPluginsPage"
+ class="org.eclipse.equinox.internal.p2.ui.KeySigningInfoFactory">
+ <adapter
+ type="org.eclipse.ui.internal.about.AboutBundleData$ExtendedSigningInfo">
+ </adapter>
+ </factory>
</extension>
<extension
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/KeySigningInfoFactory.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/KeySigningInfoFactory.java
new file mode 100644
index 000000000..782dff926
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/KeySigningInfoFactory.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Eclipse contributors and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.ui;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import org.bouncycastle.openpgp.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPPublicKeyStore;
+import org.eclipse.equinox.internal.p2.artifact.processors.pgp.PGPSignatureVerifier;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.p2.query.IQueryResult;
+import org.eclipse.equinox.p2.repository.artifact.*;
+import org.eclipse.equinox.p2.repository.spi.PGPPublicKeyService;
+import org.eclipse.ui.internal.about.AboutBundleData;
+import org.eclipse.ui.internal.about.AboutPluginsPage;
+import org.osgi.framework.Bundle;
+
+/**
+ * A factory used by the {@link AboutPluginsPage} to provide extended signing
+ * information, in particular information about PGP signing.
+ *
+ * @since 2.7.400
+ */
+public class KeySigningInfoFactory implements IAdapterFactory {
+
+ private static final Class<?>[] CLASSES = new Class[] { AboutBundleData.ExtendedSigningInfo.class };
+
+ @Override
+ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
+ if (adapterType == AboutBundleData.ExtendedSigningInfo.class) {
+ return adapterType.cast(new AboutBundleData.ExtendedSigningInfo() {
+ private final Map<File, Map<PGPSignature, PGPPublicKey>> bundlePoolArtficactSigningDetails = getBundlePoolArtficactPGPSigningDetails();
+
+ @Override
+ public boolean isSigned(Bundle bundle) {
+ return getDetails(bundle) != null;
+ }
+
+ @Override
+ public String getSigningType(Bundle bundle) {
+ return ProvUIMessages.KeySigningInfoFactory_PGPSigningType;
+ }
+
+ @Override
+ public String getSigningDetails(Bundle bundle) {
+ Map<PGPSignature, PGPPublicKey> details = getDetails(bundle);
+ if (details != null) {
+ PGPPublicKeyService keyService = getKeyService();
+ List<String> lines = new ArrayList<>();
+ for (PGPPublicKey key : details.values()) {
+ if (keyService != null) {
+ // Be sure to normalize/enhance the key so we properly don't show
+ // self-signatures.
+ key = keyService.addKey(key);
+ }
+ if (!lines.isEmpty()) {
+ lines.add(""); //$NON-NLS-1$
+ }
+ addDetails(key, lines, ""); //$NON-NLS-1$
+ if (keyService != null) {
+ Set<PGPPublicKey> verifiedCertifications = keyService.getVerifiedCertifications(key);
+ boolean first = true;
+ for (PGPPublicKey verifyingKey : verifiedCertifications) {
+ /// Don't show self-signatures.
+ if (!verifyingKey.equals(key)) {
+ if (first) {
+ lines.add(" " + ProvUIMessages.KeySigningInfoFactory_KeySignersSection); //$NON-NLS-1$
+ first = false;
+ }
+ addDetails(verifyingKey, lines, " "); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ return String.join("\n", lines); //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ @Override
+ public Date getSigningTime(Bundle bundle) {
+ Map<PGPSignature, PGPPublicKey> details = getDetails(bundle);
+ return details == null ? null : details.keySet().iterator().next().getCreationTime();
+ }
+
+ private void addDetails(PGPPublicKey key, List<String> lines, String indentation) {
+ lines.add(indentation + ProvUIMessages.KeySigningInfoFactory_FingerprintItem
+ + PGPPublicKeyService.toHex(key.getFingerprint()).toUpperCase(Locale.ROOT));
+ for (Iterator<String> userIDs = key.getUserIDs(); userIDs.hasNext();) {
+ lines.add(indentation + ProvUIMessages.KeySigningInfoFactory_UserIDItem + userIDs.next());
+ }
+ }
+
+ private PGPPublicKeyService getKeyService() {
+ IProvisioningAgent agent = org.eclipse.equinox.internal.p2.extensionlocation.Activator
+ .getCurrentAgent();
+ return agent == null ? null : agent.getService(PGPPublicKeyService.class);
+ }
+
+ private Map<PGPSignature, PGPPublicKey> getDetails(Bundle bundle) {
+ try {
+ File bundleFile = FileLocator.getBundleFile(bundle);
+ Map<PGPSignature, PGPPublicKey> details = bundlePoolArtficactSigningDetails.get(bundleFile);
+ return details;
+ } catch (IOException e) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, e.getMessage(), e));
+ return null;
+ }
+ }
+ });
+ }
+
+ return null;
+ }
+
+ @Override
+ public Class<?>[] getAdapterList() {
+ return CLASSES;
+ }
+
+ /**
+ * Returns a map from artifact files to the PGP signature/key pairs that were
+ * used to {@link PGPSignatureVerifier#close() verify} the artifact while it was
+ * being downloaded.
+ *
+ * @return a map of all the PGP signed artifact files to their signature/key
+ * pairs.
+ */
+ private static Map<File, Map<PGPSignature, PGPPublicKey>> getBundlePoolArtficactPGPSigningDetails() {
+ Map<File, Map<PGPSignature, PGPPublicKey>> result = new LinkedHashMap<>();
+ try {
+ // Look up artifact metadata for all the bundle pool repository of the
+ // installation.
+ IFileArtifactRepository bundlePoolRepository = org.eclipse.equinox.internal.p2.extensionlocation.Activator
+ .getBundlePoolRepository();
+ IQueryResult<IArtifactKey> allArtifactKeys = bundlePoolRepository.query(ArtifactKeyQuery.ALL_KEYS,
+ new NullProgressMonitor());
+ for (IArtifactKey key : allArtifactKeys) {
+ for (IArtifactDescriptor descriptor : bundlePoolRepository.getArtifactDescriptors(key)) {
+ File file = bundlePoolRepository.getArtifactFile(descriptor);
+ if (file != null) {
+ try {
+ Collection<PGPSignature> signatures = PGPSignatureVerifier.getSignatures(descriptor);
+ if (!signatures.isEmpty()) {
+ Map<PGPSignature, PGPPublicKey> details = new LinkedHashMap<>();
+ PGPPublicKeyStore keys = PGPSignatureVerifier.getKeys(descriptor);
+ for (PGPSignature signature : signatures) {
+ Collection<PGPPublicKey> signingKeys = keys.getKeys(signature.getKeyID());
+ if (!signingKeys.isEmpty()) {
+ // There is vanishingly small chance that two keys with colliding key IDs were
+ // used on two different signatures on the same artifact.
+ details.put(signature, signingKeys.iterator().next());
+ }
+ }
+ if (!details.isEmpty()) {
+ result.put(file, details);
+ }
+ }
+ } catch (IOException | PGPException | RuntimeException e) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, e.getMessage(), e));
+ }
+ }
+ }
+ }
+ } catch (RuntimeException e) {
+ ProvUIActivator.getDefault().getLog()
+ .log(new Status(IStatus.ERROR, ProvUIActivator.PLUGIN_ID, e.getMessage(), e));
+ }
+ return result;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java
index af37549e2..e3804b987 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/ProvUIMessages.java
@@ -247,6 +247,10 @@ public class ProvUIMessages extends NLS {
public static String SelectableIUsPage_Deselect_All;
public static String InstallRemediationPage_Title;
public static String InstallRemediationPage_Description;
+ public static String KeySigningInfoFactory_FingerprintItem;
+ public static String KeySigningInfoFactory_KeySignersSection;
+ public static String KeySigningInfoFactory_PGPSigningType;
+ public static String KeySigningInfoFactory_UserIDItem;
public static String UpdateRemediationPage_Title;
public static String UpdateRemediationPage_Description;
public static String RemediationPage_SubDescription;
diff --git a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties
index c9fdafb75..26fc36307 100644
--- a/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.ui/src/org/eclipse/equinox/internal/p2/ui/messages.properties
@@ -257,6 +257,10 @@ RepositoryElement_NotFound=This repository is currently not available.
RepositoryTracker_DuplicateLocation=Duplicate location
MetadataRepositoryElement_RepositoryLoadError=Error loading repository {0}
IUViewQueryContext_NoCategorizedItemsDescription=You can uncheck the 'Group items by category' check box to see items without categories.
+KeySigningInfoFactory_FingerprintItem=Fingerprint=
+KeySigningInfoFactory_KeySignersSection=Key Signers:
+KeySigningInfoFactory_PGPSigningType=PGP Public Key
+KeySigningInfoFactory_UserIDItem=UserID=
QueriedElementWrapper_NoCategorizedItemsExplanation=There are no categorized items
QueriedElementWrapper_NoItemsExplanation=There are no items available
QueriedElementWrapper_SiteNotFound=Could not find {0}

Back to the top