Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for PKCS#8 #1130

Merged
merged 4 commits into from
Jul 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions client/backwards_compatibility_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ func Test0Dot3Migration(t *testing.T) {

// We can read and publish from notary0.1 repos
func Test0Dot1RepoFormat(t *testing.T) {
if notary.FIPSEnabled() {
t.Skip("skip backward compatibility test in FIPS mode")
}
// make a temporary directory and copy the fixture into it, since updating
// and publishing will modify the files
tmpDir, err := ioutil.TempDir("", "notary-backwards-compat-test")
Expand Down Expand Up @@ -236,6 +239,9 @@ func Test0Dot1RepoFormat(t *testing.T) {

// We can read and publish from notary0.3 repos
func Test0Dot3RepoFormat(t *testing.T) {
if notary.FIPSEnabled() {
t.Skip("skip backward compatibility test in FIPS mode")
}
// make a temporary directory and copy the fixture into it, since updating
// and publishing will modify the files
tmpDir, err := ioutil.TempDir("", "notary-backwards-compat-test")
Expand Down
40 changes: 20 additions & 20 deletions cmd/notary/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestInitWithRootKey(t *testing.T) {
require.NoError(t, err)

// if the key has a root role, AddKey sets the gun to "" so we have done the same here
encryptedPEMPrivKey, err := utils.EncryptPrivateKey(privKey, data.CanonicalRootRole, "", testPassphrase)
encryptedPEMPrivKey, err := utils.ConvertPrivateKeyToPKCS8(privKey, data.CanonicalRootRole, "", testPassphrase)
require.NoError(t, err)
encryptedPEMKeyFilename := filepath.Join(tempDir, "encrypted_key.key")
err = ioutil.WriteFile(encryptedPEMKeyFilename, encryptedPEMPrivKey, 0644)
Expand Down Expand Up @@ -146,7 +146,7 @@ func TestInitWithRootKey(t *testing.T) {
// check error if unencrypted PEM used
unencryptedPrivKey, err := utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)
unencryptedPEMPrivKey, err := utils.KeyToPEM(unencryptedPrivKey, data.CanonicalRootRole, "")
unencryptedPEMPrivKey, err := utils.ConvertPrivateKeyToPKCS8(unencryptedPrivKey, data.CanonicalRootRole, "", "")
require.NoError(t, err)
unencryptedPEMKeyFilename := filepath.Join(tempDir, "unencrypted_key.key")
err = ioutil.WriteFile(unencryptedPEMKeyFilename, unencryptedPEMPrivKey, 0644)
Expand All @@ -161,7 +161,7 @@ func TestInitWithRootKey(t *testing.T) {
require.NoError(t, err)

// Blank gun name since it is a root key
badPassPEMPrivKey, err := utils.EncryptPrivateKey(badPassPrivKey, data.CanonicalRootRole, "", "bad_pass")
badPassPEMPrivKey, err := utils.ConvertPrivateKeyToPKCS8(badPassPrivKey, data.CanonicalRootRole, "", "bad_pass")
require.NoError(t, err)
badPassPEMKeyFilename := filepath.Join(tempDir, "badpass_key.key")
err = ioutil.WriteFile(badPassPEMKeyFilename, badPassPEMPrivKey, 0644)
Expand All @@ -173,7 +173,7 @@ func TestInitWithRootKey(t *testing.T) {
// check error if wrong role specified
snapshotPrivKey, err := utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)
snapshotPEMPrivKey, err := utils.KeyToPEM(snapshotPrivKey, data.CanonicalSnapshotRole, "gun2")
snapshotPEMPrivKey, err := utils.ConvertPrivateKeyToPKCS8(snapshotPrivKey, data.CanonicalSnapshotRole, "gun2", "")
require.NoError(t, err)
snapshotPEMKeyFilename := filepath.Join(tempDir, "snapshot_key.key")
err = ioutil.WriteFile(snapshotPEMKeyFilename, snapshotPEMPrivKey, 0644)
Expand Down Expand Up @@ -1150,9 +1150,9 @@ func TestClientDelegationsPublishing(t *testing.T) {
tempFile.Close()
defer os.Remove(tempFile.Name())

privKeyBytesNoRole, err := utils.KeyToPEM(privKey, "", "")
privKeyBytesNoRole, err := utils.ConvertPrivateKeyToPKCS8(privKey, "", "", "")
require.NoError(t, err)
privKeyBytesWithRole, err := utils.KeyToPEM(privKey, "user", "")
privKeyBytesWithRole, err := utils.ConvertPrivateKeyToPKCS8(privKey, "user", "", "")
require.NoError(t, err)

// Set up targets for publishing
Expand Down Expand Up @@ -1582,15 +1582,15 @@ func TestKeyRotation(t *testing.T) {
// create encrypted root keys
rootPrivKey1, err := utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)
encryptedPEMPrivKey1, err := utils.EncryptPrivateKey(rootPrivKey1, data.CanonicalRootRole, "", testPassphrase)
encryptedPEMPrivKey1, err := utils.ConvertPrivateKeyToPKCS8(rootPrivKey1, data.CanonicalRootRole, "", testPassphrase)
require.NoError(t, err)
encryptedPEMKeyFilename1 := filepath.Join(tempDir, "encrypted_key.key")
err = ioutil.WriteFile(encryptedPEMKeyFilename1, encryptedPEMPrivKey1, 0644)
require.NoError(t, err)

rootPrivKey2, err := utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)
encryptedPEMPrivKey2, err := utils.EncryptPrivateKey(rootPrivKey2, data.CanonicalRootRole, "", testPassphrase)
encryptedPEMPrivKey2, err := utils.ConvertPrivateKeyToPKCS8(rootPrivKey2, data.CanonicalRootRole, "", testPassphrase)
require.NoError(t, err)
encryptedPEMKeyFilename2 := filepath.Join(tempDir, "encrypted_key2.key")
err = ioutil.WriteFile(encryptedPEMKeyFilename2, encryptedPEMPrivKey2, 0644)
Expand Down Expand Up @@ -1663,7 +1663,7 @@ func TestKeyRotationNonRoot(t *testing.T) {
privKey, err := utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err := utils.EncryptPrivateKey(privKey, data.CanonicalTargetsRole, "", testPassphrase)
pemBytes, err := utils.ConvertPrivateKeyToPKCS8(privKey, data.CanonicalTargetsRole, "", testPassphrase)
require.NoError(t, err)

nBytes, err := tempFile.Write(pemBytes)
Expand All @@ -1678,7 +1678,7 @@ func TestKeyRotationNonRoot(t *testing.T) {
privKey2, err := utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes2, err := utils.KeyToPEM(privKey2, data.CanonicalTargetsRole, "")
pemBytes2, err := utils.ConvertPrivateKeyToPKCS8(privKey2, data.CanonicalTargetsRole, "", "")
require.NoError(t, err)

nBytes2, err := tempFile2.Write(pemBytes2)
Expand Down Expand Up @@ -2506,7 +2506,7 @@ func TestClientKeyImport(t *testing.T) {
privKey, err := utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err := utils.EncryptPrivateKey(privKey, data.CanonicalRootRole, "", "")
pemBytes, err := utils.ConvertPrivateKeyToPKCS8(privKey, data.CanonicalRootRole, "", "")
require.NoError(t, err)

nBytes, err := tempFile.Write(pemBytes)
Expand Down Expand Up @@ -2534,7 +2534,7 @@ func TestClientKeyImport(t *testing.T) {
privKey, err = utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err = utils.EncryptPrivateKey(privKey, "", "", "")
pemBytes, err = utils.ConvertPrivateKeyToPKCS8(privKey, "", "", "")
require.NoError(t, err)

nBytes, err = tempFile2.Write(pemBytes)
Expand All @@ -2560,7 +2560,7 @@ func TestClientKeyImport(t *testing.T) {
privKey, err = utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err = utils.EncryptPrivateKey(privKey, "", "", "")
pemBytes, err = utils.ConvertPrivateKeyToPKCS8(privKey, "", "", "")
require.NoError(t, err)

nBytes, err = tempFile3.Write(pemBytes)
Expand Down Expand Up @@ -2590,7 +2590,7 @@ func TestClientKeyImport(t *testing.T) {
privKey, err = utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err = utils.EncryptPrivateKey(privKey, "", "", "")
pemBytes, err = utils.ConvertPrivateKeyToPKCS8(privKey, "", "", "")
require.NoError(t, err)

nBytes, err = tempFile4.Write(pemBytes)
Expand Down Expand Up @@ -2621,7 +2621,7 @@ func TestClientKeyImport(t *testing.T) {
privKey, err = utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err = utils.EncryptPrivateKey(privKey, "", "", "")
pemBytes, err = utils.ConvertPrivateKeyToPKCS8(privKey, "", "", "")
require.NoError(t, err)

nBytes, err = tempFile5.Write(pemBytes)
Expand Down Expand Up @@ -2652,7 +2652,7 @@ func TestClientKeyImport(t *testing.T) {
privKey, err = utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err = utils.EncryptPrivateKey(privKey, data.CanonicalRootRole, "", testPassphrase)
pemBytes, err = utils.ConvertPrivateKeyToPKCS8(privKey, data.CanonicalRootRole, "", testPassphrase)
require.NoError(t, err)

nBytes, err = tempFile6.Write(pemBytes)
Expand All @@ -2678,7 +2678,7 @@ func TestClientKeyImport(t *testing.T) {
privKey, err = utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err = utils.EncryptPrivateKey(privKey, "", "", "")
pemBytes, err = utils.ConvertPrivateKeyToPKCS8(privKey, "", "", "")
require.NoError(t, err)

nBytes, err = tempFile7.Write(pemBytes)
Expand Down Expand Up @@ -2708,7 +2708,7 @@ func TestClientKeyImport(t *testing.T) {
privKey, err = utils.GenerateECDSAKey(rand.Reader)
require.NoError(t, err)

pemBytes, err = utils.EncryptPrivateKey(privKey, data.CanonicalSnapshotRole, "", "")
pemBytes, err = utils.ConvertPrivateKeyToPKCS8(privKey, data.CanonicalSnapshotRole, "", "")
require.NoError(t, err)

nBytes, err = tempFile8.Write(pemBytes)
Expand Down Expand Up @@ -2752,7 +2752,7 @@ func TestAddDelImportKeyPublishFlow(t *testing.T) {
keyFile, err := ioutil.TempFile("", "pemfile")
require.NoError(t, err)
defer os.Remove(keyFile.Name())
pemBytes, err := utils.EncryptPrivateKey(privKey, "", "", "")
pemBytes, err := utils.ConvertPrivateKeyToPKCS8(privKey, "", "", "")
require.NoError(t, err)
nBytes, err := keyFile.Write(pemBytes)
require.NoError(t, err)
Expand Down Expand Up @@ -3005,7 +3005,7 @@ func TestDelegationKeyImportExport(t *testing.T) {
defer os.Remove(keyFile.Name())
privKey, err := utils.GenerateRSAKey(rand.Reader, 2048)
require.NoError(t, err)
pemBytes, err := utils.EncryptPrivateKey(privKey, "", "", "")
pemBytes, err := utils.ConvertPrivateKeyToPKCS8(privKey, "", "", "")
require.NoError(t, err)
nBytes, err := keyFile.Write(pemBytes)
require.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion cmd/notary/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func generateKeyToFile(role, algorithm string, retriever notary.PassRetriever, o
}

if chosenPassphrase != "" {
pemPrivKey, err = tufutils.EncryptPrivateKey(privKey, data.RoleName(role), "", chosenPassphrase)
pemPrivKey, err = tufutils.ConvertPrivateKeyToPKCS8(privKey, data.RoleName(role), "", chosenPassphrase)
if err != nil {
return err
}
Expand Down
14 changes: 9 additions & 5 deletions cryptoservice/crypto_service.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package cryptoservice

import (
"fmt"

"crypto/x509"
"encoding/pem"
"errors"
"fmt"

"github.com/Sirupsen/logrus"
"github.com/docker/notary"
"github.com/docker/notary/trustmanager"
"github.com/docker/notary/tuf/data"
"github.com/docker/notary/tuf/utils"
Expand Down Expand Up @@ -143,9 +144,12 @@ func CheckRootKeyIsEncrypted(pemBytes []byte) error {
return ErrNoValidPrivateKey
}

if !x509.IsEncryptedPEMBlock(block) {
return ErrRootKeyNotEncrypted
if block.Type == "ENCRYPTED PRIVATE KEY" {
return nil
}
if !notary.FIPSEnabled() && x509.IsEncryptedPEMBlock(block) {
return nil
}

return nil
return ErrRootKeyNotEncrypted
}
13 changes: 13 additions & 0 deletions fips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package notary

import "os"

// FIPSEnvVar is the name of the environment variable that is being used to switch
// between FIPS and non-FIPS mode
const FIPSEnvVar = "GOFIPS"

// FIPSEnabled returns true if environment variable `GOFIPS` has been set to enable
// FIPS mode
func FIPSEnabled() bool {
return os.Getenv(FIPSEnvVar) != ""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: Should this check for negative values, like 0, or "false"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I personally think it should. But I tried to replicate what @FiloSottile did in his library. Basically, 0 or "false" are true values as of now in GCS. If you strongly feel it should be updated, then I'll update in here as well as send a PR there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe my UX compass is wrong but I'm a big fan of "unset" is false, and "set to anything" is true.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@endophage: fair point - this is fine as is, though we should add documentation (followup PR)

}
56 changes: 28 additions & 28 deletions fixtures/notary-server.key
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAqNt5+U61Ws6/Qg54kYp+LkscfcOLQ7aeVm7wAhNIlsNk9Jeh
hz5ymumgRZidxsUULcL3jPnEFbm9wCoyEuznSaXkAOXzq6ZwuXYL+Zfw25meUh68
wJvSYGJq8O1I9XcnkOo6T62uAoRez2DiHKHk6eHljkic87WUMn7ZwS1UYEyGF119
ZFWVX1lRbE9hUJO3ovRsP1J7JclUHR2cWGvfEgJrKEOWGW9yNdU5NSx7Akuj8vae
rS973clvayYqKjbtkYTv1sIaokrbXf8U2p8CUZQ+SFhN9glNyCOFLWmWa2A3opkX
pFVe86sIEwQMzbJmrWYQ9aOhPS2fQyRYSsMA1wIDAQABAoIBAG6mtD1dCJajGM3u
sa+d86XebqMzOtV6nDPDqt+RR2YUUNm/a4g2sd817WLt6aZRizGZq6LkIUyjVObS
P9ILEF1AqjK0fYMkJIZEBwDeQmWFOyxRHBuTgL7Mf4u10rOYC4N5GhEQnRDlMUPw
FvvwUxO4hjdA+ijx+lVErulaDQq0yj5mL4LWu4cHm576OufzgHOIp6fQtfRVJIXD
W2ginblgYFLd+PPiM1RMPR/Pj63VWXWBn1VwLAxWN889E4VG2medl0taQgkNQ3/W
0J04KiTXPrtcUBy2AGoHikvN7gG7Up2IwRRbsXkUdhQNZ/HnIQlkFfteiqqt9VNR
Nsi31nECgYEA0qE+96TvYf8jeZsqrl8YQAvjXWrNA05eKZlT6cm6XpyXq22v9Cgn
2KXEhRwHZF2dQ2C+1PvboeTUbpdPX1nY2shY59L7+t68F/jxotcjx0yL+ZC742Fy
bWsc8Us0Ir2DD5g/+0F+LRLFJKSfJPdLzEkvwuYnlm6RcFlbxIxW6h0CgYEAzTrE
6ulEhN0fKeJY/UaK/8GlLllXc2Z5t7mRicN1s782l5qi0n1R57VJw/Ezx4JN1mcQ
4axe9zzjAA5JfSDfyTyNedP1KOmCaKmBqGa9JppxGcVQpMDg8+QvYnJ8o5JXEXSE
TOnpY4RTEA1RGnA5KbbJ7R1MiHUGXC9nizVHxIMCgYB8cu1DYN5XpmoNddK4CFPJ
s7x4+5t6MpmMNp3P6nMFZ7xte3eU6QzyAq+kfjUX5f//SXA3Y0AX3Z5uYVRyYCGy
0uFEx/I9/dBg0aPjtP3cyauCnzOEW5VCdSE6qFZ7mEGRu0FCcSXd99MnnWSycLMG
Vs+zdk05osan/QQtk0XfOQKBgDfkIWy4SmjEr5AAjKutYn10hz+wJRjQd6WJbBFQ
oeVp1bxD6MPaTUwFGym5rphO7FPPjdFn2BUNB+Uj/u+M3GU5kG31Q3b44QMP5reu
AyVYOiUCj4vO23SQWDc/ZqJFYGDokn8/1Me9acGdXtEMbwTlOujQad9fv3OrlU9c
G0dxAoGAHcntflD6UvQ5/PYOirNJL1GhSspF7u72NrsYjaoZls83uIqucJiB5hMH
Ovq1TJbl0DwDBOyMmt5gZraPQB0P5/5GvnxqGlIAKIwi2VuQ2XHpSBE8Pg5Pveb8
sgFLFnwL5+JyqOP65AV3Eh5b4BJc6kqKz4gVmKLBQeo6lE13sNs=
-----END RSA PRIVATE KEY-----

-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCo23n5TrVazr9C
DniRin4uSxx9w4tDtp5WbvACE0iWw2T0l6GHPnKa6aBFmJ3GxRQtwveM+cQVub3A
KjIS7OdJpeQA5fOrpnC5dgv5l/DbmZ5SHrzAm9JgYmrw7Uj1dyeQ6jpPra4ChF7P
YOIcoeTp4eWOSJzztZQyftnBLVRgTIYXXX1kVZVfWVFsT2FQk7ei9Gw/UnslyVQd
HZxYa98SAmsoQ5YZb3I11Tk1LHsCS6Py9p6tL3vdyW9rJioqNu2RhO/WwhqiSttd
/xTanwJRlD5IWE32CU3II4UtaZZrYDeimRekVV7zqwgTBAzNsmatZhD1o6E9LZ9D
JFhKwwDXAgMBAAECggEAbqa0PV0IlqMYze6xr53zpd5uozM61XqcM8Oq35FHZhRQ
2b9riDax3zXtYu3pplGLMZmrouQhTKNU5tI/0gsQXUCqMrR9gyQkhkQHAN5CZYU7
LFEcG5OAvsx/i7XSs5gLg3kaERCdEOUxQ/AW+/BTE7iGN0D6KPH6VUSu6VoNCrTK
PmYvgta7hwebnvo65/OAc4inp9C19FUkhcNbaCKduWBgUt348+IzVEw9H8+PrdVZ
dYGfVXAsDFY3zz0ThUbaZ52XS1pCCQ1Df9bQnTgqJNc+u1xQHLYAageKS83uAbtS
nYjBFFuxeRR2FA1n8echCWQV+16Kqq31U1E2yLfWcQKBgQDSoT73pO9h/yN5myqu
XxhAC+Ndas0DTl4pmVPpybpenJerba/0KCfYpcSFHAdkXZ1DYL7U+9uh5NRul09f
WdjayFjn0vv63rwX+PGi1yPHTIv5kLvjYXJtaxzxSzQivYMPmD/7QX4tEsUkpJ8k
90vMSS/C5ieWbpFwWVvEjFbqHQKBgQDNOsTq6USE3R8p4lj9Ror/waUuWVdzZnm3
uZGJw3WzvzaXmqLSfVHntUnD8TPHgk3WZxDhrF73POMADkl9IN/JPI150/Uo6YJo
qYGoZr0mmnEZxVCkwODz5C9icnyjklcRdIRM6eljhFMQDVEacDkptsntHUyIdQZc
L2eLNUfEgwKBgHxy7UNg3lemag110rgIU8mzvHj7m3oymYw2nc/qcwVnvG17d5Tp
DPICr6R+NRfl//9JcDdjQBfdnm5hVHJgIbLS4UTH8j390GDRo+O0/dzJq4KfM4Rb
lUJ1ITqoVnuYQZG7QUJxJd330yedZLJwswZWz7N2TTmixqf9BC2TRd85AoGAN+Qh
bLhKaMSvkACMq61ifXSHP7AlGNB3pYlsEVCh5WnVvEPow9pNTAUbKbmumE7sU8+N
0WfYFQ0H5SP+74zcZTmQbfVDdvjhAw/mt64DJVg6JQKPi87bdJBYNz9mokVgYOiS
fz/Ux71pwZ1e0QxvBOU66NBp31+/c6uVT1wbR3ECgYAdye1+UPpS9Dn89g6Ks0kv
UaFKykXu7vY2uxiNqhmWzze4iq5wmIHmEwc6+rVMluXQPAME7Iya3mBmto9AHQ/n
/ka+fGoaUgAojCLZW5DZcelIETw+Dk+95vyyAUsWfAvn4nKo4/rkBXcSHlvgElzq
SorPiBWYosFB6jqUTXew2w==
-----END PRIVATE KEY-----
56 changes: 28 additions & 28 deletions fixtures/notary-signer.key
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA2E7z4r3FPoz11AL3QfGzpuZNdZDMTmhXaQt5Uqo6PAC8a3rA
ETZckIBtNLcU5Eg7Kg5VANUK/Y+TaVlcZapKsfxJja6aNEkiE8OKo31Xkz+ByYyb
YRSDCanaXhuwOTUxDoZJu53mSNgZlyn25fEBU7y18tUtAXuiEliqJ7Ek359mRDLF
OBKqsjsworWlS8Zf99roRfOkrDFNA8leIb9lBbQ+f6B2vP78J/Q9xXJX8aFzZFH5
aMrOqoCINQmgS0qb/FBVFxI9tqBUsJ7QpmvtWa0NacexS/1kH0FE2UiVFUM6FUMI
Jwy7/MS1zG4fyNrt9p+LnE23q8IGYe4JdC1NSwIDAQABAoIBAHykYhyRxYrZpv3Y
B6pUIHVX1+Ka4V98+IFrPynHNW9F7UzxmqNQc95AYq0xojQ4+v6s64ZjPMYHaaYW
/AsJKamN+sRNjEX8rko9LzIuE7yhp6QABbjXHPsAiPgZdF5CrFX2Q558yinHfFeC
sualDWK3JxEajaiBGU8BEGt2xAymuWACGblrM1aAEZa8B84TW3CzzcdyzAkn8P3e
piJCe+DWMc33441r0KlV5GruwF9ewXiWzZtXAOiP/0xEDICFdlFWbO39myMpxDdU
Y0uZ+zmn2G3gz2tz25thH0Wl7mDQ3AA0VlHurgPBBEekeZPQmjiKW+F4slCzXvuy
kW/urIECgYEA/LhY+OWlZVXzIEly7z1/cU9/WImqTs2uRKDeQHMwZrd7D9BXkJuQ
jPN+jZlMYBBrxoaCywbMrgB80Z3MgGHaSx9OIDEZmaxyuQv0zQJCMogysYkbCcaD
mHYnyAf7OXa708Z168WAisEhrwa/DXBn3/hPoBkrbMsuPF/J+tEP7lsCgYEA2x2g
86SitgPVeNV3iuZ6D/SV0QIbDWOYoST2GQn2LnfALIOrzpXRClOSQZ2pGtg9gYo1
owUyyOSv2Fke93p3ufHv3Gqvjl55lzBVV0siHkEXwHcol36DDGQcskVnXJqaL3IF
tiOisuJS9A7PW7gEi0miyGzzB/kh/IEWHKqLL9ECgYEAoBOFB+MuqMmQftsHWlLx
7qwUVdidb90IjZ/4J4rPFcESyimFzas8HIv/lWGM5yx/l/iL0F42N+FHLt9tMcTJ
qNvjeLChLp307RGNtm2/0JJEyf+2iLKdmGz/Nc0YbIWw46vJ9dXcXgeHdn4ndjPF
GDEI/rfysa7hUoy6O41BMhECgYBPJsLPgHdufLAOeD44pM0PGnFMERCoo4OtImbr
4JdXbdazvdTASYo7yriYj1VY5yhAtSZu/x+7RjDnXDo9d7XsK6NT4g4Mxb/yh3ks
kW1/tE/aLLEzGHZKcZeUJlISN57e6Ld7dh/9spf4pajuHuk1T6JH+GNKTAqk5hSQ
wmKJIQKBgCGBWGvJrCeT5X9oHdrlHj2YoKvIIG1eibagcjcKemD7sWzi7Q4P7JIo
xeX8K1WVxdBpo4/RiQcGFmwSmSUKwwr1dO00xtjxIl7ip4DU+WAM7CdmcOIOMbr4
rP9T/wy1ZBkERCIw2ElybTzB8yuOlNLuOMhUeU55xUMFNYYrWEp2
-----END RSA PRIVATE KEY-----

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDYTvPivcU+jPXU
AvdB8bOm5k11kMxOaFdpC3lSqjo8ALxresARNlyQgG00txTkSDsqDlUA1Qr9j5Np
WVxlqkqx/EmNrpo0SSITw4qjfVeTP4HJjJthFIMJqdpeG7A5NTEOhkm7neZI2BmX
Kfbl8QFTvLXy1S0Be6ISWKonsSTfn2ZEMsU4EqqyOzCitaVLxl/32uhF86SsMU0D
yV4hv2UFtD5/oHa8/vwn9D3FclfxoXNkUfloys6qgIg1CaBLSpv8UFUXEj22oFSw
ntCma+1ZrQ1px7FL/WQfQUTZSJUVQzoVQwgnDLv8xLXMbh/I2u32n4ucTberwgZh
7gl0LU1LAgMBAAECggEAfKRiHJHFitmm/dgHqlQgdVfX4prhX3z4gWs/Kcc1b0Xt
TPGao1Bz3kBirTGiNDj6/qzrhmM8xgdpphb8CwkpqY36xE2MRfyuSj0vMi4TvKGn
pAAFuNcc+wCI+Bl0XkKsVfZDnnzKKcd8V4Ky5qUNYrcnERqNqIEZTwEQa3bEDKa5
YAIZuWszVoARlrwHzhNbcLPNx3LMCSfw/d6mIkJ74NYxzffjjWvQqVXkau7AX17B
eJbNm1cA6I//TEQMgIV2UVZs7f2bIynEN1RjS5n7OafYbeDPa3Pbm2EfRaXuYNDc
ADRWUe6uA8EER6R5k9CaOIpb4XiyULNe+7KRb+6sgQKBgQD8uFj45aVlVfMgSXLv
PX9xT39YiapOza5EoN5AczBmt3sP0FeQm5CM836NmUxgEGvGhoLLBsyuAHzRncyA
YdpLH04gMRmZrHK5C/TNAkIyiDKxiRsJxoOYdifIB/s5drvTxnXrxYCKwSGvBr8N
cGff+E+gGStsyy48X8n60Q/uWwKBgQDbHaDzpKK2A9V41XeK5noP9JXRAhsNY5ih
JPYZCfYud8Asg6vOldEKU5JBnaka2D2BijWjBTLI5K/YWR73ene58e/caq+OXnmX
MFVXSyIeQRfAdyiXfoMMZByyRWdcmpovcgW2I6Ky4lL0Ds9buASLSaLIbPMH+SH8
gRYcqosv0QKBgQCgE4UH4y6oyZB+2wdaUvHurBRV2J1v3QiNn/gnis8VwRLKKYXN
qzwci/+VYYznLH+X+IvQXjY34Ucu320xxMmo2+N4sKEunfTtEY22bb/QkkTJ/7aI
sp2YbP81zRhshbDjq8n11dxeB4d2fid2M8UYMQj+t/KxruFSjLo7jUEyEQKBgE8m
ws+Ad258sA54PjikzQ8acUwREKijg60iZuvgl1dt1rO91MBJijvKuJiPVVjnKEC1
Jm7/H7tGMOdcOj13tewro1PiDgzFv/KHeSyRbX+0T9ossTMYdkpxl5QmUhI3nt7o
t3t2H/2yl/ilqO4e6TVPokf4Y0pMCqTmFJDCYokhAoGAIYFYa8msJ5Plf2gd2uUe
PZigq8ggbV6JtqByNwp6YPuxbOLtDg/skijF5fwrVZXF0Gmjj9GJBwYWbBKZJQrD
CvV07TTG2PEiXuKngNT5YAzsJ2Zw4g4xuvis/1P/DLVkGQREIjDYSXJtPMHzK46U
0u44yFR5TnnFQwU1hitYSnY=
-----END PRIVATE KEY-----
Loading