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 byte[] key, iv, keyAndIv;
public AesGcmNoPadding(int bits) throws NoSuchAlgorithmException, NoSuchProviderException,
protected AesGcmNoPadding(int bits) throws NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException {
this.length = bits;
int bytes = bits / 8;
@ -60,6 +60,19 @@ public abstract class AesGcmNoPadding {
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,
NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException {
this.length = key.length * 8;
@ -76,6 +89,19 @@ public abstract class AesGcmNoPadding {
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() {
return keyAndIv.clone();
}

View File

@ -24,6 +24,7 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.provider.ExtensionElementProvider;
import org.jivesoftware.smackx.ciphers.Aes256GcmNoPadding;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.jet.internal.JetSecurity;
import org.jivesoftware.smackx.jet.provider.JetSecurityProvider;
@ -92,7 +93,7 @@ public final class JetManager extends Manager implements JingleDescriptionManage
JingleTransportManager transportManager = jingleManager.getBestAvailableTransportManager();
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);
session.initiate(connection());

View File

@ -34,19 +34,24 @@ import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
public class JetSecurityElement extends JingleContentSecurityElement {
public static final String ATTR_NAME = "name";
public static final String ATTR_TYPE = "type";
public static final String ATTR_CIPHER = "cipher";
private final ExtensionElement child;
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.child = child;
this.cipherName = cipherName;
}
@Override
public CharSequence toXML() {
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.element(child);
xml.closeElement(this);
@ -69,4 +74,8 @@ public class JetSecurityElement extends JingleContentSecurityElement {
public String getName() {
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.packet.ExtensionElement;
import org.jivesoftware.smackx.bytestreams.BytestreamSession;
import org.jivesoftware.smackx.ciphers.Aes256GcmNoPadding;
import org.jivesoftware.smackx.ciphers.AesGcmNoPadding;
import org.jivesoftware.smackx.jet.JetManager;
import org.jivesoftware.smackx.jet.JingleEncryptionMethod;
@ -54,6 +53,7 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
private AesGcmNoPadding aesKey;
private ExtensionElement child;
private String cipherName;
private String name;
public JetSecurity(JetSecurityElement element) {
@ -61,18 +61,20 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
this.child = element.getChild();
this.methodNamespace = element.getMethodNamespace();
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,
InvalidAlgorithmParameterException, InvalidKeyException, InterruptedException,
JingleEncryptionMethod.JingleEncryptionException, SmackException.NotConnectedException,
SmackException.NoResponseException {
this.methodNamespace = method.getNamespace();
this.aesKey = new Aes256GcmNoPadding();
this.aesKey = AesGcmNoPadding.create(cipherName);
this.child = method.encryptJingleTransfer(recipient, aesKey.getKeyAndIv());
this.name = name;
this.cipherName = cipherName;
}
public void decryptEncryptionKey(JingleEncryptionMethod method, FullJid sender)
@ -81,12 +83,12 @@ public class JetSecurity extends JingleSecurity<JetSecurityElement> {
InvalidAlgorithmParameterException, NoSuchProviderException, InvalidKeyException, NoSuchPaddingException {
byte[] keyAndIv = method.decryptJingleTransfer(sender, child);
LOGGER.log(Level.INFO, "Transported JET Key has length: " + keyAndIv.length);
aesKey = new Aes256GcmNoPadding(keyAndIv);
aesKey = AesGcmNoPadding.parse(cipherName, keyAndIv);
}
@Override
public JetSecurityElement getElement() {
return new JetSecurityElement(getParent().getName(), child);
return new JetSecurityElement(getParent().getName(), cipherName, child);
}
@Override

View File

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