Skip to content

Commit

Permalink
Merge pull request #693 from eclipse-passage/572366
Browse files Browse the repository at this point in the history
572366 verify product's public key on hc-fls interaction
  • Loading branch information
eparovyshnaya authored Mar 30, 2021
2 parents f3977c7 + 8ca603e commit 769bfad
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2021 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.internal.api.io;

import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.api.registry.Service;
import org.eclipse.passage.lic.internal.api.registry.StringServiceId;

public interface Hashes extends Service<StringServiceId> {

byte[] get(byte[] source) throws LicensingException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright (c) 2020 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.internal.api.io;

import java.util.function.Supplier;

import org.eclipse.passage.lic.internal.api.registry.Registry;
import org.eclipse.passage.lic.internal.api.registry.StringServiceId;

public interface HashesRegistry extends Supplier<Registry<StringServiceId, Hashes>> {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2021 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.internal.base.io;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.api.io.KeyKeeper;

public final class KeyContent {

private final KeyKeeper keeper;

public KeyContent(KeyKeeper keeper) {
this.keeper = keeper;
}

public byte[] get() throws LicensingException {
try (InputStream in = keeper.productPublicKey(); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
int acquired = -1;
byte[] buffer = new byte[1024];
while ((acquired = in.read(buffer)) != -1) {
out.write(buffer, 0, acquired);
}
return out.toByteArray();
} catch (IOException e) {
throw new LicensingException("Failed to read public key ", e); //$NON-NLS-1$
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2021 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.internal.base.io;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.api.io.Hashes;
import org.eclipse.passage.lic.internal.api.registry.StringServiceId;

public final class MD5Hashes implements Hashes {

private final String algorithm = "MD5"; //$NON-NLS-1$

@Override
public StringServiceId id() {
return new StringServiceId(algorithm);
}

@Override
public byte[] get(byte[] source) throws LicensingException {
try {
return MessageDigest.getInstance(algorithm).digest(source);
} catch (NoSuchAlgorithmException e) {
throw new LicensingException("Failed to build a hash ", e); //$NON-NLS-1$
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@ public ReadOnlyRegistry(S service) {
super(Collections.singleton(service));
}

public ReadOnlyRegistry() {
super(Collections.emptyList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2021 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.internal.net.io;

import java.util.Base64;

import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.api.io.Hashes;
import org.eclipse.passage.lic.internal.api.io.KeyKeeper;
import org.eclipse.passage.lic.internal.base.io.KeyContent;

public final class SafePayload {

private final Hashes hashes;
private final KeyKeeper keeper;

public SafePayload(KeyKeeper keeper, Hashes hashes) {
this.keeper = keeper;
this.hashes = hashes;
}

public byte[] encode(byte[] raw) throws LicensingException {
return transportable(coded(raw));
}

public byte[] decode(byte[] raw) throws LicensingException {
return coded(transported(raw));
}

private byte[] transportable(byte[] content) {
return Base64.getEncoder().encode(content);
}

private byte[] transported(byte[] content) {
return Base64.getDecoder().decode(content);
}

private byte[] coded(byte[] source) throws LicensingException {
return new SymmetricCode(key()).get(source);
}

private byte[] key() throws LicensingException {
return hashes.get(new KeyContent(keeper).get());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2021 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.internal.net.io;

final class SymmetricCode {

private final byte[] key;

SymmetricCode(byte[] key) {
this.key = key;
}

byte[] get(byte[] source) {
int length = source.length;
byte[] cypher = enoughKey(length);
byte[] coded = new byte[length];
for (int i = 0; i < length; i++) {
coded[i] = (byte) (source[i] ^ cypher[i]);
}
return coded;
}

private byte[] enoughKey(int length) {
byte[] elongated = new byte[length];
for (int i = 0; i < length; i++) {
elongated[i] = key[i % key.length];
}
return elongated;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding//src/org/eclipse/passage/lic/net/tests/io/SafePayloadTest.java=UTF-8
19 changes: 19 additions & 0 deletions tests/org.eclipse.passage.lic.net.tests/resource/io/key.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v1.65

mI0EXz6mRAEEAMDncQ54z+JSaAc7zjfnojFCk9/jcPcZHbIENjGeUg/3NfI3GbJv
cGi//abYchzilMJS/h+kNPmKkABZ9FDvUFjdxhmjaqL1dgR4xJmd4SlczLAtPQhM
dNukFyWHIkhFL88W5yuqUtWdCPplzmLbe2wX6wLrqgwgKqchzISCi6qhABEBAAG0
GGFudGktaHVtYW4tbWFnaWMucHJvZHVjdIiiBBMBAgAMBQJfPqZEBQkAAAPoAAoJ
EHbBbJDZeiPsEV0D/iPfuVsuGjt2Xa1tsJ1gAI75dTwiNHlFAMPSSa0xuQInrRln
wzNY4JNYz9ZSEp1IjA6rsAYCgh/vgITKrqvp/MHPfk6ojRz0ecT/UkblZCB/S4CI
64lQrVxGYttX8foexs6VDD43RIO0jUpLTX7lXzBMBP0ETzYT+E0Q/qgW/LiDuI0E
Xz6mRAEEAMDncQ54z+JSaAc7zjfnojFCk9/jcPcZHbIENjGeUg/3NfI3GbJvcGi/
/abYchzilMJS/h+kNPmKkABZ9FDvUFjdxhmjaqL1dgR4xJmd4SlczLAtPQhMdNuk
FyWHIkhFL88W5yuqUtWdCPplzmLbe2wX6wLrqgwgKqchzISCi6qhABEBAAGIogQY
AQIADAUCXz6mRAUJAAAD6AAKCRB2wWyQ2Xoj7D69A/9dzrh61zov6cgSLUVR4p+W
AewU3yCRYHIx158K7jG2lmoKmiLcJKjcqWmoJcuxX8lPWHqeG2wEVqnONgLi4Yq1
/ZWrc/CqszV4258zGu8pQxZOdovbzxgPf9eTPqRtIOnrtWcwlRWKkW3K8HgMCq9X
coWMvpxXfnEvN7VrS6sePw==
=eVWh
-----END PGP PUBLIC KEY BLOCK-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2021 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.net.tests.io;

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

import java.nio.file.Paths;

import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.api.io.KeyKeeper;
import org.eclipse.passage.lic.internal.base.io.FileKeyKeeper;
import org.eclipse.passage.lic.internal.base.io.MD5Hashes;
import org.eclipse.passage.lic.internal.net.io.SafePayload;
import org.junit.Test;

public final class SafePayloadTest {

@Test
public void symmetric() {
String original = "S0me sophisticäted Str!ng"; //$NON-NLS-1$
try {
byte[] encoded = new SafePayload(keerper(), new MD5Hashes()).encode(original.getBytes());
assertTrue(encoded.length > 0);
System.out.println(new String(encoded));
byte[] decoded = new SafePayload(keerper(), new MD5Hashes()).decode(encoded);
assertTrue(decoded.length > 0);
assertEquals(original, new String(decoded));
} catch (LicensingException e) {
fail("Not intended to fail on valid data"); //$NON-NLS-1$
}
}

private KeyKeeper keerper() throws LicensingException {
return new FileKeyKeeper(Paths.get("resource").resolve("io").resolve("key.pub")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}

0 comments on commit 769bfad

Please sign in to comment.