Skip to content

Commit fe4f150

Browse files
authoredNov 13, 2017
Merge pull request #5563 from boundlessgeo/BD-2469-pem-key-encoding
[auth][bugfix] Import pvt keys with unknown file extension
2 parents 2c49631 + 822a123 commit fe4f150

16 files changed

+155
-76
lines changed
 

‎python/core/auth/qgsauthcertutils.sip

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,10 @@ Map certificate sha1 to certificate as simple cache
8181
%End
8282

8383

84-
static QByteArray fileData( const QString &path, bool astext = false );
84+
static QByteArray fileData( const QString &path );
8585
%Docstring
8686
Return data from a local file via a read-only operation
8787
\param path Path to file to read
88-
\param astext Whether to open the file as text, otherwise as binary
8988
:return: All data contained in file or empty contents if file does not exist
9089
:rtype: QByteArray
9190
%End

‎src/core/auth/qgsauthcertutils.cpp

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ QMap<QString, QList<QgsAuthConfigSslServer> > QgsAuthCertUtils::sslConfigsGroupe
101101
return orgconfigs;
102102
}
103103

104-
QByteArray QgsAuthCertUtils::fileData( const QString &path, bool astext )
104+
QByteArray QgsAuthCertUtils::fileData( const QString &path )
105105
{
106106
QByteArray data;
107107
QFile file( path );
@@ -112,8 +112,6 @@ QByteArray QgsAuthCertUtils::fileData( const QString &path, bool astext )
112112
}
113113
// TODO: add checks for locked file, etc., to ensure it can be read
114114
QFile::OpenMode openflags( QIODevice::ReadOnly );
115-
if ( astext )
116-
openflags |= QIODevice::Text;
117115
bool ret = file.open( openflags );
118116
if ( ret )
119117
{
@@ -128,7 +126,7 @@ QList<QSslCertificate> QgsAuthCertUtils::certsFromFile( const QString &certspath
128126
{
129127
QList<QSslCertificate> certs;
130128
bool pem = certspath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
131-
certs = QSslCertificate::fromData( QgsAuthCertUtils::fileData( certspath, pem ), pem ? QSsl::Pem : QSsl::Der );
129+
certs = QSslCertificate::fromData( QgsAuthCertUtils::fileData( certspath ), pem ? QSsl::Pem : QSsl::Der );
132130
if ( certs.isEmpty() )
133131
{
134132
QgsDebugMsg( QString( "Parsed cert(s) EMPTY for path: %1" ).arg( certspath ) );
@@ -191,37 +189,53 @@ QSslKey QgsAuthCertUtils::keyFromFile( const QString &keypath,
191189
const QString &keypass,
192190
QString *algtype )
193191
{
194-
bool pem = keypath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
195-
QByteArray keydata( QgsAuthCertUtils::fileData( keypath, pem ) );
196-
192+
// The approach here is to try all possible encodings and algorithms
193+
QByteArray keydata( QgsAuthCertUtils::fileData( keypath ) );
197194
QSslKey clientkey;
198-
clientkey = QSslKey( keydata,
199-
QSsl::Rsa,
200-
pem ? QSsl::Pem : QSsl::Der,
201-
QSsl::PrivateKey,
202-
!keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
203-
if ( clientkey.isNull() )
204-
{
205-
// try DSA algorithm, since Qt can't seem to determine it otherwise
195+
196+
QSsl::EncodingFormat keyEncoding( keydata.contains( QByteArrayLiteral( "-----BEGIN " ) ) ?
197+
QSsl::Pem :
198+
QSsl::Der );
199+
200+
const std::vector<QSsl::KeyAlgorithm> algs
201+
{
202+
QSsl::KeyAlgorithm::Rsa,
203+
QSsl::KeyAlgorithm::Dsa,
204+
QSsl::KeyAlgorithm::Ec,
205+
QSsl::KeyAlgorithm::Opaque
206+
};
207+
208+
for ( const auto &alg : algs )
209+
{
206210
clientkey = QSslKey( keydata,
207-
QSsl::Dsa,
208-
pem ? QSsl::Pem : QSsl::Der,
211+
alg,
212+
keyEncoding,
209213
QSsl::PrivateKey,
210214
!keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
211-
if ( clientkey.isNull() )
215+
if ( ! clientkey.isNull() )
212216
{
213-
return QSslKey();
217+
if ( algtype )
218+
{
219+
switch ( alg )
220+
{
221+
case QSsl::KeyAlgorithm::Rsa:
222+
*algtype = QStringLiteral( "rsa" );
223+
break;
224+
case QSsl::KeyAlgorithm::Dsa:
225+
*algtype = QStringLiteral( "dsa" );
226+
break;
227+
case QSsl::KeyAlgorithm::Ec:
228+
*algtype = QStringLiteral( "ec" );
229+
break;
230+
case QSsl::KeyAlgorithm::Opaque:
231+
*algtype = QStringLiteral( "opaque" );
232+
break;
233+
}
234+
}
235+
return clientkey;
214236
}
215-
if ( algtype )
216-
*algtype = QStringLiteral( "dsa" );
217-
}
218-
else
219-
{
220-
if ( algtype )
221-
*algtype = QStringLiteral( "rsa" );
222237
}
223-
224-
return clientkey;
238+
return QSslKey();
225239
}
226240

227241
QList<QSslCertificate> QgsAuthCertUtils::certsFromString( const QString &pemtext )

‎src/core/auth/qgsauthcertutils.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,9 @@ class CORE_EXPORT QgsAuthCertUtils
108108
/**
109109
* Return data from a local file via a read-only operation
110110
* \param path Path to file to read
111-
* \param astext Whether to open the file as text, otherwise as binary
112111
* \returns All data contained in file or empty contents if file does not exist
113112
*/
114-
static QByteArray fileData( const QString &path, bool astext = false );
113+
static QByteArray fileData( const QString &path );
115114

116115
//! Return list of concatenated certs from a PEM or DER formatted file
117116
static QList<QSslCertificate> certsFromFile( const QString &certspath );

‎src/core/auth/qgsauthconfig.cpp

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -183,35 +183,16 @@ const QgsPkiBundle QgsPkiBundle::fromPemPaths( const QString &certPath,
183183
if ( !certPath.isEmpty() && !keyPath.isEmpty()
184184
&& ( certPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive )
185185
|| certPath.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) )
186-
&& ( keyPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive )
187-
|| keyPath.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) )
188186
&& QFile::exists( certPath ) && QFile::exists( keyPath )
189187
)
190188
{
191189
// client cert
192190
bool pem = certPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
193-
QSslCertificate clientcert( QgsAuthCertUtils::fileData( certPath, pem ), pem ? QSsl::Pem : QSsl::Der );
191+
QSslCertificate clientcert( QgsAuthCertUtils::fileData( certPath ), pem ? QSsl::Pem : QSsl::Der );
194192
pkibundle.setClientCert( clientcert );
195193

196-
// client key
197-
bool pem_key = keyPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
198-
QByteArray keydata( QgsAuthCertUtils::fileData( keyPath, pem_key ) );
199-
200194
QSslKey clientkey;
201-
clientkey = QSslKey( keydata,
202-
QSsl::Rsa,
203-
pem_key ? QSsl::Pem : QSsl::Der,
204-
QSsl::PrivateKey,
205-
!keyPass.isNull() ? keyPass.toUtf8() : QByteArray() );
206-
if ( clientkey.isNull() )
207-
{
208-
// try DSA algorithm, since Qt can't seem to determine it otherwise
209-
clientkey = QSslKey( keydata,
210-
QSsl::Dsa,
211-
pem_key ? QSsl::Pem : QSsl::Der,
212-
QSsl::PrivateKey,
213-
!keyPass.isNull() ? keyPass.toUtf8() : QByteArray() );
214-
}
195+
clientkey = QgsAuthCertUtils::keyFromFile( keyPath, keyPass );
215196
pkibundle.setClientKey( clientkey );
216197
if ( !caChain.isEmpty() )
217198
{

‎src/gui/auth/qgsauthimportidentitydialog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ bool QgsAuthImportIdentityDialog::validatePkiPaths()
288288

289289
// check for valid private key and that any supplied password works
290290
bool keypem = keypath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
291-
QByteArray keydata( QgsAuthCertUtils::fileData( keypath, keypem ) );
291+
QByteArray keydata( QgsAuthCertUtils::fileData( keypath ) );
292292

293293
QSslKey clientkey;
294294
QString keypass = lePkiPathsKeyPass->text();

‎tests/src/core/testqgsauthcertutils.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ void TestQgsAuthCertUtils::testPkcsUtils()
9595
{
9696
QByteArray pkcs;
9797

98-
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key.pem", false );
98+
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key.pem" );
9999
QVERIFY( !pkcs.isEmpty() );
100100
QVERIFY( !QgsAuthCertUtils::pemIsPkcs8( QString( pkcs ) ) );
101101

102102
pkcs.clear();
103-
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key-pkcs8-rsa.pem", false );
103+
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key-pkcs8-rsa.pem" );
104104
QVERIFY( !pkcs.isEmpty() );
105105
QVERIFY( QgsAuthCertUtils::pemIsPkcs8( QString( pkcs ) ) );
106106

@@ -116,31 +116,31 @@ void TestQgsAuthCertUtils::testPkcsUtils()
116116
pkcs.clear();
117117
pkcs1.clear();
118118
// Is actually a PKCS#1 key, not #8
119-
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key.der", false );
119+
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key.der" );
120120
QVERIFY( !pkcs.isEmpty() );
121121
pkcs1 = QgsAuthCertUtils::pkcs8PrivateKey( pkcs );
122122
QVERIFY( pkcs1.isEmpty() );
123123

124124
pkcs.clear();
125125
pkcs1.clear();
126126
// Is PKCS#1 PEM text, not DER
127-
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key.pem", false );
127+
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key.pem" );
128128
QVERIFY( !pkcs.isEmpty() );
129129
pkcs1 = QgsAuthCertUtils::pkcs8PrivateKey( pkcs );
130130
QVERIFY( pkcs1.isEmpty() );
131131

132132
pkcs.clear();
133133
pkcs1.clear();
134134
// Is PKCS#8 PEM text, not DER
135-
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key-pkcs8-rsa.pem", false );
135+
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key-pkcs8-rsa.pem" );
136136
QVERIFY( !pkcs.isEmpty() );
137137
pkcs1 = QgsAuthCertUtils::pkcs8PrivateKey( pkcs );
138138
QVERIFY( pkcs1.isEmpty() );
139139

140140
pkcs.clear();
141141
pkcs1.clear();
142142
// Correct PKCS#8 DER input
143-
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key-pkcs8-rsa.der", false );
143+
pkcs = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key-pkcs8-rsa.der" );
144144
QVERIFY( !pkcs.isEmpty() );
145145
pkcs1 = QgsAuthCertUtils::pkcs8PrivateKey( pkcs );
146146
QVERIFY( !pkcs1.isEmpty() );
@@ -156,7 +156,7 @@ void TestQgsAuthCertUtils::testPkcsUtils()
156156
QVERIFY( !pkcs1Key.isNull() );
157157

158158
// Converted PKCS#8 DER should match PKCS#1 PEM
159-
QByteArray pkcs1PemRef = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key.pem", true );
159+
QByteArray pkcs1PemRef = QgsAuthCertUtils::fileData( sPkiData + "/gerardus_key.pem" );
160160
QVERIFY( !pkcs1PemRef.isEmpty() );
161161
QCOMPARE( pkcs1Key.toPem(), pkcs1PemRef );
162162
#endif

‎tests/src/python/test_qgsauthsystem.py

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ def widget_dialog(self, widget):
7171
dlg.setLayout(layout)
7272
return dlg
7373

74+
def mkPEMBundle(self, client_cert, client_key, password, chain):
75+
return QgsPkiBundle.fromPemPaths(PKIDATA + '/' + client_cert,
76+
PKIDATA + '/' + client_key,
77+
password,
78+
QgsAuthCertUtils.certsFromFile(
79+
PKIDATA + '/' + chain
80+
))
81+
7482
def show_editors_widget(self):
7583
editors = QgsAuthEditorWidgets()
7684
dlg = self.widget_dialog(editors)
@@ -648,16 +656,8 @@ def testChain(path):
648656
def test_validate_pki_bundle(self):
649657
"""Text the pki bundle validation"""
650658

651-
def mkPEMBundle(client_cert, client_key, password, chain):
652-
return QgsPkiBundle.fromPemPaths(PKIDATA + '/' + client_cert,
653-
PKIDATA + '/' + client_key,
654-
password,
655-
QgsAuthCertUtils.certsFromFile(
656-
PKIDATA + '/' + chain
657-
))
658-
659659
# Valid bundle:
660-
bundle = mkPEMBundle('fra_cert.pem', 'fra_key.pem', 'password', 'chain_subissuer-issuer-root.pem')
660+
bundle = self.mkPEMBundle('fra_cert.pem', 'fra_key.pem', 'password', 'chain_subissuer-issuer-root.pem')
661661

662662
# Test valid bundle with intermediates and without trusted root
663663
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted'])
@@ -667,7 +667,7 @@ def mkPEMBundle(client_cert, client_key, password, chain):
667667
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), [])
668668

669669
# Wrong chain
670-
bundle = mkPEMBundle('fra_cert.pem', 'fra_key.pem', 'password', 'chain_issuer2-root2.pem')
670+
bundle = self.mkPEMBundle('fra_cert.pem', 'fra_key.pem', 'password', 'chain_issuer2-root2.pem')
671671
# Test invalid bundle with intermediates and without trusted root
672672
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified'])
673673
# Test valid without intermediates
@@ -676,7 +676,7 @@ def mkPEMBundle(client_cert, client_key, password, chain):
676676
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified'])
677677

678678
# Wrong key
679-
bundle = mkPEMBundle('fra_cert.pem', 'ptolemy_key.pem', 'password', 'chain_subissuer-issuer-root.pem')
679+
bundle = self.mkPEMBundle('fra_cert.pem', 'ptolemy_key.pem', 'password', 'chain_subissuer-issuer-root.pem')
680680
# Test invalid bundle with intermediates and without trusted root
681681
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted', 'Private key does not match client certificate public key.'])
682682
# Test invalid without intermediates
@@ -685,25 +685,25 @@ def mkPEMBundle(client_cert, client_key, password, chain):
685685
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['Private key does not match client certificate public key.'])
686686

687687
# Expired root CA
688-
bundle = mkPEMBundle('piri_cert.pem', 'piri_key.pem', 'password', 'chain_issuer3-root3-EXPIRED.pem')
688+
bundle = self.mkPEMBundle('piri_cert.pem', 'piri_key.pem', 'password', 'chain_issuer3-root3-EXPIRED.pem')
689689
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired'])
690690
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified'])
691691
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired'])
692692

693693
# Expired intermediate CA
694-
bundle = mkPEMBundle('marinus_cert-EXPIRED.pem', 'marinus_key_w-pass.pem', 'password', 'chain_issuer2-root2.pem')
694+
bundle = self.mkPEMBundle('marinus_cert-EXPIRED.pem', 'marinus_key_w-pass.pem', 'password', 'chain_issuer2-root2.pem')
695695
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired'])
696696
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified'])
697697
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The certificate has expired'])
698698

699699
# Expired client cert
700-
bundle = mkPEMBundle('henricus_cert.pem', 'henricus_key_w-pass.pem', 'password', 'chain_issuer4-EXPIRED-root2.pem')
700+
bundle = self.mkPEMBundle('henricus_cert.pem', 'henricus_key_w-pass.pem', 'password', 'chain_issuer4-EXPIRED-root2.pem')
701701
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle), ['The root certificate of the certificate chain is self-signed, and untrusted', 'The certificate has expired'])
702702
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, False), ['The issuer certificate of a locally looked up certificate could not be found', 'No certificates could be verified'])
703703
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), ['The certificate has expired'])
704704

