pyca / service-identity Goto Github PK
View Code? Open in Web Editor NEWService Identity Verification for Python
Home Page: https://service-identity.readthedocs.io/
License: MIT License
Service Identity Verification for Python
Home Page: https://service-identity.readthedocs.io/
License: MIT License
service_identity 18.1.0 includes 469c59f which makes use of attr.ib()
's converter
parameter:
attr.ib(converter=ipaddress.ip_address)
The converter
parameter was added in attrs 17.4.0, but service_identity's setup.py
claims it's enough to use 16.0.0.
RFC2818 has said that using commonName for service identity is a legacy thing, and the CAB forum baseline requirements has required a subjectAltName since 2012. We should emit a warning when commonName is relied upon for validation.
urllib3 already emits a warning if the certificate does not have SANs
I tried to use service-identity to do a configuration check for a server.
Basically checking if the configured names are available in the provided certificate.
cert = x509.load_pem_x509_certificate(stream.read(), default_backend())
for hostname in hostnames:
svcid.cryptography.verify_certificate_hostname(cert, hostname)
This does not work, if the certificate contains dual entries for an IP both in IPAddress and in a DNS field in the SAN, because it throws an "CertificateError: Invalid DNS pattern". This might be not allowed by the CAB rules (as mentioned in #12 ), but is not uncommon for inhouse CAs trying to support legacy systems.
So even if the correct hostname is included in the certificate, i cannot check it, due to the unrelated issue of IPs in the SAN throwing an Exception.
It would be nice, if the API would provide a way to collect all issues found instead of raising an exception on the first issue. This would make the API more useful for server side configuration checkers instead of client side checking only.
The link on the Github repo description needs updating for the RTD migration, as per their blog post of the 27th April ‘Securing subdomains’:
Starting today, Read the Docs will start hosting projects from subdomains on the domain readthedocs.io, instead of on readthedocs.org. This change addresses some security concerns around site cookies while hosting user generated data on the same domain as our dashboard.
https://service-identity.readthedocs.io/en/stable/ is where one now ends up
The 17.0.0 tarball uploaded to PyPI doesn't have the tests
directory, and it is therefore impossible to test the release. This is important for distro packaging. Could you please fix the MANIFEST.in
to include tests?
I'm using the following:
user@garage2:/$ pip3 --version
pip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)
user@garage2:/$ python3 --version
Python 3.6.5
This is the output:
user@garage2:~/$ pip3 install --user service_identity
Collecting service_identity
Using cached https://files.pythonhosted.org/packages/29/fa/995e364220979e577e7ca232440961db0bf996b6edaf586a7d1bd14d81f1/service_identity-17.0.0-py2.py3-none-any.whl
Collecting pyopenssl>=0.12 (from service_identity)
Using cached https://files.pythonhosted.org/packages/96/af/9d29e6bd40823061aea2e0574ccb2fcf72bfd6130ce53d32773ec375458c/pyOpenSSL-18.0.0-py2.py3-none-any.whl
Collecting attrs (from service_identity)
Using cached https://files.pythonhosted.org/packages/3a/e1/5f9023cc983f1a628a8c2fd051ad19e76ff7b142a0faf329336f9a62a514/attrs-18.2.0-py2.py3-none-any.whl
Collecting pyasn1 (from service_identity)
Using cached https://files.pythonhosted.org/packages/d1/a1/7790cc85db38daa874f6a2e6308131b9953feb1367f2ae2d1123bb93a9f5/pyasn1-0.4.4-py2.py3-none-any.whl
Collecting pyasn1-modules (from service_identity)
Using cached https://files.pythonhosted.org/packages/19/02/fa63f7ba30a0d7b925ca29d034510fc1ffde53264b71b4155022ddf3ab5d/pyasn1_modules-0.2.2-py2.py3-none-any.whl
Collecting cryptography>=2.2.1 (from pyopenssl>=0.12->service_identity)
Using cached https://files.pythonhosted.org/packages/59/32/92cade62c645756a83598edf56289e9b19aae5370642a7ce690cd06bc72f/cryptography-2.3.1-cp34-abi3-manylinux1_x86_64.whl
Collecting six>=1.5.2 (from pyopenssl>=0.12->service_identity)
Using cached https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
Collecting cffi!=1.11.3,>=1.7 (from cryptography>=2.2.1->pyopenssl>=0.12->service_identity)
Using cached https://files.pythonhosted.org/packages/6d/c0/47db8f624f3e4e2f3f27be03a93379d1ba16a1450a7b1aacfa0366e2c0dd/cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl
Collecting idna>=2.1 (from cryptography>=2.2.1->pyopenssl>=0.12->service_identity)
Using cached https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl
Collecting asn1crypto>=0.21.0 (from cryptography>=2.2.1->pyopenssl>=0.12->service_identity)
Using cached https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl
Collecting pycparser (from cffi!=1.11.3,>=1.7->cryptography>=2.2.1->pyopenssl>=0.12->service_identity)
Installing collected packages: six, pycparser, cffi, idna, asn1crypto, cryptography, pyopenssl, attrs, pyasn1, pyasn1-modules, service-identity
Successfully installed asn1crypto-0.24.0 attrs-18.2.0 cffi-1.11.5 cryptography-2.3.1 idna-2.7 pyasn1-0.4.4 pyasn1-modules-0.2.2 pycparser-2.19 pyopenssl-18.0.0 service-identity-17.0.0 six-1.11.0
Segmentation fault (core dumped)
Currently 0.2 is only available as a wheel, which results in older versions of pip installing 0.1 instead.
As seen here: https://gist.github.com/wallrj/8eb2c07b4eb8d384fa9b#file-gistfile3-txt
We add a URI SAN to our certificates that contain multiple colons, for example:
$ openssl x509 -in cert.crt -noout -text
...
X509v3 Subject Alternative Name:
URI:arn:aws:ec2:us-west-2:12345678:instance/i-0123456789
When verifying the hostname of the certificate (actually being called by Datadog's TLS check), we get a ValueError
exception since the code assumes only a single colon will be contained in the URI, and does not parse the URI correctly.
Partial Traceback:
File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/service_identity/cryptography.py", line 59, in verify_certificate_hostname
cert_patterns=extract_ids(certificate),
File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/service_identity/cryptography.py", line 123, in extract_ids
[
File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/service_identity/cryptography.py", line 124, in <listcomp>
URIPattern(uri.encode("utf-8"))
File "/opt/datadog-agent/embedded/lib/python3.8/site-packages/service_identity/_common.py", line 205, in __init__
self.protocol_pattern, hostname = pattern.split(b":")
ValueError: too many values to unpack (expected 2)
The warning gives you absolutely no clue what certificate is missing subjectAltName
.
Hi, the last release has been from 2018, which is quite old.
In the meanwhile the module canonical name has been renamed: 4ebe154
Can this get a release?
I am doing a simple test in which the target hosname is just 'xps' and it fails.
I know that in public you might never hit this error, but for private networks, you can do whatever you want and I would be nice if I don't have to add extra validation before calling service_identity.
Thanks!
The high level code
actual
(Pdb) [DNSPattern(pattern='*.example.com'), DNSPattern(pattern='*.sub.example.org')]
self._remote_id
(Pdb) DNS_ID(hostname='xps')
verify_service_identity(cert_patterns=actual,obligatory_ids=[self._remote_id],optional_ids=[])
(Pdb) *** ValueError: need more than 1 value to unpack
if I go deeper
cert_pattern
(Pdb) '*.example.com'
actual_hostname
(Pdb) 'xps'
if b'*' in cert_pattern:
cert_head, cert_tail = cert_pattern.split(b".", 1)
actual_head, actual_tail = actual_hostname.split(b".", 1)
Debian/Ubuntu users have found that service_identity 14.0.0 is crashing Deluge.
File "/usr/lib/python2.7/dist-packages/service_identity/pyopenssl.py", line 14, in <module>
from ._common import (
File "/usr/lib/python2.7/dist-packages/service_identity/_common.py", line 136, in <module>
@attributes(["pattern"], apply_with_init=False)
TypeError: attributes() got an unexpected keyword argument 'apply_with_init'
https://bugs.launchpad.net/ubuntu/+source/deluge/+bug/1492394
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=797921
It looks like it might be fixed in your repo as the code has changed dramatically for _common
.
It is a thing. See http://tools.ietf.org/html/rfc5280#section-4.2.1.6 I guess.
I have created this ticket to start a conversion.
Feel free to close it if you think this is not an issue.
This ticket is triggerd by the converstation from twisted/twisted#12074
It looks like if the server certificate has no subjectAltName, the verification will fail but the error is
<class 'service_identity.exceptions.VerificationError'>: VerificationError(errors=[DNSMismatch(mismatched_id=DNS_ID(hostname=b'default'))])
It's not very obvious that the issue is misisng subjectAltName
This is related to the change from here
In PR #52, if the certificate has no subjectAltName
it is handled as a valid certificate without any match.
Maybe, a CertificateError('Certificate without subjectAltName.')
exception should be raised.
Thanks
Ran into this while trying to serialize some errors.
import pickle
from service_identity.exceptions import VerificationError
error = VerificationError(errors=[])
pickle.loads(pickle.dumps(error))
Traceback (most recent call last):
File "foo.py", line 4, in <module>
pickle.loads(pickle.dumps(error))
TypeError: __init__() missing 1 required positional argument: 'errors'
Maybe it needs auto_exc=True? :)
Compare a verification error using service_identity:
<VerificationError(errors=[<DNSMismatch(mismatched_id=<DNS_ID(hostname='pancakes.com')>)>])>
to the corresponding request made by requests
:
SSLError(SSLError(CertificateError("hostname 'pancakes.com' doesn't match either of '*.potato.com', 'potato.com'",),),)
In the second case it's trivial to actually tell what the mismatch is from just the exception repr.
(names have been changed to protect the guilty.)
I'd like something I can pass a cryptography.x509.Certificate
and hostname to.
The X.509 RFC mandates that:
“A certificate using system MUST reject the certificate if it encounters a critical extension it does not recognize”
OpenSSL obviously doesn't do that for us.
Unfortunately OpenSSL totally processes some of the extensions, like basicConstraints
, so we can't quite blindly look at them.
It would be nice if service_identity
could take care of identifying critical extensions which it doesn't process yet and fail verification if they're present.
#18 introduced a dependency on the cryptography.x509
module. However, that dependency is not declared in setup.py
, and so even though the service_identity
module is installed (17.0.0), Twisted complains:
You do not have a working installation of the service_identity module: 'No module named cryptography.x509'. Please install it from <https://pypi.python.org/pypi/service_identity> and make sure all of its dependencies are satisfied. Without the service_identity module and a recent enough pyOpenSSL to support it, Twisted can perform only rudimentary TLS client hostname verification. Many valid certificate/hostname mappings may be rejected.
Would it be reasonable to add the cryptography.x509
dependency to setup.py
?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.