Allow AES agility

This commit is contained in:
vanitasvitae 2017-08-04 15:08:16 +02:00
parent a07a1cdc61
commit cc4de48966
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
5 changed files with 50 additions and 10 deletions

View File

@ -37,7 +37,7 @@ public abstract class AesGcmNoPadding {
protected final Cipher cipher; protected final Cipher cipher;
protected final byte[] key, iv, keyAndIv; protected final byte[] key, iv, keyAndIv;
public AesGcmNoPadding(int bits) throws NoSuchAlgorithmException, NoSuchProviderException, protected AesGcmNoPadding(int bits) throws NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException { NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException {
this.length = bits; this.length = bits;
int bytes = bits / 8; int bytes = bits / 8;
@ -60,6 +60,19 @@ public abstract class AesGcmNoPadding {
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
} }
public static AesGcmNoPadding create(String cipherName)
throws NoSuchProviderException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
InvalidAlgorithmParameterException {
switch (cipherName) {
case Aes128GcmNoPadding.NAMESPACE:
return new Aes128GcmNoPadding();
case Aes256GcmNoPadding.NAMESPACE:
return new Aes256GcmNoPadding();
default: throw new NoSuchAlgorithmException("Invalid cipher.");
}
}
public AesGcmNoPadding(byte[] key, byte[] iv) throws NoSuchPaddingException, NoSuchAlgorithmException, public AesGcmNoPadding(byte[] key, byte[] iv) throws NoSuchPaddingException, NoSuchAlgorithmException,
NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException { NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException {
this.length = key.length * 8; this.length = key.length * 8;
@ -76,6 +89,19 @@ public abstract class AesGcmNoPadding {
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
} }
public static AesGcmNoPadding parse(String namespace, byte[] serialized)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, NoSuchProviderException,
InvalidKeyException, NoSuchPaddingException {
switch (namespace) {
case Aes128GcmNoPadding.NAMESPACE:
return new Aes128GcmNoPadding(serialized);
case Aes256GcmNoPadding.NAMESPACE:
return new Aes256GcmNoPadding(serialized);
default: throw new NoSuchAlgorithmException("Invalid cipher.");
}
}
public byte[] getKeyAndIv() { public byte[] getKeyAndIv() {
return keyAndIv.clone(); return keyAndIv.clone();
} }

View File

@ -24,6 +24,7 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.provider.ExtensionElementProvider; import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.ciphers.Aes256GcmNoPadding;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.jet.internal.JetSecurity; import org.jivesoftware.smackx.jet.internal.JetSecurity;
import org.jivesoftware.smackx.jet.provider.JetSecurityProvider; import org.jivesoftware.smackx.jet.provider.JetSecurityProvider;
@ -92,7 +93,7 @@ public final class JetManager extends Manager implements JingleDescriptionManage
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager(); JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager();
content.setTransport(transportManager.createTransport(content)); content.setTransport(transportManager.createTransport(content));
JetSecurity security = new JetSecurity(method, recipient, content.getName()); JetSecurity security = new JetSecurity(method, recipient, content.getName(), Aes256GcmNoPadding.NAMESPACE);
content.setSecurity(security); content.setSecurity(security);
session.initiate(connection()); session.initiate(connection());

View File

@ -34,19 +34,24 @@ import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
public class JetSecurityElement extends JingleContentSecurityElement { public class JetSecurityElement extends JingleContentSecurityElement {
public static final String ATTR_NAME = "name"; public static final String ATTR_NAME = "name";
public static final String ATTR_TYPE = "type"; public static final String ATTR_TYPE = "type";
public static final String ATTR_CIPHER = "cipher";
private final ExtensionElement child; private final ExtensionElement child;
private final String name; private final String name;
private final String cipherName;
public JetSecurityElement(String name, ExtensionElement child) { public JetSecurityElement(String name, String cipherName, ExtensionElement child) {
this.name = name; this.name = name;
this.child = child; this.child = child;
this.cipherName = cipherName;
} }
@Override @Override
public CharSequence toXML() { public CharSequence toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this); XmlStringBuilder xml = new XmlStringBuilder(this);
xml.attribute(ATTR_NAME, name).attribute(ATTR_TYPE, child.getNamespace()); xml.attribute(ATTR_NAME, name)
.attribute(ATTR_CIPHER, cipherName)
.attribute(ATTR_TYPE, child.getNamespace());
xml.rightAngleBracket(); xml.rightAngleBracket();
xml.element(child); xml.element(child);
xml.closeElement(this); xml.closeElement(this);
@ -69,4 +74,8 @@ public class JetSecurityElement extends JingleContentSecurityElement {
public String getName() { public String getName() {
return name; return name;
} }
public String getCipherName() {
return cipherName;
}
} }

View File

@ -29,7 +29,6 @@ import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smackx.bytestreams.BytestreamSession; import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.ciphers.Aes256GcmNoPadding;
import org.jivesoftware.smackx.ciphers.AesGcmNoPadding; import org.jivesoftware.smackx.ciphers.AesGcmNoPadding;
import org.jivesoftware.smackx.jet.JetManager; import org.jivesoftware.smackx.jet.JetManager;
import org.jivesoftware.smackx.jet.JingleEncryptionMethod; import org.jivesoftware.smackx.jet.JingleEncryptionMethod;
@ -54,6 +53,7 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
private AesGcmNoPadding aesKey; private AesGcmNoPadding aesKey;
private ExtensionElement child; private ExtensionElement child;
private String cipherName;
private String name; private String name;
public JetSecurity(JetSecurityElement element) { public JetSecurity(JetSecurityElement element) {
@ -61,18 +61,20 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
this.child = element.getChild(); this.child = element.getChild();
this.methodNamespace = element.getMethodNamespace(); this.methodNamespace = element.getMethodNamespace();
this.name = element.getName(); this.name = element.getName();
this.cipherName = element.getCipherName();
} }
public JetSecurity(JingleEncryptionMethod method, FullJid recipient, String name) public JetSecurity(JingleEncryptionMethod method, FullJid recipient, String name, String cipherName)
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
InvalidAlgorithmParameterException, InvalidKeyException, InterruptedException, InvalidAlgorithmParameterException, InvalidKeyException, InterruptedException,
JingleEncryptionMethod.JingleEncryptionException, SmackException.NotConnectedException, JingleEncryptionMethod.JingleEncryptionException, SmackException.NotConnectedException,
SmackException.NoResponseException { SmackException.NoResponseException {
this.methodNamespace = method.getNamespace(); this.methodNamespace = method.getNamespace();
this.aesKey = new Aes256GcmNoPadding(); this.aesKey = AesGcmNoPadding.create(cipherName);
this.child = method.encryptJingleTransfer(recipient, aesKey.getKeyAndIv()); this.child = method.encryptJingleTransfer(recipient, aesKey.getKeyAndIv());
this.name = name; this.name = name;
this.cipherName = cipherName;
} }
public void decryptEncryptionKey(JingleEncryptionMethod method, FullJid sender) public void decryptEncryptionKey(JingleEncryptionMethod method, FullJid sender)
@ -81,12 +83,12 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
InvalidAlgorithmParameterException, NoSuchProviderException, InvalidKeyException, NoSuchPaddingException { InvalidAlgorithmParameterException, NoSuchProviderException, InvalidKeyException, NoSuchPaddingException {
byte[] keyAndIv = method.decryptJingleTransfer(sender, child); byte[] keyAndIv = method.decryptJingleTransfer(sender, child);
LOGGER.log(Level.INFO, "Transported JET Key has length: " + keyAndIv.length); LOGGER.log(Level.INFO, "Transported JET Key has length: " + keyAndIv.length);
aesKey = new Aes256GcmNoPadding(keyAndIv); aesKey = AesGcmNoPadding.parse(cipherName, keyAndIv);
} }
@Override @Override
public JetSecurityElement getElement() { public JetSecurityElement getElement() {
return new JetSecurityElement(getParent().getName(), child); return new JetSecurityElement(getParent().getName(), cipherName, child);
} }
@Override @Override

View File

@ -38,10 +38,12 @@ public class JetSecurityProvider extends JingleContentSecurityProvider<JetSecuri
@Override @Override
public JetSecurityElement parse(XmlPullParser parser, int initialDepth) throws Exception { public JetSecurityElement parse(XmlPullParser parser, int initialDepth) throws Exception {
String name = parser.getAttributeValue("", JetSecurityElement.ATTR_NAME); String name = parser.getAttributeValue("", JetSecurityElement.ATTR_NAME);
String cipher = parser.getAttributeValue("", JetSecurityElement.ATTR_CIPHER);
String type = parser.getAttributeValue("", JetSecurityElement.ATTR_TYPE); String type = parser.getAttributeValue("", JetSecurityElement.ATTR_TYPE);
ExtensionElement child; ExtensionElement child;
Objects.requireNonNull(type); Objects.requireNonNull(type);
Objects.requireNonNull(cipher);
ExtensionElementProvider<?> encryptionElementProvider = ExtensionElementProvider<?> encryptionElementProvider =
JetManager.getEncryptionMethodProvider(type); JetManager.getEncryptionMethodProvider(type);
@ -53,7 +55,7 @@ public class JetSecurityProvider extends JingleContentSecurityProvider<JetSecuri
return null; return null;
} }
return new JetSecurityElement(name, child); return new JetSecurityElement(name, cipher, child);
} }
@Override @Override