Are conditionals in salt stack pillar templates secure? - salt-stack

I recently saw the following construction in a salt pillar in a thread here
/srv/pillar/ssh.sls:
ssh_certs:
{% if grains['fqdn'] == 'server1.example.com' %}
dsa: |
-----BEGIN DSA PRIVATE KEY-----
{# key text goes here with consistant indentation... #}
-----END DSA PRIVATE KEY-----
ecdsa: |
-----BEGIN ECDSA PRIVATE KEY-----
{# key text goes here with consistant indentation... #}
-----END ECDSA PRIVATE KEY-----
rsa: |
-----BEGIN RSA PRIVATE KEY-----
{# key text goes here with consistant indentation... #}
-----END RSA PRIVATE KEY-----
{% elif grains['fqdn'] == 'server2.example.com' %}
# same as above but with different key texts of course....
{% endif %}
This pillar was then distributed in the top file via the * glob to all nodes in the cluster.
Question:
Since our unevaluated template contains all of the private keys for our entire cluster, how secure is this?
I believe that the minions evaluate their own salt formulae. If they evaluate their own pillars as well, then they would temporarily be given the private keys for every node in the cluster!
If I somehow gained access to server2.example.com, would I be able to dig up the uncompiled template?
Another way to ask this question would be: where does pillar template evaluation take place?

Pillar data is compiled on the Salt Master and the Pillar dictionary is sent encrypted directly to each Salt Minion. So there's no chance that each minion got the entirety of that pillar file.
That being said, a Minion's grains could be tampered with. The only absolute you have is the minion's id. The minion ID can't be tampered with without causing the minion's authentication being rejected.

Related

JWK Key Creation with x5c and x5t parameters

I have the need to generate a JWK with the following parameters:
“kty”: Key Type
“kid”: Key ID
“use”: “sig” Public Key Use
“n”: the modulus
“e”: “AQAB” the public exponent
“x5c”: X. 509 Certificate Chain
“x5t”: X.509 Certificate SHA-1 Thumbprint
Note:
JWKs should contain a public key using RSA algorithm. RSA provides a key ID for key
matching purposes.
Should contain X.509 certificate using both “x5t” (X.509 SHA-1 Thumbprint) and “x5c” (X.509
certificate Chain) parameters
The first 5 parameters ("kty", "kid", "use", "n", "e") are fairly straight forward and not an issue. However, for the "x5c" and "x5t" components, I am not sure how to generate these. It seems as I can create an x509 cert using tools such as the one found at https://www.samltool.com/self_signed_certs.php and I suppose the x509 cert generated there would be the x5c parameter. Is this correct and how would I generate a x5t (cert thumbprint) from this?
All help is appreciated.
Since you have neither a tool nor a language tagged, I assume that it is rather a general explanation of both parameters.
In x5c a certificate or certificate chain is stored, in x5t the associated thumbprint. A certificate or certificate chain is used to prove ownership of a public key, the thumbprint is a hash of a certificate used to identify/compare certificates.
The exact definition of both parameters is described in RFC 7517, JSON Web Key (JWK), chapters 4.7 x5c and 4.8 x5t:
x5c:
The "x5c" (X.509 certificate chain) parameter contains a chain of one or more PKIX certificates [RFC5280]. The certificate chain is represented as a JSON array of certificate value strings. Each string in the array is a base64-encoded (Section 4 of [RFC4648] -- not base64url-encoded) DER [ITU.X690.1994] PKIX certificate value. The PKIX certificate containing the key value MUST be the first certificate. This MAY be followed by additional certificates, with each subsequent certificate being the one used to certify the previous one. The key in the first certificate MUST match the public key represented by other members of the JWK. Use of this member is OPTIONAL...
x5t:
The "x5t" (X.509 certificate SHA-1 thumbprint) parameter is a base64url-encoded SHA-1 thumbprint (a.k.a. digest) of the DER encoding of an X.509 certificate [RFC5280]. Note that certificate thumbprints are also sometimes known as certificate fingerprints. The key in the certificate MUST match the public key represented by other members of the JWK. Use of this member is OPTIONAL.
Creation of a certificate:
A self signed certificate can (apart from the online tool you use) also be generated e.g. with OpenSSL. The following OpenSSL statement
openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.crt -days 365
generates a private (unencrypted) PEM encoded 4096 bit key in PKCS#8 format (key.pem):
-----BEGIN PRIVATE KEY-----
MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQDkWIfV9uL3XMay
...
OPAsywknGU1A/xTa3fFKO9KV6t/T9z3G
-----END PRIVATE KEY-----
and a PEM encoded certificate (cert.crt):
-----BEGIN CERTIFICATE-----
MIIF4zCCA8ugAwIBAgIJAKSZ5oC4tblkMA0GCSqGSIb3DQEBCwUAMIGHMQswCQYD
...
6aBMYeKy0dqjtZIlO8rm2Rialc7Qt+0=
-----END CERTIFICATE-----
For more options and details, see openssl req and the post How to generate a self-signed SSL certificate using OpenSSL?.
Note that a self-signed certificate is signed by the owner. Self-signed certificates are used on internal pages or in test environments. A CA-signed certificate, in contrast, is signed by a third-party, publicly trusted certificate authority (CA) like DigiCert or Thawte etc. used e.g. for public-facing websites, s. also here. A signed certificate is requested with a CSR.
Certificates, certificate chains, certificate authorities, etc. are part of a public key infrastructure.
Example use of x5c:
In Appendix B of RFC 7517, an example of the use of the x5c parameter is given. The DER encoded certificate is Base64 encoded and is contained in a JSON array:
{
"kty":"RSA",
"use":"sig",
"kid":"1b94c",
"n":"vrjOfz9Ccdgx5nQudyhdoR17V-IubWMeOZCwX_jj0hgAsz2J_pqYW08
PLbK_PdiVGKPrqzmDIsLI7sA25VEnHU1uCLNwBuUiCO11_-7dYbsr4iJmG0Q
u2j8DsVyT1azpJC_NG84Ty5KKthuCaPod7iI7w0LK9orSMhBEwwZDCxTWq4a
YWAchc8t-emd9qOvWtVMDC2BXksRngh6X5bUYLy6AyHKvj-nUy1wgzjYQDwH
MTplCoLtU-o-8SNnZ1tmRoGE9uJkBLdh5gFENabWnU5m1ZqZPdwS-qo-meMv
VfJb6jJVWRpl2SUtCnYG2C32qvbWbjZ_jBPD5eunqsIo1vQ",
"e":"AQAB",
"x5c":
["MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSIb3DQEBBQUAMGIxCzAJB
gNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYD
VQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1
wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBg
NVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDV
QQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1w
YmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64zn8/QnH
YMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66
s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3WG7K+IiZhtELto/A7Fck9Ws6
SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpn
fajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/p1MtcIM42EA8BzE6ZQqC7VPq
PvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVk
aZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCKNb0CAwEAATANBgkqhkiG9w0BA
QUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL
+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9AqBNTqNgHq2G03X09266X5CpOe1
zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL
2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKVMJyf/RuP2SmmaIzmnw9JiSlYhzo
4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTq
gawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5MPvACWpkA6SdS4xSvdXK3IVfOWA=="]
}
Note that the line breaks within values are for display purposes only. The DER encoding results from the PEM encoding by removing header, footer and line breaks and Base64 decoding the rest, i.e. the Base64 decoded DER encoded certificate is the body of the PEM encoded certificate without line breaks.
For a certificate chain, the certificates are separated by commas, see e.g. RFC 7515, Appendix B, x5c.
Thumbprint/Fingerprint:
The thumbprint of a certificate is the SHA-1 hash of the DER encoded certificate and can be generated with OpenSSL as follows, s. also here:
openssl x509 -in cert.crt -noout -fingerprint
Here cert.crt is the PEM encoded certificate. For more details, see openssl x509.
Example: If the certificate from RFC 7517, Appendix B is used, the OpenSSL statement returns the following output:
SHA1 Fingerprint=E2:93:5E:9C:40:4B:BF:42:69:2C:87:6E:81:6C:50:90:EB:19:70:AD
i.e. the hex encoded thumbprint is: E2935E9C404BBF42692C876E816C5090EB1970AD or Base64url encoded: 4pNenEBLv0JpLIdugWxQkOsZcK0. The latter is the value of x5t:
"x5t":"4pNenEBLv0JpLIdugWxQkOsZcK0"
Thank you #Topaco for the last comment on your own answer. For anyone still confused, here's a complete flow with sample code:
In a JS environment with Buffer and crypto:
function generateX5t(certificate) {
// Extracts everything between `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----`
// and remove line-breaks
const data = certificate
.replaceAll('\n', '')
.match(/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm)
.join('');
const sha1 = crypto.subtle.digest('SHA-1', Buffer.from(data, 'base64'));
const hex = sha1.then((r) => Buffer.from(r).toString('hex'));
const x5t = hex.then((r) => Buffer.from(r, 'hex').toString('base64url'));
return x5t
}
const certificate = `-----BEGIN CERTIFICATE-----
MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSIb3DQEBBQUAMGIxCzAJB
gNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYD
VQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1
wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBg
NVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDV
QQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1w
YmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64zn8/QnH
YMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66
s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3WG7K+IiZhtELto/A7Fck9Ws6
SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpn
fajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/p1MtcIM42EA8BzE6ZQqC7VPq
PvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVk
aZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCKNb0CAwEAATANBgkqhkiG9w0BA
QUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL
+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9AqBNTqNgHq2G03X09266X5CpOe1
zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL
2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKVMJyf/RuP2SmmaIzmnw9JiSlYhzo
4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTq
gawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5MPvACWpkA6SdS4xSvdXK3IVfOWA==
-----END CERTIFICATE-----`
generateX5t(certificate).then(r => console.log(r))
To summarize:
1. Get certificate content between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----
2. Remove new lines or line breaks
MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3WG7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCKNb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9AqBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKVMJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5MPvACWpkA6SdS4xSvdXK3IVfOWA==
3. Decode the resulting string as Base64
4. SHA1 encode the result
5. HEX decode the result
6. URL-safe Base64 encode the result, this is the value for x5t

Bouncycastle encrypted private key PEM output: RSA PRIVATE KEY vs PRIVATE KEY

I'm having difficulties exchanging private keys between a client using Java Bouncycastle and a keyserver using Python RSA libraries. The PEM format is used to transfer the keys via REST.
The keyserver can't decrypt the key (needed when the encryption password changes) i'm supplying, it is expecting a PKCS#1 or PKCS#8 key with a PEM as follows:
-----BEGIN PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,ACCB65DDEB20F5AB
EcU3fekuLeUc0viPJ20vAG+Jg1Igkvm+JTjnLmMBE6SwDS/hkf3KP0bFto7Pv6fJ
But bouncycastle's output, using JcePEMEncryptorBuilder and a JcaMiscPEMGenerator has a slightly different BEGIN string:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,ACCB65DDEB20F5AB
EcU3fekuLeUc0viPJ20vAG+Jg1Igkvm+JTjnLmMBE6SwDS/hkf3KP0bFto7Pv6fJ
As I did some research, I learned that a PEM starting BEGIN RSA PRIVATE KEY indicates the key is encoded using PKCS#1.
When I try to get a PKCS#8 encrypted output using JceOpenSSLPKCS8EncryptorBuilder and JcaPKCS8Generator I get a PEM as follows:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIICrjAoBgoqhkiG9w0BDAEDMBoEFP+MLFFaKGC6J/37jF7wRgL3coZdAgIIAASC
AoAdWVo4kAQ1S0stQZbzca7wL876nzlKfcOa4BKsCttPnFVPugJOvGDnATgUK5P/
So my question is: is there a way to get bouncycastle to output a PEM with an encrypted private key in the form of BEGIN PRIVATE KEY or is the python library expecting the wrong format?
Next to that I can't get a grip on whether bouncycastle is using PKCS#1 or PKCS#8 in the JcePEMEncryptorBuilder. It's using PrivateKeyInfo#getEncoded but the documentation is not clear about the PKCS format.
Bouncycastle version: bcpkix-jdk15on 1.52
It turned out the Python lib was not handling all standard formats correctly, so we fixed it by using another Python lib which supports the format Bouncycastle is sending.

Is Jinja in pillars rendered before or after it's sent to the minion?

Suppose I have different credentials in two different environments, but that's the only thing that differs between them, and I don't want to make extra pillar files for a single item.
Suppose I attack the problem like this:
{%- set deployment = grains.get('deployment') %}
{%- load_yaml as credentials %}
prod: prodpassword
test: testpassword
dev: devpassword
{%- endload %}
some_app:
user: someuser
password: {{ credentials[deployment] }}
...more configuration here...
This works as expected. But can a minion in test theoretically get the password for prod? That depends on whether the dict lookup happens before or after data is sent to the client, I think, which in turn depends on when the jinja is rendered. Does the master render it first and then send the resulting data, or does the minion receive the pillar file as-is, then render it itself?
Pillar data is always rendered on the master, never the minion. The master does have access to the minion's grains, however, which is why your example works.
Given a Pillar SLS file with the following contents:
test: {{ grains['id'] }}
The following pillar data will result:
# salt testminion pillar.item test
testminion:
----------
test:
testminion
Source: I'm a SaltStack core developer.

Delete public key from Private for Private key storage with GPG

I'm trying to make a paper based backup of a 4092 bit secret/private PGP key using a QR code generator, but the key is just too big. I'm going to go low tech here and split it into two pieces, but perhaps I don't need to. I know that when exporting the secret key, it also exports the public key embedded within it.
Is there any way to remove the public portion of the key from that file, or prior to exporting, so that the resulting file is only the private key?
I'm not certain the resulting file will be small enough still, but it is worth a shot.
D:\Users\tharding>gpg --edit-key "04EAC14C"
gpg (GnuPG) 2.0.26; Copyright (C) 2013 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
pub 4096R/04EAC14C created: 2015-02-11 expires: never usage: SCE
trust: unknown validity: unknown
[ unknown] (1). Timothy Harding <hardingt#gmail.com>
gpg> key 1
No subkey with index 1
gpg> delkey
You must select at least one key.
gpg> delkey 0
You must select at least one key.
Update:
From what I can tell, (looking at the ASCII Armored output for both the public key and the private key) it looks like they are structured this way:
Update 2:
Looked at the files again, and this is what I've got, I haven't pulled out a hex editor yet to verify the non armored files, but I've found surprisingly little help online about how these key files are internally structured:
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version:
4 header chars ??
1517 pub key chars
4 footer chars ??
-----END PGP PUBLIC KEY BLOCK-----
and
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version:
4 different header chars from pub key ??
700 pub key chars
1772 private key chars (possibly some header/footer to do with the symmetric cipher)
817 pub key chars (same total 1517, exact same ASCII sequence if put together)
4 different footer chars from pub key ??
-----END PGP PRIVATE KEY BLOCK-----
Update 3:
Took a look at the binary pub/private keys and found that:
public key is 1138 bytes
4 unique bytes
1134 bytes found in private key as well
private key is 2467 bytes
4 unique bytes
524 of which are found verbatim in the public key
1329 of which are unique to the private key
38 bytes which are found verbatim in the public key (key name & Email address)
572 bytes which are found verbatim in the public key
There is a program called Paperkey[1], written by David Shaw[2], that extracts only the private key information from an exported OpenPGP private key.
Excerpt from the package description:
extract just the secret information out of OpenPGP secret keys
The Paperkey page has a version already built for Windows 32bit, and provides the source to compile on Linux, Unix, *BSD and OSX.
Paperkey is also available via the package manager on some Linux/BSD distributions.
Example package manager installs -
apt (debian) -
apt-get install paperkey
yum (redhat)
yum install paperkey
pkg (bsd)
pkg install paperkey
ports (bsd)
cd /usr/ports/security/paperkey
make install clean

How can I specify a multi-line property value in a Flyway DB configuration file?

I'm trying to put a PGP encryption key into a Flyway DB configuration file. Something like this:
# Encryption key for encrypting stuff
flyway.placeholders.encryptionKey=-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG C# v1.2.3.4
mQEGBFRgnDEBCACi4yRYnmLtgEBoXfx+YYwZ1b6xPRN5oZBqp76YGPwtVfNGOzpK
JKclFD1uIr/MIQZB89G2Z4gJB/q2E+CNbHUGc/bxU8DpGOOo3DsN2UP2xxz41sRY
7eW0SiSSIw2Cu+4dG3Ic+pBv8pxUFZDCyGCtENucfoxKe3J69IWNbBRCiftndW2A
Wf7vPyrygcD+9Ju/7OrLL7FnWJ66TZk6DUgjMm1c4J4ZoyHRfZHEvhx/j2OlxzIV
ysHXThyrVZzkO0sA0kobzJEfdpKhRg==
=SpNy
-----END PGP PUBLIC KEY BLOCK-----
I'm then using the property in an update SQL script, e.g.
UPDATE [MyTable] SET [MyColumn] = '${encryptionKey}'
When I run the update it simply updates with the first line of the key. Is there a way to specify multi-line properties in a Flyway configuration file?
One has to add \n\ to the end of each line, like this:
# Encryption key for encrypting stuff
flyway.placeholders.encryptionKey=-----BEGIN PGP PUBLIC KEY BLOCK----- \n\
Version: BCPG C# v1.2.3.4 \n\
\n\
mQEGBFRgnDEBCACi4yRYnmLtgEBoXfx+YYwZ1b6xPRN5oZBqp76YGPwtVfNGOzpK\n\
JKclFD1uIr/MIQZB89G2Z4gJB/q2E+CNbHUGc/bxU8DpGOOo3DsN2UP2xxz41sRY\n\
7eW0SiSSIw2Cu+4dG3Ic+pBv8pxUFZDCyGCtENucfoxKe3J69IWNbBRCiftndW2A\n\
Wf7vPyrygcD+9Ju/7OrLL7FnWJ66TZk6DUgjMm1c4J4ZoyHRfZHEvhx/j2OlxzIV\n\
ysHXThyrVZzkO0sA0kobzJEfdpKhRg==\n\
=SpNy\n\
-----END PGP PUBLIC KEY BLOCK-----

Resources