[Freeipa-devel] [freeipa PR#217][synchronized] change certificate processing code to use python-cryptography

2016-11-09 Thread frasertweedale
   URL: https://github.com/freeipa/freeipa/pull/217
Author: frasertweedale
 Title: #217: change certificate processing code to use python-cryptography
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/217/head:pr217
git checkout pr217
From fe126fcb59f9fbca4b448f5acf0126f8e74d8a38 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale 
Date: Mon, 10 Oct 2016 16:08:52 +1000
Subject: [PATCH 1/7] dn: support conversion from python-cryptography Name

The upcoming change to using python-cryptography for certificate
process will require a way to convert
``cryptography.x509.name.Name`` values to ``ipapython.dn.DN``.
Update the ``DN`` constructor to accept a ``Name``.

Part of: https://fedorahosted.org/freeipa/ticket/6398
---
 ipapython/dn.py| 44 --
 ipatests/test_ipapython/test_dn.py | 23 ++--
 2 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/ipapython/dn.py b/ipapython/dn.py
index 3ee35c6..2f7655d 100644
--- a/ipapython/dn.py
+++ b/ipapython/dn.py
@@ -422,6 +422,7 @@
 import sys
 import functools
 
+import cryptography.x509
 from ldap.dn import str2dn, dn2str
 from ldap import DECODING_ERROR
 import six
@@ -976,6 +977,8 @@ class DN(object):
   to yield one or more RDN's which will be appended in order to
   the DN. The parsing recognizes the DN syntax escaping rules.
 
+* A single ``cryptography.x509.name.Name`` object.
+
 * A RDN object, the RDN will copied respecting the constructors
   keyword configuration parameters and appended in order.
 
@@ -1125,9 +1128,17 @@ def _rdns_from_value(self, value):
 rdns = [[ava]]
 elif isinstance(value, RDN):
 rdns = [value.to_openldap()]
+elif isinstance(value, cryptography.x509.name.Name):
+rdns = list(reversed([
+[get_ava(
+_ATTR_NAME_BY_OID.get(ava.oid, ava.oid.dotted_string),
+ava.value)]
+for ava in value
+]))
 else:
-raise TypeError("must be str, unicode, tuple, or RDN or DN, got %s instead" %
-type(value))
+raise TypeError(
+"must be str, unicode, tuple, Name, RDN or DN, got %s instead"
+% type(value))
 return rdns
 
 def _rdns_from_sequence(self, seq):
@@ -1407,3 +1418,32 @@ def rindex(self, pattern, start=None, end=None):
 if i == -1:
 raise ValueError("pattern not found")
 return i
+
+
+_ATTR_NAME_BY_OID = {
+cryptography.x509.oid.NameOID.COMMON_NAME: 'CN',
+cryptography.x509.oid.NameOID.COUNTRY_NAME: 'C',
+cryptography.x509.oid.NameOID.LOCALITY_NAME: 'L',
+cryptography.x509.oid.NameOID.STATE_OR_PROVINCE_NAME: 'ST',
+cryptography.x509.oid.NameOID.ORGANIZATION_NAME: 'O',
+cryptography.x509.oid.NameOID.ORGANIZATIONAL_UNIT_NAME: 'OU',
+cryptography.x509.oid.NameOID.SERIAL_NUMBER: 'serialNumber',
+cryptography.x509.oid.NameOID.SURNAME: 'SN',
+cryptography.x509.oid.NameOID.GIVEN_NAME: 'givenName',
+cryptography.x509.oid.NameOID.TITLE: 'title',
+cryptography.x509.oid.NameOID.GENERATION_QUALIFIER: 'generationQualifier',
+cryptography.x509.oid.NameOID.DN_QUALIFIER: 'dnQualifier',
+cryptography.x509.oid.NameOID.PSEUDONYM: 'pseudonym',
+cryptography.x509.oid.NameOID.DOMAIN_COMPONENT: 'DC',
+cryptography.x509.oid.NameOID.EMAIL_ADDRESS: 'E',
+cryptography.x509.oid.NameOID.JURISDICTION_COUNTRY_NAME:
+'incorporationCountry',
+cryptography.x509.oid.NameOID.JURISDICTION_LOCALITY_NAME:
+'incorporationLocality',
+cryptography.x509.oid.NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME:
+'incorporationState',
+cryptography.x509.oid.NameOID.BUSINESS_CATEGORY: 'businessCategory',
+cryptography.x509.ObjectIdentifier('2.5.4.9'): 'STREET',
+cryptography.x509.ObjectIdentifier('2.5.4.17'): 'postalCode',
+cryptography.x509.ObjectIdentifier('0.9.2342.19200300.100.1.1'): 'UID',
+}
diff --git a/ipatests/test_ipapython/test_dn.py b/ipatests/test_ipapython/test_dn.py
index a96bd33..3ca3b57 100644
--- a/ipatests/test_ipapython/test_dn.py
+++ b/ipatests/test_ipapython/test_dn.py
@@ -2,6 +2,7 @@
 import unittest
 import pytest
 
+from cryptography import x509
 import six
 
 from ipapython.dn import DN, RDN, AVA
@@ -621,7 +622,7 @@ class TestDN(unittest.TestCase):
 def setUp(self):
 # ava1 must sort before ava2
 self.attr1= 'cn'
-self.value1   = 'Bob'
+self.value1   = u'Bob'
 self.str_ava1 = '%s=%s' % (self.attr1, self.value1)
 self.ava1 = AVA(self.attr1, self.value1)
 
@@ -629,7 +630,7 @@ def setUp(self):
 self.rdn1 = RDN((self.attr1, self.value1))
 
 self.attr2= 'ou'
-self.value2   = 'people'
+self.value2   = u'people'
 

[Freeipa-devel] [freeipa PR#217][synchronized] change certificate processing code to use python-cryptography

2016-11-09 Thread frasertweedale
   URL: https://github.com/freeipa/freeipa/pull/217
Author: frasertweedale
 Title: #217: change certificate processing code to use python-cryptography
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/217/head:pr217
git checkout pr217
From a32a6b2129e12305134bced7e2880bf08220ca81 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale 
Date: Mon, 10 Oct 2016 16:08:52 +1000
Subject: [PATCH 1/7] dn: support conversion from python-cryptography Name

The upcoming change to using python-cryptography for certificate
process will require a way to convert
``cryptography.x509.name.Name`` values to ``ipapython.dn.DN``.
Update the ``DN`` constructor to accept a ``Name``.

Part of: https://fedorahosted.org/freeipa/ticket/6398
---
 ipapython/dn.py| 44 --
 ipatests/test_ipapython/test_dn.py | 23 ++--
 2 files changed, 63 insertions(+), 4 deletions(-)

diff --git a/ipapython/dn.py b/ipapython/dn.py
index 3ee35c6..2f7655d 100644
--- a/ipapython/dn.py
+++ b/ipapython/dn.py
@@ -422,6 +422,7 @@
 import sys
 import functools
 
+import cryptography.x509
 from ldap.dn import str2dn, dn2str
 from ldap import DECODING_ERROR
 import six
@@ -976,6 +977,8 @@ class DN(object):
   to yield one or more RDN's which will be appended in order to
   the DN. The parsing recognizes the DN syntax escaping rules.
 
+* A single ``cryptography.x509.name.Name`` object.
+
 * A RDN object, the RDN will copied respecting the constructors
   keyword configuration parameters and appended in order.
 
@@ -1125,9 +1128,17 @@ def _rdns_from_value(self, value):
 rdns = [[ava]]
 elif isinstance(value, RDN):
 rdns = [value.to_openldap()]
+elif isinstance(value, cryptography.x509.name.Name):
+rdns = list(reversed([
+[get_ava(
+_ATTR_NAME_BY_OID.get(ava.oid, ava.oid.dotted_string),
+ava.value)]
+for ava in value
+]))
 else:
-raise TypeError("must be str, unicode, tuple, or RDN or DN, got %s instead" %
-type(value))
+raise TypeError(
+"must be str, unicode, tuple, Name, RDN or DN, got %s instead"
+% type(value))
 return rdns
 
 def _rdns_from_sequence(self, seq):
@@ -1407,3 +1418,32 @@ def rindex(self, pattern, start=None, end=None):
 if i == -1:
 raise ValueError("pattern not found")
 return i
+
+
+_ATTR_NAME_BY_OID = {
+cryptography.x509.oid.NameOID.COMMON_NAME: 'CN',
+cryptography.x509.oid.NameOID.COUNTRY_NAME: 'C',
+cryptography.x509.oid.NameOID.LOCALITY_NAME: 'L',
+cryptography.x509.oid.NameOID.STATE_OR_PROVINCE_NAME: 'ST',
+cryptography.x509.oid.NameOID.ORGANIZATION_NAME: 'O',
+cryptography.x509.oid.NameOID.ORGANIZATIONAL_UNIT_NAME: 'OU',
+cryptography.x509.oid.NameOID.SERIAL_NUMBER: 'serialNumber',
+cryptography.x509.oid.NameOID.SURNAME: 'SN',
+cryptography.x509.oid.NameOID.GIVEN_NAME: 'givenName',
+cryptography.x509.oid.NameOID.TITLE: 'title',
+cryptography.x509.oid.NameOID.GENERATION_QUALIFIER: 'generationQualifier',
+cryptography.x509.oid.NameOID.DN_QUALIFIER: 'dnQualifier',
+cryptography.x509.oid.NameOID.PSEUDONYM: 'pseudonym',
+cryptography.x509.oid.NameOID.DOMAIN_COMPONENT: 'DC',
+cryptography.x509.oid.NameOID.EMAIL_ADDRESS: 'E',
+cryptography.x509.oid.NameOID.JURISDICTION_COUNTRY_NAME:
+'incorporationCountry',
+cryptography.x509.oid.NameOID.JURISDICTION_LOCALITY_NAME:
+'incorporationLocality',
+cryptography.x509.oid.NameOID.JURISDICTION_STATE_OR_PROVINCE_NAME:
+'incorporationState',
+cryptography.x509.oid.NameOID.BUSINESS_CATEGORY: 'businessCategory',
+cryptography.x509.ObjectIdentifier('2.5.4.9'): 'STREET',
+cryptography.x509.ObjectIdentifier('2.5.4.17'): 'postalCode',
+cryptography.x509.ObjectIdentifier('0.9.2342.19200300.100.1.1'): 'UID',
+}
diff --git a/ipatests/test_ipapython/test_dn.py b/ipatests/test_ipapython/test_dn.py
index a96bd33..3ca3b57 100644
--- a/ipatests/test_ipapython/test_dn.py
+++ b/ipatests/test_ipapython/test_dn.py
@@ -2,6 +2,7 @@
 import unittest
 import pytest
 
+from cryptography import x509
 import six
 
 from ipapython.dn import DN, RDN, AVA
@@ -621,7 +622,7 @@ class TestDN(unittest.TestCase):
 def setUp(self):
 # ava1 must sort before ava2
 self.attr1= 'cn'
-self.value1   = 'Bob'
+self.value1   = u'Bob'
 self.str_ava1 = '%s=%s' % (self.attr1, self.value1)
 self.ava1 = AVA(self.attr1, self.value1)
 
@@ -629,7 +630,7 @@ def setUp(self):
 self.rdn1 = RDN((self.attr1, self.value1))
 
 self.attr2= 'ou'
-self.value2   = 'people'
+self.value2   = u'people'