mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-14 16:32:06 +01:00
Kotlin conversion: PGPKeyRingCollection
This commit is contained in:
parent
a50b8cb200
commit
2025f18478
4 changed files with 100 additions and 124 deletions
|
@ -1,114 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org>, 2021 Flowcrypt a.s.
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package org.pgpainless.key.collection;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
|
||||||
import org.bouncycastle.openpgp.PGPKeyRing;
|
|
||||||
import org.bouncycastle.openpgp.PGPMarker;
|
|
||||||
import org.bouncycastle.openpgp.PGPObjectFactory;
|
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
|
||||||
import org.pgpainless.implementation.ImplementationFactory;
|
|
||||||
import org.pgpainless.util.ArmorUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class describes a logic of handling a collection of different {@link PGPKeyRing}. The logic was inspired by
|
|
||||||
* {@link PGPSecretKeyRingCollection} and {@link PGPPublicKeyRingCollection}.
|
|
||||||
*/
|
|
||||||
public class PGPKeyRingCollection {
|
|
||||||
|
|
||||||
private final PGPSecretKeyRingCollection pgpSecretKeyRingCollection;
|
|
||||||
private final PGPPublicKeyRingCollection pgpPublicKeyRingCollection;
|
|
||||||
|
|
||||||
public PGPKeyRingCollection(@Nonnull byte[] encoding, boolean isSilent) throws IOException, PGPException {
|
|
||||||
this(new ByteArrayInputStream(encoding), isSilent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a {@link PGPKeyRingCollection} from the passed in input stream.
|
|
||||||
*
|
|
||||||
* @param in input stream containing data
|
|
||||||
* @param isSilent flag indicating that unsupported objects will be ignored
|
|
||||||
* @throws IOException if a problem parsing the base stream occurs
|
|
||||||
* @throws PGPException if an object is encountered which isn't a {@link PGPSecretKeyRing} or {@link PGPPublicKeyRing}
|
|
||||||
*/
|
|
||||||
public PGPKeyRingCollection(@Nonnull InputStream in, boolean isSilent) throws IOException, PGPException {
|
|
||||||
// Double getDecoderStream because of #96
|
|
||||||
InputStream decoderStream = ArmorUtils.getDecoderStream(in);
|
|
||||||
PGPObjectFactory pgpFact = ImplementationFactory.getInstance().getPGPObjectFactory(decoderStream);
|
|
||||||
Object obj;
|
|
||||||
|
|
||||||
List<PGPSecretKeyRing> secretKeyRings = new ArrayList<>();
|
|
||||||
List<PGPPublicKeyRing> publicKeyRings = new ArrayList<>();
|
|
||||||
|
|
||||||
while ((obj = pgpFact.nextObject()) != null) {
|
|
||||||
if (obj instanceof PGPMarker) {
|
|
||||||
// Skip marker packets
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (obj instanceof PGPSecretKeyRing) {
|
|
||||||
secretKeyRings.add((PGPSecretKeyRing) obj);
|
|
||||||
} else if (obj instanceof PGPPublicKeyRing) {
|
|
||||||
publicKeyRings.add((PGPPublicKeyRing) obj);
|
|
||||||
} else if (!isSilent) {
|
|
||||||
throw new PGPException(obj.getClass().getName() + " found where " +
|
|
||||||
PGPSecretKeyRing.class.getSimpleName() + " or " +
|
|
||||||
PGPPublicKeyRing.class.getSimpleName() + " expected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pgpSecretKeyRingCollection = new PGPSecretKeyRingCollection(secretKeyRings);
|
|
||||||
pgpPublicKeyRingCollection = new PGPPublicKeyRingCollection(publicKeyRings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PGPKeyRingCollection(@Nonnull Collection<PGPKeyRing> collection, boolean isSilent)
|
|
||||||
throws PGPException {
|
|
||||||
List<PGPSecretKeyRing> secretKeyRings = new ArrayList<>();
|
|
||||||
List<PGPPublicKeyRing> publicKeyRings = new ArrayList<>();
|
|
||||||
|
|
||||||
for (PGPKeyRing pgpKeyRing : collection) {
|
|
||||||
if (pgpKeyRing instanceof PGPSecretKeyRing) {
|
|
||||||
secretKeyRings.add((PGPSecretKeyRing) pgpKeyRing);
|
|
||||||
} else if (pgpKeyRing instanceof PGPPublicKeyRing) {
|
|
||||||
publicKeyRings.add((PGPPublicKeyRing) pgpKeyRing);
|
|
||||||
} else if (!isSilent) {
|
|
||||||
throw new PGPException(pgpKeyRing.getClass().getName() + " found where " +
|
|
||||||
PGPSecretKeyRing.class.getSimpleName() + " or " +
|
|
||||||
PGPPublicKeyRing.class.getSimpleName() + " expected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pgpSecretKeyRingCollection = new PGPSecretKeyRingCollection(secretKeyRings);
|
|
||||||
pgpPublicKeyRingCollection = new PGPPublicKeyRingCollection(publicKeyRings);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nonnull PGPSecretKeyRingCollection getPGPSecretKeyRingCollection() {
|
|
||||||
return pgpSecretKeyRingCollection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @Nonnull PGPPublicKeyRingCollection getPgpPublicKeyRingCollection() {
|
|
||||||
return pgpPublicKeyRingCollection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the number of rings in this collection.
|
|
||||||
*
|
|
||||||
* @return total size of {@link PGPSecretKeyRingCollection} and {@link PGPPublicKeyRingCollection}
|
|
||||||
* in this collection
|
|
||||||
*/
|
|
||||||
public int size() {
|
|
||||||
return pgpSecretKeyRingCollection.size() + pgpPublicKeyRingCollection.size();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2018 Paul Schaub <vanitasvitae@fsfe.org>
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OpenPGP key collections.
|
|
||||||
*/
|
|
||||||
package org.pgpainless.key.collection;
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 Paul Schaub <vanitasvitae@fsfe.org>, 2021 Flowcrypt a.s.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package org.pgpainless.key.collection
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.*
|
||||||
|
import org.pgpainless.implementation.ImplementationFactory
|
||||||
|
import org.pgpainless.util.ArmorUtils
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class describes a logic of handling a collection of different [PGPKeyRing]. The logic was inspired by
|
||||||
|
* [PGPSecretKeyRingCollection] and [PGPPublicKeyRingCollection].
|
||||||
|
*/
|
||||||
|
class PGPKeyRingCollection(
|
||||||
|
val pgpSecretKeyRingCollection: PGPSecretKeyRingCollection,
|
||||||
|
val pgpPublicKeyRingCollection: PGPPublicKeyRingCollection
|
||||||
|
) {
|
||||||
|
|
||||||
|
constructor(encoding: ByteArray, isSilent: Boolean): this(encoding.inputStream(), isSilent)
|
||||||
|
|
||||||
|
constructor(inputStream: InputStream, isSilent: Boolean): this(parse(inputStream, isSilent))
|
||||||
|
|
||||||
|
constructor(collection: Collection<PGPKeyRing>, isSilent: Boolean): this(segment(collection, isSilent))
|
||||||
|
|
||||||
|
private constructor(arguments: Pair<PGPSecretKeyRingCollection, PGPPublicKeyRingCollection>): this(arguments.first, arguments.second)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of rings in this collection.
|
||||||
|
*
|
||||||
|
* @return total size of [PGPSecretKeyRingCollection] plus [PGPPublicKeyRingCollection] in this collection
|
||||||
|
*/
|
||||||
|
val size: Int
|
||||||
|
get() = pgpSecretKeyRingCollection.size() + pgpPublicKeyRingCollection.size()
|
||||||
|
|
||||||
|
fun size() = size
|
||||||
|
|
||||||
|
@Deprecated("Wrong case of PGP -> Pgp", ReplaceWith("getPgpSecretKeyRingCollection()"))
|
||||||
|
fun getPGPSecretKeyRingCollection() = pgpSecretKeyRingCollection
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic
|
||||||
|
private fun parse(inputStream: InputStream, isSilent: Boolean): Pair<PGPSecretKeyRingCollection, PGPPublicKeyRingCollection> {
|
||||||
|
val secretKeyRings = mutableListOf<PGPSecretKeyRing>()
|
||||||
|
val certificates = mutableListOf<PGPPublicKeyRing>()
|
||||||
|
// Double getDecoderStream because of #96
|
||||||
|
val objectFactory = ImplementationFactory.getInstance().getPGPObjectFactory(ArmorUtils.getDecoderStream(inputStream))
|
||||||
|
|
||||||
|
for (obj in objectFactory) {
|
||||||
|
if (obj == null) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj is PGPMarker) {
|
||||||
|
// Skip marker packets
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj is PGPSecretKeyRing) {
|
||||||
|
secretKeyRings.add(obj)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj is PGPPublicKeyRing) {
|
||||||
|
certificates.add(obj)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSilent) {
|
||||||
|
throw PGPException("${obj.javaClass.name} found where ${PGPSecretKeyRing::class.java.simpleName}" +
|
||||||
|
" or ${PGPPublicKeyRing::class.java.simpleName} expected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PGPSecretKeyRingCollection(secretKeyRings) to PGPPublicKeyRingCollection(certificates)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
private fun segment(collection: Collection<PGPKeyRing>, isSilent: Boolean): Pair<PGPSecretKeyRingCollection, PGPPublicKeyRingCollection> {
|
||||||
|
val secretKeyRings = mutableListOf<PGPSecretKeyRing>()
|
||||||
|
val certificates = mutableListOf<PGPPublicKeyRing>()
|
||||||
|
|
||||||
|
for (keyRing in collection) {
|
||||||
|
if (keyRing is PGPSecretKeyRing) {
|
||||||
|
secretKeyRings.add(keyRing)
|
||||||
|
} else if (keyRing is PGPPublicKeyRing) {
|
||||||
|
certificates.add(keyRing)
|
||||||
|
} else if (!isSilent) {
|
||||||
|
throw PGPException("${keyRing.javaClass.name} found where ${PGPSecretKeyRing::class.java.simpleName}" +
|
||||||
|
" or ${PGPPublicKeyRing::class.java.simpleName} expected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PGPSecretKeyRingCollection(secretKeyRings) to PGPPublicKeyRingCollection(certificates)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ public class PGPKeyRingCollectionTest {
|
||||||
// silent = true -> No exception, but not keys either
|
// silent = true -> No exception, but not keys either
|
||||||
PGPKeyRingCollection collection = new PGPKeyRingCollection(bytes, true);
|
PGPKeyRingCollection collection = new PGPKeyRingCollection(bytes, true);
|
||||||
assertEquals(0, collection.getPgpPublicKeyRingCollection().size());
|
assertEquals(0, collection.getPgpPublicKeyRingCollection().size());
|
||||||
assertEquals(0, collection.getPGPSecretKeyRingCollection().size());
|
assertEquals(0, collection.getPgpSecretKeyRingCollection().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -63,7 +63,7 @@ public class PGPKeyRingCollectionTest {
|
||||||
Collection<PGPKeyRing> keys = Arrays.asList(first, second, secondPub);
|
Collection<PGPKeyRing> keys = Arrays.asList(first, second, secondPub);
|
||||||
|
|
||||||
PGPKeyRingCollection collection = new PGPKeyRingCollection(keys, true);
|
PGPKeyRingCollection collection = new PGPKeyRingCollection(keys, true);
|
||||||
assertEquals(2, collection.getPGPSecretKeyRingCollection().size());
|
assertEquals(2, collection.getPgpSecretKeyRingCollection().size());
|
||||||
assertEquals(1, collection.getPgpPublicKeyRingCollection().size());
|
assertEquals(1, collection.getPgpPublicKeyRingCollection().size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue