Skip to content

Commit

Permalink
added sgning verification. user can now sign a custom message, and ve…
Browse files Browse the repository at this point in the history
…rified any message, providing a public key, original message, and signature values produced by handoff.
  • Loading branch information
odds-get-evened committed Jan 29, 2022
1 parent 63068d4 commit 2d5024c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 27 deletions.
71 changes: 49 additions & 22 deletions src/main/java/org/white5moke/handoff/client/HandoffClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,18 @@
import java.security.spec.X509EncodedKeySpec;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Scanner;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.Deflater;
import java.util.zip.DataFormatException;

public class HandoffClient {
private final Path home;
private final Scanner scan = new Scanner(System.in);
private List<Path> hashList;
private List<Path> hashList = new ArrayList<>();
private String currentDocumentHash = StringUtils.EMPTY;

public HandoffClient() throws IOException, NoSuchAlgorithmException, SignatureException,
InvalidKeyException, InvalidKeySpecException {
InvalidKeyException, InvalidKeySpecException, DataFormatException {
// establish file structure
home = Path.of(System.getProperty("user.home"), ".handoff");
Files.createDirectories(home.getParent());
Expand All @@ -41,7 +38,9 @@ public HandoffClient() throws IOException, NoSuchAlgorithmException, SignatureEx
}

private void runLoop() throws IOException, NoSuchAlgorithmException, SignatureException,
InvalidKeyException, InvalidKeySpecException {
InvalidKeyException, InvalidKeySpecException, DataFormatException {
initHashList();

while (true) {
System.out.print("> ");

Expand All @@ -68,14 +67,29 @@ private void runLoop() throws IOException, NoSuchAlgorithmException, SignatureEx
case "list" -> list();
case "peek" -> peek(theMsg);
case "sign" -> signMessage(theMsg);
case "vsign" -> verifyMessageSignature(theMsg);
case "vsign" -> verifyMessageSignature();
case "use" -> useKey(theMsg);
default -> {}
}
}
}

private void verifyMessageSignature(String msg) {
private void initHashList() throws NoSuchAlgorithmException, SignatureException, IOException,
InvalidKeyException {
try {
hashList = Files
.list(home)
.sorted((f1, f2) -> Long.compare(f2.toFile().lastModified(), f1.toFile().lastModified()))
.toList();
useKey("0");
} catch (NullPointerException | IOException e) {}
if(hashList.size() <= 0) {
System.out.println("no key documents found. making one...");
generateKey("");
}
}

private void verifyMessageSignature() throws DataFormatException, NoSuchAlgorithmException, InvalidKeySpecException, SignatureException, InvalidKeyException {
System.out.print("key? > ");
String keyS = scan.nextLine();
System.out.print("orig. message: > ");
Expand All @@ -84,6 +98,22 @@ private void verifyMessageSignature(String msg) {
String signatureS = scan.nextLine();

System.out.printf("key: `%s`\nmessage: `%s`; signature: `%s`%n", keyS, origMsgS, signatureS);

byte[] pubBs = SignThis.notEz(keyS);
byte[] sigBs = SignThis.notEz(signatureS);

X509EncodedKeySpec spec = new X509EncodedKeySpec(pubBs);
KeyFactory factory = KeyFactory.getInstance("EC");

PublicKey pub = factory.generatePublic(spec);

try {
boolean isValid = SignThis.isValidSignature(origMsgS.trim().getBytes(StandardCharsets.UTF_8), pub, sigBs);
if(isValid) System.out.println("signature is GOOD");
} catch (SignatureException e) {
System.out.println("INVALID signature");
return;
}
}

private void signMessage(String msg) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException,
Expand All @@ -97,16 +127,18 @@ private void signMessage(String msg) throws IOException, NoSuchAlgorithmExceptio

byte[] signature = SignThis.sign(msgBs, getPrivateKeyFromFile());

System.out.printf("signature: `%s`\nfor the message `%s`%n",
Base58.encode(SignThis.compress(signature)),
PublicKey pub = getPublicKeyFromFile();

System.out.printf("key: `%s`\nsignature: `%s`\nfor the message `%s`%n",
SignThis.ez(pub.getEncoded()),
SignThis.ez(signature),
msg.trim()
);
}

private PublicKey getPublicKeyFromFile() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
if(currentDocumentHash.isEmpty()) throw new IllegalArgumentException("no key document is set");

System.out.printf("your active key document is `%s`%n", currentDocumentHash);
Path p = Path.of(home.toString(), currentDocumentHash);
String doc = Files.readString(p);
JSONObject j = new JSONObject(doc);
Expand Down Expand Up @@ -153,6 +185,9 @@ private void help() {
System.out.println("sign : sign a message. `sign <any text here>`");

System.out.println("use : designate currently used key document. `use <# from `list`>`");

System.out.println("vsign : verify a signed message. user will be prompted for public key, original message, " +
"and signature. `vsign`.");
}

private void delete() throws IOException {
Expand All @@ -170,15 +205,11 @@ private void delete() throws IOException {
currentDocumentHash = StringUtils.EMPTY;
}

private void current() throws IOException {
private void current() {
if (currentDocumentHash.isEmpty()) {
System.out.println("no key document is active. try `use #` command.");
} else {
System.out.printf("your active key document is `%s`%n", currentDocumentHash);

Path p = Path.of(home.toString(), currentDocumentHash);
String keyDoc = Files.readString(p);
JSONObject doc = new JSONObject(keyDoc);
}
}

Expand Down Expand Up @@ -226,9 +257,6 @@ private void peek(String msg) throws IOException {

/**
* sets the user's active key document
* @param msg
* @throws IOException
* @throws ArrayIndexOutOfBoundsException
*/
private void useKey(String msg) throws IOException, ArrayIndexOutOfBoundsException {
String[] arr = StringUtils.split(msg, StringUtils.SPACE);
Expand Down Expand Up @@ -281,7 +309,6 @@ private void sayGoodbye() {

/**
* prints a list of all key documents
* @throws IOException
*/
private void list() throws IOException {
try {
Expand Down
27 changes: 22 additions & 5 deletions src/main/java/org/white5moke/handoff/client/SignThis.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

import io.leonard.Base58;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.GZIPOutputStream;
import java.util.zip.Inflater;

public class SignThis {
public static byte[] sign(byte[] msg, PrivateKey privKey) throws NoSuchAlgorithmException,
Expand All @@ -27,11 +28,27 @@ public static boolean isValidSignature(byte[] origMsg, PublicKey pubKey, byte[]
return verity.verify(signedMsg);
}

public static byte[] compress(byte[] signature) throws IOException {
public static byte[] compress(byte[] stuff) throws IOException {
Deflater comp = new Deflater();
comp.setLevel(Deflater.BEST_COMPRESSION);
comp.deflate(signature);
comp.deflate(stuff);

return signature;
return stuff;
}

public static byte[] decompress(byte[] stuff) throws DataFormatException {
Inflater decomp = new Inflater();
byte[] ns = stuff;
decomp.inflate(ns);

return ns;
}

public static String ez(byte[] stuff) throws IOException {
return Base58.encode(compress(stuff));
}

public static byte[] notEz(String stuff) throws DataFormatException {
return decompress(Base58.decode(stuff));
}
}

0 comments on commit 2d5024c

Please sign in to comment.