add support of password protected pgp keys
parent
2a0ddd43af
commit
d9cf671b98
|
@ -3,8 +3,8 @@ FROM python:${PYTHON_RELEASE}-alpine as dist
|
|||
LABEL maintainer aynic.os <support+docker@asycn.io>
|
||||
|
||||
ARG DOCKER_BUILD_DIR=.
|
||||
ARG OPERATING_SYSTEM=Linux
|
||||
ARG PROCESSOR_ARCHITECTURE=x86_64
|
||||
ARG OPERATING_SYSTEM=$(uname -s)
|
||||
ARG PROCESSOR_ARCHITECTURE=$(uname -m)
|
||||
ARG PYTHON_RELEASE=3.10
|
||||
|
||||
WORKDIR /opt/dpgpid
|
||||
|
@ -19,7 +19,7 @@ RUN apk upgrade --no-cache \
|
|||
&& /usr/local/bin/python${PYTHON_RELEASE} -m venv ./ \
|
||||
&& ./bin/pip${PYTHON_RELEASE} install -U pip wheel \
|
||||
&& ./bin/pip${PYTHON_RELEASE} install -r ./requirements.txt \
|
||||
&& wget https://github.com/libp2p/go-libp2p-core/raw/master/crypto/pb/crypto.proto \
|
||||
&& wget https://raw.githubusercontent.com/libp2p/go-libp2p/master/core/crypto/pb/crypto.proto \
|
||||
&& protoc --python_out=./lib/python${PYTHON_RELEASE}/site-packages/ crypto.proto \
|
||||
&& cp -a /usr/lib/python${PYTHON_RELEASE}/site-packages/gpg ./lib/python${PYTHON_RELEASE}/site-packages/ \
|
||||
&& rm -rf /root/.cache ./build ./crypto.proto \
|
||||
|
@ -48,7 +48,7 @@ RUN apk add --no-cache \
|
|||
|tar --strip-components 1 -C /opt/shellspec -xzf - \
|
||||
&& ln -s /opt/shellspec/shellspec ./bin/shellspec
|
||||
|
||||
COPY --from=ipfs/go-ipfs:v0.13.0 /usr/local/bin/ipfs ./bin/
|
||||
COPY --from=ipfs/kubo:v0.14.0 /usr/local/bin/ipfs ./bin/
|
||||
COPY README.md ./
|
||||
COPY COPYING ./
|
||||
COPY Makefile ./
|
||||
|
@ -66,27 +66,38 @@ FROM dist as master
|
|||
ARG UID
|
||||
ARG USER
|
||||
ENV UID=${UID:-999}
|
||||
ENV GID=${UID}
|
||||
ENV USER=dpgpid
|
||||
|
||||
# If we provide a specific UID
|
||||
RUN let $UID >/dev/null 2>&1 \
|
||||
# Remove user with $UID if it is not our $USER
|
||||
&& if [ "$(getent passwd $UID |awk 'BEGIN {FS=":"} {print $1}')" != "$USER" ]; then \
|
||||
sed -i '/^'$(getent passwd $UID |awk 'BEGIN {FS=":"} {print $1}')':x:'$UID':/d' /etc/passwd; \
|
||||
sed -i '/^'$(getent group $GID |awk 'BEGIN {FS=":"} {print $1}')':x:'$GID':/d' /etc/group; \
|
||||
fi \
|
||||
# Force $UID if our $USER already exists
|
||||
&& sed -i 's/^'$USER':x:[0-9]\+:[0-9]\+:/'$USER':x:'$UID':'$GID':/' /etc/passwd \
|
||||
&& sed -i 's/^'$USER':x:[0-9]\+:/'$USER':x:'$GID':/' /etc/group \
|
||||
# Create $USER if it does not exist
|
||||
&& if [ "$(getent passwd $UID)" = "" ]; then \
|
||||
echo "$USER:x:$UID:$GID::/home/$USER:/bin/false" >> /etc/passwd; \
|
||||
echo "$USER:!:$(($(date +%s) / 60 / 60 / 24)):0:99999:7:::" >> /etc/shadow; \
|
||||
echo "$USER:x:$GID:" >> /etc/group; \
|
||||
fi \
|
||||
&& mkdir -p /home/$USER \
|
||||
&& chown $UID:$GID /home/$USER \
|
||||
|| true
|
||||
# If we provide a numeric UID
|
||||
RUN if [ "${UID}" -eq "${UID}" ] 2>/dev/null; then \
|
||||
# Force $UID of $USER if it exists
|
||||
if [ "$(awk -F: '$1 == "'"${USER}"'" {print $3}' /etc/passwd)" != "${UID}" ]; then \
|
||||
sed -i 's/^\('"${USER}"':x\):[0-9]\+:/\1:'"${UID}"':/' /etc/passwd; \
|
||||
fi; \
|
||||
# Create $USER if $UID does not exist
|
||||
if [ "$(awk -F: '$3 == "'"${UID}"'" {print $1}' /etc/passwd)" = "" ]; then \
|
||||
echo "${USER}:x:${UID}:${GID:-${UID}}::/home/${USER}:${SHELL:-/bin/sh}" >> /etc/passwd; \
|
||||
echo "${USER}:\!:$(($(date +%s) / 60 / 60 / 24)):0:99999:7:::" >> /etc/shadow; \
|
||||
mkdir -p /home/"${USER}"; \
|
||||
fi; \
|
||||
chown "${UID}" $(awk -F: '$1 == "'"${USER}"'" {print $(NF-1)}' /etc/passwd); \
|
||||
fi
|
||||
|
||||
# If we provide a numeric GID
|
||||
RUN if [ "${GID}" -eq "${GID}" ] 2>/dev/null; then \
|
||||
# Force $GID of $GROUP if it already exists
|
||||
if [ "$(awk -F: '$1 == "'"${GROUP}"'" {print $3}' /etc/group)" != "${GID}" ]; then \
|
||||
sed -i 's/^\('"${GROUP}"':x\):[0-9]\+:/\1:'"${GID}"':/' /etc/group; \
|
||||
fi; \
|
||||
# Create $GROUP if $GID does not exist
|
||||
if [ "$(awk -F: '$3 == "'"${GID}"'" {print $1}' /etc/group)" = "" ]; then \
|
||||
echo "${GROUP}:x:${GID}:" >> /etc/group; \
|
||||
fi; \
|
||||
# Force $GID of $USER if it exists
|
||||
if [ "$(awk -F: '$1 == "'"${USER}"'" {print $4}' /etc/passwd)" != "${GID}" ]; then \
|
||||
sed -i 's/^\('"${USER}"':x:[0-9]\+\):[0-9]\+:/\1:'"${GID}"':/' /etc/passwd; \
|
||||
fi; \
|
||||
chgrp "${GID}" $(awk -F: '$1 == "'"${USER}"'" {print $(NF-1)}' /etc/passwd); \
|
||||
fi
|
||||
|
||||
USER $USER
|
||||
|
|
72
keygen
72
keygen
|
@ -35,12 +35,14 @@ import gpg
|
|||
import nacl.bindings
|
||||
import nacl.encoding
|
||||
import pgpy
|
||||
import pynentry
|
||||
import logging as log
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
import warnings
|
||||
|
||||
__version__='0.0.1'
|
||||
|
||||
|
@ -109,7 +111,6 @@ class keygen:
|
|||
def _check_args(self, args):
|
||||
log.debug("def keygen._check_args(self, args)")
|
||||
log.debug("self.username=%s" % self.username)
|
||||
log.debug("self.password=%s" % self.password)
|
||||
if self.input is None:
|
||||
if self.password is None:
|
||||
if self.username is None or args.gpg is False:
|
||||
|
@ -212,27 +213,73 @@ sec: {self.base58_secret_key}
|
|||
def ed25519_from_gpg(self):
|
||||
log.debug("def keygen.ed25519_from_gpg(self)")
|
||||
self.gpg_pubkeys = list(self.gpg.keylist(pattern=self.username, secret=False))
|
||||
self.gpg_seckeys = list(self.gpg.keylist(pattern=self.username, secret=True))
|
||||
log.debug("self.gpg_pubkeys=%s" % self.gpg_pubkeys)
|
||||
self.gpg_seckeys = list(self.gpg.keylist(pattern=self.username, secret=True))
|
||||
log.debug("self.gpg_seckeys=%s" % self.gpg_seckeys)
|
||||
self.gpg_seckey = self.gpg_seckeys[0]
|
||||
if not self.gpg_seckeys:
|
||||
log.error(f"""Unable to find any key matching username "{self.username}".""")
|
||||
exit(1)
|
||||
else:
|
||||
self.gpg_seckey = self.gpg_seckeys[0]
|
||||
log.info(f"""Found key id "{self.gpg_seckey.fpr}" matching username "{self.username}".""")
|
||||
log.debug("self.gpg_seckey.__repr__=%s" % self.gpg_seckey.__repr__)
|
||||
log.debug("self.gpg_seckey.fpr=%s" % self.gpg_seckey.fpr)
|
||||
log.debug("self.gpg_seckey.key=%s" % self.gpg_seckey.__repr__)
|
||||
self.armored_pgp_public_key = self.gpg.key_export(self.gpg_seckey.fpr)
|
||||
self.armored_pgp_secret_key = self.gpg.key_export_secret(self.gpg_seckey.fpr)
|
||||
log.debug("self.armored_pgp_public_key=%s" % self.armored_pgp_public_key)
|
||||
if self.password:
|
||||
self.gpg.set_pinentry_mode(gpg.constants.PINENTRY_MODE_LOOPBACK)
|
||||
self.armored_pgp_secret_key = self.gpg.key_export_secret(self.gpg_seckey.fpr)
|
||||
log.debug("self.armored_pgp_secret_key=%s" % self.armored_pgp_secret_key)
|
||||
self.pgpy, _ = pgpy.PGPKey.from_blob(self.armored_pgp_secret_key)
|
||||
log.debug("self.pgpy.fingerprint.keyid=%s" % self.pgpy.fingerprint.keyid)
|
||||
if not self.armored_pgp_secret_key:
|
||||
log.error(f"""Unable to export secret key id "{self.gpg_seckey.fpr}" of user "{self.username}". Please check your password!""")
|
||||
exit(2)
|
||||
with warnings.catch_warnings():
|
||||
# remove CryptographyDeprecationWarning about deprecated
|
||||
# SymmetricKeyAlgorithm IDEA, CAST5 and Blowfish (PGPy v0.5.4)
|
||||
warnings.simplefilter('ignore')
|
||||
self.pgpy, _ = pgpy.PGPKey.from_blob(self.armored_pgp_secret_key)
|
||||
self.ed25519_from_pgpy()
|
||||
|
||||
def ed25519_from_pgpy(self):
|
||||
log.debug("def keygen.ed25519_from_pgpy(self)")
|
||||
self.pgpy_key_seed()
|
||||
log.debug("self.pgpy.fingerprint.keyid=%s" % self.pgpy.fingerprint.keyid)
|
||||
log.debug("self.pgpy.is_protected=%s" % self.pgpy.is_protected)
|
||||
if self.pgpy.is_protected:
|
||||
if not self.password:
|
||||
with pynentry.PynEntry() as p:
|
||||
p.description = f"""The exported key id "{self.pgpy.fingerprint.keyid}" of user "{self.username}" is password protected.
|
||||
Please enter the passphrase again to unlock it.
|
||||
"""
|
||||
p.prompt = 'Passphrase:'
|
||||
try:
|
||||
self.password = p.get_pin()
|
||||
except pynentry.PinEntryCancelled:
|
||||
log.warning('Cancelled! Goodbye.')
|
||||
exit(2)
|
||||
try:
|
||||
with warnings.catch_warnings():
|
||||
# remove CryptographyDeprecationWarning about deprecated
|
||||
# SymmetricKeyAlgorithm IDEA, CAST5 and Blowfish (PGPy v0.5.4)
|
||||
warnings.simplefilter('ignore')
|
||||
with self.pgpy.unlock(self.password):
|
||||
assert self.pgpy.is_unlocked
|
||||
log.debug("self.pgpy.is_unlocked=%s" % self.pgpy.is_unlocked)
|
||||
self.pgpy_key_seed()
|
||||
except Exception as e:
|
||||
log.error(f"""Unable to unlock secret key id "{self.gpg_seckey.fpr}" of user "{self.username}". Please check your password!""")
|
||||
exit(2)
|
||||
else:
|
||||
self.pgpy_key_seed()
|
||||
self.ed25519_public_bytes, self.ed25519_secret_bytes = nacl.bindings.crypto_sign_seed_keypair(self.pgpy_key_seed)
|
||||
log.debug("self.ed25519_public_bytes=%s" % self.ed25519_public_bytes)
|
||||
log.debug("self.ed25519_secret_bytes=%s" % self.ed25519_secret_bytes)
|
||||
|
||||
def gpg_passphrase_cb(self, uid_hint, passphrase_info, prev_was_bad):
|
||||
log.debug("uid_hint=%s" % uid_hint)
|
||||
log.debug("passphrase_info=%s" % passphrase_info)
|
||||
log.debug("prev_was_bad=%s" % prev_was_bad)
|
||||
return self.password
|
||||
|
||||
def ipfs_from_ed25519(self):
|
||||
log.debug("def keygen.ipfs_from_ed25519(self)")
|
||||
|
||||
|
@ -275,8 +322,6 @@ sec: {self.base58_secret_key}
|
|||
def pgpy_key_seed(self):
|
||||
log.debug("def keygen.pgpy_key_seed(self)")
|
||||
self.pgpy_key_type()
|
||||
# todo : unlock password protected key
|
||||
# assert self.pgpy.is_unlocked
|
||||
if self.pgpy_key_type == 'RSA':
|
||||
log.debug("self.pgpy._key.keymaterial.p=%s" % self.pgpy._key.keymaterial.p)
|
||||
log.debug("self.pgpy._key.keymaterial.q=%s" % self.pgpy._key.keymaterial.q)
|
||||
|
@ -289,7 +334,6 @@ sec: {self.base58_secret_key}
|
|||
log.debug("self.pgpy_key_seed=%s" % self.pgpy_key_seed)
|
||||
log.debug("self.pgpy_key_value=%s" % self.pgpy_key_value)
|
||||
log.debug("self.pgpy_key_size=%s" % self.pgpy_key_size)
|
||||
log.debug("self.pgpy._key.keymaterial.encbytes=%s" % self.pgpy._key.keymaterial.encbytes)
|
||||
elif self.pgpy_key_type in ('ECDSA', 'EdDSA', 'ECDH'):
|
||||
log.debug("self.pgpy._key.keymaterial.s=%s" % self.pgpy._key.keymaterial.s)
|
||||
self.pgpy_key_seed = long_to_bytes(self.pgpy._key.keymaterial.s)
|
||||
|
@ -299,7 +343,7 @@ sec: {self.base58_secret_key}
|
|||
log.debug("self.pgpy_key_value=%s" % self.pgpy_key_value)
|
||||
log.debug("self.pgpy_key_size=%s" % self.pgpy_key_size)
|
||||
else:
|
||||
raise NotImplementedError(f"Get seed from {self.pgpy_key_type} key is not supported")
|
||||
raise NotImplementedError(f"Getting seed from {self.pgpy_key_type} key is not implemented")
|
||||
|
||||
def pgpy_key_type(self):
|
||||
log.debug("def keygen.pgpy_key_type(self)")
|
||||
|
@ -344,7 +388,9 @@ sec: {self.base58_secret_key}
|
|||
self._check_args(args)
|
||||
self._load_config()
|
||||
# self.gpg = gpg.Context(armor=True, offline=True, homedir=GNUPGHOME)
|
||||
self.gpg = gpg.Context(armor=True, offline=True)
|
||||
self.gpg = gpg.Context( armor=True,
|
||||
offline=True)
|
||||
self.gpg.set_passphrase_cb(self.gpg_passphrase_cb)
|
||||
self.ed25519(args)
|
||||
method = getattr(self, f'do_{self.type}', self._invalid_type)
|
||||
return method()
|
||||
|
|
|
@ -3,5 +3,6 @@ cryptography
|
|||
duniterpy
|
||||
google
|
||||
pgpy
|
||||
pynentry
|
||||
protobuf
|
||||
pynacl
|
||||
|
|
|
@ -102,35 +102,53 @@ Describe 'keygen'
|
|||
rm -f /tmp/keygen_test_ipfs.pem
|
||||
End
|
||||
Describe '-t pgp username password birthday:'
|
||||
gpg --import --quiet specs/username.asc
|
||||
gpg --import --quiet specs/username.pub
|
||||
It 'creates a gpg key for user username'
|
||||
gpg --batch --import --quiet specs/username.asc
|
||||
gpg --batch --import --quiet specs/username_protected.asc
|
||||
It 'creates a password protected gpg key for user username'
|
||||
Skip "You should implement it !"
|
||||
When run keygen -t pgp username password
|
||||
When run keygen -t pgp username password birthday
|
||||
The status should be success
|
||||
End
|
||||
End
|
||||
Describe '-g -t duniter username:'
|
||||
It 'prints duniter keys for gpg key matching username'
|
||||
When run keygen -g -t duniter username
|
||||
When run keygen -g -t duniter 079E5BF4721944FB
|
||||
The output should include 'pub: 2g5UL2zhkn5i7oNYDpWo3fBuWvRYVU1AbMtdVmnGzPNv'
|
||||
The output should include 'sec: 5WtYFfA26nTfG496gAKhkrLYUMMnwXexmE1E8Q7PvtQEyscHfirsdMzW34zDp7WEkt3exNEVwoG4ajZYrm62wpi2'
|
||||
The status should be success
|
||||
The stderr should equal ""
|
||||
End
|
||||
End
|
||||
Describe '-g -t duniter username@protected password:'
|
||||
It 'prints duniter keys for gpg key matching username@protected locked with password'
|
||||
When run keygen -g -t duniter 6222A29CBC31A087 password
|
||||
The output should include 'pub: C1cRu7yb5rZhsmRHQkeZxusAhtYYJypcnXpY3HycEKsU'
|
||||
The output should include 'sec: VWaEdDroSCoagJDsBnDNUtXJtKAJYdqL6XKNiomz8DtiyF44FvpiMmhidXt2j8HhDBKPZ67xBGcZPnj4Myk6cB8'
|
||||
The status should be success
|
||||
The stderr should equal ""
|
||||
End
|
||||
End
|
||||
Describe '-g -t ipfs username:'
|
||||
It 'prints ipfs keys for gpg key matching username'
|
||||
When run keygen -g -t ipfs username
|
||||
When run keygen -g -t ipfs 079E5BF4721944FB
|
||||
The output should include 'PeerID: 12D3KooWBVSe5AaQwgMCXgsxrRG8pTGk1FUBXA5eYxFeskwAtL6r'
|
||||
The output should include 'PrivKEY: CAESQOHXwPgzoiDca1ZnvhU/W3zdogZXulkoErnUsqt+ut82GN5k4MIbVvz2m6Vq0ij9fQFPNUz+ZZdv2D31K6mzBQc='
|
||||
The status should be success
|
||||
The stderr should equal ""
|
||||
End
|
||||
End
|
||||
Describe '-g -t ipfs username@protected password:'
|
||||
It 'prints ipfs keys for gpg key matching username@protected locked with password'
|
||||
When run keygen -g -t ipfs 6222A29CBC31A087 password
|
||||
The output should include 'PeerID: 12D3KooWLpybeFZJGkqCHevi3MPujhx1CDbBLfu6k8BZRH8W8GbQ'
|
||||
The output should include 'PrivKEY: CAESQBiV+XnBNnryoeBs6SNj9e7Cd9Xj6INn24wyxxacylYqo5idwBHJto4Vbbp6NQzuUF+e7aCmrCf6y+BSyL42/i8='
|
||||
The status should be success
|
||||
The stderr should equal ""
|
||||
End
|
||||
End
|
||||
Describe '-g -o /tmp/keygen_test_duniter.pubsec -t duniter username:'
|
||||
It 'writes duniter keys to file for gpg key matching username'
|
||||
When run keygen -g -o /tmp/keygen_test_duniter.pubsec -t duniter username
|
||||
When run keygen -g -o /tmp/keygen_test_duniter.pubsec -t duniter 079E5BF4721944FB
|
||||
The path '/tmp/keygen_test_duniter.pubsec' should exist
|
||||
The contents of file '/tmp/keygen_test_duniter.pubsec' should include 'pub: 2g5UL2zhkn5i7oNYDpWo3fBuWvRYVU1AbMtdVmnGzPNv'
|
||||
The contents of file '/tmp/keygen_test_duniter.pubsec' should include 'sec: 5WtYFfA26nTfG496gAKhkrLYUMMnwXexmE1E8Q7PvtQEyscHfirsdMzW34zDp7WEkt3exNEVwoG4ajZYrm62wpi2'
|
||||
|
@ -139,9 +157,20 @@ Describe 'keygen'
|
|||
End
|
||||
rm -f /tmp/keygen_test_duniter.pubsec
|
||||
End
|
||||
Describe '-g -o /tmp/keygen_test_duniter.pubsec -t duniter username@protected password:'
|
||||
It 'writes duniter keys to file for gpg key matching username@protected locked with password'
|
||||
When run keygen -g -o /tmp/keygen_test_duniter.pubsec -t duniter 6222A29CBC31A087 password
|
||||
The path '/tmp/keygen_test_duniter.pubsec' should exist
|
||||
The contents of file '/tmp/keygen_test_duniter.pubsec' should include 'pub: C1cRu7yb5rZhsmRHQkeZxusAhtYYJypcnXpY3HycEKsU'
|
||||
The contents of file '/tmp/keygen_test_duniter.pubsec' should include 'sec: VWaEdDroSCoagJDsBnDNUtXJtKAJYdqL6XKNiomz8DtiyF44FvpiMmhidXt2j8HhDBKPZ67xBGcZPnj4Myk6cB8'
|
||||
The status should be success
|
||||
The stderr should equal ""
|
||||
End
|
||||
rm -f /tmp/keygen_test_duniter.pubsec
|
||||
End
|
||||
Describe '-g -o /tmp/keygen_test_ipfs.pem -t ipfs username:'
|
||||
It 'writes ipfs keys to file for gpg key matching username'
|
||||
When run keygen -g -o /tmp/keygen_test_ipfs.pem -t ipfs username
|
||||
When run keygen -g -o /tmp/keygen_test_ipfs.pem -t ipfs 079E5BF4721944FB
|
||||
The path '/tmp/keygen_test_ipfs.pem' should exist
|
||||
The contents of file '/tmp/keygen_test_ipfs.pem' should include '-----BEGIN PRIVATE KEY-----'
|
||||
The contents of file '/tmp/keygen_test_ipfs.pem' should include 'MC4CAQAwBQYDK2VwBCIEIOHXwPgzoiDca1ZnvhU/W3zdogZXulkoErnUsqt+ut82'
|
||||
|
@ -151,4 +180,18 @@ Describe 'keygen'
|
|||
End
|
||||
rm -f /tmp/keygen_test_ipfs.pem
|
||||
End
|
||||
Describe '-g -o /tmp/keygen_test_ipfs.pem -t ipfs username@protected password:'
|
||||
It 'writes ipfs keys to file for gpg key matching username@protected locked with password'
|
||||
When run keygen -g -o /tmp/keygen_test_ipfs.pem -t ipfs 6222A29CBC31A087 password
|
||||
The path '/tmp/keygen_test_ipfs.pem' should exist
|
||||
The contents of file '/tmp/keygen_test_ipfs.pem' should include '-----BEGIN PRIVATE KEY-----'
|
||||
The contents of file '/tmp/keygen_test_ipfs.pem' should include 'MC4CAQAwBQYDK2VwBCIEIBiV+XnBNnryoeBs6SNj9e7Cd9Xj6INn24wyxxacylYq'
|
||||
The contents of file '/tmp/keygen_test_ipfs.pem' should include '-----END PRIVATE KEY-----'
|
||||
The status should be success
|
||||
The stderr should equal ""
|
||||
End
|
||||
rm -f /tmp/keygen_test_ipfs.pem
|
||||
End
|
||||
gpg --batch --delete-secret-and-public-key --yes 4D1CDB77E91FFCD81B10F9A7079E5BF4721944FB
|
||||
gpg --batch --delete-secret-and-public-key --yes 6AF574897D4979B7956AC31B6222A29CBC31A087
|
||||
End
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
xjMEAAAAABYJKwYBBAHaRw8BAQdAGN5k4MIbVvz2m6Vq0ij9fQFPNUz+ZZdv2D31
|
||||
K6mzBQfNCHVzZXJuYW1lwmEEExYIABMFAmKD2B0JEAeeW/RyGUT7AhsDAADy8AD/
|
||||
QvC5UvW8TVUdbCd0EQvPjlfVzRauBlxQP4oy+vjnItcA/R1RgGS0D9zAGHC6CRHt
|
||||
AwxzDz3dIpKQAJxxliD8ZO0G
|
||||
=51r3
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
|
@ -0,0 +1,10 @@
|
|||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
|
||||
xYYEAAAAABYJKwYBBAHaRw8BAQdAo5idwBHJto4Vbbp6NQzuUF+e7aCmrCf6y+BS
|
||||
yL42/i/+CQMIyF96+qn63Oj/SwKcSRdzCPa5/1+HIJs/eXZFqSADs+Qj/e/XRts2
|
||||
xpcnRErR8CYZo3OzHDtlhj5sejX1nH9mErGvA3JpjO9KT+GKCF+T4s0SdXNlcm5h
|
||||
bWVAcHJvdGVjdGVkwmEEExYIABMFAgAAAAAJEGIiopy8MaCHAhsDAADFPgD9Fz0e
|
||||
vsLZpGbBIOE87ITJQWqAguawC57wi1YH3t+qj98BAMyos3sZjh9csrgecDPvpsjd
|
||||
SOUtnZgEvISe1r4WMKUM
|
||||
=ZnDt
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
Loading…
Reference in New Issue