Browse Source

Improve elements and providers and create tests

ox_provider_elements
Paul Schaub 2 years ago
parent
commit
c909f15f23
No known key found for this signature in database GPG Key ID: 62BEE9264BF17311
27 changed files with 1126 additions and 44 deletions
  1. +1
    -0
      settings.gradle
  2. +27
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpInitializer.java
  3. +40
    -2
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpManager.java
  4. +1
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpMessage.java
  5. +1
    -1
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpProvider.java
  6. +17
    -5
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/CryptElement.java
  7. +23
    -2
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/EncryptedOpenPgpContentElement.java
  8. +21
    -9
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/OpenPgpContentElement.java
  9. +9
    -6
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/OpenPgpElement.java
  10. +97
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PubkeyElement.java
  11. +147
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java
  12. +57
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/SecretkeyElement.java
  13. +10
    -5
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/SignElement.java
  14. +14
    -5
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/SigncryptElement.java
  15. +5
    -1
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/CryptElementProvider.java
  16. +84
    -7
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/OpenPgpContentElementProvider.java
  17. +3
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/OpenPgpElementProvider.java
  18. +53
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/PubkeyElementProvider.java
  19. +65
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/PublicKeysListElementProvider.java
  20. +35
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/SecretkeyElementProvider.java
  21. +2
    -0
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/SignElementProvider.java
  22. +4
    -1
      smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/SigncryptElementProvider.java
  23. +28
    -0
      smack-openpgp/src/main/resources/org.jivesoftware.smackx.ox/openpgp.providers
  24. +178
    -0
      smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpElementTest.java
  25. +59
    -0
      smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PubkeyElementTest.java
  26. +93
    -0
      smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PublicKeysListElementTest.java
  27. +52
    -0
      smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/SecretkeyElementTest.java

+ 1
- 0
settings.gradle View File

@@ -29,3 +29,4 @@ include 'smack-core',
'smack-repl',
'smack-openpgp',
'smack-openpgp-bouncycastle'


+ 27
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpInitializer.java View File

@@ -0,0 +1,27 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox;

import org.jivesoftware.smack.initializer.UrlInitializer;

public class OpenPgpInitializer extends UrlInitializer {

@Override
protected String getProvidersUri() {
return "classpath:org.jivesoftware.smackx.ox/openpgp.providers";
}
}

+ 40
- 2
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpManager.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,48 @@
package org.jivesoftware.smackx.ox;

import java.io.InputStream;
import java.util.Map;
import java.util.WeakHashMap;

