Skip to content

Commit

Permalink
Fix bugs with encoding LDAP URIs
Browse files Browse the repository at this point in the history
  • Loading branch information
wbond committed Feb 27, 2017
1 parent c76c0c9 commit 8c9011f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
34 changes: 26 additions & 8 deletions asn1crypto/_iri.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,29 @@ def iri_to_uri(value):
type_name(value)
))

parsed = urlsplit(value)

scheme = _urlquote(parsed.scheme)
scheme = None
# Python 2.6 doesn't split properly is the URL doesn't start with http:// or https://
if sys.version_info < (2, 7) and not value.startswith('http://') and not value.startswith('https://'):
real_prefix = None
prefix_match = re.match('^[^:]*://', value)
if prefix_match:
real_prefix = prefix_match.group(0)
value = 'http://' + value[len(real_prefix):]
parsed = urlsplit(value)
if real_prefix:
value = real_prefix + value[7:]
scheme = _urlquote(real_prefix[:-3])
else:
parsed = urlsplit(value)

if scheme is None:
scheme = _urlquote(parsed.scheme)
hostname = parsed.hostname
if hostname is not None:
hostname = hostname.encode('idna')
username = _urlquote(parsed.username)
password = _urlquote(parsed.password)
# RFC 3986 allows userinfo to contain sub-delims
username = _urlquote(parsed.username, safe='!$&\'()*+,;=')
password = _urlquote(parsed.password, safe='!$&\'()*+,;=')
port = parsed.port
if port is not None:
port = str_cls(port).encode('ascii')
Expand All @@ -79,9 +94,12 @@ def iri_to_uri(value):
if not default_http and not default_https:
netloc += b':' + port

path = _urlquote(parsed.path, safe='/')
query = _urlquote(parsed.query, safe='&=')
fragment = _urlquote(parsed.fragment)
# RFC 3986 allows a path to contain sub-delims, plus "@" and ":"
path = _urlquote(parsed.path, safe='/!$&\'()*+,;=@:')
# RFC 3986 allows the query to contain sub-delims, plus "@", ":" , "/" and "?"
query = _urlquote(parsed.query, safe='/?!$&\'()*+,;=@:')
# RFC 3986 allows the fragment to contain sub-delims, plus "@", ":" , "/" and "?"
fragment = _urlquote(parsed.fragment, safe='/?!$&\'()*+,;=@:')

if query is None and fragment is None and path == b'/':
path = None
Expand Down
14 changes: 14 additions & 0 deletions tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,17 @@ def test_extended_datetime_date_time(self):
self.assertEqual(util.extended_date(0, 1, 1), util.extended_datetime(0, 1, 1).date())
self.assertEqual(util.extended_date(0, 2, 29), util.extended_datetime(0, 2, 29).date())
self.assertEqual(time(0, 0, 0), util.extended_datetime(0, 1, 1).time())

def test_iri_to_uri(self):
self.assertEqual(
b'ldap://ldap.e-szigno.hu/CN=Microsec%20e-Szigno%20Root%20CA,OU=e-Szigno%20CA,O=Microsec%20Ltd.,L=Budapest,C=HU?certificateRevocationList;binary',
util.iri_to_uri('ldap://ldap.e-szigno.hu/CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU?certificateRevocationList;binary')
)
self.assertEqual(
b'ldap://directory.d-trust.net/CN=D-TRUST%20Root%20Class%203%20CA%202%202009,O=D-Trust%20GmbH,C=DE?certificaterevocationlist',
util.iri_to_uri('ldap://directory.d-trust.net/CN=D-TRUST Root Class 3 CA 2 2009,O=D-Trust GmbH,C=DE?certificaterevocationlist')
)
self.assertEqual(
b'ldap://directory.d-trust.net/CN=D-TRUST%20Root%20Class%203%20CA%202%20EV%202009,O=D-Trust%20GmbH,C=DE?certificaterevocationlist',
util.iri_to_uri('ldap://directory.d-trust.net/CN=D-TRUST Root Class 3 CA 2 EV 2009,O=D-Trust GmbH,C=DE?certificaterevocationlist')
)

0 comments on commit 8c9011f

Please sign in to comment.