Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2012-07-31 20:58:23 +0000
committerThomas Watson2012-08-01 20:56:57 +0000
commit66c6af17ae5302064ecd7489eaf29fa1532fab90 (patch)
tree9e17c46ae9185029927684855d966ee901798ea0
parent6a3e9c363c1b9c9a3623207fabb0fff01d042881 (diff)
downloadrt.equinox.framework-66c6af17ae5302064ecd7489eaf29fa1532fab90.tar.gz
rt.equinox.framework-66c6af17ae5302064ecd7489eaf29fa1532fab90.tar.xz
rt.equinox.framework-66c6af17ae5302064ecd7489eaf29fa1532fab90.zip
update signed content impl for new container
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BundleInstallListener.java40
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/DigestedInputStream.java11
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/PKCS7Processor.java4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java15
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java57
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java297
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentConstants.java4
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java12
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedStorageHook.java338
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/TrustEngineListener.java115
10 files changed, 345 insertions, 548 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BundleInstallListener.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BundleInstallListener.java
deleted file mode 100644
index 47c8066fe..000000000
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/BundleInstallListener.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007, 2008 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.osgi.internal.signedcontent;
-
-import org.eclipse.osgi.baseadaptor.BaseData;
-import org.eclipse.osgi.framework.internal.core.AbstractBundle;
-import org.eclipse.osgi.internal.provisional.service.security.AuthorizationEngine;
-import org.eclipse.osgi.signedcontent.SignedContent;
-import org.osgi.framework.*;
-
-public class BundleInstallListener implements SynchronousBundleListener {
-
- public void bundleChanged(BundleEvent event) {
- Bundle bundle = event.getBundle();
- switch (event.getType()) {
- case BundleEvent.UPDATED :
- // fall through to INSTALLED
- case BundleEvent.INSTALLED :
- TrustEngineListener listener = TrustEngineListener.getInstance();
- AuthorizationEngine authEngine = listener == null ? null : listener.getAuthorizationEngine();
- if (authEngine != null) {
- BaseData baseData = (BaseData) ((AbstractBundle) bundle).getBundleData();
- SignedStorageHook hook = (SignedStorageHook) baseData.getStorageHook(SignedStorageHook.KEY);
- SignedContent signedContent = hook != null ? hook.signedContent : null;
- authEngine.authorize(signedContent, bundle);
- }
- break;
- default :
- break;
- }
- }
-}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/DigestedInputStream.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/DigestedInputStream.java
index 7eac65521..fe68bd3d9 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/DigestedInputStream.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/DigestedInputStream.java
@@ -11,14 +11,14 @@
package org.eclipse.osgi.internal.signedcontent;
-import org.eclipse.osgi.storage.bundlefile.BundleEntry;
-import org.eclipse.osgi.storage.bundlefile.BundleFile;
-
import java.io.FilterInputStream;
import java.io.IOException;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
import org.eclipse.osgi.signedcontent.InvalidContentException;
import org.eclipse.osgi.signedcontent.SignerInfo;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.util.NLS;
/**
@@ -42,15 +42,16 @@ class DigestedInputStream extends FilterInputStream {
* @param signerInfos the signers.
* @param results the expected digest.
* @throws IOException
+ * @throws NoSuchAlgorithmException
*/
- DigestedInputStream(BundleEntry entry, BundleFile bundleFile, SignerInfo[] signerInfos, byte results[][], long size) throws IOException {
+ DigestedInputStream(BundleEntry entry, BundleFile bundleFile, SignerInfo[] signerInfos, byte results[][], long size) throws IOException, NoSuchAlgorithmException {
super(entry.getInputStream());
this.entry = entry;
this.bundleFile = bundleFile;
this.remaining = size;
this.digests = new MessageDigest[signerInfos.length];
for (int i = 0; i < signerInfos.length; i++)
- this.digests[i] = SignatureBlockProcessor.getMessageDigest(signerInfos[i].getMessageDigestAlgorithm());
+ this.digests[i] = MessageDigest.getInstance(signerInfos[i].getMessageDigestAlgorithm());
this.result = results;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/PKCS7Processor.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/PKCS7Processor.java
index a1267a8e1..7650083bd 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/PKCS7Processor.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/PKCS7Processor.java
@@ -16,7 +16,6 @@ import java.security.cert.Certificate;
import java.text.*;
import java.util.*;
import javax.security.auth.x500.X500Principal;
-import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.util.NLS;
/**
@@ -30,7 +29,8 @@ public class PKCS7Processor implements SignedContentConstants {
try {
certFact = CertificateFactory.getInstance("X.509"); //$NON-NLS-1$
} catch (CertificateException e) {
- SignedBundleHook.log(e.getMessage(), FrameworkLogEntry.ERROR, e);
+ // TODO this is bad and will lead to NPEs
+ // Should we just throw a runtime exception to fail <clinit>?
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
index 1b3e0b5c4..dc20915ba 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignatureBlockProcessor.java
@@ -8,9 +8,6 @@
******************************************************************************/
package org.eclipse.osgi.internal.signedcontent;
-import org.eclipse.osgi.storage.bundlefile.BundleEntry;
-import org.eclipse.osgi.storage.bundlefile.BundleFile;
-
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
@@ -19,6 +16,8 @@ import java.security.cert.CertificateException;
import java.util.*;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.signedcontent.SignerInfo;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.util.NLS;
public class SignatureBlockProcessor implements SignedContentConstants {
@@ -28,10 +27,12 @@ public class SignatureBlockProcessor implements SignedContentConstants {
// map of tsa singers keyed by SignerInfo -> {tsa_SignerInfo, signingTime}
private Map<SignerInfo, Object[]> tsaSignerInfos;
private final int supportFlags;
+ private final SignedBundleHook signedBundleHook;
- public SignatureBlockProcessor(SignedBundleFile signedContent, int supportFlags) {
+ public SignatureBlockProcessor(SignedBundleFile signedContent, int supportFlags, SignedBundleHook signedBundleHook) {
this.signedBundle = signedContent;
this.supportFlags = supportFlags;
+ this.signedBundleHook = signedBundleHook;
}
public SignedContentImpl process() throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException {
@@ -155,7 +156,7 @@ public class SignatureBlockProcessor implements SignedContentConstants {
// check if the the computed digest value of manifest file equals to the digest value in the .sf file
if (!digestValue.equals(manifestDigest)) {
SignatureException se = new SignatureException(NLS.bind(SignedContentMessages.Security_File_Is_Tampered, new String[] {signedBundle.getBaseFile().toString()}));
- SignedBundleHook.log(se.getMessage(), FrameworkLogEntry.ERROR, se);
+ signedBundleHook.log(se.getMessage(), FrameworkLogEntry.ERROR, se);
throw se;
}
}
@@ -309,11 +310,11 @@ public class SignatureBlockProcessor implements SignedContentConstants {
return new String(Base64.encode(digest.digest(bytes)));
}
- static synchronized MessageDigest getMessageDigest(String algorithm) {
+ synchronized MessageDigest getMessageDigest(String algorithm) {
try {
return MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
- SignedBundleHook.log(e.getMessage(), FrameworkLogEntry.ERROR, e);
+ signedBundleHook.log(e.getMessage(), FrameworkLogEntry.ERROR, e);
}
return null;
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
index a6ead3f06..010ce5b3c 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleFile.java
@@ -11,19 +11,15 @@
package org.eclipse.osgi.internal.signedcontent;
-import org.eclipse.osgi.storage.bundlefile.BundleEntry;
-import org.eclipse.osgi.storage.bundlefile.BundleFile;
-
import java.io.*;
import java.net.URL;
import java.security.*;
import java.security.cert.*;
-import java.security.cert.Certificate;
import java.util.Date;
import java.util.Enumeration;
-import org.eclipse.osgi.framework.log.FrameworkLogEntry;
-import org.eclipse.osgi.service.security.TrustEngine;
import org.eclipse.osgi.signedcontent.*;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.util.NLS;
/**
@@ -35,60 +31,23 @@ public class SignedBundleFile extends BundleFile implements SignedContentConstan
private BundleFile wrappedBundleFile;
SignedContentImpl signedContent;
private final int supportFlags;
+ private final SignedBundleHook signedBundleHook;
- SignedBundleFile(SignedContentImpl signedContent, int supportFlags) {
+ SignedBundleFile(SignedContentImpl signedContent, int supportFlags, SignedBundleHook signedBundleHook) {
+ super(null);
this.signedContent = signedContent;
this.supportFlags = supportFlags;
+ this.signedBundleHook = signedBundleHook;
}
void setBundleFile(BundleFile bundleFile) throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException {
wrappedBundleFile = bundleFile;
if (signedContent == null) {
- SignatureBlockProcessor signatureProcessor = new SignatureBlockProcessor(this, supportFlags);
+ SignatureBlockProcessor signatureProcessor = new SignatureBlockProcessor(this, supportFlags, signedBundleHook);
signedContent = signatureProcessor.process();
if (signedContent != null)
- determineTrust(signedContent, supportFlags);
- }
- }
-
- static void determineTrust(SignedContentImpl trustedContent, int supportFlags) {
- TrustEngine[] engines = null;
- SignerInfo[] signers = trustedContent.getSignerInfos();
- for (int i = 0; i < signers.length; i++) {
- // first check if we need to find an anchor
- if (signers[i].getTrustAnchor() == null) {
- // no anchor set ask the trust engines
- if (engines == null)
- engines = SignedBundleHook.getTrustEngines();
- // check trust of singer certs
- Certificate[] signerCerts = signers[i].getCertificateChain();
- ((SignerInfoImpl) signers[i]).setTrustAnchor(findTrustAnchor(signerCerts, engines, supportFlags));
- // if signer has a tsa check trust of tsa certs
- SignerInfo tsaSignerInfo = trustedContent.getTSASignerInfo(signers[i]);
- if (tsaSignerInfo != null) {
- Certificate[] tsaCerts = tsaSignerInfo.getCertificateChain();
- ((SignerInfoImpl) tsaSignerInfo).setTrustAnchor(findTrustAnchor(tsaCerts, engines, supportFlags));
- }
- }
- }
- }
-
- private static Certificate findTrustAnchor(Certificate[] certs, TrustEngine[] engines, int supportFlags) {
- if ((supportFlags & SignedBundleHook.VERIFY_TRUST) == 0)
- // we are not searching the engines; in this case we just assume the root cert is trusted
- return certs != null && certs.length > 0 ? certs[certs.length - 1] : null;
- for (int i = 0; i < engines.length; i++) {
- try {
- Certificate anchor = engines[i].findTrustAnchor(certs);
- if (anchor != null)
- // found an anchor
- return anchor;
- } catch (IOException e) {
- // log the exception and continue
- SignedBundleHook.log("TrustEngine failure: " + engines[i].getName(), FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
- }
+ signedBundleHook.determineTrust(signedContent, supportFlags);
}
- return null;
}
public File getFile(String path, boolean nativeCode) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java
index c823a609c..66ade8aab 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedBundleHook.java
@@ -10,94 +10,90 @@
*******************************************************************************/
package org.eclipse.osgi.internal.signedcontent;
-import org.eclipse.osgi.internal.framework.FilterImpl;
-
import java.io.File;
import java.io.IOException;
-import java.net.*;
+import java.lang.reflect.Field;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.security.*;
+import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.util.*;
-import org.eclipse.osgi.baseadaptor.*;
-import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
-import org.eclipse.osgi.baseadaptor.hooks.BundleFileWrapperFactoryHook;
-import org.eclipse.osgi.framework.adaptor.BundleData;
-import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor;
-import org.eclipse.osgi.framework.internal.core.*;
-import org.eclipse.osgi.framework.log.FrameworkLog;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
-import org.eclipse.osgi.internal.provisional.service.security.AuthorizationEngine;
-import org.eclipse.osgi.internal.provisional.verifier.CertificateVerifierFactory;
-import org.eclipse.osgi.internal.service.security.DefaultAuthorizationEngine;
+import org.eclipse.osgi.internal.framework.*;
+import org.eclipse.osgi.internal.hookregistry.*;
import org.eclipse.osgi.internal.service.security.KeyStoreTrustEngine;
+import org.eclipse.osgi.internal.signedcontent.SignedStorageHook.StorageHookImpl;
import org.eclipse.osgi.service.security.TrustEngine;
-import org.eclipse.osgi.signedcontent.SignedContent;
-import org.eclipse.osgi.signedcontent.SignedContentFactory;
+import org.eclipse.osgi.signedcontent.*;
+import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.bundlefile.*;
import org.eclipse.osgi.util.ManifestElement;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.*;
-import org.osgi.framework.Constants;
import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* Implements signed bundle hook support for the framework
*/
-public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHook, HookConfigurator, SignedContentFactory {
+public class SignedBundleHook implements ActivatorHookFactory, BundleFileWrapperFactoryHook, HookConfigurator, SignedContentFactory {
static final int VERIFY_CERTIFICATE = 0x01;
static final int VERIFY_TRUST = 0x02;
static final int VERIFY_RUNTIME = 0x04;
- static final int VERIFY_AUTHORITY = 0x08;
- static final int VERIFY_ALL = VERIFY_CERTIFICATE | VERIFY_TRUST | VERIFY_RUNTIME | VERIFY_AUTHORITY;
- private static String SUPPORT_CERTIFICATE = "certificate"; //$NON-NLS-1$
- private static String SUPPORT_TRUST = "trust"; //$NON-NLS-1$
- private static String SUPPORT_RUNTIME = "runtime"; //$NON-NLS-1$
- private static String SUPPORT_AUTHORITY = "authority"; //$NON-NLS-1$
- private static String SUPPORT_ALL = "all"; //$NON-NLS-1$
- private static String SUPPORT_TRUE = "true"; //$NON-NLS-1$
+ static final int VERIFY_ALL = VERIFY_CERTIFICATE | VERIFY_TRUST | VERIFY_RUNTIME;
+ private final static String SUPPORT_CERTIFICATE = "certificate"; //$NON-NLS-1$
+ private final static String SUPPORT_TRUST = "trust"; //$NON-NLS-1$
+ private final static String SUPPORT_RUNTIME = "runtime"; //$NON-NLS-1$
+ private final static String SUPPORT_ALL = "all"; //$NON-NLS-1$
+ private final static String SUPPORT_TRUE = "true"; //$NON-NLS-1$
//TODO: comes from configuration!;
- private static String CACERTS_PATH = System.getProperty("java.home") + File.separatorChar + "lib" + File.separatorChar + "security" + File.separatorChar + "cacerts"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
- private static String CACERTS_TYPE = "JKS"; //$NON-NLS-1$
- private static ServiceTracker<TrustEngine, TrustEngine> trustEngineTracker;
- private static BaseAdaptor ADAPTOR;
- private static String SIGNED_BUNDLE_SUPPORT = "osgi.support.signature.verify"; //$NON-NLS-1$
- private static String SIGNED_CONTENT_SUPPORT = "osgi.signedcontent.support"; //$NON-NLS-1$
- private static String OSGI_KEYSTORE = "osgi.framework.keystore"; //$NON-NLS-1$
- private static int supportSignedBundles;
- private TrustEngineListener trustEngineListener;
- private BundleInstallListener installListener;
+ private final static String CACERTS_PATH = System.getProperty("java.home") + File.separatorChar + "lib" + File.separatorChar + "security" + File.separatorChar + "cacerts"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
+ private final static String CACERTS_TYPE = "JKS"; //$NON-NLS-1$
+ private final static String SIGNED_BUNDLE_SUPPORT = "osgi.support.signature.verify"; //$NON-NLS-1$
+ private final static String SIGNED_CONTENT_SUPPORT = "osgi.signedcontent.support"; //$NON-NLS-1$
+ private final static String OSGI_KEYSTORE = "osgi.framework.keystore"; //$NON-NLS-1$
+ private int supportSignedBundles;
+ TrustEngineListener trustEngineListener;
+ private String trustEngineNameProp;
private ServiceRegistration<?> signedContentFactoryReg;
private ServiceRegistration<?> systemTrustEngineReg;
- private ServiceRegistration<?> defaultAuthEngineReg;
private List<ServiceRegistration<?>> osgiTrustEngineReg;
- private ServiceRegistration<?> legacyFactoryReg;
+ private ServiceTracker<TrustEngine, TrustEngine> trustEngineTracker;
+ private BundleContext context;
+ private EquinoxContainer container;
+
+ @Override
+ public BundleActivator createActivator() {
+ return new BundleActivator() {
+
+ @Override
+ public void start(BundleContext bc) throws Exception {
+ frameworkStart(bc);
+ }
- public void initialize(BaseAdaptor adaptor) {
- SignedBundleHook.ADAPTOR = adaptor;
+ @Override
+ public void stop(BundleContext bc) throws Exception {
+ frameworkStop(bc);
+ }
+ };
}
- /**
- * @throws BundleException
- */
- public void frameworkStart(BundleContext context) throws BundleException {
- // check if load time authority is enabled
- if ((supportSignedBundles & VERIFY_AUTHORITY) != 0) {
- // install the default bundle install listener
- installListener = new BundleInstallListener();
- context.addBundleListener(installListener);
- // register the default authorization engine
- Dictionary<String, Object> properties = new Hashtable<String, Object>(7);
- properties.put(Constants.SERVICE_RANKING, new Integer(Integer.MIN_VALUE));
- properties.put(SignedContentConstants.AUTHORIZATION_ENGINE, SignedContentConstants.DEFAULT_AUTHORIZATION_ENGINE);
- defaultAuthEngineReg = context.registerService(AuthorizationEngine.class.getName(), new DefaultAuthorizationEngine(context, ADAPTOR.getState()), properties);
- }
+ BundleContext getContext() {
+ return context;
+ }
+ void frameworkStart(BundleContext bc) {
+ this.context = bc;
+ if ((supportSignedBundles & VERIFY_TRUST) != 0)
+ // initialize the trust engine listener only if trust is being established with a trust engine
+ trustEngineListener = new TrustEngineListener(context, this);
// always register the trust engine
Dictionary<String, Object> trustEngineProps = new Hashtable<String, Object>(7);
trustEngineProps.put(Constants.SERVICE_RANKING, new Integer(Integer.MIN_VALUE));
trustEngineProps.put(SignedContentConstants.TRUST_ENGINE, SignedContentConstants.DEFAULT_TRUST_ENGINE);
- KeyStoreTrustEngine systemTrustEngine = new KeyStoreTrustEngine(CACERTS_PATH, CACERTS_TYPE, null, "System"); //$NON-NLS-1$
+ KeyStoreTrustEngine systemTrustEngine = new KeyStoreTrustEngine(CACERTS_PATH, CACERTS_TYPE, null, "System", this); //$NON-NLS-1$
systemTrustEngineReg = context.registerService(TrustEngine.class.getName(), systemTrustEngine, trustEngineProps);
String osgiTrustPath = context.getProperty(OSGI_KEYSTORE);
if (osgiTrustPath != null) {
@@ -107,10 +103,10 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
trustEngineProps.put(SignedContentConstants.TRUST_ENGINE, OSGI_KEYSTORE);
String path = url.getPath();
osgiTrustEngineReg = new ArrayList<ServiceRegistration<?>>(1);
- osgiTrustEngineReg.add(context.registerService(TrustEngine.class.getName(), new KeyStoreTrustEngine(path, CACERTS_TYPE, null, OSGI_KEYSTORE), trustEngineProps));
+ osgiTrustEngineReg.add(context.registerService(TrustEngine.class.getName(), new KeyStoreTrustEngine(path, CACERTS_TYPE, null, OSGI_KEYSTORE, this), trustEngineProps));
}
} catch (MalformedURLException e) {
- SignedBundleHook.log("Invalid setting for " + OSGI_KEYSTORE, FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
+ log("Invalid setting for " + OSGI_KEYSTORE, FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
}
} else {
String osgiTrustRepoPaths = context.getProperty(Constants.FRAMEWORK_TRUST_REPOSITORIES);
@@ -120,26 +116,15 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
osgiTrustEngineReg = new ArrayList<ServiceRegistration<?>>(1);
while (st.hasMoreTokens()) {
String trustRepoPath = st.nextToken();
- osgiTrustEngineReg.add(context.registerService(TrustEngine.class.getName(), new KeyStoreTrustEngine(trustRepoPath, CACERTS_TYPE, null, OSGI_KEYSTORE), trustEngineProps));
+ osgiTrustEngineReg.add(context.registerService(TrustEngine.class.getName(), new KeyStoreTrustEngine(trustRepoPath, CACERTS_TYPE, null, OSGI_KEYSTORE, this), trustEngineProps));
}
}
}
- if ((supportSignedBundles & VERIFY_TRUST) != 0)
- // initialize the trust engine listener only if trust is being established with a trust engine
- trustEngineListener = new TrustEngineListener(context);
// always register the signed content factory
signedContentFactoryReg = context.registerService(SignedContentFactory.class.getName(), this, null);
- legacyFactoryReg = context.registerService(CertificateVerifierFactory.class.getName(), new LegacyVerifierFactory(this), null);
}
- /**
- * @throws BundleException
- */
- public void frameworkStop(BundleContext context) throws BundleException {
- if (legacyFactoryReg != null) {
- legacyFactoryReg.unregister();
- legacyFactoryReg = null;
- }
+ void frameworkStop(BundleContext bc) {
if (signedContentFactoryReg != null) {
signedContentFactoryReg.unregister();
signedContentFactoryReg = null;
@@ -153,61 +138,26 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
it.next().unregister();
osgiTrustEngineReg = null;
}
- if (defaultAuthEngineReg != null) {
- defaultAuthEngineReg.unregister();
- defaultAuthEngineReg = null;
- }
- if (trustEngineListener != null) {
- trustEngineListener.stopTrustEngineListener();
- trustEngineListener = null;
- }
- if (installListener != null) {
- context.removeBundleListener(installListener);
- installListener = null;
- }
if (trustEngineTracker != null) {
trustEngineTracker.close();
trustEngineTracker = null;
}
}
- public void frameworkStopping(BundleContext context) {
- // do nothing
- }
-
- public void addProperties(Properties properties) {
- // do nothing
- }
-
- /**
- * @throws IOException
- */
- public URLConnection mapLocationToURLConnection(String location) throws IOException {
- return null;
- }
-
- public void handleRuntimeError(Throwable error) {
- // do nothing
- }
-
- public FrameworkLog createFrameworkLog() {
- return null;
- }
-
- public BundleFile wrapBundleFile(BundleFile bundleFile, Object content, BaseData data, boolean base) {
+ public BundleFile wrapBundleFile(BundleFile bundleFile, Generation generation, boolean base) {
try {
if (bundleFile != null) {
- SignedStorageHook hook = (SignedStorageHook) data.getStorageHook(SignedStorageHook.KEY);
+ StorageHookImpl hook = generation.getStorageHook(SignedStorageHook.class);
SignedBundleFile signedBaseFile;
if (base && hook != null) {
- signedBaseFile = new SignedBundleFile(hook.signedContent, supportSignedBundles);
+ signedBaseFile = new SignedBundleFile(hook.signedContent, supportSignedBundles, this);
if (hook.signedContent == null) {
signedBaseFile.setBundleFile(bundleFile);
SignedContentImpl signedContent = signedBaseFile.getSignedContent();
hook.signedContent = signedContent != null && signedContent.isSigned() ? signedContent : null;
}
} else
- signedBaseFile = new SignedBundleFile(null, supportSignedBundles);
+ signedBaseFile = new SignedBundleFile(null, supportSignedBundles, this);
signedBaseFile.setBundleFile(bundleFile);
SignedContentImpl signedContent = signedBaseFile.getSignedContent();
if (signedContent != null && signedContent.isSigned()) {
@@ -217,16 +167,17 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
}
}
} catch (IOException e) {
- SignedBundleHook.log("Bad bundle file: " + bundleFile.getBaseFile(), FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
+ log("Bad bundle file: " + bundleFile.getBaseFile(), FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
} catch (GeneralSecurityException e) {
- SignedBundleHook.log("Bad bundle file: " + bundleFile.getBaseFile(), FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
+ log("Bad bundle file: " + bundleFile.getBaseFile(), FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
}
return bundleFile;
}
public void addHooks(HookRegistry hookRegistry) {
- hookRegistry.addAdaptorHook(this);
- String[] support = ManifestElement.getArrayFromList(FrameworkProperties.getProperty(SIGNED_CONTENT_SUPPORT, FrameworkProperties.getProperty(SIGNED_BUNDLE_SUPPORT)), ","); //$NON-NLS-1$
+ container = hookRegistry.getContainer();
+ hookRegistry.addActivatorHookFactory(this);
+ String[] support = ManifestElement.getArrayFromList(hookRegistry.getConfiguration().getConfiguration(SIGNED_CONTENT_SUPPORT, hookRegistry.getConfiguration().getConfiguration(SIGNED_BUNDLE_SUPPORT)), ","); //$NON-NLS-1$
for (int i = 0; i < support.length; i++) {
if (SUPPORT_CERTIFICATE.equals(support[i]))
supportSignedBundles |= VERIFY_CERTIFICATE;
@@ -234,13 +185,13 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
supportSignedBundles |= VERIFY_CERTIFICATE | VERIFY_TRUST;
else if (SUPPORT_RUNTIME.equals(support[i]))
supportSignedBundles |= VERIFY_CERTIFICATE | VERIFY_RUNTIME;
- else if (SUPPORT_AUTHORITY.equals(support[i]))
- supportSignedBundles |= VERIFY_CERTIFICATE | VERIFY_TRUST | VERIFY_AUTHORITY;
else if (SUPPORT_TRUE.equals(support[i]) || SUPPORT_ALL.equals(support[i]))
supportSignedBundles |= VERIFY_ALL;
}
+ trustEngineNameProp = hookRegistry.getConfiguration().getConfiguration(SignedContentConstants.TRUST_ENGINE);
+
if ((supportSignedBundles & VERIFY_CERTIFICATE) != 0) {
- hookRegistry.addStorageHook(new SignedStorageHook());
+ hookRegistry.addStorageHookFactory(new SignedStorageHook());
hookRegistry.addBundleFileWrapperFactoryHook(this);
}
}
@@ -252,8 +203,8 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
if (content.isDirectory())
contentBundleFile = new DirBundleFile(content);
else
- contentBundleFile = new ZipBundleFile(content, null);
- SignedBundleFile result = new SignedBundleFile(null, VERIFY_ALL);
+ contentBundleFile = new ZipBundleFile(content, null, null);
+ SignedBundleFile result = new SignedBundleFile(null, VERIFY_ALL, this);
try {
result.setBundleFile(contentBundleFile);
} catch (InvalidKeyException e) {
@@ -271,20 +222,18 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
}
public SignedContent getSignedContent(Bundle bundle) throws IOException, InvalidKeyException, SignatureException, CertificateException, NoSuchAlgorithmException, NoSuchProviderException, IllegalArgumentException {
- final BundleData data = ((AbstractBundle) bundle).getBundleData();
- if (!(data instanceof BaseData))
- throw new IllegalArgumentException("Invalid bundle object. No BaseData found."); //$NON-NLS-1$
- SignedStorageHook hook = (SignedStorageHook) ((BaseData) data).getStorageHook(SignedStorageHook.KEY);
+ final Generation generation = (Generation) ((EquinoxBundle) bundle).getModule().getCurrentRevision().getRevisionInfo();
+ StorageHookImpl hook = generation.getStorageHook(SignedStorageHook.class);
SignedContent result = hook != null ? hook.signedContent : null;
if (result != null)
return result; // just reuse the signed content the storage hook
// must create a new signed content using the raw file
if (System.getSecurityManager() == null)
- return getSignedContent(((BaseData) data).getBundleFile().getBaseFile());
+ return getSignedContent(generation.getBundleFile().getBaseFile());
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<SignedContent>() {
public SignedContent run() throws Exception {
- return getSignedContent(((BaseData) data).getBundleFile().getBaseFile());
+ return getSignedContent(generation.getBundleFile().getBaseFile());
}
});
} catch (PrivilegedActionException e) {
@@ -304,41 +253,27 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
}
}
- public static void log(String msg, int severity, Throwable t) {
- if (SignedBundleHook.ADAPTOR == null) {
- System.err.println(msg);
- t.printStackTrace();
- return;
- }
- FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, severity, 0, msg, 0, t, null);
- SignedBundleHook.ADAPTOR.getFrameworkLog().log(entry);
- }
-
- static BundleContext getContext() {
- if (ADAPTOR == null)
- return null;
- return ADAPTOR.getContext();
+ public void log(String msg, int severity, Throwable t) {
+ container.getLogServices().log(EquinoxContainer.NAME, severity, msg, t);
}
- static TrustEngine[] getTrustEngines() {
+ private TrustEngine[] getTrustEngines() {
// find all the trust engines available
- BundleContext context = SignedBundleHook.getContext();
if (context == null)
return new TrustEngine[0];
if (trustEngineTracker == null) {
// read the trust provider security property
- String trustEngineProp = FrameworkProperties.getProperty(SignedContentConstants.TRUST_ENGINE);
Filter filter = null;
- if (trustEngineProp != null)
+ if (trustEngineNameProp != null)
try {
- filter = FilterImpl.newInstance("(&(" + Constants.OBJECTCLASS + "=" + TrustEngine.class.getName() + ")(" + SignedContentConstants.TRUST_ENGINE + "=" + trustEngineProp + "))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$//$NON-NLS-5$
+ filter = FilterImpl.newInstance("(&(" + Constants.OBJECTCLASS + "=" + TrustEngine.class.getName() + ")(" + SignedContentConstants.TRUST_ENGINE + "=" + trustEngineNameProp + "))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$//$NON-NLS-5$
} catch (InvalidSyntaxException e) {
- SignedBundleHook.log("Invalid trust engine filter", FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
+ log("Invalid trust engine filter", FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
}
if (filter != null) {
- trustEngineTracker = new ServiceTracker<TrustEngine, TrustEngine>(context, filter, null);
+ trustEngineTracker = new ServiceTracker<TrustEngine, TrustEngine>(context, filter, new TrustEngineCustomizer());
} else
- trustEngineTracker = new ServiceTracker<TrustEngine, TrustEngine>(context, TrustEngine.class.getName(), null);
+ trustEngineTracker = new ServiceTracker<TrustEngine, TrustEngine>(context, TrustEngine.class.getName(), new TrustEngineCustomizer());
trustEngineTracker.open();
}
Object[] services = trustEngineTracker.getServices();
@@ -349,4 +284,74 @@ public class SignedBundleHook implements AdaptorHook, BundleFileWrapperFactoryHo
}
return new TrustEngine[0];
}
+
+ class TrustEngineCustomizer implements ServiceTrackerCustomizer<TrustEngine, TrustEngine> {
+
+ @Override
+ public TrustEngine addingService(ServiceReference<TrustEngine> reference) {
+ TrustEngine engine = getContext().getService(reference);
+ if (engine != null) {
+ try {
+ Field trustEngineListenerField = TrustEngine.class.getDeclaredField("trustEngineListener"); //$NON-NLS-1$
+ trustEngineListenerField.setAccessible(true);
+ trustEngineListenerField.set(engine, SignedBundleHook.this.trustEngineListener);
+ } catch (Exception e) {
+ log("Unable to set the trust engine listener.", FrameworkLogEntry.ERROR, e); //$NON-NLS-1$
+ }
+
+ }
+ return engine;
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<TrustEngine> reference, TrustEngine service) {
+ // nothing
+ }
+
+ @Override
+ public void removedService(ServiceReference<TrustEngine> reference, TrustEngine service) {
+ // nothing
+ }
+
+ }
+
+ void determineTrust(SignedContentImpl trustedContent, int supportFlags) {
+ TrustEngine[] engines = null;
+ SignerInfo[] signers = trustedContent.getSignerInfos();
+ for (int i = 0; i < signers.length; i++) {
+ // first check if we need to find an anchor
+ if (signers[i].getTrustAnchor() == null) {
+ // no anchor set ask the trust engines
+ if (engines == null)
+ engines = getTrustEngines();
+ // check trust of singer certs
+ Certificate[] signerCerts = signers[i].getCertificateChain();
+ ((SignerInfoImpl) signers[i]).setTrustAnchor(findTrustAnchor(signerCerts, engines, supportFlags));
+ // if signer has a tsa check trust of tsa certs
+ SignerInfo tsaSignerInfo = trustedContent.getTSASignerInfo(signers[i]);
+ if (tsaSignerInfo != null) {
+ Certificate[] tsaCerts = tsaSignerInfo.getCertificateChain();
+ ((SignerInfoImpl) tsaSignerInfo).setTrustAnchor(findTrustAnchor(tsaCerts, engines, supportFlags));
+ }
+ }
+ }
+ }
+
+ private Certificate findTrustAnchor(Certificate[] certs, TrustEngine[] engines, int supportFlags) {
+ if ((supportFlags & SignedBundleHook.VERIFY_TRUST) == 0)
+ // we are not searching the engines; in this case we just assume the root cert is trusted
+ return certs != null && certs.length > 0 ? certs[certs.length - 1] : null;
+ for (int i = 0; i < engines.length; i++) {
+ try {
+ Certificate anchor = engines[i].findTrustAnchor(certs);
+ if (anchor != null)
+ // found an anchor
+ return anchor;
+ } catch (IOException e) {
+ // log the exception and continue
+ log("TrustEngine failure: " + engines[i].getName(), FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentConstants.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentConstants.java
index 115621a91..38302584e 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentConstants.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentConstants.java
@@ -59,10 +59,6 @@ public interface SignedContentConstants {
public static final String TRUST_ENGINE = "osgi.signedcontent.trust.engine"; //$NON-NLS-1$
public static final Object DEFAULT_TRUST_ENGINE = "org.eclipse.osgi"; //$NON-NLS-1$
- // constants for authorization engine service
- public static final String AUTHORIZATION_ENGINE = "osgi.signedcontent.authorization.engine"; //$NON-NLS-1$
- public static final Object DEFAULT_AUTHORIZATION_ENGINE = "org.eclipse.osgi"; //$NON-NLS-1$
-
// constant for the timestamp related
public static final int TIMESTAMP_OID[] = {1, 2, 840, 113549, 1, 9, 16, 2, 14};
public static final int TIMESTAMP_TST_OID[] = {1, 2, 840, 113549, 1, 9, 16, 1, 4};
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
index e9746df84..64f6a01e3 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedContentImpl.java
@@ -8,14 +8,14 @@
******************************************************************************/
package org.eclipse.osgi.internal.signedcontent;
-import org.eclipse.osgi.storage.bundlefile.BundleEntry;
-import org.eclipse.osgi.storage.bundlefile.BundleFile;
-
import java.io.IOException;
import java.io.InputStream;
+import java.security.NoSuchAlgorithmException;
import java.security.cert.*;
import java.util.*;
import org.eclipse.osgi.signedcontent.*;
+import org.eclipse.osgi.storage.bundlefile.BundleEntry;
+import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.util.NLS;
public class SignedContentImpl implements SignedContent {
@@ -126,7 +126,11 @@ public class SignedContentImpl implements SignedContent {
Object[] mdResult = (Object[]) contentMDResults.get(nestedEntry.getName());
if (mdResult == null)
return null;
- return new DigestedInputStream(nestedEntry, content, (SignerInfo[]) mdResult[0], (byte[][]) mdResult[1], nestedEntry.getSize());
+ try {
+ return new DigestedInputStream(nestedEntry, content, (SignerInfo[]) mdResult[0], (byte[][]) mdResult[1], nestedEntry.getSize());
+ } catch (NoSuchAlgorithmException e) {
+ throw new IOException(e);
+ }
}
public class SignedContentEntryImpl implements SignedContentEntry {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedStorageHook.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedStorageHook.java
index 2fe55e59c..df5cbbab7 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedStorageHook.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/SignedStorageHook.java
@@ -11,233 +11,177 @@ package org.eclipse.osgi.internal.signedcontent;
import java.io.*;
import java.security.cert.*;
import java.util.*;
-import org.eclipse.osgi.baseadaptor.BaseData;
-import org.eclipse.osgi.baseadaptor.hooks.StorageHook;
-import org.eclipse.osgi.framework.util.KeyedElement;
+import org.eclipse.osgi.internal.hookregistry.StorageHookFactory;
import org.eclipse.osgi.signedcontent.SignedContent;
import org.eclipse.osgi.signedcontent.SignerInfo;
-import org.osgi.framework.Bundle;
+import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.osgi.framework.BundleException;
-public class SignedStorageHook implements StorageHook {
- public static final String KEY = SignedStorageHook.class.getName();
- public static final int HASHCODE = KEY.hashCode();
- private static final int STORAGE_VERSION = 3;
- private static List<SignerInfo> savedSignerInfo = new ArrayList<SignerInfo>(5);
- private static long firstIDSaved = -1;
- private static long lastIDSaved = -1;
- private static List<SignerInfo> loadedSignerInfo = new ArrayList<SignerInfo>(5);
- private static long lastIDLoaded;
-
- private BaseData bundledata;
- SignedContentImpl signedContent;
+public class SignedStorageHook extends StorageHookFactory<List<SignerInfo>, List<SignerInfo>, SignedStorageHook.StorageHookImpl> {
+ private static final int STORAGE_VERSION = 4;
public int getStorageVersion() {
return STORAGE_VERSION;
}
- /**
- * @throws BundleException
- */
- public StorageHook create(BaseData data) throws BundleException {
- SignedStorageHook hook = new SignedStorageHook();
- hook.bundledata = data;
- return hook;
+ @Override
+ public List<SignerInfo> createSaveContext() {
+ return new ArrayList<SignerInfo>();
}
- /**
- * @throws BundleException
- */
- public void initialize(Dictionary<String, String> manifest) throws BundleException {
- // do nothing
+ @Override
+ public List<SignerInfo> createLoadContext(int version) {
+ return new ArrayList<SignerInfo>();
}
- public StorageHook load(BaseData target, DataInputStream is) throws IOException {
- if (lastIDLoaded > target.getBundleID())
- loadedSignerInfo.clear();
- lastIDLoaded = target.getBundleID();
- SignedStorageHook hook = new SignedStorageHook();
- hook.bundledata = target;
- boolean signed = is.readBoolean();
- if (!signed)
- return hook;
- int numSigners = is.readInt();
- SignerInfo[] signerInfos = new SignerInfo[numSigners];
- for (int i = 0; i < numSigners; i++)
- signerInfos[i] = readSignerInfo(is);
-
- int resultsSize = is.readInt();
- Map<String, Object> contentMDResults = null;
- if (resultsSize > 0) {
- contentMDResults = new HashMap<String, Object>(resultsSize);
- for (int i = 0; i < resultsSize; i++) {
- String path = is.readUTF();
- int numEntrySigners = is.readInt();
- SignerInfo[] entrySigners = new SignerInfo[numEntrySigners];
- byte[][] entryResults = new byte[numEntrySigners][];
- for (int j = 0; j < numEntrySigners; j++) {
- entrySigners[j] = readSignerInfo(is);
- int resultSize = is.readInt();
- entryResults[j] = new byte[resultSize];
- is.readFully(entryResults[j]);
- }
- contentMDResults.put(path, new Object[] {entrySigners, entryResults});
- }
+ @Override
+ public StorageHookImpl createStorageHook(Generation generation) {
+ return new StorageHookImpl(generation);
+ }
+
+ static class StorageHookImpl extends StorageHookFactory.StorageHook<List<SignerInfo>, List<SignerInfo>> {
+ SignedContentImpl signedContent;
+
+ public StorageHookImpl(Generation generation) {
+ super(generation, SignedStorageHook.class);
}
- SignedContentImpl result = new SignedContentImpl(signerInfos, contentMDResults);
- for (int i = 0; i < numSigners; i++) {
- boolean hasTSA = is.readBoolean();
- if (!hasTSA)
- continue;
- SignerInfo tsaSigner = readSignerInfo(is);
- Date signingDate = new Date(is.readLong());
- result.addTSASignerInfo(signerInfos[i], tsaSigner, signingDate);
+
+ @SuppressWarnings("unused")
+ @Override
+ public void initialize(Dictionary<String, String> manifest) throws BundleException {
+ // do nothing
}
- hook.signedContent = result;
- return hook;
- }
- public void save(DataOutputStream os) throws IOException {
- getFirstLastID();
- if (firstIDSaved == bundledata.getBundleID())
- savedSignerInfo.clear();
- if (lastIDSaved == bundledata.getBundleID())
- firstIDSaved = lastIDSaved = -1;
- os.writeBoolean(signedContent != null);
- if (signedContent == null)
- return;
- SignerInfo[] signerInfos = signedContent.getSignerInfos();
- os.writeInt(signerInfos.length);
- for (int i = 0; i < signerInfos.length; i++)
- saveSignerInfo(signerInfos[i], os);
-
- // keyed by entry path -> {SignerInfo[] infos, byte[][] results)}
- Map<String, Object> contentMDResults = signedContent.getContentMDResults();
- os.writeInt(contentMDResults == null ? -1 : contentMDResults.size());
- if (contentMDResults != null)
- for (Map.Entry<String, Object> entry : contentMDResults.entrySet()) {
- String path = entry.getKey();
- os.writeUTF(path);
- Object[] signerResults = (Object[]) entry.getValue();
- SignerInfo[] entrySigners = (SignerInfo[]) signerResults[0];
- byte[][] entryResults = (byte[][]) signerResults[1];
- os.writeInt(entrySigners.length);
- for (int i = 0; i < entrySigners.length; i++) {
- saveSignerInfo(entrySigners[i], os);
- os.writeInt(entryResults[i].length);
- os.write(entryResults[i]);
+ @Override
+ public void load(List<SignerInfo> loadContext, DataInputStream is) throws IOException {
+ boolean signed = is.readBoolean();
+ if (!signed)
+ return;
+ int numSigners = is.readInt();
+ SignerInfo[] signerInfos = new SignerInfo[numSigners];
+ for (int i = 0; i < numSigners; i++)
+ signerInfos[i] = readSignerInfo(is, loadContext);
+
+ int resultsSize = is.readInt();
+ Map<String, Object> contentMDResults = null;
+ if (resultsSize > 0) {
+ contentMDResults = new HashMap<String, Object>(resultsSize);
+ for (int i = 0; i < resultsSize; i++) {
+ String path = is.readUTF();
+ int numEntrySigners = is.readInt();
+ SignerInfo[] entrySigners = new SignerInfo[numEntrySigners];
+ byte[][] entryResults = new byte[numEntrySigners][];
+ for (int j = 0; j < numEntrySigners; j++) {
+ entrySigners[j] = readSignerInfo(is, loadContext);
+ int resultSize = is.readInt();
+ entryResults[j] = new byte[resultSize];
+ is.readFully(entryResults[j]);
+ }
+ contentMDResults.put(path, new Object[] {entrySigners, entryResults});
}
}
-
- for (int i = 0; i < signerInfos.length; i++) {
- SignerInfo tsaInfo = signedContent.getTSASignerInfo(signerInfos[i]);
- os.writeBoolean(tsaInfo != null);
- if (tsaInfo == null)
- continue;
- saveSignerInfo(tsaInfo, os);
- Date signingTime = signedContent.getSigningTime(signerInfos[i]);
- os.writeLong(signingTime != null ? signingTime.getTime() : Long.MIN_VALUE);
+ SignedContentImpl result = new SignedContentImpl(signerInfos, contentMDResults);
+ for (int i = 0; i < numSigners; i++) {
+ boolean hasTSA = is.readBoolean();
+ if (!hasTSA)
+ continue;
+ SignerInfo tsaSigner = readSignerInfo(is, loadContext);
+ Date signingDate = new Date(is.readLong());
+ result.addTSASignerInfo(signerInfos[i], tsaSigner, signingDate);
+ }
+ signedContent = result;
}
- }
- private void saveSignerInfo(SignerInfo signerInfo, DataOutputStream os) throws IOException {
- int cacheIdx = savedSignerInfo.indexOf(signerInfo);
- os.writeInt(cacheIdx);
- if (cacheIdx >= 0)
- return;
- Certificate[] certs = signerInfo.getCertificateChain();
- int anchorIndex = -1;
- os.writeInt(certs == null ? 0 : certs.length);
- if (certs != null)
- for (int i = 0; i < certs.length; i++) {
- if (certs[i].equals(signerInfo.getTrustAnchor()))
- anchorIndex = i;
- byte[] certBytes;
+ private SignerInfo readSignerInfo(DataInputStream is, List<SignerInfo> loadContext) throws IOException {
+ int index = is.readInt();
+ if (index >= 0)
+ return loadContext.get(index);
+ int numCerts = is.readInt();
+ Certificate[] certs = new Certificate[numCerts];
+ for (int i = 0; i < numCerts; i++) {
+ int certSize = is.readInt();
+ byte[] certBytes = new byte[certSize];
+ is.readFully(certBytes);
try {
- certBytes = certs[i].getEncoded();
- } catch (CertificateEncodingException e) {
+ certs[i] = PKCS7Processor.certFact.generateCertificate(new ByteArrayInputStream(certBytes));
+ } catch (CertificateException e) {
throw (IOException) new IOException(e.getMessage()).initCause(e);
}
- os.writeInt(certBytes.length);
- os.write(certBytes);
}
- os.writeInt(anchorIndex);
- os.writeUTF(signerInfo.getMessageDigestAlgorithm());
- savedSignerInfo.add(signerInfo);
- }
+ int anchorIdx = is.readInt();
+ SignerInfoImpl result = new SignerInfoImpl(certs, anchorIdx >= 0 ? certs[anchorIdx] : null, is.readUTF());
+ loadContext.add(result);
+ return result;
+ }
- private SignerInfo readSignerInfo(DataInputStream is) throws IOException {
- int index = is.readInt();
- if (index >= 0)
- return loadedSignerInfo.get(index);
- int numCerts = is.readInt();
- Certificate[] certs = new Certificate[numCerts];
- for (int i = 0; i < numCerts; i++) {
- int certSize = is.readInt();
- byte[] certBytes = new byte[certSize];
- is.readFully(certBytes);
- try {
- certs[i] = PKCS7Processor.certFact.generateCertificate(new ByteArrayInputStream(certBytes));
- } catch (CertificateException e) {
- throw (IOException) new IOException(e.getMessage()).initCause(e);
+ @Override
+ public void save(List<SignerInfo> saveContext, DataOutputStream os) throws IOException {
+ os.writeBoolean(signedContent != null);
+ if (signedContent == null)
+ return;
+ SignerInfo[] signerInfos = signedContent.getSignerInfos();
+ os.writeInt(signerInfos.length);
+ for (int i = 0; i < signerInfos.length; i++)
+ saveSignerInfo(signerInfos[i], os, saveContext);
+
+ // keyed by entry path -> {SignerInfo[] infos, byte[][] results)}
+ Map<String, Object> contentMDResults = signedContent.getContentMDResults();
+ os.writeInt(contentMDResults == null ? -1 : contentMDResults.size());
+ if (contentMDResults != null)
+ for (Map.Entry<String, Object> entry : contentMDResults.entrySet()) {
+ String path = entry.getKey();
+ os.writeUTF(path);
+ Object[] signerResults = (Object[]) entry.getValue();
+ SignerInfo[] entrySigners = (SignerInfo[]) signerResults[0];
+ byte[][] entryResults = (byte[][]) signerResults[1];
+ os.writeInt(entrySigners.length);
+ for (int i = 0; i < entrySigners.length; i++) {
+ saveSignerInfo(entrySigners[i], os, saveContext);
+ os.writeInt(entryResults[i].length);
+ os.write(entryResults[i]);
+ }
+ }
+
+ for (int i = 0; i < signerInfos.length; i++) {
+ SignerInfo tsaInfo = signedContent.getTSASignerInfo(signerInfos[i]);
+ os.writeBoolean(tsaInfo != null);
+ if (tsaInfo == null)
+ continue;
+ saveSignerInfo(tsaInfo, os, saveContext);
+ Date signingTime = signedContent.getSigningTime(signerInfos[i]);
+ os.writeLong(signingTime != null ? signingTime.getTime() : Long.MIN_VALUE);
}
}
- int anchorIdx = is.readInt();
- SignerInfoImpl result = new SignerInfoImpl(certs, anchorIdx >= 0 ? certs[anchorIdx] : null, is.readUTF());
- loadedSignerInfo.add(result);
- return result;
- }
- private void getFirstLastID() {
- if (firstIDSaved >= 0)
- return;
- Bundle[] bundles = bundledata.getAdaptor().getContext().getBundles();
- if (bundles.length > 1) {
- firstIDSaved = bundles[1].getBundleId();
- lastIDSaved = bundles[bundles.length - 1].getBundleId();
+ private void saveSignerInfo(SignerInfo signerInfo, DataOutputStream os, List<SignerInfo> saveContext) throws IOException {
+ int cacheIdx = saveContext.indexOf(signerInfo);
+ os.writeInt(cacheIdx);
+ if (cacheIdx >= 0)
+ return;
+ Certificate[] certs = signerInfo.getCertificateChain();
+ int anchorIndex = -1;
+ os.writeInt(certs == null ? 0 : certs.length);
+ if (certs != null)
+ for (int i = 0; i < certs.length; i++) {
+ if (certs[i].equals(signerInfo.getTrustAnchor()))
+ anchorIndex = i;
+ byte[] certBytes;
+ try {
+ certBytes = certs[i].getEncoded();
+ } catch (CertificateEncodingException e) {
+ throw (IOException) new IOException(e.getMessage()).initCause(e);
+ }
+ os.writeInt(certBytes.length);
+ os.write(certBytes);
+ }
+ os.writeInt(anchorIndex);
+ os.writeUTF(signerInfo.getMessageDigestAlgorithm());
+ saveContext.add(signerInfo);
}
- }
- public void copy(StorageHook storageHook) {
- // do nothing
- }
-
- public void validate() throws IllegalArgumentException {
- // do nothing
- }
-
- /**
- * @throws BundleException
- */
- public Dictionary<String, String> getManifest(boolean firstLoad) throws BundleException {
- // do nothing
- return null;
- }
-
- public boolean forgetStatusChange(int status) {
- // do nothing
- return false;
- }
-
- public boolean forgetStartLevelChange(int startlevel) {
- // do nothing
- return false;
- }
-
- public int getKeyHashCode() {
- return HASHCODE;
- }
-
- public boolean compare(KeyedElement other) {
- return other.getKey() == KEY;
- }
-
- public Object getKey() {
- return KEY;
- }
-
- public SignedContent getSignedContent() {
- return signedContent;
+ public SignedContent getSignedContent() {
+ return signedContent;
+ }
}
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/TrustEngineListener.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/TrustEngineListener.java
index ba10d0f5a..f5746e133 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/TrustEngineListener.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/signedcontent/TrustEngineListener.java
@@ -8,110 +8,45 @@
******************************************************************************/
package org.eclipse.osgi.internal.signedcontent;
-import org.eclipse.osgi.internal.framework.FilterImpl;
-
import java.security.cert.Certificate;
import java.util.*;
-import org.eclipse.osgi.baseadaptor.BaseData;
-import org.eclipse.osgi.framework.internal.core.*;
-import org.eclipse.osgi.framework.log.FrameworkLogEntry;
-import org.eclipse.osgi.internal.provisional.service.security.AuthorizationEngine;
+import org.eclipse.osgi.internal.framework.EquinoxBundle;
+import org.eclipse.osgi.internal.signedcontent.SignedStorageHook.StorageHookImpl;
import org.eclipse.osgi.signedcontent.SignerInfo;
-import org.osgi.framework.*;
-import org.osgi.framework.Constants;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.osgi.util.tracker.ServiceTracker;
+import org.eclipse.osgi.storage.BundleInfo.Generation;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
public class TrustEngineListener {
- // this is a singleton listener; see SignedBundleHook for initialization
- private volatile static TrustEngineListener instance;
private final BundleContext context;
- private final ServiceTracker<AuthorizationEngine, AuthorizationEngine> authorizationTracker;
+ private final SignedBundleHook signedBundleHook;
- TrustEngineListener(BundleContext context) {
+ TrustEngineListener(BundleContext context, SignedBundleHook signedBundleHook) {
this.context = context;
- // read the trust provider security property
- String authEngineProp = FrameworkProperties.getProperty(SignedContentConstants.AUTHORIZATION_ENGINE);
- Filter filter = null;
- if (authEngineProp != null)
- try {
- filter = FilterImpl.newInstance("(&(" + Constants.OBJECTCLASS + "=" + AuthorizationEngine.class.getName() + ")(" + SignedContentConstants.AUTHORIZATION_ENGINE + "=" + authEngineProp + "))"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$//$NON-NLS-5$
- } catch (InvalidSyntaxException e) {
- SignedBundleHook.log("Invalid authorization filter", FrameworkLogEntry.WARNING, e); //$NON-NLS-1$
- }
- if (filter != null)
- authorizationTracker = new ServiceTracker<AuthorizationEngine, AuthorizationEngine>(context, filter, null);
- else
- authorizationTracker = new ServiceTracker<AuthorizationEngine, AuthorizationEngine>(context, AuthorizationEngine.class.getName(), null);
- authorizationTracker.open();
- instance = this;
- }
-
- public static TrustEngineListener getInstance() {
- return instance;
- }
-
- void stopTrustEngineListener() {
- authorizationTracker.close();
- instance = null;
+ this.signedBundleHook = signedBundleHook;
}
public void addedTrustAnchor(Certificate anchor) {
// find any SignedContent with SignerInfos that do not have an anchor;
// re-evaluate trust and check authorization for these SignedContents
Bundle[] bundles = context.getBundles();
- Set<Bundle> unresolved = new HashSet<Bundle>();
for (int i = 0; i < bundles.length; i++) {
SignedContentImpl signedContent = getSignedContent(bundles[i]);
if (signedContent != null && signedContent.isSigned()) {
// check the SignerInfos for this content
SignerInfo[] infos = signedContent.getSignerInfos();
for (int j = 0; j < infos.length; j++) {
- if (infos[j].getTrustAnchor() == null)
+ if (infos[j].getTrustAnchor() == null) {
// one of the signers is not trusted
- unresolved.add(bundles[i]);
- SignerInfo tsa = signedContent.getTSASignerInfo(infos[j]);
- if (tsa != null && tsa.getTrustAnchor() == null)
- // one of the tsa signers is not trusted
- unresolved.add(bundles[i]);
+ signedBundleHook.determineTrust(signedContent, SignedBundleHook.VERIFY_TRUST);
+ } else {
+ SignerInfo tsa = signedContent.getTSASignerInfo(infos[j]);
+ if (tsa != null && tsa.getTrustAnchor() == null)
+ // one of the tsa signers is not trusted
+ signedBundleHook.determineTrust(signedContent, SignedBundleHook.VERIFY_TRUST);
+ }
}
}
- if (unresolved.contains(bundles[i])) {
- // found an untrusted signer for this bundle re-evaluate trust
- SignedBundleFile.determineTrust(signedContent, SignedBundleHook.VERIFY_TRUST);
- // now check the authorization handler
- checkAuthorization(signedContent, bundles[i]);
- }
- }
- // try to resolve
- if (unresolved.size() > 0)
- resolveBundles(unresolved.toArray(new Bundle[unresolved.size()]), false);
- }
-
- private void checkAuthorization(SignedContentImpl signedContent, Bundle bundle) {
- AuthorizationEngine authEngine = getAuthorizationEngine();
- if (authEngine != null)
- authEngine.authorize(signedContent, bundle);
- }
-
- AuthorizationEngine getAuthorizationEngine() {
- return authorizationTracker.getService();
- }
-
- private void resolveBundles(Bundle[] bundles, boolean refresh) {
- ServiceReference<?> ref = context.getServiceReference(PackageAdmin.class.getName());
- if (ref == null)
- return;
- PackageAdmin pa = (PackageAdmin) context.getService(ref);
- if (pa == null)
- return;
- try {
- if (refresh)
- pa.refreshPackages(bundles);
- else
- pa.resolveBundles(bundles);
- } finally {
- context.ungetService(ref);
}
}
@@ -144,26 +79,18 @@ public class TrustEngineListener {
// remove trust anchors from untrusted signers
for (Iterator<SignerInfo> untrusted = untrustedSigners.iterator(); untrusted.hasNext();)
((SignerInfoImpl) untrusted.next()).setTrustAnchor(null);
- // re-establish trust and check authorization
+ // re-establish trust
for (Iterator<Bundle> untrustedBundles = usingAnchor.iterator(); untrustedBundles.hasNext();) {
Bundle bundle = untrustedBundles.next();
SignedContentImpl signedContent = getSignedContent(bundle);
// found an signer using the anchor for this bundle re-evaluate trust
- SignedBundleFile.determineTrust(signedContent, SignedBundleHook.VERIFY_TRUST);
- // now check the authorization handler
- checkAuthorization(signedContent, bundle);
+ signedBundleHook.determineTrust(signedContent, SignedBundleHook.VERIFY_TRUST);
}
- // TODO an optimization here would be to check for real DisabledInfo objects for each bundle
- // try to refresh
- if (usingAnchor.size() > 0)
- resolveBundles(usingAnchor.toArray(new Bundle[usingAnchor.size()]), true);
}
private SignedContentImpl getSignedContent(Bundle bundle) {
- BaseData data = (BaseData) ((AbstractBundle) bundle).getBundleData();
- SignedStorageHook hook = (SignedStorageHook) data.getStorageHook(SignedStorageHook.KEY);
- if (hook == null)
- return null;
- return (SignedContentImpl) hook.getSignedContent();
+ Generation generation = (Generation) ((EquinoxBundle) bundle).getModule().getCurrentRevision().getRevisionInfo();
+ StorageHookImpl hook = generation.getStorageHook(SignedStorageHook.class);
+ return hook != null ? hook.signedContent : null;
}
}

Back to the top