diff --git a/test/java/foundation/pEp/jniadapter/test/speedtest/MTMsgCodec.java b/test/java/foundation/pEp/jniadapter/test/speedtest/MTMsgCodec.java new file mode 100644 index 0000000..f1b96d3 --- /dev/null +++ b/test/java/foundation/pEp/jniadapter/test/speedtest/MTMsgCodec.java @@ -0,0 +1,480 @@ +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 p≡p for SWIFT messages. + * + *
+ * See SWIFT message structure, MT message format, MT999 + *
+ *+ * Copyright 2019, p≡p + * Security. + *
+ * + * @author Volker Birk + * @version %I% %G% + */ + +// FIXME: rework to stringbuffer + +public class MTMsgCodec { + public Engine pEp; + + /** + * Constructs a MessageCodec using p≡p engine. + * + * @param pEp_engine p≡p 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 (?pgp_text
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 payload
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 p≡p 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) {
+
+ Vectorlongmsg
; in this case
+ * message direction is being taken from there, too
+ * @param config properties with configuration
+ * @return String with encoded p≡p for SWIFT message
+ * @throws UnsupportedOperationException if EncFormat
is other than
+ * None
, Inline
+ * or PEP
+ */
+
+ 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