Smack/smack-openpgp/src/main/java/org/jivesoftware/smackx/ox/store/abstr/AbstractOpenPgpKeyStore.java

185 lines
8.0 KiB
Java
Raw Normal View History

2018-07-07 17:58:32 +02:00
/**
*
2018-07-08 22:31:35 +02:00
* Copyright 2018 Paul Schaub.
2018-07-07 17:58:32 +02:00
*
* 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.
*/
2018-07-08 19:36:44 +02:00
package org.jivesoftware.smackx.ox.store.abstr;
2018-07-07 17:58:32 +02:00
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.HashMap;
import java.util.Map;
2018-07-08 22:31:35 +02:00
import java.util.logging.Level;
import java.util.logging.Logger;
2018-07-07 17:58:32 +02:00
2018-07-08 22:31:35 +02:00
import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException;
import org.jivesoftware.smackx.ox.selection_strategy.BareJidUserId;
2018-07-08 19:36:44 +02:00
import org.jivesoftware.smackx.ox.store.definition.OpenPgpKeyStore;
2018-07-07 17:58:32 +02:00
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.jxmpp.jid.BareJid;
import org.pgpainless.pgpainless.PGPainless;
2018-07-08 19:36:44 +02:00
import org.pgpainless.pgpainless.key.OpenPgpV4Fingerprint;
2018-07-09 15:01:15 +02:00
import org.pgpainless.pgpainless.util.BCUtil;
2018-07-07 17:58:32 +02:00
public abstract class AbstractOpenPgpKeyStore implements OpenPgpKeyStore {
2018-07-08 22:31:35 +02:00
private static final Logger LOGGER = Logger.getLogger(AbstractOpenPgpKeyStore.class.getName());
2018-07-07 17:58:32 +02:00
2018-07-08 22:31:35 +02:00
protected Map<BareJid, PGPPublicKeyRingCollection> publicKeyRingCollections = new HashMap<>();
protected Map<BareJid, PGPSecretKeyRingCollection> secretKeyRingCollections = new HashMap<>();
2018-07-07 17:58:32 +02:00
2018-07-08 16:25:56 +02:00
protected abstract PGPPublicKeyRingCollection readPublicKeysOf(BareJid owner) throws IOException, PGPException;
protected abstract void writePublicKeysOf(BareJid owner, PGPPublicKeyRingCollection publicKeys) throws IOException;
protected abstract PGPSecretKeyRingCollection readSecretKeysOf(BareJid owner) throws IOException, PGPException;
protected abstract void writeSecretKeysOf(BareJid owner, PGPSecretKeyRingCollection secretKeys) throws IOException;
2018-07-07 17:58:32 +02:00
@Override
public PGPPublicKeyRingCollection getPublicKeysOf(BareJid owner) throws IOException, PGPException {
2018-07-08 22:31:35 +02:00
PGPPublicKeyRingCollection keys = publicKeyRingCollections.get(owner);
2018-07-07 17:58:32 +02:00
if (keys == null) {
keys = readPublicKeysOf(owner);
if (keys != null) {
2018-07-08 22:31:35 +02:00
publicKeyRingCollections.put(owner, keys);
2018-07-07 17:58:32 +02:00
}
}
return keys;
}
@Override
public PGPSecretKeyRingCollection getSecretKeysOf(BareJid owner) throws IOException, PGPException {
2018-07-08 22:31:35 +02:00
PGPSecretKeyRingCollection keys = secretKeyRingCollections.get(owner);
2018-07-07 17:58:32 +02:00
if (keys == null) {
keys = readSecretKeysOf(owner);
if (keys != null) {
2018-07-08 22:31:35 +02:00
secretKeyRingCollections.put(owner, keys);
2018-07-07 17:58:32 +02:00
}
}
return keys;
}
2018-07-08 22:31:35 +02:00
@Override
public void importSecretKey(BareJid owner, PGPSecretKeyRing secretKeys)
throws IOException, PGPException, MissingUserIdOnKeyException {
if (!new BareJidUserId.SecRingSelectionStrategy().accept(owner, secretKeys)) {
throw new MissingUserIdOnKeyException(owner, secretKeys.getPublicKey().getKeyID());
}
2018-07-11 18:47:06 +02:00
PGPSecretKeyRing importKeys = BCUtil.removeUnassociatedKeysFromKeyRing(secretKeys, secretKeys.getPublicKey());
2018-07-08 22:31:35 +02:00
PGPSecretKeyRingCollection secretKeyRings = getSecretKeysOf(owner);
try {
2018-07-09 15:01:15 +02:00
if (secretKeyRings != null) {
2018-07-11 18:47:06 +02:00
secretKeyRings = PGPSecretKeyRingCollection.addSecretKeyRing(secretKeyRings, importKeys);
2018-07-09 15:01:15 +02:00
} else {
2018-07-11 18:47:06 +02:00
secretKeyRings = BCUtil.keyRingsToKeyRingCollection(importKeys);
2018-07-09 15:01:15 +02:00
}
2018-07-08 22:31:35 +02:00
} catch (IllegalArgumentException e) {
2018-07-11 18:47:06 +02:00
LOGGER.log(Level.INFO, "Skipping secret key ring " + Long.toHexString(importKeys.getPublicKey().getKeyID()) +
2018-07-08 22:31:35 +02:00
" as it is already in the key ring of " + owner.toString());
}
this.secretKeyRingCollections.put(owner, secretKeyRings);
2018-07-09 15:01:15 +02:00
importPublicKey(owner, BCUtil.publicKeyRingFromSecretKeyRing(secretKeys));
2018-07-08 22:31:35 +02:00
writeSecretKeysOf(owner, secretKeyRings);
}
@Override
public void importPublicKey(BareJid owner, PGPPublicKeyRing publicKeys) throws IOException, PGPException, MissingUserIdOnKeyException {
if (!new BareJidUserId.PubRingSelectionStrategy().accept(owner, publicKeys)) {
throw new MissingUserIdOnKeyException(owner, publicKeys.getPublicKey().getKeyID());
}
2018-07-11 18:47:06 +02:00
PGPPublicKeyRing importKeys = BCUtil.removeUnassociatedKeysFromKeyRing(publicKeys, publicKeys.getPublicKey());
2018-07-08 22:31:35 +02:00
PGPPublicKeyRingCollection publicKeyRings = getPublicKeysOf(owner);
try {
2018-07-09 15:01:15 +02:00
if (publicKeyRings != null) {
2018-07-11 18:47:06 +02:00
publicKeyRings = PGPPublicKeyRingCollection.addPublicKeyRing(publicKeyRings, importKeys);
2018-07-09 15:01:15 +02:00
} else {
2018-07-11 18:47:06 +02:00
publicKeyRings = BCUtil.keyRingsToKeyRingCollection(importKeys);
2018-07-09 15:01:15 +02:00
}
2018-07-08 22:31:35 +02:00
} catch (IllegalArgumentException e) {
2018-07-11 18:47:06 +02:00
LOGGER.log(Level.INFO, "Skipping public key ring " + Long.toHexString(importKeys.getPublicKey().getKeyID()) +
2018-07-08 22:31:35 +02:00
" as it is already in the key ring of " + owner.toString());
}
this.publicKeyRingCollections.put(owner, publicKeyRings);
writePublicKeysOf(owner, publicKeyRings);
}
2018-07-07 17:58:32 +02:00
@Override
public PGPPublicKeyRing getPublicKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException {
PGPPublicKeyRingCollection publicKeyRings = getPublicKeysOf(owner);
if (publicKeyRings != null) {
return publicKeyRings.getPublicKeyRing(fingerprint.getKeyId());
}
return null;
}
@Override
public PGPSecretKeyRing getSecretKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException {
PGPSecretKeyRingCollection secretKeyRings = getSecretKeysOf(owner);
if (secretKeyRings != null) {
return secretKeyRings.getSecretKeyRing(fingerprint.getKeyId());
}
return null;
}
2018-07-10 16:39:53 +02:00
@Override
public void deletePublicKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException {
PGPPublicKeyRingCollection publicKeyRings = getPublicKeysOf(owner);
if (publicKeyRings.contains(fingerprint.getKeyId())) {
publicKeyRings = PGPPublicKeyRingCollection.removePublicKeyRing(publicKeyRings, publicKeyRings.getPublicKeyRing(fingerprint.getKeyId()));
if (!publicKeyRings.iterator().hasNext()) {
publicKeyRings = null;
}
this.publicKeyRingCollections.put(owner, publicKeyRings);
writePublicKeysOf(owner, publicKeyRings);
}
}
@Override
public void deleteSecretKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException {
PGPSecretKeyRingCollection secretKeyRings = getSecretKeysOf(owner);
if (secretKeyRings.contains(fingerprint.getKeyId())) {
secretKeyRings = PGPSecretKeyRingCollection.removeSecretKeyRing(secretKeyRings, secretKeyRings.getSecretKeyRing(fingerprint.getKeyId()));
if (!secretKeyRings.iterator().hasNext()) {
secretKeyRings = null;
}
this.secretKeyRingCollections.put(owner, secretKeyRings);
writeSecretKeysOf(owner, secretKeyRings);
}
}
2018-07-07 17:58:32 +02:00
@Override
public PGPSecretKeyRing generateKeyRing(BareJid owner)
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
2018-07-11 18:47:06 +02:00
return PGPainless.generateKeyRing().simpleEcKeyRing("xmpp:" + owner.toString());
2018-07-07 17:58:32 +02:00
}
}