aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rwxr-xr-x.travis/install.sh7
-rw-r--r--CHANGELOG.rst4
-rw-r--r--README.rst2
-rw-r--r--docs/development/submitting-patches.rst2
-rw-r--r--docs/development/test-vectors.rst4
-rw-r--r--docs/installation.rst4
-rw-r--r--docs/spelling_wordlist.txt1
-rw-r--r--docs/x509.rst85
-rw-r--r--setup.py3
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py29
-rw-r--r--src/cryptography/hazmat/bindings/openssl/x509.py1
-rw-r--r--src/cryptography/x509.py51
-rw-r--r--tests/hazmat/backends/test_openssl.py10
-rw-r--r--tests/test_x509.py14
-rw-r--r--vectors/cryptography_vectors/x509/verisign_md2_root.pem14
16 files changed, 214 insertions, 19 deletions
diff --git a/.travis.yml b/.travis.yml
index 9b900eb9..b6f6f0cf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -40,6 +40,8 @@ notifications:
- "irc.freenode.org#cryptography-dev"
use_notice: true
skip_join: true
+ webhooks:
+ - https://buildtimetrend.herokuapp.com/travis
matrix:
exclude:
diff --git a/.travis/install.sh b/.travis/install.sh
index 26a82c44..f82cc4a3 100755
--- a/.travis/install.sh
+++ b/.travis/install.sh
@@ -3,13 +3,8 @@
set -e
set -x
-if [[ "$(uname -s)" == 'Darwin' ]]; then
- DARWIN=true
-else
- DARWIN=false
-fi
-if [[ "$DARWIN" = true ]]; then
+if [[ "$(uname -s)" == 'Darwin' ]]; then
brew update
if [[ "${OPENSSL}" != "0.9.8" ]]; then
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e106ff44..da529f68 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -9,6 +9,9 @@ Changelog
* :func:`~cryptography.hazmat.primitives.serialization.load_ssh_public_key` can
now load elliptic curve public keys.
* Added
+ :attr:`~cryptography.x509.Certificate.signature_hash_algorithm` support to
+ :class:`~cryptography.x509.Certificate`.
+* Added
:func:`~cryptography.hazmat.primitives.asymmetric.rsa.rsa_recover_prime_factors`
* :class:`~cryptography.hazmat.primitives.kdf.KeyDerivationFunction` was moved
from :mod:`~cryptography.hazmat.primitives.interfaces` to
@@ -74,6 +77,7 @@ Changelog
:func:`~cryptography.hazmat.primitives.serialization.load_der_public_key` to
support loading DER encoded public keys.
* Fixed building against LibreSSL, a compile-time substitute for OpenSSL.
+* FreeBSD 9.2 was removed from the continuous integration system.
0.7.2 - 2015-01-16
~~~~~~~~~~~~~~~~~~
diff --git a/README.rst b/README.rst
index e0ef886e..1277505a 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,7 @@
Cryptography
============
-.. image:: https://pypip.in/version/cryptography/badge.svg
+.. image:: https://pypip.in/version/cryptography/badge.svg?style=flat
:target: https://pypi.python.org/pypi/cryptography/
:alt: Latest Version
diff --git a/docs/development/submitting-patches.rst b/docs/development/submitting-patches.rst
index 810b8748..66105843 100644
--- a/docs/development/submitting-patches.rst
+++ b/docs/development/submitting-patches.rst
@@ -151,6 +151,6 @@ So, specifically:
.. _`Write comments as complete sentences.`: http://nedbatchelder.com/blog/201401/comments_should_be_sentences.html
.. _`syntax`: http://sphinx-doc.org/domains.html#info-field-lists
-.. _`Studies have shown`: http://www.ibm.com/developerworks/rational/library/11-proven-practices-for-peer-review/
+.. _`Studies have shown`: https://smartbear.com/smartbear/media/pdfs/wp-cc-11-best-practices-of-peer-code-review.pdf
.. _`our mailing list`: https://mail.python.org/mailman/listinfo/cryptography-dev
.. _`doc8`: https://github.com/stackforge/doc8
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index 4c048abf..2cd9faa6 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -80,6 +80,9 @@ X.509
* ``v1_cert.pem`` from the OpenSSL source tree (`testx509.pem`_).
* ``ecdsa_root.pem`` - `DigiCert Global Root G3`_, a ``secp384r1`` ECDSA root
certificate.
+* ``verisign-md2-root.pem`` - A legacy Verisign public root signed using the
+ MD2 algorithm. This is a PEM conversion of the `root data`_ in the NSS source
+ tree.
Custom X.509 Vectors
~~~~~~~~~~~~~~~~~~~~
@@ -219,3 +222,4 @@ header format (substituting the correct information):
.. _`NIST PKI Testing`: http://csrc.nist.gov/groups/ST/crypto_apps_infra/pki/pkitesting.html
.. _`testx509.pem`: https://github.com/openssl/openssl/blob/master/test/testx509.pem
.. _`DigiCert Global Root G3`: http://cacerts.digicert.com/DigiCertGlobalRootG3.crt
+.. _`root data`: https://hg.mozilla.org/projects/nss/file/25b2922cc564/security/nss/lib/ckfw/builtins/certdata.txt#l2053
diff --git a/docs/installation.rst b/docs/installation.rst
index c8a37bfa..c061903e 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -14,7 +14,7 @@ Currently we test ``cryptography`` on Python 2.6, 2.7, 3.2, 3.3, 3.4 and PyPy
on these operating systems.
* x86-64 CentOS 7.x, 6.4 and CentOS 5.x
-* x86-64 FreeBSD 9.2 and FreeBSD 10
+* x86-64 FreeBSD 10
* OS X 10.10 Yosemite, 10.9 Mavericks, 10.8 Mountain Lion, and 10.7 Lion
* x86-64 Ubuntu 12.04 LTS
* x86-64 Debian Wheezy (7.x) and Jessie (8.x)
@@ -30,7 +30,7 @@ OpenSSL releases:
* ``OpenSSL 1.0.0-fips`` (``RHEL/CentOS 6.4``)
* ``OpenSSL 1.0.1``
* ``OpenSSL 1.0.1e-fips`` (``RHEL/CentOS 7``)
-* ``OpenSSL 1.0.1e-freebsd``
+* ``OpenSSL 1.0.1j-freebsd``
* ``OpenSSL 1.0.1-latest`` (The most recent 1.0.1 release)
* ``OpenSSL 1.0.2``
diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt
index fefd26b3..ddd37897 100644
--- a/docs/spelling_wordlist.txt
+++ b/docs/spelling_wordlist.txt
@@ -51,3 +51,4 @@ Ubuntu
unencrypted
unpadded
unpadding
+Verisign
diff --git a/docs/x509.rst b/docs/x509.rst
index 0298d94d..27f1d544 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -182,6 +182,19 @@ X.509 Certificate Object
The :class:`Name` of the subject.
+ .. attribute:: signature_hash_algorithm
+
+ :type: :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+
+ Returns the
+ :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` which
+ was used in signing this certificate.
+
+ .. doctest::
+
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> isinstance(cert.signature_hash_algorithm, hashes.SHA256)
+ True
.. class:: Name
@@ -266,6 +279,9 @@ Object Identifiers
X.509 elements are frequently identified by :class:`ObjectIdentifier`
instances. The following common OIDs are available as constants.
+Name OIDs
+~~~~~~~~~
+
.. data:: OID_COMMON_NAME
Corresponds to the dotted string ``"2.5.4.3"``. Historically the domain
@@ -346,6 +362,75 @@ instances. The following common OIDs are available as constants.
Corresponds to the dotted string ``"1.2.840.113549.1.9.1"``. This OID is
typically seen in X.509 names.
+Signature Algorithm OIDs
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. data:: OID_RSA_WITH_MD5
+
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.4"``. This is
+ an MD5 digest signed by an RSA key.
+
+.. data:: OID_RSA_WITH_SHA1
+
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.5"``. This is
+ a SHA1 digest signed by an RSA key.
+
+.. data:: OID_RSA_WITH_SHA224
+
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.14"``. This is
+ a SHA224 digest signed by an RSA key.
+
+.. data:: OID_RSA_WITH_SHA256
+
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.11"``. This is
+ a SHA256 digest signed by an RSA key.
+
+.. data:: OID_RSA_WITH_SHA384
+
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.12"``. This is
+ a SHA384 digest signed by an RSA key.
+
+.. data:: OID_RSA_WITH_SHA512
+
+ Corresponds to the dotted string ``"1.2.840.113549.1.1.13"``. This is
+ a SHA512 digest signed by an RSA key.
+
+.. data:: OID_ECDSA_WITH_SHA224
+
+ Corresponds to the dotted string ``"1.2.840.10045.4.3.1"``. This is
+ a SHA224 digest signed by an ECDSA key.
+
+.. data:: OID_ECDSA_WITH_SHA256
+
+ Corresponds to the dotted string ``"1.2.840.10045.4.3.2"``. This is
+ a SHA256 digest signed by an ECDSA key.
+
+.. data:: OID_ECDSA_WITH_SHA384
+
+ Corresponds to the dotted string ``"1.2.840.10045.4.3.3"``. This is
+ a SHA384 digest signed by an ECDSA key.
+
+.. data:: OID_ECDSA_WITH_SHA512
+
+ Corresponds to the dotted string ``"1.2.840.10045.4.3.4"``. This is
+ a SHA512 digest signed by an ECDSA key.
+
+.. data:: OID_DSA_WITH_SHA1
+
+ Corresponds to the dotted string ``"1.2.840.10040.4.3"``. This is
+ a SHA1 digest signed by a DSA key.
+
+.. data:: OID_DSA_WITH_SHA224
+
+ Corresponds to the dotted string ``"2.16.840.1.101.3.4.3.1"``. This is
+ a SHA224 digest signed by a DSA key.
+
+.. data:: OID_DSA_WITH_SHA256
+
+ Corresponds to the dotted string ``2.16.840.1.101.3.4.3.2"``. This is
+ a SHA256 digest signed by a DSA key.
+
+
Exceptions
~~~~~~~~~~
diff --git a/setup.py b/setup.py
index 32a87ba3..2324d54f 100644
--- a/setup.py
+++ b/setup.py
@@ -135,7 +135,8 @@ class PyTest(test):
def run_tests(self):
# Import here because in module scope the eggs are not loaded.
import pytest
- errno = pytest.main(self.test_args)
+ test_args = [os.path.join(base_dir, "tests")]
+ errno = pytest.main(test_args)
sys.exit(errno)
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 76dcf32f..b712f1f9 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -16,6 +16,7 @@ from __future__ import absolute_import, division, print_function
import datetime
from cryptography import utils, x509
+from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.primitives import hashes
@@ -121,14 +122,7 @@ class _Certificate(object):
buf, lambda buf: self._backend._lib.OPENSSL_free(buf[0])
)
value = self._backend._ffi.buffer(buf[0], res)[:].decode('utf8')
- # Set to 80 on the recommendation of
- # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html
- buf_len = 80
- buf = self._backend._ffi.new("char[]", buf_len)
- res = self._backend._lib.OBJ_obj2txt(buf, buf_len, obj, 1)
- assert res > 0
- oid = self._backend._ffi.buffer(buf, res)[:].decode()
-
+ oid = self._obj2txt(obj)
attributes.append(
x509.NameAttribute(
x509.ObjectIdentifier(oid), value
@@ -136,3 +130,22 @@ class _Certificate(object):
)
return x509.Name(attributes)
+
+ def _obj2txt(self, obj):
+ # Set to 80 on the recommendation of
+ # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values
+ buf_len = 80
+ buf = self._backend._ffi.new("char[]", buf_len)
+ res = self._backend._lib.OBJ_obj2txt(buf, buf_len, obj, 1)
+ assert res > 0
+ return self._backend._ffi.buffer(buf, res)[:].decode()
+
+ @property
+ def signature_hash_algorithm(self):
+ oid = self._obj2txt(self._x509.sig_alg.algorithm)
+ try:
+ return x509._SIG_OIDS_TO_HASH[oid]
+ except KeyError:
+ raise UnsupportedAlgorithm(
+ "Signature algorithm OID:{0} not recognized".format(oid)
+ )
diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py
index 585a2e90..f5638da7 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509.py
@@ -65,6 +65,7 @@ typedef struct {
} X509_CRL;
typedef struct {
+ X509_ALGOR *sig_alg;
X509_CINF *cert_info;
...;
} X509;
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 8a6ecc8d..ad7ebbe0 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -10,6 +10,7 @@ from enum import Enum
import six
from cryptography import utils
+from cryptography.hazmat.primitives import hashes
_OID_NAMES = {
@@ -28,6 +29,19 @@ _OID_NAMES = {
"2.5.4.65": "pseudonym",
"0.9.2342.19200300.100.1.25": "domainComponent",
"1.2.840.113549.1.9.1": "emailAddress",
+ "1.2.840.113549.1.1.4": "md5WithRSAEncryption",
+ "1.2.840.113549.1.1.5": "sha1WithRSAEncryption",
+ "1.2.840.113549.1.1.14": "sha224WithRSAEncryption",
+ "1.2.840.113549.1.1.11": "sha256WithRSAEncryption",
+ "1.2.840.113549.1.1.12": "sha384WithRSAEncryption",
+ "1.2.840.113549.1.1.13": "sha512WithRSAEncryption",
+ "1.2.840.10045.4.3.1": "ecdsa-with-SHA224",
+ "1.2.840.10045.4.3.2": "ecdsa-with-SHA256",
+ "1.2.840.10045.4.3.3": "ecdsa-with-SHA384",
+ "1.2.840.10045.4.3.4": "ecdsa-with-SHA512",
+ "1.2.840.10040.4.3": "dsa-with-sha1",
+ "2.16.840.1.101.3.4.3.1": "dsa-with-sha224",
+ "2.16.840.1.101.3.4.3.2": "dsa-with-sha256",
}
@@ -143,6 +157,36 @@ OID_PSEUDONYM = ObjectIdentifier("2.5.4.65")
OID_DOMAIN_COMPONENT = ObjectIdentifier("0.9.2342.19200300.100.1.25")
OID_EMAIL_ADDRESS = ObjectIdentifier("1.2.840.113549.1.9.1")
+OID_RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
+OID_RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
+OID_RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
+OID_RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
+OID_RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
+OID_RSA_WITH_SHA512 = ObjectIdentifier("1.2.840.113549.1.1.13")
+OID_ECDSA_WITH_SHA224 = ObjectIdentifier("1.2.840.10045.4.3.1")
+OID_ECDSA_WITH_SHA256 = ObjectIdentifier("1.2.840.10045.4.3.2")
+OID_ECDSA_WITH_SHA384 = ObjectIdentifier("1.2.840.10045.4.3.3")
+OID_ECDSA_WITH_SHA512 = ObjectIdentifier("1.2.840.10045.4.3.4")
+OID_DSA_WITH_SHA1 = ObjectIdentifier("1.2.840.10040.4.3")
+OID_DSA_WITH_SHA224 = ObjectIdentifier("2.16.840.1.101.3.4.3.1")
+OID_DSA_WITH_SHA256 = ObjectIdentifier("2.16.840.1.101.3.4.3.2")
+
+_SIG_OIDS_TO_HASH = {
+ OID_RSA_WITH_MD5.dotted_string: hashes.MD5(),
+ OID_RSA_WITH_SHA1.dotted_string: hashes.SHA1(),
+ OID_RSA_WITH_SHA224.dotted_string: hashes.SHA224(),
+ OID_RSA_WITH_SHA256.dotted_string: hashes.SHA256(),
+ OID_RSA_WITH_SHA384.dotted_string: hashes.SHA384(),
+ OID_RSA_WITH_SHA512.dotted_string: hashes.SHA512(),
+ OID_ECDSA_WITH_SHA224.dotted_string: hashes.SHA224(),
+ OID_ECDSA_WITH_SHA256.dotted_string: hashes.SHA256(),
+ OID_ECDSA_WITH_SHA384.dotted_string: hashes.SHA384(),
+ OID_ECDSA_WITH_SHA512.dotted_string: hashes.SHA512(),
+ OID_DSA_WITH_SHA1.dotted_string: hashes.SHA1(),
+ OID_DSA_WITH_SHA224.dotted_string: hashes.SHA224(),
+ OID_DSA_WITH_SHA256.dotted_string: hashes.SHA256()
+}
+
@six.add_metaclass(abc.ABCMeta)
class Certificate(object):
@@ -193,3 +237,10 @@ class Certificate(object):
"""
Returns the subject name object.
"""
+
+ @abc.abstractproperty
+ def signature_hash_algorithm(self):
+ """
+ Returns a HashAlgorithm corresponding to the type of the digest signed
+ in the certificate.
+ """
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index 2bf66a0c..0e4d75ed 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -234,9 +234,19 @@ class TestOpenSSLRandomEngine(object):
)
engine_name = tmpdir.join('engine_name')
+ # If we're running tests via ``python setup.py test`` in a clean
+ # environment then all of our dependencies are going to be installed
+ # into either the current directory or the .eggs directory. However the
+ # subprocess won't know to activate these dependencies, so we'll get it
+ # to do so by passing our entire sys.path into the subprocess via the
+ # PYTHONPATH environment variable.
+ env = os.environ.copy()
+ env["PYTHONPATH"] = os.pathsep.join(sys.path)
+
with engine_name.open('w') as out:
subprocess.check_call(
[sys.executable, "-c", engine_printer],
+ env=env,
stdout=out
)
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 55a94084..8f00eeed 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -13,6 +13,7 @@ import pytest
import six
from cryptography import x509
+from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.backends.interfaces import (
DSABackend, EllipticCurveBackend, RSABackend, X509Backend
)
@@ -45,6 +46,7 @@ class TestRSACertificate(object):
assert cert.serial == 11559813051657483483
fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
assert fingerprint == b"2b619ed04bfc9c3b08eb677d272192286a0947a8"
+ assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
def test_load_der_cert(self, backend):
cert = _load_cert(
@@ -56,6 +58,7 @@ class TestRSACertificate(object):
assert cert.serial == 2
fingerprint = binascii.hexlify(cert.fingerprint(hashes.SHA1()))
assert fingerprint == b"6f49779533d565e8b7c1062503eab41492c38e4d"
+ assert isinstance(cert.signature_hash_algorithm, hashes.SHA256)
def test_issuer(self, backend):
cert = _load_cert(
@@ -328,6 +331,15 @@ class TestRSACertificate(object):
with pytest.raises(ValueError):
x509.load_der_x509_certificate(b"notacert", backend)
+ def test_unsupported_signature_hash_algorithm_cert(self, backend):
+ cert = _load_cert(
+ os.path.join("x509", "verisign_md2_root.pem"),
+ x509.load_pem_x509_certificate,
+ backend
+ )
+ with pytest.raises(UnsupportedAlgorithm):
+ cert.signature_hash_algorithm
+
@pytest.mark.requires_backend_interface(interface=DSABackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)
@@ -338,6 +350,7 @@ class TestDSACertificate(object):
x509.load_pem_x509_certificate,
backend
)
+ assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
public_key = cert.public_key()
assert isinstance(public_key, interfaces.DSAPublicKey)
if isinstance(public_key, interfaces.DSAPublicKeyWithNumbers):
@@ -390,6 +403,7 @@ class TestECDSACertificate(object):
x509.load_pem_x509_certificate,
backend
)
+ assert isinstance(cert.signature_hash_algorithm, hashes.SHA384)
public_key = cert.public_key()
assert isinstance(public_key, interfaces.EllipticCurvePublicKey)
if isinstance(
diff --git a/vectors/cryptography_vectors/x509/verisign_md2_root.pem b/vectors/cryptography_vectors/x509/verisign_md2_root.pem
new file mode 100644
index 00000000..87676acf
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/verisign_md2_root.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
+A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
+cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
+MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
+BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
+ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
+BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
+I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
+CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
+lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
+AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
+-----END CERTIFICATE-----