Browse Source

speedtest: adhoc Makefile

pull/2/head
heck 5 years ago
parent
commit
d88e3befcf
  1. 38
      test/java/foundation/pEp/jniadapter/test/speedtest/Makefile
  2. 480
      test/java/foundation/pEp/jniadapter/test/speedtest/MtMsgCodec.java

38
test/java/foundation/pEp/jniadapter/test/speedtest/Makefile

@ -0,0 +1,38 @@
include ../../../../../../../Makefile.conf
include ../Makefile.conf
TEST_UNIT_NAME=speedtest
JAVA_CLASSES = \
MT999.class \
MTConstants.class \
MTMsgCodec.class \
SpeedTest.class \
SWIFTMsg.class
.PHONY: pitytest compile alice test clean
all: alice compile
pitytest:
$(MAKE) -C $(PITYTEST_DIR)
alice: compile clean-pep-home-alice
cd $(JAVA_CWD);pwd;HOME=$(JAVA_PEP_HOME_DIR_ALICE) $(JAVA) $(JAVA_PKG_BASENAME).$(TEST_UNIT_NAME).SpeedTest
compile: $(JAVA_CLASSES) pitytest
%.class: %.java
cd $(JAVA_CWD);javac -cp $(CLASSPATH) $(JAVA_PKG_BASEPATH)/$(TEST_UNIT_NAME)/$<
clean:
rm -f $(JAVA_CLASSES)
rm -f *.class
rm -f *.log
rm -Rf .gnupg
rm -Rf .lldb
clean-pep-home: clean-pep-home-alice
clean-pep-home-alice:
rm -rf $(PEP_HOME_DIR_ALICE)/.pEp

480
test/java/foundation/pEp/jniadapter/test/speedtest/MtMsgCodec.java

