mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-27 14:32:06 +01:00
Add UnknownSecurityElement
Fix parsing of JingleSecurityElements Switch to 12 byte IV for AES keys
This commit is contained in:
parent
792a9a348b
commit
a23eb6aeea
10 changed files with 128 additions and 48 deletions
|
@ -32,8 +32,8 @@ public class Aes128GcmNoPadding extends AesGcmNoPadding {
|
||||||
|
|
||||||
public Aes128GcmNoPadding(byte[] keyAndIv, int MODE) throws NoSuchProviderException, InvalidAlgorithmParameterException,
|
public Aes128GcmNoPadding(byte[] keyAndIv, int MODE) throws NoSuchProviderException, InvalidAlgorithmParameterException,
|
||||||
NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
|
NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
|
||||||
super(AesGcmNoPadding.copyOfRange(keyAndIv, 0, keyAndIv.length / 2), //Key
|
super(AesGcmNoPadding.copyOfRange(keyAndIv, 0, 16), // 16 byte key
|
||||||
AesGcmNoPadding.copyOfRange(keyAndIv, keyAndIv.length / 2, keyAndIv.length), MODE); //IV
|
AesGcmNoPadding.copyOfRange(keyAndIv, 16, keyAndIv.length), MODE); // rest (12 byte) IV
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,8 +32,8 @@ public class Aes256GcmNoPadding extends AesGcmNoPadding {
|
||||||
|
|
||||||
public Aes256GcmNoPadding(byte[] keyAndIv, int MODE) throws NoSuchProviderException, InvalidAlgorithmParameterException,
|
public Aes256GcmNoPadding(byte[] keyAndIv, int MODE) throws NoSuchProviderException, InvalidAlgorithmParameterException,
|
||||||
NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
|
NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
|
||||||
super(AesGcmNoPadding.copyOfRange(keyAndIv, 0, keyAndIv.length / 2), //Key
|
super(AesGcmNoPadding.copyOfRange(keyAndIv, 0, 32), // 32 byte key
|
||||||
AesGcmNoPadding.copyOfRange(keyAndIv, keyAndIv.length / 2, keyAndIv.length), MODE); //IV
|
AesGcmNoPadding.copyOfRange(keyAndIv, 32, keyAndIv.length), MODE); // rest (12 byte) IV
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -47,12 +47,12 @@ public abstract class AesGcmNoPadding {
|
||||||
key = keyGenerator.generateKey().getEncoded();
|
key = keyGenerator.generateKey().getEncoded();
|
||||||
|
|
||||||
SecureRandom secureRandom = new SecureRandom();
|
SecureRandom secureRandom = new SecureRandom();
|
||||||
iv = new byte[bytes];
|
iv = new byte[12];
|
||||||
secureRandom.nextBytes(iv);
|
secureRandom.nextBytes(iv);
|
||||||
|
|
||||||
keyAndIv = new byte[2 * bytes];
|
keyAndIv = new byte[bytes + 12];
|
||||||
System.arraycopy(key, 0, keyAndIv, 0, bytes);
|
System.arraycopy(key, 0, keyAndIv, 0, bytes);
|
||||||
System.arraycopy(iv, 0, keyAndIv, bytes, bytes);
|
System.arraycopy(iv, 0, keyAndIv, bytes, 12);
|
||||||
|
|
||||||
cipher = Cipher.getInstance(cipherMode, "BC");
|
cipher = Cipher.getInstance(cipherMode, "BC");
|
||||||
SecretKey keySpec = new SecretKeySpec(key, keyType);
|
SecretKey keySpec = new SecretKeySpec(key, keyType);
|
||||||
|
@ -86,6 +86,7 @@ public abstract class AesGcmNoPadding {
|
||||||
*/
|
*/
|
||||||
public AesGcmNoPadding(byte[] key, byte[] iv, int MODE) throws NoSuchPaddingException, NoSuchAlgorithmException,
|
public AesGcmNoPadding(byte[] key, byte[] iv, int MODE) throws NoSuchPaddingException, NoSuchAlgorithmException,
|
||||||
NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException {
|
NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException {
|
||||||
|
assert iv.length == 12;
|
||||||
this.length = key.length * 8;
|
this.length = key.length * 8;
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.iv = iv;
|
this.iv = iv;
|
||||||
|
|
|
@ -42,8 +42,8 @@ public class AesGcmNoPaddingTest extends SmackTestSuite {
|
||||||
AesGcmNoPadding aes128 = AesGcmNoPadding.createEncryptionKey(Aes128GcmNoPadding.NAMESPACE);
|
AesGcmNoPadding aes128 = AesGcmNoPadding.createEncryptionKey(Aes128GcmNoPadding.NAMESPACE);
|
||||||
assertNotNull(aes128);
|
assertNotNull(aes128);
|
||||||
assertEquals(16, aes128.getKey().length);
|
assertEquals(16, aes128.getKey().length);
|
||||||
assertEquals(16, aes128.getIv().length);
|
assertEquals(12, aes128.getIv().length);
|
||||||
assertEquals(32, aes128.getKeyAndIv().length);
|
assertEquals(28, aes128.getKeyAndIv().length);
|
||||||
assertNotNull(aes128.getCipher());
|
assertNotNull(aes128.getCipher());
|
||||||
assertEquals(128, aes128.getLength());
|
assertEquals(128, aes128.getLength());
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,8 @@ public class AesGcmNoPaddingTest extends SmackTestSuite {
|
||||||
AesGcmNoPadding aes256 = AesGcmNoPadding.createEncryptionKey(Aes256GcmNoPadding.NAMESPACE);
|
AesGcmNoPadding aes256 = AesGcmNoPadding.createEncryptionKey(Aes256GcmNoPadding.NAMESPACE);
|
||||||
assertNotNull(aes256);
|
assertNotNull(aes256);
|
||||||
assertEquals(32, aes256.getKey().length);
|
assertEquals(32, aes256.getKey().length);
|
||||||
assertEquals(32, aes256.getIv().length);
|
assertEquals(12, aes256.getIv().length);
|
||||||
assertEquals(64, aes256.getKeyAndIv().length);
|
assertEquals(44, aes256.getKeyAndIv().length);
|
||||||
assertNotNull(aes256.getCipher());
|
assertNotNull(aes256.getCipher());
|
||||||
assertEquals(256, aes256.getLength());
|
assertEquals(256, aes256.getLength());
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,14 @@ public abstract class JingleContentSecurityElement implements ExtensionElement {
|
||||||
public static final String ELEMENT = "security";
|
public static final String ELEMENT = "security";
|
||||||
private JingleContentSecurityInfoElement securityInfo;
|
private JingleContentSecurityInfoElement securityInfo;
|
||||||
|
|
||||||
|
public JingleContentSecurityElement() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public JingleContentSecurityElement(JingleContentSecurityInfoElement info) {
|
||||||
|
this.securityInfo = info;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENT;
|
return ELEMENT;
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 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.jingle.element;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.StandardExtensionElement;
|
||||||
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
|
|
||||||
|
public final class UnknownJingleContentSecurityElement extends JingleContentSecurityElement {
|
||||||
|
|
||||||
|
private final StandardExtensionElement standardExtensionElement;
|
||||||
|
|
||||||
|
public UnknownJingleContentSecurityElement(StandardExtensionElement standardExtensionElement) {
|
||||||
|
super();
|
||||||
|
this.standardExtensionElement = standardExtensionElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName() {
|
||||||
|
return standardExtensionElement.getElementName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return standardExtensionElement.getNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlStringBuilder toXML() {
|
||||||
|
return standardExtensionElement.toXML();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JingleContentSecurityInfoElement getSecurityInfo() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardExtensionElement getStandardExtensionElement() {
|
||||||
|
return standardExtensionElement;
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,10 +26,12 @@ import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleAction;
|
import org.jivesoftware.smackx.jingle.element.JingleAction;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
||||||
|
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
|
import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.UnknownJingleContentDescriptionElement;
|
import org.jivesoftware.smackx.jingle.element.UnknownJingleContentDescriptionElement;
|
||||||
|
import org.jivesoftware.smackx.jingle.element.UnknownJingleContentSecurityElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.UnknownJingleContentTransportElement;
|
import org.jivesoftware.smackx.jingle.element.UnknownJingleContentTransportElement;
|
||||||
|
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
|
@ -120,45 +122,57 @@ public class JingleProvider extends IQProvider<JingleElement> {
|
||||||
outerloop: while (true) {
|
outerloop: while (true) {
|
||||||
int eventType = parser.next();
|
int eventType = parser.next();
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case XmlPullParser.START_TAG:
|
case XmlPullParser.START_TAG:
|
||||||
String tagName = parser.getName();
|
String tagName = parser.getName();
|
||||||
String namespace = parser.getNamespace();
|
String namespace = parser.getNamespace();
|
||||||
switch (tagName) {
|
switch (tagName) {
|
||||||
case JingleContentDescriptionElement.ELEMENT: {
|
case JingleContentDescriptionElement.ELEMENT: {
|
||||||
JingleContentDescriptionElement description;
|
JingleContentDescriptionElement description;
|
||||||
JingleContentDescriptionProvider<?> provider = JingleManager.getJingleDescriptionProvider(namespace);
|
JingleContentDescriptionProvider<?> provider = JingleManager.getJingleDescriptionProvider(namespace);
|
||||||
if (provider == null) {
|
if (provider == null) {
|
||||||
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
|
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
|
||||||
description = new UnknownJingleContentDescriptionElement(standardExtensionElement);
|
description = new UnknownJingleContentDescriptionElement(standardExtensionElement);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
description = provider.parse(parser);
|
||||||
|
}
|
||||||
|
builder.setDescription(description);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JingleContentTransportElement.ELEMENT: {
|
||||||
|
JingleContentTransportElement transport;
|
||||||
|
JingleContentTransportProvider<?> provider = JingleManager.getJingleTransportProvider(namespace);
|
||||||
|
if (provider == null) {
|
||||||
|
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
|
||||||
|
transport = new UnknownJingleContentTransportElement(standardExtensionElement);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
transport = provider.parse(parser);
|
||||||
|
}
|
||||||
|
builder.setTransport(transport);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case JingleContentSecurityElement.ELEMENT: {
|
||||||
|
JingleContentSecurityElement security;
|
||||||
|
JingleContentSecurityProvider<?> provider = JingleManager.getJingleSecurityProvider(namespace);
|
||||||
|
if (provider == null) {
|
||||||
|
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
|
||||||
|
security = new UnknownJingleContentSecurityElement(standardExtensionElement);
|
||||||
|
} else {
|
||||||
|
security = provider.parse(parser);
|
||||||
|
}
|
||||||
|
builder.setSecurity(security);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
LOGGER.severe("Unknown Jingle content element: " + tagName);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
description = provider.parse(parser);
|
|
||||||
}
|
|
||||||
builder.setDescription(description);
|
|
||||||
break;
|
break;
|
||||||
}
|
case XmlPullParser.END_TAG:
|
||||||
case JingleContentTransportElement.ELEMENT: {
|
if (parser.getDepth() == initialDepth) {
|
||||||
JingleContentTransportElement transport;
|
break outerloop;
|
||||||
JingleContentTransportProvider<?> provider = JingleManager.getJingleTransportProvider(namespace);
|
|
||||||
if (provider == null) {
|
|
||||||
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
|
|
||||||
transport = new UnknownJingleContentTransportElement(standardExtensionElement);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
transport = provider.parse(parser);
|
|
||||||
}
|
|
||||||
builder.setTransport(transport);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
LOGGER.severe("Unknown Jingle content element: " + tagName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case XmlPullParser.END_TAG:
|
|
||||||
if (parser.getDepth() == initialDepth) {
|
|
||||||
break outerloop;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -469,6 +469,7 @@ public class JingleS5BTransport extends JingleTransport<JingleS5BTransportElemen
|
||||||
private void handleProxyError(JingleS5BTransportInfoElement info) {
|
private void handleProxyError(JingleS5BTransportInfoElement info) {
|
||||||
callback.onTransportFailed(new S5BTransportException.ProxyError(null));
|
callback.onTransportFailed(new S5BTransportException.ProxyError(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dummy candidate used to represent failure.
|
* Internal dummy candidate used to represent failure.
|
||||||
* Kinda depressing, isn't it?
|
* Kinda depressing, isn't it?
|
||||||
|
|
|
@ -65,7 +65,7 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
|
||||||
private List<Bytestream.StreamHost> localStreamHosts = null;
|
private List<Bytestream.StreamHost> localStreamHosts = null;
|
||||||
private List<Bytestream.StreamHost> availableStreamHosts = null;
|
private List<Bytestream.StreamHost> availableStreamHosts = null;
|
||||||
|
|
||||||
public static boolean useLocalCandidates = false;
|
public static boolean useLocalCandidates = true;
|
||||||
public static boolean useExternalCandidates = true;
|
public static boolean useExternalCandidates = true;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
|
@ -68,6 +68,7 @@ import org.jivesoftware.smackx.omemo.internal.OmemoDevice;
|
||||||
import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation;
|
import org.jivesoftware.smackx.omemo.internal.OmemoMessageInformation;
|
||||||
import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener;
|
import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener;
|
||||||
import org.jivesoftware.smackx.omemo.listener.OmemoMucMessageListener;
|
import org.jivesoftware.smackx.omemo.listener.OmemoMucMessageListener;
|
||||||
|
import org.jivesoftware.smackx.omemo.util.OmemoConstants;
|
||||||
import org.jivesoftware.smackx.pep.PEPListener;
|
import org.jivesoftware.smackx.pep.PEPListener;
|
||||||
import org.jivesoftware.smackx.pep.PEPManager;
|
import org.jivesoftware.smackx.pep.PEPManager;
|
||||||
import org.jivesoftware.smackx.pubsub.EventElement;
|
import org.jivesoftware.smackx.pubsub.EventElement;
|
||||||
|
@ -115,6 +116,7 @@ public final class OmemoManager extends Manager implements JingleEncryptionMetho
|
||||||
setConnectionListener();
|
setConnectionListener();
|
||||||
this.deviceId = deviceId;
|
this.deviceId = deviceId;
|
||||||
service = OmemoService.getInstance();
|
service = OmemoService.getInstance();
|
||||||
|
ServiceDiscoveryManager.getInstanceFor(connection).addFeature(OmemoConstants.OMEMO_NAMESPACE_V_AXOLOTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue