Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

572366 verify product's public key on hc-fls interaction #693

Merged
merged 3 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
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
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$
}
}