mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-12-07 03:21:08 +01:00
Implement exporting secret key
This commit is contained in:
parent
55b9c1ac2a
commit
878ac56ed0
10 changed files with 179 additions and 17 deletions
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.ox;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -30,8 +31,10 @@ import org.jivesoftware.smack.XMPPException;
|
|||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.Async;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.ox.callback.DisplayBackupCodeCallback;
|
||||
import org.jivesoftware.smackx.ox.element.PubkeyElement;
|
||||
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
|
||||
import org.jivesoftware.smackx.ox.element.SecretkeyElement;
|
||||
import org.jivesoftware.smackx.ox.exception.CorruptedOpenPgpKeyException;
|
||||
import org.jivesoftware.smackx.pep.PEPListener;
|
||||
import org.jivesoftware.smackx.pep.PEPManager;
|
||||
|
|
@ -57,6 +60,11 @@ public final class OpenPgpManager extends Manager {
|
|||
*/
|
||||
public static final String PEP_NODE_PUBLIC_KEYS = "urn:xmpp:openpgp:0:public-keys";
|
||||
|
||||
/**
|
||||
* Name of the OX secret key node.
|
||||
*/
|
||||
public static final String PEP_NODE_SECRET_KEY = "urn:xmpp:openpgp:0:secret-key";
|
||||
|
||||
/**
|
||||
* Feature to be announced using the {@link ServiceDiscoveryManager} to subscribe to the OX metadata node.
|
||||
*
|
||||
|
|
@ -272,12 +280,20 @@ public final class OpenPgpManager extends Manager {
|
|||
/**
|
||||
* TODO: Implement and document.
|
||||
*/
|
||||
public void depositSecretKey() {
|
||||
public void depositSecretKey(DisplayBackupCodeCallback callback)
|
||||
throws CorruptedOpenPgpKeyException, InterruptedException, PubSubException.NotALeafNodeException,
|
||||
XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException {
|
||||
ensureProviderIsSet();
|
||||
// Create key backup by appending serialized unencrypted secret keys.
|
||||
// Encrypt the backup using a random generated password
|
||||
// Publish the backup to the secret key node (whitelist protected)
|
||||
// Display the backup key to the user
|
||||
|
||||
String password = generateBackupPassword();
|
||||
SecretkeyElement secretKeyElement = provider.createSecretkeyElement(password);
|
||||
|
||||
PubSubManager pm = PubSubManager.getInstance(connection());
|
||||
LeafNode secretKeyNode = pm.getOrCreateLeafNode(PEP_NODE_SECRET_KEY);
|
||||
PubSubHelper.whitelist(secretKeyNode);
|
||||
|
||||
secretKeyNode.publish(new PayloadItem<>(secretKeyElement));
|
||||
callback.displayBackupCode(password);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -349,4 +365,32 @@ public final class OpenPgpManager extends Manager {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a secure backup code.
|
||||
*
|
||||
* @see <a href="https://xmpp.org/extensions/xep-0373.html#sect-idm140425111347232">XEP-0373 §5.3</a>
|
||||
* @return backup code
|
||||
*/
|
||||
private String generateBackupPassword() {
|
||||
final String alphabet = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
|
||||
SecureRandom random = new SecureRandom();
|
||||
StringBuilder code = new StringBuilder();
|
||||
|
||||
// 6 blocks
|
||||
for (int i = 0; i < 6; i++) {
|
||||
|
||||
// of 4 chars
|
||||
for (int j = 0; j < 4; j++) {
|
||||
char c = alphabet.charAt(random.nextInt(alphabet.length()));
|
||||
code.append(c);
|
||||
}
|
||||
|
||||
// dash after every block except the last one
|
||||
if (i != 5) {
|
||||
code.append('-');
|
||||
}
|
||||
}
|
||||
return code.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.jivesoftware.smackx.ox.element.CryptElement;
|
|||
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
|
||||
import org.jivesoftware.smackx.ox.element.PubkeyElement;
|
||||
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
|
||||
import org.jivesoftware.smackx.ox.element.SecretkeyElement;
|
||||
import org.jivesoftware.smackx.ox.element.SignElement;
|
||||
import org.jivesoftware.smackx.ox.element.SigncryptElement;
|
||||
import org.jivesoftware.smackx.ox.exception.CorruptedOpenPgpKeyException;
|
||||
|
|
@ -151,4 +152,6 @@ public interface OpenPgpProvider {
|
|||
* @throws CorruptedOpenPgpKeyException if for some reason the fingerprint cannot be derived from the key pair.
|
||||
*/
|
||||
String getFingerprint() throws CorruptedOpenPgpKeyException;
|
||||
|
||||
SecretkeyElement createSecretkeyElement(String password) throws CorruptedOpenPgpKeyException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,16 +21,18 @@ import org.jivesoftware.smack.XMPPException;
|
|||
import org.jivesoftware.smackx.pubsub.AccessModel;
|
||||
import org.jivesoftware.smackx.pubsub.ConfigureForm;
|
||||
import org.jivesoftware.smackx.pubsub.LeafNode;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
|
||||
public class PubSubHelper {
|
||||
|
||||
public static void whitelist(LeafNode node)
|
||||
throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException,
|
||||
SmackException.NoResponseException {
|
||||
ConfigureForm config = node.getNodeConfiguration();
|
||||
if (config.getAccessModel() != AccessModel.whitelist) {
|
||||
config.setAccessModel(AccessModel.whitelist);
|
||||
node.sendConfigurationForm(config);
|
||||
ConfigureForm old = node.getNodeConfiguration();
|
||||
if (old.getAccessModel() != AccessModel.whitelist) {
|
||||
ConfigureForm _new = new ConfigureForm(DataForm.Type.submit);
|
||||
_new.setAccessModel(AccessModel.whitelist);
|
||||
node.sendConfigurationForm(_new);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
*
|
||||
* 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.callback;
|
||||
|
||||
public interface AskForBackupCodeCallback {
|
||||
String askForBackupCode();
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
*
|
||||
* 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.callback;
|
||||
|
||||
public interface DisplayBackupCodeCallback {
|
||||
void displayBackupCode(String backupCode);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* Callback classes for XEP-0373: OpenPGP for XMPP.
|
||||
*/
|
||||
package org.jivesoftware.smackx.ox.callback;
|
||||
Loading…
Add table
Add a link
Reference in a new issue