@ -1,480 +0,0 @@
package foundation.pEp.jniadapter.test.speedtest;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import foundation.pEp.jniadapter.Blob;
import foundation.pEp.jniadapter.Engine;
import foundation.pEp.jniadapter.Identity;
import foundation.pEp.jniadapter.Message;
import foundation.pEp.jniadapter.Pair;
/**
* MTMsgCodec is the Codec class for encoding/decoding pp for SWIFT messages.
*
* <p>
* See <a href=
* "https://www.sepaforcorporates.com/swift-for-corporates/read-swift-message-structure/"
* target="_blank">SWIFT message structure</a>, <a href=
* "https://www.ibm.com/support/knowledgecenter/SSRH32_3.0.0_SWS/mt_msg_format.html"
* target="_blank">MT message format</a>, <a href=
* "http://www.iotafinance.com/en/SWIFT-ISO15022-Message-type-MT999.html" target
* ="_blank">MT999</a>
* </p>
* <p>
* Copyright 2019, <a href="https://pep.security" target="_blank">pp
* Security</a>.
* </p>
*
* @author Volker Birk
* @version %I% %G%
*/
// FIXME: rework to stringbuffer
public class MTMsgCodec {
public Engine pEp;
/**
* Constructs a MessageCodec using pp engine.
*
* @param pEp_engine pp engine to use
*/
public MTMsgCodec(Engine pEp_engine) {
pEp = pEp_engine;
}
private final static String magicKeys = "pEpKeys";
private final static String magicEnc = "pEpMessage";
private final static String pgp_regex = "(?ms)" + "-----BEGIN PGP (?<type>.*?)-----\n" + "(\\w:.*?$\n)*" + "\n"
+ "(?<block>.*?)" + "-----END PGP (.*?)-----.*";
private static final Pattern pgp_pattern = Pattern.compile(pgp_regex);
private static final String pgptypeMessage = "MESSAGE";
private static final String pgptypePubkey = "PUBLIC KEY BLOCK";
// FIXME: private final static String uri_regex = "payto://swift/(?<bic>\\w+)";
private final static String uri_regex = "(?<bic>\\w+)@BIC";
private final static Pattern uri_pattern = Pattern.compile(uri_regex);
/**
* Strips PGP header and footer from encryption or key data.
*
* @param pgp_text text to work on
* @throws ParseException if text is not valid PGP data
* @return <code>pgp_text</code> without PGP header
*/
protected static String stripFromPGP(String pgp_text) throws ParseException {
Matcher m = pgp_pattern.matcher(pgp_text);
if (!m.matches())
throw new ParseException("not a PGP block", 0);
return m.group("block");
}
/**
* Adds PGP header and footer.
*
* @param payload text to decorate
* @param pgp_type PGP data type
* @return <code>payload</code> with added header and footer
*/
protected static String addPGPHeader(String payload, String pgp_type) {
// FIXME: rework to stringbuffer
return "-----BEGIN PGP " + pgp_type + "-----\n\n" + payload + "\n-----END PGP " + pgp_type + "-----\n";
}
/**
* Decodes a BIC from an URI.
*
* @param uri the URI to decode from
* @throws ParseException if URI has not the correct form
* @return decoded BIC
*/
public static String decodeBIC(String uri) throws ParseException {
Matcher m = uri_pattern.matcher(uri);
if (!m.matches())
throw new ParseException("not a valid URI", 0);
return m.group("bic");
}
/**
* Encodes a BIC into an URI.
*
* @param bic BIC to encode
* @return encoded URI
*/
public static String encodeBIC(String bic) {
// return "payto://swift/" + bic
return bic + "@BIC";
}
/**
* Generates a list of transporting MT999 messages for a payload.
*
* @param from source address
* @param to destination address
* @param ii message direction
* @param trn message id
* @param payload payload to split
* @param magic magic string to mark as pp message
*
* @return array of String with MT999 messages
*/
protected String[] transportMT999(String from, String to, String ii, String trn, String rr, String payload,
String magic) {
Vector<String> result = new Vector<String>();
payload = payload.trim();
int j = 1, f = 0, t = 0;
for (int i = payload.indexOf("\n"); i != -1; i = payload.indexOf("\n", i + 1), j++) {
if (j % 34 == 0) {
t = i + 1;
String cont = t < payload.length() - 1 ? "." : "";
MT999 mt999 = new MT999(from, to, ii, trn, rr, magic + "\n" + payload.substring(f, t) + cont);
result.add(mt999.toString());
f = i + 1;
}
}
if (t < payload.length() - 1) {
int z = payload.charAt(payload.length() - 1) == '\n' ? 1 : 0;
MT999 mt999 = new MT999(from, to, ii, "23", // fixed trn
"", magic + "\n" + payload.substring(t, payload.length() - z));
result.add(mt999.toString());
}
return result.toArray(new String[result.size()]);
}
/**
* encodes a pp Message to a String with a serialized pp for SWIFT message.
*
* @param msg pp Message to encode if from or to are not set they're taken
* by parsing the header of <code>longmsg</code>; in this case
* message direction is being taken from there, too
* @param config properties with configuration
* @return String with encoded pp for SWIFT message
* @throws UnsupportedOperationException if <code>EncFormat</code> is other than
* <code>None</code>, <code>Inline</code>
* or <code>PEP</code>
*/
public String encode(Message msg, Properties config) {
if (msg.getLongmsg() == null || msg.getLongmsg().length() < 1)
throw new IllegalArgumentException("longmsg must contain the message");
String result = "";
String msgid = msg.getId() != null && msg.getId().length() > 0 ? msg.getId() : "23";
String dir = msg.getDir() == Message.Direction.Incoming ? "I" : "O";
if (msgid.length() > 12) {
if (msgid.substring(0, 3).compareTo("pEp.") == 0 && msgid.length() >= 15)
msgid = msgid.substring(4, 15);
else
msgid = msgid.substring(0, 11);
}
String from = msg.getFrom() != null && msg.getFrom().address.length() > 0 ? msg.getFrom().address : null;
String to = msg.getTo() != null && msg.getTo().size() > 0 && msg.getTo().elementAt(0).address.length() > 0
? msg.getTo().elementAt(0).address
: null;
if (from != null) {
try {
from = decodeBIC(from);
if (from.length() != 12)
throw new IllegalArgumentException("from address must be URI with BIC12");
} catch (ParseException ex) {
throw new IllegalArgumentException("from address must be URI with BIC12");
}
}
if (to != null) {
try {
to = decodeBIC(to);
if (to.length() != 12)
throw new IllegalArgumentException("to address must be URI with BIC12");
} catch (ParseException ex) {
throw new IllegalArgumentException("to address must be URI with BIC12");
}
}
switch (msg.getEncFormat()) {
case None:
result = msg.getLongmsg(); // we send the message unmodified
if (result.substring(0, 3).compareTo("{1:") == 0) {
// probably SWIFT MTFIN
if (from == null || to == null || msgid == null) {
// parse SWIFT header
SWIFTMsg mh = new SWIFTMsg();
try {
mh.parseHeader(result);
} catch (ParseException ex) {
throw new UnsupportedOperationException("unsupported message format");
}
if (from == null)
from = mh.logicalTerminalAddress;
if (to == null)
to = mh.destinationAddress;
dir = mh.inputIdentifier;
}
} else if (result.substring(0, 1).compareTo("<") == 0) {
// probably XML
// FIXME: let's do the job for MTXML, too
return result;
} else { // we don't know this format, so let it be
return result;
}
if(msg.getAttachments() != null)
for (int i = 0; i < msg.getAttachments().size(); ++i) { // FIXME: can attachments become null?
Blob attach = msg.getAttachments().elementAt(i);
String magic;
if (attach.mime_type.compareToIgnoreCase("application/pgp-keys") == 0)
magic = magicKeys;
else
break; // don't know this MIME type
// we send an MT999 with the keys
String payload;
try {
payload = stripFromPGP(new String(attach.data, StandardCharsets.UTF_8));
} catch (ParseException ex) {
// cannot parse this
break;
}
String[] msgs = transportMT999(from, to, dir, msgid, "", payload, magic);
for (int j = 0; j < msgs.length; ++j) {
if (j > 0)
result += "\n";
result += msgs[j].toString();
}
}
break;
case PEP:
case PGPMIME:
case Inline:
if (from == null || to == null)
throw new IllegalArgumentException("from and to must be set to URIs with BIC12");
String pgp_txt;
Vector<Blob> attachments = null;
if (msg.getEncFormat() == Message.EncFormat.PEP || msg.getEncFormat() == Message.EncFormat.PGPMIME) {
if (msg.getAttachments() == null || msg.getAttachments().size() != 2)
throw new IllegalArgumentException("no valid message format");
Blob attach = msg.getAttachments().elementAt(1);
pgp_txt = new String(attach.data, StandardCharsets.UTF_8);
} else /* Inline */ {
pgp_txt = msg.getLongmsg();
}
String payload;
try {
payload = stripFromPGP(pgp_txt);
} catch (ParseException ex) {
// cannot parse this
throw new IllegalArgumentException("illegal encryption text");
}
String[] msgs = transportMT999(from, to, dir, msgid, "", payload, magicEnc);
for (int j = 0; j < msgs.length; ++j) {
if (j > 0)
result += "\n";
result += msgs[j].toString();
}
if (msg.getEncFormat() == Message.EncFormat.Inline) {
String[] attached_key = null;
attachments = msg.getAttachments();
for (int i = 0; attachments != null && i < attachments.size(); ++i) {
Blob attach = attachments.elementAt(i);
if (attach.mime_type.compareTo("application/pgp-keys") == 0) {
// we send an MT999 with the keys
try {
payload = stripFromPGP(new String(attach.data, StandardCharsets.UTF_8));
} catch (ParseException ex) {
// cannot parse this
break;
}
msgs = transportMT999(from, to, dir, msgid, "", payload, magicKeys);
for (int j = 0; j < msgs.length; ++j) {
if (j > 0)
result += "\n";
result += msgs[j].toString();
}
} else {
throw new UnsupportedOperationException(
"only application/pgp-keys is supported with Inline but got " + attach.mime_type);
}
}
}
break;
default:
throw new UnsupportedOperationException("unsupported encryption format");
}
return result;
}
/**
* Creates pp message from MTFIN or MTXML using SWIFT header info
*
* @param header MTFIN header structure
* @param txt MTFIN message text
* @return pp message
*/
protected Message pEpMessageFromSWIFTMessage(SWIFTMsg header, String txt) {
Message m = new Message();
Identity from = new Identity();
from.address = encodeBIC(header.logicalTerminalAddress);
m.setFrom(from);
Identity to = new Identity();
to.address = encodeBIC(header.destinationAddress);
Vector<Identity> _to = new Vector<Identity>();
_to.add(to);
m.setTo(_to);
m.setDir(header.inputIdentifier.compareTo("I") == 0 ? Message.Direction.Incoming : Message.Direction.Outgoing);
m.setLongmsg(txt);
ArrayList<Pair<String, String>> al = new ArrayList<Pair<String, String>>();
Pair<String, String> field = new Pair<String, String>("X-pEp-Version", pEp.getProtocolVersion());
al.add(field);
m.setOptFields(al);
return m;
}
/**
* decodes pp Messages from a String with serialized pp for SWIFT messages.
*
* @param txt String to decode from
* @throws ParseException if the String does not contain SWIFT messages only
* @return array with pp Messages
*
*/
public Message[] decode(String txt) throws ParseException {
Vector<Message> result = new Vector<Message>();
if (txt.substring(0, 3).compareTo("{1:") == 0) {
// probably SWIFT MTFIN
int f = 0;
int t = txt.indexOf("{1:", 3);
if (t == -1)
t = txt.length();
String key_payload = "";
String enc_payload = "";
while (f < txt.length()) {
String _txt = txt.substring(f, t);
f = t;
t = txt.indexOf("{1:", f + 3);
if (t == -1)
t = txt.length();
Message last = null;
SWIFTMsg m = new SWIFTMsg();
m.parseHeader(_txt);
boolean done = false;
if (m.messageType.compareTo("999") == 0) {
MT999 _m = new MT999(_txt);
String narrative = _m.narrative.trim();
if (narrative.substring(0, magicKeys.length()).compareTo(magicKeys) == 0) {
key_payload += narrative.substring(magicKeys.length()).trim();
if (key_payload.substring(key_payload.length()).compareTo(".") == 0) {
key_payload = key_payload.substring(0, key_payload.length() - 2);
} else {
// p≡p keys
String keydata = addPGPHeader(key_payload, pgptypePubkey);
key_payload = "";
if (last == null)
last = pEpMessageFromSWIFTMessage(m, "p≡p keys");
Vector<Blob> a = new Vector<Blob>();
Blob b = new Blob();
b.data = keydata.getBytes(StandardCharsets.UTF_8);
b.mime_type = "application/pgp-keys";
b.filename = "pEpKeys.asc";
a.add(b);
last.setAttachments(a);
result.add(last);
last = null;
}
done = true;
} else if (narrative.substring(0, magicEnc.length()).compareTo(magicEnc) == 0) {
// p≡p encrypted data
enc_payload += narrative.substring(magicEnc.length()).trim();
if (enc_payload.substring(enc_payload.length()).compareTo(".") == 0) {
enc_payload = enc_payload.substring(0, enc_payload.length() - 2);
} else {
// p≡p encryption
String encdata = addPGPHeader(enc_payload, pgptypeMessage);
Message r = pEpMessageFromSWIFTMessage(m, encdata);
r.setEncFormat(Message.EncFormat.Inline);
result.add(r);
}
done = true;
}
}
if (!done) {
last = pEpMessageFromSWIFTMessage(m, _txt);
result.add(last);
}
}
} else if (txt.substring(0, 1).compareTo("<") == 0) {
// probably XML
// FIXME: let's do the job for MTXML, too
throw new UnsupportedOperationException("XML not yet implemented");
} else { // we don't know this format
throw new ParseException("not a valid SWIFT message", 0);
}
Message[] _result = new Message[result.size()];
return result.toArray(_result);
}
}
Loading…
Cancel
Save