705705
# Untrusted root, positive test before untrust is applied
706-
bundle = mkPEMBundle('nicholas_cert.pem', 'nicholas_key.pem', 'password', 'chain_issuer2-root2.pem')
706+
bundle = self.mkPEMBundle('nicholas_cert.pem', 'nicholas_key.pem', 'password', 'chain_issuer2-root2.pem')
707707
# Test valid with intermediates and trusted root
708708
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(bundle, True, True), [])
709709
# Untrust this root
@@ -743,6 +743,29 @@ def test_160_cert_viable(self):
743743
self.assertTrue(QSslError(QSslError.CertificateExpired, cert) in res)
744744
self.assertFalse(QgsAuthCertUtils.certIsViable(cert))
745745

746+
def test_170_pki_key_encoding(self):
747+
"""Test that a DER/PEM RSA/DSA/EC keys can be opened whatever the extension is"""
748+
749+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key.pem').isNull())
750+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key.der').isNull())
751+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key_pem.key').isNull())
752+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'ptolemy_key_der.key').isNull())
753+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_EC.pem').isNull())
754+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_EC.der').isNull())
755+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.pem').isNull())
756+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.der').isNull())
757+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_crlf.pem').isNull())
758+
self.assertFalse(QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_nonl.pem').isNull())
759+
donald_dsa = QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.pem').toPem()
760+
self.assertEqual(donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA.der').toPem())
761+
self.assertEqual(donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_crlf.pem').toPem())
762+
self.assertEqual(donald_dsa, QgsAuthCertUtils.keyFromFile(PKIDATA + '/' + 'donald_key_DSA_nonl.pem').toPem())
763+
764+
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key.pem', 'password', 'chain_subissuer-issuer-root.pem'), True, True), [])
765+
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key.der', 'password', 'chain_subissuer-issuer-root.pem'), True, True), [])
766+
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key_pem.key', 'password', 'chain_subissuer-issuer-root.pem'), True, True), [])
767+
self.assertEqual(QgsAuthCertUtils.validatePKIBundle(self.mkPEMBundle('ptolemy_cert.pem', 'ptolemy_key_der.key', 'password', 'chain_subissuer-issuer-root.pem'), True, True), [])
768+
746769

747770
if __name__ == '__main__':
748771
unittest.main()
Binary file not shown.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN DSA PRIVATE KEY-----
2+
MIIDVgIBAAKCAQEAwVdYLRBhy3TS0vjvf7cHOwSdumAqX3klBOvgUiU8uG3+BmBA
3+
01u9x2xZDigsc6fAS0SF4ZO9Hzd3AQwixGIX9hXNVYCpxm35g/IosoyKfNyXHC+Y
4+
qNRhPOIBuRft4+2EADpElWYPIXG9AKRTqmZ8Hoicga06gRdx71qofi6iQcbDl9vW
5+
2lo6LDk4KCiaD3fWUvgO2nQplMk8G84JTLJ0mlXyWMDmF/72zeK80KRRN9GSr90b
6+
4PgSQBC97UWQlAkL/+7ryVVoyQID/1K0jB8Y5sA697l3Z0Az55b177j9TNJLnzBw
7+
ffs22KWPQ/h1h6R0XQbK6Ln948884pqmTg5xJwIhANZMSTMzqxSu6EaAOUmueWbd
8+
GAMcGdzThv1XLCZWecTxAoIBAQC9UQifo/aMtI/oHDNYiGGT7kG5dhZrUvZERL37
9+
9UBZAOh8REf7WjQkmwpG/WjCE+Mhzx5Rnvx7rQQ//PJEkHOI5FJJVZ7Ud439uVMA
10+
iJt2kLOUtGQefNCY50fPzik/dC/juFOTsatEvXB9u2JTaDZUYZs8OiKs7dhkPKV9
11+
u6fmhNl6hNjF8E9C1Q9jqxMjjJ3QWdGtmeOAj0XqKc6oLO+jP1qzIP6LEwOrX3SK
12+
YZBA3z/g/+I1Z4lboeTtAgsRKh0TxDEIj8UxfKHYWh3lu1isccljPTH5qIlGLihN
13+
MksKJSfJP0+oKN0E12hzS4+Ey0oBQuwa3rcuf6Dc14ujOnmNAoIBACq2MPjY9LhL
14+
9ky11ZF9a7dKJ08SSlaqkzKWdwV6ZyqNsWbDNnc0IWvgcIfVjFpvdmom1VkOvZ4w
15+
Qp7G/pN6FYfATbZbCcm1+EZTAIyqDbfqbE6Sh8w/U29FdBdE0xBChSfnqFcRT7Gt
16+
5JpEsPrwfgDKkaqQBdZzXU6xfELheQUGEwqS5e2JgaC68x5QwqrbGyXGmM0qQA7s
17+
1b/6gzSnX3xWADXSBBC+/9mjXmWj63LoQovAL2qJk/C/62AYrtNypsKCZmWAYXUz
18+
woArLlJjKVKcsKkf2qcwntQuzWcke/+GCAdxKVgbvBj6bIxFAL4GbuR+pQJ0qJk5
19+
nSook39BtmICIEIBucuiezcjv66iBble6PE+XycVvY68cLH7OLDN4rkV
20+
-----END DSA PRIVATE KEY-----
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN DSA PRIVATE KEY-----
2+
MIIDVgIBAAKCAQEAwVdYLRBhy3TS0vjvf7cHOwSdumAqX3klBOvgUiU8uG3+BmBA
3+
01u9x2xZDigsc6fAS0SF4ZO9Hzd3AQwixGIX9hXNVYCpxm35g/IosoyKfNyXHC+Y
4+
qNRhPOIBuRft4+2EADpElWYPIXG9AKRTqmZ8Hoicga06gRdx71qofi6iQcbDl9vW
5+
2lo6LDk4KCiaD3fWUvgO2nQplMk8G84JTLJ0mlXyWMDmF/72zeK80KRRN9GSr90b
6+
4PgSQBC97UWQlAkL/+7ryVVoyQID/1K0jB8Y5sA697l3Z0Az55b177j9TNJLnzBw
7+
ffs22KWPQ/h1h6R0XQbK6Ln948884pqmTg5xJwIhANZMSTMzqxSu6EaAOUmueWbd
8+
GAMcGdzThv1XLCZWecTxAoIBAQC9UQifo/aMtI/oHDNYiGGT7kG5dhZrUvZERL37
9+
9UBZAOh8REf7WjQkmwpG/WjCE+Mhzx5Rnvx7rQQ//PJEkHOI5FJJVZ7Ud439uVMA
10+
iJt2kLOUtGQefNCY50fPzik/dC/juFOTsatEvXB9u2JTaDZUYZs8OiKs7dhkPKV9
11+
u6fmhNl6hNjF8E9C1Q9jqxMjjJ3QWdGtmeOAj0XqKc6oLO+jP1qzIP6LEwOrX3SK
12+
YZBA3z/g/+I1Z4lboeTtAgsRKh0TxDEIj8UxfKHYWh3lu1isccljPTH5qIlGLihN
13+
MksKJSfJP0+oKN0E12hzS4+Ey0oBQuwa3rcuf6Dc14ujOnmNAoIBACq2MPjY9LhL
14+
9ky11ZF9a7dKJ08SSlaqkzKWdwV6ZyqNsWbDNnc0IWvgcIfVjFpvdmom1VkOvZ4w
15+
Qp7G/pN6FYfATbZbCcm1+EZTAIyqDbfqbE6Sh8w/U29FdBdE0xBChSfnqFcRT7Gt
16+
5JpEsPrwfgDKkaqQBdZzXU6xfELheQUGEwqS5e2JgaC68x5QwqrbGyXGmM0qQA7s
17+
1b/6gzSnX3xWADXSBBC+/9mjXmWj63LoQovAL2qJk/C/62AYrtNypsKCZmWAYXUz
18+
woArLlJjKVKcsKkf2qcwntQuzWcke/+GCAdxKVgbvBj6bIxFAL4GbuR+pQJ0qJk5
19+
nSook39BtmICIEIBucuiezcjv66iBble6PE+XycVvY68cLH7OLDN4rkV
20+
-----END DSA PRIVATE KEY-----
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-----BEGIN DSA PRIVATE KEY-----
2+
MIIDVgIBAAKCAQEAwVdYLRBhy3TS0vjvf7cHOwSdumAqX3klBOvgUiU8uG3+BmBA01u9x2xZDigsc6fAS0SF4ZO9Hzd3AQwixGIX9hXNVYCpxm35g/IosoyKfNyXHC+YqNRhPOIBuRft4+2EADpElWYPIXG9AKRTqmZ8Hoicga06gRdx71qofi6iQcbDl9vW2lo6LDk4KCiaD3fWUvgO2nQplMk8G84JTLJ0mlXyWMDmF/72zeK80KRRN9GSr90b4PgSQBC97UWQlAkL/+7ryVVoyQID/1K0jB8Y5sA697l3Z0Az55b177j9TNJLnzBwffs22KWPQ/h1h6R0XQbK6Ln948884pqmTg5xJwIhANZMSTMzqxSu6EaAOUmueWbdGAMcGdzThv1XLCZWecTxAoIBAQC9UQifo/aMtI/oHDNYiGGT7kG5dhZrUvZERL379UBZAOh8REf7WjQkmwpG/WjCE+Mhzx5Rnvx7rQQ//PJEkHOI5FJJVZ7Ud439uVMAiJt2kLOUtGQefNCY50fPzik/dC/juFOTsatEvXB9u2JTaDZUYZs8OiKs7dhkPKV9u6fmhNl6hNjF8E9C1Q9jqxMjjJ3QWdGtmeOAj0XqKc6oLO+jP1qzIP6LEwOrX3SKYZBA3z/g/+I1Z4lboeTtAgsRKh0TxDEIj8UxfKHYWh3lu1isccljPTH5qIlGLihNMksKJSfJP0+oKN0E12hzS4+Ey0oBQuwa3rcuf6Dc14ujOnmNAoIBACq2MPjY9LhL9ky11ZF9a7dKJ08SSlaqkzKWdwV6ZyqNsWbDNnc0IWvgcIfVjFpvdmom1VkOvZ4wQp7G/pN6FYfATbZbCcm1+EZTAIyqDbfqbE6Sh8w/U29FdBdE0xBChSfnqFcRT7Gt5JpEsPrwfgDKkaqQBdZzXU6xfELheQUGEwqS5e2JgaC68x5QwqrbGyXGmM0qQA7s1b/6gzSnX3xWADXSBBC+/9mjXmWj63LoQovAL2qJk/C/62AYrtNypsKCZmWAYXUzwoArLlJjKVKcsKkf2qcwntQuzWcke/+GCAdxKVgbvBj6bIxFAL4GbuR+pQJ0qJk5nSook39BtmICIEIBucuiezcjv66iBble6PE+XycVvY68cLH7OLDN4rkV
3+
-----END DSA PRIVATE KEY-----
Binary file not shown.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN EC PRIVATE KEY-----
2+
MF8CAQEEGIsQLxNQtoHQcIzLa3vu1MVG9en2pUgqKKAKBggqhkjOPQMBAaE0AzIA
3+
BDhZ5yKtc6E9igj0XMsTMP2rN6SPAryUoAn5yFrOvkaWlqATluDMx9VTuzBELeDL
4+
Jg==
5+
-----END EC PRIVATE KEY-----
Binary file not shown.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIICXAIBAAKBgQCuyiO7qMUYFkOACHQKrBmqPzNTINAvKaDELr+JNjkaZYqDy5Z2
3+
uX05YQRWQYgfX/OkC6KJ8EtIhMIbN+VXSbZbxKK47nex5kHrFOklpO2zQUE3VmyT
4+
yYDOPIryI2Uo1bwY98xAyS+bvePLieu8z9YEOaqjq1wwleSqVxjpEQw7mwIDAQAB
5+
AoGAIDUHGJEkoCeaEIF+QGkt4Xz7zBmDwuz8vqmOiY4AP6juORLOitnrBSOnVO2G
6+
U6Gul0+9h4VLmfU8fx9xlv/yJfDCYVhJosuoQfsl98hIKvgrlAoMZ2XegYV+h9zu
7+
HUQRcR2kxFI0CaWVqyEtLwM23YCbjLw2zQ2LmIBf2QDMBmECQQDW8Qyc62EMSHpW
8+
psIhDvbjxrzqB0aKS6CGhWT53kp6aZCMi6AqopAI0LqnqlRDhV5WBX0fMFU/Wqv0
9+
V6msNANNAkEA0C2ZxsIYmqbQZ/AS/ukYyTNUZnNY5o4kjZKfqMOe97bSYXYB5wtP
10+
goznMELuQ29p8w5E/pJDi5uWgszrmf12hwJBAIAFDlggMatZN9SIejOqcA52fmp9
11+
btxL8w5sQRo59e43Fes/9mOuc09s0t+uKYYV13wwxLdg2EVlwelElUCFsjkCQHRJ
12+
BJ0BzryUcdWdRP8fNbkt8vdHd2FSBRkPzh93JlU4ykumn2lv5/oEux86Q91nXsdm
13+
MSQCj7hsMKbf0Lsz2gECQBj/J4+YPaGMcw/sdNfH8Un/wbE411Nkukq2yIOQ+Aeb
14+
OZGBVzry1EuK34xlsbLMh3bWbhX+01TJkqeW00u2AH0=
15+
-----END RSA PRIVATE KEY-----
2.04 KB
Binary file not shown.

0 commit comments

Comments
 (0)
Please sign in to comment.