mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-23 12:52:07 +01:00
Merge branch 'parse_public_key_ring_collection_from_armored_source'
This commit is contained in:
commit
d0a162ce74
3 changed files with 262 additions and 2 deletions
|
@ -27,6 +27,7 @@ import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.PGPUtil;
|
import org.bouncycastle.openpgp.PGPUtil;
|
||||||
|
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||||
import org.pgpainless.implementation.ImplementationFactory;
|
import org.pgpainless.implementation.ImplementationFactory;
|
||||||
|
|
||||||
public class KeyRingReader {
|
public class KeyRingReader {
|
||||||
|
@ -96,7 +97,7 @@ public class KeyRingReader {
|
||||||
public static PGPPublicKeyRingCollection readPublicKeyRingCollection(@Nonnull InputStream inputStream)
|
public static PGPPublicKeyRingCollection readPublicKeyRingCollection(@Nonnull InputStream inputStream)
|
||||||
throws IOException, PGPException {
|
throws IOException, PGPException {
|
||||||
return new PGPPublicKeyRingCollection(
|
return new PGPPublicKeyRingCollection(
|
||||||
PGPUtil.getDecoderStream(inputStream),
|
getDecoderStream(inputStream),
|
||||||
ImplementationFactory.getInstance().getKeyFingerprintCalculator());
|
ImplementationFactory.getInstance().getKeyFingerprintCalculator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ public class KeyRingReader {
|
||||||
public static PGPSecretKeyRingCollection readSecretKeyRingCollection(@Nonnull InputStream inputStream)
|
public static PGPSecretKeyRingCollection readSecretKeyRingCollection(@Nonnull InputStream inputStream)
|
||||||
throws IOException, PGPException {
|
throws IOException, PGPException {
|
||||||
return new PGPSecretKeyRingCollection(
|
return new PGPSecretKeyRingCollection(
|
||||||
PGPUtil.getDecoderStream(inputStream),
|
getDecoderStream(inputStream),
|
||||||
ImplementationFactory.getInstance().getKeyFingerprintCalculator());
|
ImplementationFactory.getInstance().getKeyFingerprintCalculator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,4 +133,23 @@ public class KeyRingReader {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hacky workaround for #96.
|
||||||
|
* For {@link PGPPublicKeyRingCollection#PGPPublicKeyRingCollection(InputStream, KeyFingerPrintCalculator)}
|
||||||
|
* or {@link PGPSecretKeyRingCollection#PGPSecretKeyRingCollection(InputStream, KeyFingerPrintCalculator)}
|
||||||
|
* to read all PGPKeyRings properly, we apparently have to make sure that the {@link InputStream} that is given
|
||||||
|
* as constructor argument is a {@link PGPUtil.BufferedInputStreamExt}.
|
||||||
|
* Since {@link PGPUtil#getDecoderStream(InputStream)} will return an {@link org.bouncycastle.bcpg.ArmoredInputStream}
|
||||||
|
* if the underlying input stream contains armored data, we have to nest two method calls to make sure that the
|
||||||
|
* end-result is a {@link PGPUtil.BufferedInputStreamExt}.
|
||||||
|
*
|
||||||
|
* This is a hacky solution.
|
||||||
|
*
|
||||||
|
* @param inputStream input stream
|
||||||
|
* @return BufferedInputStreamExt
|
||||||
|
*/
|
||||||
|
private static InputStream getDecoderStream(InputStream inputStream) throws IOException {
|
||||||
|
return PGPUtil.getDecoderStream(PGPUtil.getDecoderStream(inputStream));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 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.pgpainless.key.parsing;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.bouncycastle.openpgp.PGPUtil;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.pgpainless.PGPainless;
|
||||||
|
import org.pgpainless.implementation.ImplementationFactory;
|
||||||
|
import org.pgpainless.key.util.KeyRingUtils;
|
||||||
|
|
||||||
|
class KeyRingReaderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void assertThatPGPUtilsDetectAsciiArmoredData() throws IOException, PGPException {
|
||||||
|
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("pub_keys_10_pieces.asc");
|
||||||
|
|
||||||
|
InputStream possiblyArmored = PGPUtil.getDecoderStream(PGPUtil.getDecoderStream(inputStream));
|
||||||
|
|
||||||
|
PGPPublicKeyRingCollection collection = new PGPPublicKeyRingCollection(
|
||||||
|
possiblyArmored, ImplementationFactory.getInstance().getKeyFingerprintCalculator());
|
||||||
|
assertEquals(10, collection.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void publicKeyRingCollectionFromStream() throws IOException, PGPException {
|
||||||
|
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("pub_keys_10_pieces.asc");
|
||||||
|
PGPPublicKeyRingCollection rings = PGPainless.readKeyRing().publicKeyRingCollection(inputStream);
|
||||||
|
assertEquals(10, rings.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void publicKeyRingCollectionFromNotArmoredStream() throws IOException, PGPException,
|
||||||
|
InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||||
|
Collection<PGPPublicKeyRing> collection = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
PGPSecretKeyRing secretKeys = PGPainless.generateKeyRing().simpleEcKeyRing("user_" + i + "@encrypted.key");
|
||||||
|
collection.add(KeyRingUtils.publicKeyRingFrom(secretKeys));
|
||||||
|
}
|
||||||
|
|
||||||
|
PGPPublicKeyRingCollection originalRings = new PGPPublicKeyRingCollection(collection);
|
||||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
originalRings.encode(out);
|
||||||
|
|
||||||
|
ByteArrayInputStream inputStream = new ByteArrayInputStream(out.toByteArray());
|
||||||
|
PGPPublicKeyRingCollection parsedRings = PGPainless.readKeyRing().publicKeyRingCollection(inputStream);
|
||||||
|
assertEquals(10, parsedRings.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void publicKeyRingCollectionFromString() throws IOException, PGPException, URISyntaxException {
|
||||||
|
URL resource = getClass().getClassLoader().getResource("pub_keys_10_pieces.asc");
|
||||||
|
String armoredString = new String(Files.readAllBytes(new File(resource.toURI()).toPath()));
|
||||||
|
InputStream inputStream = new ByteArrayInputStream(armoredString.getBytes(StandardCharsets.UTF_8));
|
||||||
|
PGPPublicKeyRingCollection rings = PGPainless.readKeyRing().publicKeyRingCollection(inputStream);
|
||||||
|
assertEquals(10, rings.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void publicKeyRingCollectionFromBytes() throws IOException, PGPException, URISyntaxException {
|
||||||
|
URL resource = getClass().getClassLoader().getResource("pub_keys_10_pieces.asc");
|
||||||
|
byte[] bytes = Files.readAllBytes(new File(resource.toURI()).toPath());
|
||||||
|
InputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
|
||||||
|
PGPPublicKeyRingCollection rings = PGPainless.readKeyRing().publicKeyRingCollection(byteArrayInputStream);
|
||||||
|
assertEquals(10, rings.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
139
pgpainless-core/src/test/resources/pub_keys_10_pieces.asc
Normal file
139
pgpainless-core/src/test/resources/pub_keys_10_pieces.asc
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdAyfub9GUlTvuIicT6gnLTe5IK7ulwRjh6AmNW
|
||||||
|
9pGVpb60E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEJSMRVGPhjdgOUABAIU80GMm2v8oWrQyctAi
|
||||||
|
VhpkRhNXFBoxzV2Ocg47eWukAQCHjjA10tTIzq5umoNXrb1vLXmubzT77fXJwFA2
|
||||||
|
qUonD7g4BGBR3XISCisGAQQBl1UBBQEBB0AZuOnF7dxM/+U9kZtHkf4ze9mlm7mF
|
||||||
|
nzt2ugq/LrgLKAMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEJSMRVGPhjdghv8BAMYlDl20Kn3K1KWFBSU8bw7OZsgz5ppzEywU/xpr
|
||||||
|
v2yHAP470or42l5oTh/xAnWQEReD0d5pnh5fIKkeWBQTL7Y9Bg==
|
||||||
|
=L01J
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdA3zRVckfne2fxGDOv5c2Tm7C4Azxbc+CZKP1R
|
||||||
|
+XjpLKG0E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEBOTT2Wz+JaqlwwA/3k6FiMD9hsPATpPgsmB
|
||||||
|
dG6oz/pklaMlUvEzCh7NFRQqAP40nX6T3L4UwYbrvm4FXTle3DaL98DfFjH8ox1N
|
||||||
|
e/ziC7g4BGBR3XISCisGAQQBl1UBBQEBB0BRwE/EJ/ocQ3nqm4jv8tB0nYYliJ72
|
||||||
|
tvDVQhsD4mQLIAMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEBOTT2Wz+JaqztIBAJvwyo0pw+q+48MYd0yIKRavkJ2Y71msPwSQ7Tnj
|
||||||
|
gK7ZAQDW9L8pc9m1WISpI4HqVUGBbiaEm/U9vdNZ22fiehK+Dw==
|
||||||
|
=F7rW
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdA4N4vZfhHcDvneIkPyTnBt4Ms3MSJAUwnxKKa
|
||||||
|
hFs7tKS0E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEONPfCWrUaykZC8BAJ0QAfFQAT4rSx3SWc8I
|
||||||
|
FTHIflpj6G9OiV5EZcbDlUArAP0XtetsnNdba5wpeITZpL+/L3lgeb9pphr/rA/8
|
||||||
|
/LLYDbg4BGBR3XISCisGAQQBl1UBBQEBB0DDwrx6U+u5yTlagwJHlSenorBjF6B2
|
||||||
|
dAhNwblxhGA8fQMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEONPfCWrUaykxQgBANUWnD5V2HhWTmi0ArVNKivW4Mvtj8GnH1m37qPp
|
||||||
|
3D8VAP9SLOQrdGj1kFBtQSefkUCgMHdT1cddL919y8nRIevdAw==
|
||||||
|
=9/eE
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdAflONZMOFFXT8HEwrjeRowixJ/CQwu1jF8WIf
|
||||||
|
I4MYreq0E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEGUsIC1Do6/1JisBAKTbbh6CaxhR9C0GqGMq
|
||||||
|
Bd7y36wkd+qw7MyR63dUj/6MAQCkt+4h/YbiWnMFL1pLY+u5rERyyT4zDlZTDDV0
|
||||||
|
vHsUB7g4BGBR3XISCisGAQQBl1UBBQEBB0AEFOE5+gHfw50UxFxY2MGT6e/M2oUB
|
||||||
|
MBaOsIsVOPuZZwMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEGUsIC1Do6/1EusBAL/IRKILeXCwAnXGfpnO3smCFSsGtCYJ1rhVaYhj
|
||||||
|
zeVtAP47EXBKYvhbHgRy+Qx2BMFXX+VGFA2hWHZbo9OhbPpTAg==
|
||||||
|
=cCbp
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdAYXkCPGptUC4P0LeQCC0kzi5PnzcZAFfX8S5b
|
||||||
|
t8hRITy0E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEIJgTO3chyrRB2UA+wfyFgnPEd8xkAwlPPJ7
|
||||||
|
Bo0Ou6qFWzgigG1mGw2yHfogAQD5SW73I2bByhyP8LfyYRSQGjM6msxkECVDEVUw
|
||||||
|
/hxaCbg4BGBR3XISCisGAQQBl1UBBQEBB0DUh3Sai70XUwzPQpe2mqppwn9ApUCk
|
||||||
|
hStE1Giy4bzNdgMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEIJgTO3chyrRgusA/3TbfgIiRL3Ype2LlfEZ2evyo1T8hQlH5yOmbKGW
|
||||||
|
UxOIAQDWufEmTWpeV+bWfSkcb1C7dU8wSvM78GvAMMESrxozCw==
|
||||||
|
=stfa
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdAPybWtX75zj1GIjPEITKpjyG7MccvPLoU9HrU
|
||||||
|
d3QwWmO0E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEI1HfhWTysXbKqAA/igvr9eCnSGKzYD6KnrZ
|
||||||
|
wd6MKM4OD5NsiX6DkCew/AaPAQDK9lyRdibbR52CNVeueVYkCbMaPohChf9nvx2M
|
||||||
|
4XLcBbg4BGBR3XISCisGAQQBl1UBBQEBB0AfsNRAXC/naStyC9666gAOtgEOqQ3e
|
||||||
|
XhxgfITehCabBQMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEI1HfhWTysXb2AIBALmv9be7RWcRnHvvVw3sCqzH5P3dQlOiYkzp++wj
|
||||||
|
HFBQAQC1XRes+v9nawkkQPLL6W6TTdJsrqdRTghLO9oWad7DAQ==
|
||||||
|
=ILBW
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdAtW6tSlO27WD5JWBmfzfmy/VLcB7yfPdvqxux
|
||||||
|
byKVk6O0E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEP9Vh6wldIQkKwABAKC8xwjkT4qeOWV2bKu/
|
||||||
|
3C7a1T4hlhQtRqSiFcdK9pDrAQCAdN1+XDkoKz6b717PcRc+6vhUJWGO4GaoCucS
|
||||||
|
cIuiD7g4BGBR3XISCisGAQQBl1UBBQEBB0C5b5/Zh4wZUOqihUebwjS8djSDvn2h
|
||||||
|
AuzD3w0FKXgiGQMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEP9Vh6wldIQkjxIBAOx8lL/3oYnA5CxueagTmGJSl8CvFiirnfzDF34/
|
||||||
|
zCx6AP9viCSUII6a9z2vphe7XWRm1VOZNDG4R5Pzg2x32B7tAQ==
|
||||||
|
=oiKv
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdAo0Hx0pRqnU4mZwfK3CgwzV53QHhMIfltKOM8
|
||||||
|
i6kzIN60E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEMrL/Yggs136P+kA/3doLAoG5jju2MZFZAeW
|
||||||
|
zeBQFCfb103lvYeWGxU9BlhNAP49Ce/Y8SsokcQwmsR8datld+Pe/QmF4/zQl2+R
|
||||||
|
D30tB7g4BGBR3XISCisGAQQBl1UBBQEBB0DOngNGofghQ3QrqoO/WUJ958cJMGmE
|
||||||
|
wInz5Gfiby0BOAMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEMrL/Yggs1365w0A/26IRKTvZpcIGIypXY5B9v5MySrCJJeMFaBTZ2oP
|
||||||
|
q0MDAP9vWnMlAbAGkdRqbw6uA+rKuTyTnOR7sIroMWQXOy9pBw==
|
||||||
|
=5H8m
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdA8RbR/TCSQTRszBfELI+TckBaXusWSzQWmJ+A
|
||||||
|
m6R2vdO0E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJECFoxR5ec+rpzCsBAOPe/5BHmPuS6lRDPFK2
|
||||||
|
Ww2lgEaCo0z88mLKp2DTzzwlAQDlnlrUpA0huJLmI0qqAi+eH0bgUwciqmsC7/4d
|
||||||
|
6/6sCbg4BGBR3XISCisGAQQBl1UBBQEBB0ASLlXkJvhzAihOff7OLGQNlyD/+lCQ
|
||||||
|
1/qu/Ojr5GVbCwMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJECFoxR5ec+rptOcA/iBkqa5nJNM03BDEyBaz87Ez28K5L8vltRwBUE/+
|
||||||
|
LIrJAP43S3skfM1ErB/BPFv9YJzoTVaY5vESyEYoB6sw1H4iCA==
|
||||||
|
=wnXr
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: PGPainless
|
||||||
|
|
||||||
|
mDMEYFHdchYJKwYBBAHaRw8BAQdA7qoKX7JDTjgbrnFKLfb43veznuC7z4KJ7acI
|
||||||
|
dXZI2om0E2ZyZXNoQGVuY3J5cHRlZC5rZXmIeAQTFgoAIAUCYFHdcgIbAwUWAgMB
|
||||||
|
AAQLCQgHBRUKCQgLAh4BAhkBAAoJEON4/e8A5cOx9c0BAPtneXwDhnhrtqG7JSue
|
||||||
|
0youMdGRCzKd8mfAkao/JAu+AP9TKRY6aqLQtwWUEhAUfE6TEic3x+WRlYAGBp7I
|
||||||
|
5XPpDLg4BGBR3XISCisGAQQBl1UBBQEBB0DSEcmogCWdMfhfmq7MlWuuzj9BuJo+
|
||||||
|
qdrEvcSyAOolaAMBCAeIdQQYFgoAHQUCYFHdcgIbDAUWAgMBAAQLCQgHBRUKCQgL
|
||||||
|
Ah4BAAoJEON4/e8A5cOxpusA/iyib7m5aFuStRWlBs9MYfmEv3vbDGrDZoN+6wj0
|
||||||
|
U3y7AQDskovK4Wd/vf2ljUOxP6knS01zriQpHy9ro5Qgi8bTCQ==
|
||||||
|
=p/wh
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
Loading…
Reference in a new issue