public class OpenPgpManager {
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.XMPPConnection;

import org.jxmpp.jid.BareJid;

public final class OpenPgpManager extends Manager {

public static final String PEP_NODE_PUBLIC_KEYS = "urn:xmpp:openpgp:0:public-keys";

public static String PEP_NODE_PUBLIC_KEY(String id) {
return PEP_NODE_PUBLIC_KEYS + ":" + id;
}

private static final Map<XMPPConnection, OpenPgpManager> INSTANCES = new WeakHashMap<>();

private OpenPgpManager(XMPPConnection connection) {
super(connection);
}

public static OpenPgpManager getInstanceFor(XMPPConnection connection) {
OpenPgpManager manager = INSTANCES.get(connection);
if (manager == null) {
manager = new OpenPgpManager(connection);
INSTANCES.put(connection, manager);
}
return manager;
}

public static String bareJidToIdentity(BareJid jid) {
return "xmpp:" + jid.toString();
}

public static OpenPgpMessage toOpenPgpMessage(InputStream is) {
return null;
}

public void publishPublicKey() {
// Check if key available at data node
// If not, publish key to data node
// Publish ID to metadata node
}
}

+ 1
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpMessage.java View File

@@ -23,6 +23,7 @@ import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
import org.jivesoftware.smackx.ox.element.SignElement;
import org.jivesoftware.smackx.ox.element.SigncryptElement;
import org.jivesoftware.smackx.ox.provider.OpenPgpContentElementProvider;

import org.xmlpull.v1.XmlPullParserException;

public class OpenPgpMessage {


+ 1
- 1
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/OpenPgpProvider.java View File

@@ -20,6 +20,6 @@ import java.io.InputStream;

public interface OpenPgpProvider {

public OpenPgpMessage toOpenPgpMessage(InputStream is);
OpenPgpMessage toOpenPgpMessage(InputStream is);

}

+ 17
- 5
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/CryptElement.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,27 +18,39 @@ package org.jivesoftware.smackx.ox.element;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;

import org.jxmpp.jid.Jid;

/**
* This class describes an OpenPGP content element which is encrypted, but not signed.
*/
public class CryptElement extends EncryptedOpenPgpContentElement {

public static final String ELEMENT = "crypt";

public CryptElement(List<Jid> to, String rpad, Date timestamp, List<ExtensionElement> payload) {
public CryptElement(Set<Jid> to, String rpad, Date timestamp, List<ExtensionElement> payload) {
super(to, rpad, timestamp, payload);
}

public CryptElement(Set<Jid> to, List<ExtensionElement> payload) {
super(to, payload);
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public CharSequence toXML() {
// TODO Auto-generated method stub
return null;
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this).rightAngleBracket();
addCommonXml(xml);
xml.closeElement(this);
return xml;
}

}

+ 23
- 2
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/EncryptedOpenPgpContentElement.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,22 +16,43 @@
*/
package org.jivesoftware.smackx.ox.element;

import java.security.SecureRandom;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;

import org.jxmpp.jid.Jid;

public abstract class EncryptedOpenPgpContentElement extends OpenPgpContentElement {

public static final String ELEM_RPAD = "rpad";

private final String rpad;

protected EncryptedOpenPgpContentElement(List<Jid> to, String rpad, Date timestamp, List<ExtensionElement> payload) {
protected EncryptedOpenPgpContentElement(Set<Jid> to, String rpad, Date timestamp, List<ExtensionElement> payload) {
super(to, timestamp, payload);
this.rpad = rpad;
}

protected EncryptedOpenPgpContentElement(Set<Jid> to, List<ExtensionElement> payload) {
super(to, new Date(), payload);
this.rpad = createRandomPadding();
}

public String getRandomPadding() {
return rpad;
}

private static String createRandomPadding() {
SecureRandom secRan = new SecureRandom();
int len = secRan.nextInt(256); // TODO: Find suitable value.
return StringUtils.randomString(len);
}

@Override
protected void addCommonXml(XmlStringBuilder xml) {
super.addCommonXml(xml);


+ 21
- 9
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/OpenPgpContentElement.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,27 +18,39 @@ package org.jivesoftware.smackx.ox.element;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;

import org.jxmpp.jid.Jid;
import org.jxmpp.util.XmppDateTime;

/**
* This class describes an OpenPGP content element. It defines the elements and fields that OpenPGP content elements
* do have in common.
*/
public abstract class OpenPgpContentElement implements ExtensionElement {

private final List<Jid> to;
public static final String ELEM_TO = "to";
public static final String ATTR_JID = "jid";
public static final String ELEM_TIME = "time";
public static final String ATTR_STAMP = "stamp";
public static final String ELEM_PAYLOAD = "payload";

private final Set<Jid> to;
private final Date timestamp;
private final List<ExtensionElement> payload;

private String timestampString;

protected OpenPgpContentElement(List<Jid> to, Date timestamp, List<ExtensionElement> payload) {
protected OpenPgpContentElement(Set<Jid> to, Date timestamp, List<ExtensionElement> payload) {
this.to = to;
this.timestamp = timestamp;
this.payload = payload;
}

public final List<Jid> getTo() {
public final Set<Jid> getTo() {
return to;
}

@@ -63,16 +75,16 @@ public abstract class OpenPgpContentElement implements ExtensionElement {

protected void addCommonXml(XmlStringBuilder xml) {
for (Jid toJid : to) {
xml.halfOpenElement("to").attribute("jid", toJid).closeEmptyElement();
xml.halfOpenElement(ELEM_TO).attribute(ATTR_JID, toJid).closeEmptyElement();
}

ensureTimestampStringSet();
xml.halfOpenElement("time").attribute("stamp", timestampString).closeEmptyElement();
xml.halfOpenElement(ELEM_TIME).attribute(ATTR_STAMP, timestampString).closeEmptyElement();

xml.openElement("payload");
xml.openElement(ELEM_PAYLOAD);
for (ExtensionElement element : payload) {
xml.append(element.toXML());
xml.append(element.toXML(getNamespace()));
}
xml.closeElement("payload");
xml.closeElement(ELEM_PAYLOAD);
}
}

+ 9
- 6
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/OpenPgpElement.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,15 +21,17 @@ import java.io.IOException;
import java.io.InputStream;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smack.util.stringencoder.Base64;
import org.jivesoftware.smackx.ox.OpenPgpManager;
import org.jivesoftware.smackx.ox.OpenPgpMessage;

import org.xmlpull.v1.XmlPullParserException;

public class OpenPgpElement implements ExtensionElement {

public static final String ELEMENT = "openpgp";
public static final String NAMESPACE = "urn:xmpp:openpg:0";
public static final String NAMESPACE = "urn:xmpp:openpgp:0";

private final String base64EncodedOpenPgpMessage;

@@ -72,12 +74,13 @@ public class OpenPgpElement implements ExtensionElement {
}

@Override
public CharSequence toXML() {
// TODO Auto-generated method stub
return null;
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.rightAngleBracket().append(base64EncodedOpenPgpMessage).closeElement(this);
return xml;
}

private final void ensureOpenPgpMessageBytesSet() {
private void ensureOpenPgpMessageBytesSet() {
if (openPgpMessageBytes != null) return;

openPgpMessageBytes = Base64.decode(base64EncodedOpenPgpMessage);


+ 97
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PubkeyElement.java View File

@@ -0,0 +1,97 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.element;

import java.nio.charset.Charset;
import java.util.Date;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.XmlStringBuilder;

public class PubkeyElement implements ExtensionElement {

public static final String NAMESPACE = OpenPgpElement.NAMESPACE;
public static final String ELEMENT = "pubkey";
public static final String ATTR_DATE = "date";

private final PubkeyDataElement dataElement;
private final Date date;

public PubkeyElement(PubkeyDataElement dataElement, Date date) {
this.dataElement = Objects.requireNonNull(dataElement);
this.date = date;
}

public PubkeyDataElement getDataElement() {
return dataElement;
}

public Date getDate() {
return date;
}

@Override
public String getNamespace() {
return NAMESPACE;
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this)
.optAttribute(ATTR_DATE, date)
.rightAngleBracket()
.element(getDataElement())
.closeElement(this);
return xml;
}

public static class PubkeyDataElement implements NamedElement {

public static final String ELEMENT = "data";

private final byte[] b64Data;

public PubkeyDataElement(byte[] b64Data) {
this.b64Data = b64Data;
}

public byte[] getB64Data() {
return b64Data;
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this)
.rightAngleBracket()
.append(new String(b64Data, Charset.forName("UTF-8")))
.closeElement(this);
return xml;
}
}
}

+ 147
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/PublicKeysListElement.java View File

@@ -0,0 +1,147 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.element;

import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.XmlStringBuilder;

public final class PublicKeysListElement implements ExtensionElement {

public static final String NAMESPACE = OpenPgpElement.NAMESPACE;
public static final String ELEMENT = "public-keys-list";

private final Map<String, PubkeyMetadataElement> metadata;

private PublicKeysListElement(TreeMap<String, PubkeyMetadataElement> metadata) {
this.metadata = Collections.unmodifiableMap(metadata);
}

public static Builder builder() {
return new Builder();
}

public TreeMap<String, PubkeyMetadataElement> getMetadata() {
return new TreeMap<>(metadata);
}

@Override
public String getNamespace() {
return NAMESPACE;
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this).rightAngleBracket();
for (PubkeyMetadataElement metadataElement : metadata.values()) {
xml.element(metadataElement);
}
xml.closeElement(this);
return xml;
}

public static final class Builder {

private final TreeMap<String, PubkeyMetadataElement> metadata = new TreeMap<>();

private Builder() {
// Empty
}

public Builder addMetadata(PubkeyMetadataElement key) {
metadata.put(key.getV4Fingerprint(), key);
return this;
}

public PublicKeysListElement build() {
return new PublicKeysListElement(metadata);
}
}

public static class PubkeyMetadataElement implements NamedElement {

public static final String ELEMENT = "pubkey-metadata";
public static final String ATTR_V4_FINGERPRINT = "v4-fingerprint";
public static final String ATTR_DATE = "date";

private final String v4_fingerprint;
private final Date date;

public PubkeyMetadataElement(String v4_fingerprint, Date date) {
this.v4_fingerprint = Objects.requireNonNull(v4_fingerprint);
this.date = Objects.requireNonNull(date);

if (v4_fingerprint.length() != 40) {
throw new IllegalArgumentException("OpenPGP v4 fingerprint must be 40 characters long.");
}
}

public String getV4Fingerprint() {
return v4_fingerprint;
}

public Date getDate() {
return date;
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this)
.attribute(ATTR_V4_FINGERPRINT, getV4Fingerprint())
.attribute(ATTR_DATE, date).closeEmptyElement();
return xml;
}

@Override
public int hashCode() {
return getV4Fingerprint().hashCode() + 3 * getDate().hashCode();
}

@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}

if (!(o instanceof PubkeyMetadataElement)) {
return false;
}

if (o == this) {
return true;
}

return hashCode() == o.hashCode();
}
}
}

+ 57
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/SecretkeyElement.java View File

@@ -0,0 +1,57 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.element;

import java.nio.charset.Charset;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;

public class SecretkeyElement implements ExtensionElement {

public static final String NAMESPACE = OpenPgpElement.NAMESPACE;
public static final String ELEMENT = "secretkey";

private final byte[] b64Data;

public SecretkeyElement(byte[] b64Data) {
this.b64Data = b64Data;
}

public byte[] getB64Data() {
return b64Data;
}

@Override
public String getNamespace() {
return NAMESPACE;
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this)
.rightAngleBracket()
.append(new String(b64Data, Charset.forName("UTF-8")))
.closeElement(this);
return xml;
}
}

+ 10
- 5
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/SignElement.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,13 +18,16 @@ package org.jivesoftware.smackx.ox.element;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;

import org.jxmpp.jid.Jid;

public class SignElement extends OpenPgpContentElement {

public SignElement(List<Jid> to, Date timestamp, List<ExtensionElement> payload) {
public SignElement(Set<Jid> to, Date timestamp, List<ExtensionElement> payload) {
super(to, timestamp, payload);
}

@@ -36,9 +39,11 @@ public class SignElement extends OpenPgpContentElement {
}

@Override
public CharSequence toXML() {
// TODO Auto-generated method stub
return null;
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this).rightAngleBracket();
addCommonXml(xml);
xml.closeElement(this);
return xml;
}

}

+ 14
- 5
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/element/SigncryptElement.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,27 +18,36 @@ package org.jivesoftware.smackx.ox.element;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;

import org.jxmpp.jid.Jid;

public class SigncryptElement extends EncryptedOpenPgpContentElement {

public static final String ELEMENT = "signcrypt";

public SigncryptElement(List<Jid> to, String rpad, Date timestamp, List<ExtensionElement> payload) {
public SigncryptElement(Set<Jid> to, String rpad, Date timestamp, List<ExtensionElement> payload) {
super(to, rpad, timestamp, payload);
}

public SigncryptElement(Set<Jid> to, List<ExtensionElement> payload) {
super(to, payload);
}

@Override
public String getElementName() {
return ELEMENT;
}

@Override
public CharSequence toXML() {
// TODO Auto-generated method stub
return null;
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this).rightAngleBracket();
addCommonXml(xml);
xml.closeElement(this);
return xml;
}

}

+ 5
- 1
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/CryptElementProvider.java View File

@@ -17,12 +17,16 @@
package org.jivesoftware.smackx.ox.provider;

import org.jivesoftware.smackx.ox.element.CryptElement;

import org.xmlpull.v1.XmlPullParser;

public class CryptElementProvider extends OpenPgpContentElementProvider<CryptElement> {

public static final CryptElementProvider TEST_INSTANCE = new CryptElementProvider();

@Override
public CryptElement parse(XmlPullParser parser, int initialDepth) throws Exception {
public CryptElement parse(XmlPullParser parser, int initialDepth)
throws Exception {
OpenPgpContentElementData data = parseOpenPgpContentElementData(parser, initialDepth);

return new CryptElement(data.to, data.rpad, data.timestamp, data.payload);


+ 84
- 7
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/OpenPgpContentElementProvider.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,50 +16,127 @@
*/
package org.jivesoftware.smackx.ox.provider;

import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smackx.ox.element.CryptElement;
import org.jivesoftware.smackx.ox.element.EncryptedOpenPgpContentElement;
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
import org.jivesoftware.smackx.ox.element.SignElement;
import org.jivesoftware.smackx.ox.element.SigncryptElement;

import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.util.XmppDateTime;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

public abstract class OpenPgpContentElementProvider<O extends OpenPgpContentElement> extends ExtensionElementProvider<O> {

private static final Logger LOGGER = Logger.getLogger(OpenPgpContentElementProvider.class.getName());

public static OpenPgpContentElement parseOpenPgpContentElement(String element)
throws XmlPullParserException, IOException {
XmlPullParser parser = PacketParserUtils.getParserFor(element);
return parseOpenPgpContentElement(parser);
}

public static OpenPgpContentElement parseOpenPgpContentElement(XmlPullParser parser) {
public static OpenPgpContentElement parseOpenPgpContentElement(XmlPullParser parser)
throws IOException, XmlPullParserException {
// TODO
return null;
}

@Override
public abstract O parse(XmlPullParser parser, int initialDepth) throws Exception;

protected static OpenPgpContentElementData parseOpenPgpContentElementData(XmlPullParser parser, int initialDepth) {
List<Jid> to = new LinkedList<>();
protected static OpenPgpContentElementData parseOpenPgpContentElementData(XmlPullParser parser, int initialDepth)
throws Exception {
Set<Jid> to = new HashSet<>();
Date timestamp = null;
String rpad = null;
List<ExtensionElement> payload = new LinkedList<>();

outerloop: while (true) {
int tag = parser.next();
String name = parser.getName();
switch (tag) {
case START_TAG:
switch (name) {

case OpenPgpContentElement.ELEM_TIME:
String stamp = parser.getAttributeValue("", OpenPgpContentElement.ATTR_STAMP);
timestamp = XmppDateTime.parseDate(stamp);
break;

case OpenPgpContentElement.ELEM_TO:
String jid = parser.getAttributeValue("", OpenPgpContentElement.ATTR_JID);
to.add(JidCreate.bareFrom(jid));
break;

case EncryptedOpenPgpContentElement.ELEM_RPAD:
rpad = parser.nextText();
break;

case OpenPgpContentElement.ELEM_PAYLOAD:
innerloop: while (true) {
int ptag = parser.next();
String pname = parser.getName();
String pns = parser.getNamespace();
switch (ptag) {

case START_TAG:
ExtensionElementProvider<ExtensionElement> provider =
ProviderManager.getExtensionProvider(pname, pns);
if (provider == null) {
LOGGER.log(Level.INFO, "No provider found for " + pname + " " + pns);
continue innerloop;
}
payload.add(provider.parse(parser));
break;

case END_TAG:
break innerloop;
}
}
break;
}
break;

case END_TAG:
switch (name) {
case CryptElement.ELEMENT:
case SigncryptElement.ELEMENT:
case SignElement.ELEMENT:
break outerloop;
}
break;
}
}

return new OpenPgpContentElementData(to, timestamp, rpad, payload);
}

protected final static class OpenPgpContentElementData {
protected final List<Jid> to;
protected static final class OpenPgpContentElementData {
protected final Set<Jid> to;
protected final Date timestamp;
protected final String rpad;
protected final List<ExtensionElement> payload;

private OpenPgpContentElementData(List<Jid> to, Date timestamp, String rpad, List<ExtensionElement> payload) {
private OpenPgpContentElementData(Set<Jid> to, Date timestamp, String rpad, List<ExtensionElement> payload) {
this.to = to;
this.timestamp = timestamp;
this.rpad = rpad;


+ 3
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/OpenPgpElementProvider.java View File

@@ -18,10 +18,13 @@ package org.jivesoftware.smackx.ox.provider;

import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.ox.element.OpenPgpElement;

import org.xmlpull.v1.XmlPullParser;

public class OpenPgpElementProvider extends ExtensionElementProvider<OpenPgpElement> {

public static final OpenPgpElementProvider TEST_INSTANCE = new OpenPgpElementProvider();

@Override
public OpenPgpElement parse(XmlPullParser parser, int initialDepth) throws Exception {
String base64EncodedOpenPgpMessage = parser.nextText();


+ 53
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/PubkeyElementProvider.java View File

@@ -0,0 +1,53 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.provider;

import static org.xmlpull.v1.XmlPullParser.START_TAG;

import java.nio.charset.Charset;
import java.util.Date;

import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.ox.element.PubkeyElement;

import org.jxmpp.util.XmppDateTime;
import org.xmlpull.v1.XmlPullParser;

public class PubkeyElementProvider extends ExtensionElementProvider<PubkeyElement> {

public static final PubkeyElementProvider TEST_INSTANCE = new PubkeyElementProvider();

@Override
public PubkeyElement parse(XmlPullParser parser, int initialDepth) throws Exception {
String dateString = parser.getAttributeValue(null, PubkeyElement.ATTR_DATE);
Date date = dateString != null ? XmppDateTime.parseXEP0082Date(dateString) : null;
while (true) {
int tag = parser.next();
String name = parser.getName();
if (tag == START_TAG) {
switch (name) {
case PubkeyElement.PubkeyDataElement.ELEMENT:
String data = parser.nextText();
if (data != null) {
byte[] bytes = data.getBytes(Charset.forName("UTF-8"));
return new PubkeyElement(new PubkeyElement.PubkeyDataElement(bytes), date);
}
}
}
}
}
}

+ 65
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/PublicKeysListElementProvider.java View File

@@ -0,0 +1,65 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.provider;

import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;

import java.util.Date;

import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;

import org.jxmpp.util.XmppDateTime;
import org.xmlpull.v1.XmlPullParser;

public final class PublicKeysListElementProvider extends ExtensionElementProvider<PublicKeysListElement> {

public static final PublicKeysListElementProvider TEST_INSTANCE = new PublicKeysListElementProvider();

@Override
public PublicKeysListElement parse(XmlPullParser parser, int initialDepth) throws Exception {

PublicKeysListElement.Builder builder = PublicKeysListElement.builder();

while (true) {

int tag = parser.nextTag();
String name = parser.getName();

switch (tag) {
case START_TAG:

if (PublicKeysListElement.PubkeyMetadataElement.ELEMENT.equals(name)) {
String finger = parser.getAttributeValue(null,
PublicKeysListElement.PubkeyMetadataElement.ATTR_V4_FINGERPRINT);
String dt = parser.getAttributeValue(null,
PublicKeysListElement.PubkeyMetadataElement.ATTR_DATE);
Date date = XmppDateTime.parseXEP0082Date(dt);
builder.addMetadata(new PublicKeysListElement.PubkeyMetadataElement(finger, date));
}
break;

case END_TAG:

if (name.equals(PublicKeysListElement.ELEMENT)) {
return builder.build();
}
}
}
}
}

+ 35
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/SecretkeyElementProvider.java View File

@@ -0,0 +1,35 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.provider;

import java.nio.charset.Charset;

import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.ox.element.SecretkeyElement;

import org.xmlpull.v1.XmlPullParser;

public class SecretkeyElementProvider extends ExtensionElementProvider<SecretkeyElement> {

public static final SecretkeyElementProvider TEST_INSTANCE = new SecretkeyElementProvider();

@Override
public SecretkeyElement parse(XmlPullParser parser, int initialDepth) throws Exception {
String data = parser.nextText();
return new SecretkeyElement(data.getBytes(Charset.forName("UTF-8")));
}
}

+ 2
- 0
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/SignElementProvider.java View File

@@ -20,11 +20,13 @@ import java.util.logging.Logger;

import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.ox.element.SignElement;

import org.xmlpull.v1.XmlPullParser;

public class SignElementProvider extends OpenPgpContentElementProvider<SignElement> {

private static final Logger LOGGER = Logger.getLogger(SigncryptElementProvider.class.getName());
public static final SignElementProvider TEST_INSTANCE = new SignElementProvider();

@Override
public SignElement parse(XmlPullParser parser, int initialDepth) throws Exception {


+ 4
- 1
smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/provider/SigncryptElementProvider.java View File

@@ -1,6 +1,6 @@
/**
*
* Copyright 2017 Florian Schmaus.
* Copyright 2017 Florian Schmaus, 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,13 @@
package org.jivesoftware.smackx.ox.provider;

import org.jivesoftware.smackx.ox.element.SigncryptElement;

import org.xmlpull.v1.XmlPullParser;

public class SigncryptElementProvider extends OpenPgpContentElementProvider<SigncryptElement> {

public static final SigncryptElementProvider TEST_INSTANCE = new SigncryptElementProvider();

@Override
public SigncryptElement parse(XmlPullParser parser, int initialDepth) throws Exception {
OpenPgpContentElementData data = parseOpenPgpContentElementData(parser, initialDepth);


+ 28
- 0
smack-openpgp/src/main/resources/org.jivesoftware.smackx.ox/openpgp.providers View File

@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<!-- Providers for OpenPGP for XMPP -->
<smackProviders>

<!-- Stanza extensions -->
<extensionProvider>
<elementName>openpgp</elementName>
<namespace>urn:xmpp:openpgp:0</namespace>
<className>org.jivesoftware.smackx.ox.provider.OpenPgpElementProvider</className>
</extensionProvider>

<!-- PubSub extensions -->
<extensionProvider>
<elementName>pubkey</elementName>
<namespace>urn:xmpp:openpgp:0</namespace>
<className>org.jivesoftware.smackx.ox.provider.PubkeyElementProvider</className>
</extensionProvider>
<extensionProvider>
<elementName>secretkey</elementName>
<namespace>urn:xmpp:openpgp:0</namespace>
<className>org.jivesoftware.smackx.ox.provider.SecretkeyElementProvider</className>
</extensionProvider>
<extensionProvider>
<elementName>public-keys-list</elementName>
<namespace>urn:xmpp:openpgp:0</namespace>
<className>org.jivesoftware.smackx.ox.provider.PublicKeysListElementProvider</className>
</extensionProvider>
</smackProviders>

+ 178
- 0
smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/OpenPgpElementTest.java View File

@@ -0,0 +1,178 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smackx.ox.element.CryptElement;
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
import org.jivesoftware.smackx.ox.element.SignElement;
import org.jivesoftware.smackx.ox.element.SigncryptElement;
import org.jivesoftware.smackx.ox.provider.CryptElementProvider;
import org.jivesoftware.smackx.ox.provider.OpenPgpElementProvider;
import org.jivesoftware.smackx.ox.provider.SignElementProvider;
import org.jivesoftware.smackx.ox.provider.SigncryptElementProvider;

import org.junit.Test;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
import org.xmlpull.v1.XmlPullParser;

public class OpenPgpElementTest extends SmackTestSuite {

private final Set<Jid> recipients;

// 2014-07-10T15:06:00.000+00:00
private static final Date testDate = new Date(1405004760000L);

public OpenPgpElementTest() throws XmppStringprepException {
super();
Set<Jid> jids = new HashSet<>();
jids.add(JidCreate.bareFrom("alice@wonderland.lit"));
jids.add(JidCreate.bareFrom("bob@builder.lit"));
this.recipients = Collections.unmodifiableSet(jids);
}

@Test
public void providerTest() throws Exception {
String expected =
"<openpgp xmlns='urn:xmpp:openpgp:0'>" +
"BASE64_OPENPGP_MESSAGE" +
"</openpgp>";

OpenPgpElement element = new OpenPgpElement("BASE64_OPENPGP_MESSAGE");

assertXMLEqual(expected, element.toXML(null).toString());

XmlPullParser parser = TestUtils.getParser(expected);
OpenPgpElement parsed = OpenPgpElementProvider.TEST_INSTANCE.parse(parser);
}

@Test
public void simplifiedConstructorTest() {
ArrayList<ExtensionElement> payload = new ArrayList<>();
payload.add(new Message.Body("de", "Hallo Welt!"));
CryptElement element = new CryptElement(recipients, payload);

assertNotNull(element.getRandomPadding());
assertNotNull(element.getTimestamp());
}

@Test
public void signElementProviderTest() throws Exception {
String expected =
"<sign xmlns='urn:xmpp:openpgp:0'>" +
"<to jid='alice@wonderland.lit'/>" +
"<to jid='bob@builder.lit'/>" +
"<time stamp='2014-07-10T15:06:00.000+00:00'/>" +
"<payload>" +
"<body xmlns='jabber:client' xml:lang='en'>Hello World!</body>" +
"</payload>" +
"</sign>";

List<ExtensionElement> payload = new ArrayList<>();
payload.add(new Message.Body("en", "Hello World!"));
SignElement element = new SignElement(recipients, testDate, payload);

assertXMLEqual(expected, element.toXML(null).toString());

XmlPullParser parser = TestUtils.getParser(expected);
SignElement parsed = SignElementProvider.TEST_INSTANCE.parse(parser);

assertEquals(element.getTimestamp(), parsed.getTimestamp());
assertEquals(element.getTo(), parsed.getTo());
assertEquals(element.getPayload(), parsed.getPayload());
}

@Test
public void cryptElementProviderTest() throws Exception {
String expected =
"<crypt xmlns='urn:xmpp:openpgp:0'>" +
"<to jid='alice@wonderland.lit'/>" +
"<time stamp='2014-07-10T15:06:00.000+00:00'/>" +
"<payload>" +
"<body xmlns='jabber:client' xml:lang='en'>The cake is a lie.</body>" +
"</payload>" +
"<rpad>f0rm1l4n4-mT8y33j!Y%fRSrcd^ZE4Q7VDt1L%WEgR!kv</rpad>" +
"</crypt>";
List<ExtensionElement> payload = new ArrayList<>();
payload.add(new Message.Body("en", "The cake is a lie."));
Set<Jid> to = new HashSet<>();
to.add(JidCreate.bareFrom("alice@wonderland.lit"));
CryptElement element = new CryptElement(to,
"f0rm1l4n4-mT8y33j!Y%fRSrcd^ZE4Q7VDt1L%WEgR!kv",
testDate,
payload);

assertXMLEqual(expected, element.toXML(null).toString());

XmlPullParser parser = TestUtils.getParser(expected);
CryptElement parsed = CryptElementProvider.TEST_INSTANCE.parse(parser);

assertEquals(element.getTimestamp(), parsed.getTimestamp());
assertEquals(element.getTo(), parsed.getTo());
assertEquals(element.getPayload(), parsed.getPayload());
assertEquals(element.getRandomPadding(), parsed.getRandomPadding());
}

@Test
public void signcryptElementProviderTest() throws Exception {
String expected =
"<signcrypt xmlns='urn:xmpp:openpgp:0'>" +
"<to jid='juliet@example.org'/>" +
"<time stamp='2014-07-10T15:06:00.000+00:00'/>" +
"<payload>" +
"<body xmlns='jabber:client' xml:lang='en'>This is a secret message.</body>" +
"</payload>" +
"<rpad>f0rm1l4n4-mT8y33j!Y%fRSrcd^ZE4Q7VDt1L%WEgR!kv</rpad>" +
"</signcrypt>";

List<ExtensionElement> payload = new ArrayList<>();
payload.add(new Message.Body("en", "This is a secret message."));
Set<Jid> jids = new HashSet<>();
jids.add(JidCreate.bareFrom("juliet@example.org"));
SigncryptElement element = new SigncryptElement(jids,
"f0rm1l4n4-mT8y33j!Y%fRSrcd^ZE4Q7VDt1L%WEgR!kv",
testDate, payload);

assertXMLEqual(expected, element.toXML(null).toString());

XmlPullParser parser = TestUtils.getParser(expected);
SigncryptElement parsed = SigncryptElementProvider.TEST_INSTANCE.parse(parser);

assertEquals(element.getTimestamp(), parsed.getTimestamp());
assertEquals(element.getTo(), parsed.getTo());
assertEquals(element.getPayload(), parsed.getPayload());
assertEquals(element.getRandomPadding(), parsed.getRandomPadding());
}


}

+ 59
- 0
smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PubkeyElementTest.java View File

@@ -0,0 +1,59 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Date;

import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smackx.ox.element.PubkeyElement;
import org.jivesoftware.smackx.ox.provider.PubkeyElementProvider;

import org.junit.Test;
import org.jxmpp.util.XmppDateTime;
import org.xmlpull.v1.XmlPullParser;

public class PubkeyElementTest extends SmackTestSuite {

@Test
public void providerTest() throws Exception {
String expected =
"<pubkey xmlns='urn:xmpp:openpgp:0' date='2018-01-21T10:46:21.000+00:00'>" +
"<data>" +
"BASE64_OPENPGP_PUBLIC_KEY" +
"</data>" +
"</pubkey>";

Date date = XmppDateTime.parseXEP0082Date("2018-01-21T10:46:21.000+00:00");
byte[] key = "BASE64_OPENPGP_PUBLIC_KEY".getBytes(Charset.forName("UTF-8"));
PubkeyElement element = new PubkeyElement(new PubkeyElement.PubkeyDataElement(key), date);

assertXMLEqual(expected, element.toXML(null).toString());

XmlPullParser parser = TestUtils.getParser(expected);
PubkeyElement parsed = PubkeyElementProvider.TEST_INSTANCE.parse(parser);

assertEquals(element.getDate(), parsed.getDate());
assertTrue(Arrays.equals(element.getDataElement().getB64Data(), parsed.getDataElement().getB64Data()));
}
}

+ 93
- 0
smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/PublicKeysListElementTest.java View File

@@ -0,0 +1,93 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox;

import static junit.framework.TestCase.assertEquals;

import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;

import java.util.Date;

import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
import org.jivesoftware.smackx.ox.provider.PublicKeysListElementProvider;

import org.junit.Test;
import org.jxmpp.util.XmppDateTime;
import org.xmlpull.v1.XmlPullParser;

public class PublicKeysListElementTest extends SmackTestSuite {

@Test
public void providerTest() throws Exception {
String expected =
"<public-keys-list xmlns='urn:xmpp:openpgp:0'>" +
"<pubkey-metadata " +
"v4-fingerprint='1357B01865B2503C18453D208CAC2A9678548E35' " +
"date='2018-03-01T15:26:12.000+00:00'" +
"/>" +
"<pubkey-metadata " +
"v4-fingerprint='67819B343B2AB70DED9320872C6464AF2A8E4C02' " +
"date='1953-05-16T12:00:00.000+00:00'" +
"/>" +
"</public-keys-list>";

Date date1 = XmppDateTime.parseDate("2018-03-01T15:26:12.000+00:00");
Date date2 = XmppDateTime.parseDate("1953-05-16T12:00:00.000+00:00");
PublicKeysListElement.PubkeyMetadataElement child1 =
new PublicKeysListElement.PubkeyMetadataElement(
"1357B01865B2503C18453D208CAC2A9678548E35", date1);
PublicKeysListElement.PubkeyMetadataElement child2 =
new PublicKeysListElement.PubkeyMetadataElement(
"67819B343B2AB70DED9320872C6464AF2A8E4C02", date2);

PublicKeysListElement element = PublicKeysListElement.builder()
.addMetadata(child1)
.addMetadata(child2)
.build();

assertXMLEqual(expected, element.toXML(null).toString());

XmlPullParser parser = TestUtils.getParser(expected);
PublicKeysListElement parsed = PublicKeysListElementProvider.TEST_INSTANCE.parse(parser);

assertEquals(element.getMetadata(), parsed.getMetadata());
}

@Test
public void listBuilderRefusesDuplicatesTest() {
PublicKeysListElement.Builder builder = PublicKeysListElement.builder();
String fp40 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN";
Date oneDate = new Date(12337883234L);
Date otherDate = new Date(8888348384L);

// Check if size of metadata is one after insert.
builder.addMetadata(new PublicKeysListElement.PubkeyMetadataElement(fp40, oneDate));
assertEquals(builder.build().getMetadata().size(), 1);

// Check if size is still one after inserting element with same fp.
builder.addMetadata(new PublicKeysListElement.PubkeyMetadataElement(fp40, otherDate));
assertEquals(builder.build().getMetadata().size(), 1);
}

@Test(expected = IllegalArgumentException.class)
public void metadataFingerprintLengthTest() {
PublicKeysListElement.PubkeyMetadataElement element =
new PublicKeysListElement.PubkeyMetadataElement("thisIsNotTheCorrectLength", new Date());
}
}

+ 52
- 0
smack-openpgp/src/test/java/org/jivesoftware/smackx/ox/SecretkeyElementTest.java View File

@@ -0,0 +1,52 @@
/**
*
* Copyright 2018 Paul Schaub.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox;

import static junit.framework.TestCase.assertTrue;
import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;

import java.nio.charset.Charset;
import java.util.Arrays;

import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smackx.ox.element.SecretkeyElement;
import org.jivesoftware.smackx.ox.provider.SecretkeyElementProvider;

import org.junit.Test;
import org.xmlpull.v1.XmlPullParser;

public class SecretkeyElementTest extends SmackTestSuite {

@Test
public void providerTest() throws Exception {
String expected =
"<secretkey xmlns='urn:xmpp:openpgp:0'>" +
"BASE64_OPENPGP_ENCRYPTED_SECRET_KEY" +
"</secretkey>";
byte[] key = "BASE64_OPENPGP_ENCRYPTED_SECRET_KEY".getBytes(Charset.forName("UTF-8"));

SecretkeyElement element = new SecretkeyElement(key);

assertXMLEqual(expected, element.toXML(null).toString());

XmlPullParser parser = TestUtils.getParser(expected);
SecretkeyElement parsed = SecretkeyElementProvider.TEST_INSTANCE.parse(parser);

assertTrue(Arrays.equals(element.getB64Data(), parsed.getB64Data()));
}
}

Loading…
Cancel
Save