Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 97 additions & 1 deletion 98 src/main/java/com/openfin/desktop/demo/Signer.java
Original file line number Diff line number Diff line change
@@ -1,2 +1,98 @@
package com.openfin.desktop.demo;public class Signer {
package com.openfin.desktop.demo;

import java.io.InputStream;
import java.security.CodeSigner;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

public class Signer {
private final String filename;

public Signer(String filename) {
this.filename = filename;
}

public void verify() throws Exception {
JarFile jar = new JarFile(this.filename, true);

Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
byte[] buffer = new byte[8192];
InputStream is = jar.getInputStream(entry);
while ((is.read(buffer, 0, buffer.length)) != -1) {
// We just read. This will throw a SecurityException
// if a signature/digest check fails.
}
is.close();
}

if (!checkSign(jar)) {
throw new SecurityException("not signed");
}

}

private boolean checkSign(JarFile jar) throws Exception {
InputStream jis = jar.getInputStream(jar.getEntry("META-INF/MANIFEST.MF"));
Manifest man = new Manifest(jis);
jis.close();

HashSet<String> signed = new HashSet<>();
for(Map.Entry<String, Attributes> entry: man.getEntries().entrySet()) {
for(Object attrkey: entry.getValue().keySet()) {
if (attrkey instanceof Attributes.Name && attrkey.toString().contains("-Digest")) {
signed.add(entry.getKey());
}
}
}
System.out.printf("Number of Digest from manifest %d \n", signed.size());

Set<String> entries = new HashSet<>();
for(Enumeration<JarEntry> entry = jar.entries(); entry.hasMoreElements(); ) {
JarEntry je = entry.nextElement();
String fileName = je.getName().toUpperCase();
if (!je.isDirectory()
&& !fileName.endsWith(".MF")
&& !fileName.endsWith(".SF")
&& !fileName.endsWith(".DSA")
&& !fileName.endsWith(".EC")
&& !fileName.endsWith(".RSA")
) {
CodeSigner[] signers = je.getCodeSigners();
if (signers != null && signers.length == 1) {
CodeSigner signer = signers[0];
if (signer.getSignerCertPath().getCertificates().size() != 4) {
throw new SecurityException(String.format("invalid cert chain %s", je.getName()));
}
X509Certificate cert = (X509Certificate) signer.getSignerCertPath().getCertificates().get(0);
if (!cert.getSubjectDN().toString().contains("OpenFin Inc.")) {
throw new SecurityException(String.format("invalid signed %s", je.getName()));
}
entries.add(je.getName());
} else {
throw new SecurityException(String.format("missing cert %s", je.getName()));
}
}
}
System.out.printf("Number of signed entries %d \n", entries.size());

Set<String> unsigned = new HashSet<>(entries);
unsigned.removeAll(signed);
return unsigned.size() == 0;
}

public static void main(String[] args) throws Exception {
Signer signer = new Signer(args[0]);
signer.verify();
}

}
2 changes: 1 addition & 1 deletion 2 src/test/java/com/openfin/desktop/AllTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
*/

@RunWith(Suite.class)
@Suite.SuiteClasses({ ApplicationTest.class, OpenFinRuntimeTest.class, WindowTest.class, SystemTest.class, InterApplicationBusTest.class, ChannelTest.class, RuntimeConfigTest.class})
@Suite.SuiteClasses({ ApplicationTest.class, OpenFinRuntimeTest.class, WindowTest.class, SystemTest.class, InterApplicationBusTest.class, ChannelTest.class, RuntimeConfigTest.class, SnapshotTest.class})
public class AllTests {
}
124 changes: 124 additions & 0 deletions 124 src/test/java/com/openfin/desktop/SnapshotTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.openfin.desktop;

import com.openfin.desktop.snapshot.SnapshotSource;
import com.openfin.desktop.snapshot.SnapshotSourceProvider;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.LocatorEx;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class SnapshotTest implements SnapshotSourceProvider {

private static Logger logger = LoggerFactory.getLogger(SnapshotTest.class.getName());

private static final String DESKTOP_UUID = SnapshotTest.class.getName();
private static DesktopConnection desktopConnection;
private static OpenFinRuntime runtime;
private static final JSONObject SNAPSHOT_CONTENT = new JSONObject("{width: 123}");

private JSONObject randomSnapshot;

@BeforeClass
public static void setup() throws Exception {
logger.debug("starting");
desktopConnection = TestUtils.setupConnection(DESKTOP_UUID);
if (desktopConnection != null) {
runtime = new OpenFinRuntime(desktopConnection);
}
}

@AfterClass
public static void teardown() throws Exception {
TestUtils.teardownDesktopConnection(desktopConnection);
}

@Test
public void initProviderThenCreateClient() throws Exception {
CountDownLatch latch = new CountDownLatch(2);
final String appUuid = "initProviderThenCreateClient";
desktopConnection.getSnapshotSource().initSnapshotSourceProviderAsync(appUuid, this).thenAccept(provider -> {
logger.debug("Snapshot provider created");
latch.countDown();
});
desktopConnection.getSnapshotSource().createSnapshotSourceClientAsync(appUuid).thenAccept(client -> {
logger.debug("Snapshot client created");
latch.countDown();
});

latch.await(5, TimeUnit.SECONDS);

assertEquals("initProviderThenCreateClient timeout", latch.getCount(), 0);
}

@Test
public void initProviderThenCreateClientThenGetSnapshot() throws Exception {
CountDownLatch latch = new CountDownLatch(2);
final String appUuid = "initProviderThenCreateClientThenGetSnapshot";
desktopConnection.getSnapshotSource().initSnapshotSourceProviderAsync(appUuid, this).thenAccept(provider -> {
logger.debug("Snapshot provider created");
latch.countDown();
});

desktopConnection.getSnapshotSource().createSnapshotSourceClientAsync(appUuid).thenAccept(client -> {
client.getSnapshotAsync().thenAccept(snapshot -> {
if (SNAPSHOT_CONTENT.toString().equals(snapshot.toString())) {
latch.countDown();
}
});
});

latch.await(5, TimeUnit.SECONDS);

assertEquals("initProviderThenCreateClientThenGetSnapshot timeout", latch.getCount(), 0);
}

@Test
public void initProviderThenCreateClientThenApplySnapshot() throws Exception {
CountDownLatch latch = new CountDownLatch(2);
final JSONObject random = new JSONObject(String.format("{value: %f}", Math.random()));
final String appUuid = "initProviderThenCreateClientThenApplySnapshot";
desktopConnection.getSnapshotSource().initSnapshotSourceProviderAsync(appUuid, this).thenAccept(provider -> {
latch.countDown();
});

desktopConnection.getSnapshotSource().createSnapshotSourceClientAsync(appUuid).thenAccept(client -> {
client.applySnapshotAsync(random).thenAccept(ack -> {
client.getSnapshotAsync().thenAccept(snapshot -> {
if (random.toString().equals(snapshot.toString())) {
latch.countDown();
}
});

});
});

latch.await(5, TimeUnit.SECONDS);

assertEquals("initProviderThenCreateClientThenGetSnapshot timeout", latch.getCount(), 0);
}

@Override
public JSONObject getSnapshot() {
if (this.randomSnapshot != null) {
return this.randomSnapshot;
} else {
return SNAPSHOT_CONTENT;
}
}

@Override
public void applySnapshot(JSONObject snapshot) {
this.randomSnapshot = snapshot;
}
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.