Commit ffe576dc authored by Bill Janssen's avatar Bill Janssen

SSL certificate distinguished names should be represented by tuples

parent 38336406
......@@ -173,6 +173,8 @@ use the first chain it finds in the file which matches.
Some "standard" root certificates are available at
http://www.thawte.com/roots/ (for Thawte roots) and
http://www.verisign.com/support/roots.html (for Verisign roots).
See also :rfc:`4158` for more discussion of the way in which
certification chains can be built.
sslsocket Objects
......@@ -242,23 +244,23 @@ sslsocket Objects
the certificate), ``notBefore`` (the time before which the certificate should not be trusted),
and ``notAfter`` (the time after which the certificate should not be trusted) filled in.
The "subject" and "issuer" fields are themselves dictionaries containing the fields given
in the certificate's data structure for each principal::
{'issuer': {'commonName': u'somemachine.python.org',
'countryName': u'US',
'localityName': u'Wilmington',
'organizationName': u'Python Software Foundation',
'organizationalUnitName': u'SSL',
'stateOrProvinceName': u'Delaware'},
'subject': {'commonName': u'somemachine.python.org',
'countryName': u'US',
'localityName': u'Wilmington',
'organizationName': u'Python Software Foundation',
'organizationalUnitName': u'SSL',
'stateOrProvinceName': u'Delaware'},
'notAfter': 'Sep 4 21:54:26 2007 GMT',
'notBefore': 'Aug 25 21:54:26 2007 GMT',
The "subject" and "issuer" fields are tuples containing the name-value fields
given in the certificate's data structure for each principal::
{'issuer': (('countryName', u'US'),
('stateOrProvinceName', u'Delaware'),
('localityName', u'Wilmington'),
('organizationName', u'Python Software Foundation'),
('organizationalUnitName', u'SSL'),
('commonName', u'somemachine.python.org')),
'notAfter': 'Feb 16 16:54:50 2013 GMT',
'notBefore': 'Aug 27 16:54:50 2007 GMT',
'subject': (('countryName', u'US'),
('stateOrProvinceName', u'Delaware'),
('localityName', u'Wilmington'),
('organizationName', u'Python Software Foundation'),
('organizationalUnitName', u'SSL'),
('commonName', u'somemachine.python.org')),
'version': 2}
This certificate is said to be *self-signed*, because the subject
......@@ -314,27 +316,32 @@ sends some bytes, and reads part of the response::
# note that closing the sslsocket will also close the underlying socket
ssl_sock.close()
As of August 25, 2007, the certificate printed by this program
As of September 4, 2007, the certificate printed by this program
looked like this::
{'issuer': {'commonName': u'VeriSign Class 3 Extended Validation SSL SGC CA',
'countryName': u'US',
'organizationName': u'VeriSign, Inc.',
'organizationalUnitName': u'Terms of use at https://www.verisign.com/rpa (c)06'},
'subject': {'1.3.6.1.4.1.311.60.2.1.2': u'Delaware',
'1.3.6.1.4.1.311.60.2.1.3': u'US',
'commonName': u'www.verisign.com',
'countryName': u'US',
'localityName': u'Mountain View',
'organizationName': u'VeriSign, Inc.',
'organizationalUnitName': u'Terms of use at www.verisign.com/rpa (c)06',
'postalCode': u'94043',
'serialNumber': u'2497886',
'stateOrProvinceName': u'California',
'streetAddress': u'487 East Middlefield Road'},
'notAfter': 'May 8 23:59:59 2009 GMT',
'notBefore': 'May 9 00:00:00 2007 GMT',
'version': 2}
{'issuer': (('countryName', u'US'),
('organizationName', u'VeriSign, Inc.'),
('organizationalUnitName', u'VeriSign Trust Network'),
('organizationalUnitName',
u'Terms of use at https://www.verisign.com/rpa (c)06'),
('commonName',
u'VeriSign Class 3 Extended Validation SSL SGC CA')),
'notAfter': 'May 8 23:59:59 2009 GMT',
'notBefore': 'May 9 00:00:00 2007 GMT',
'subject': (('serialNumber', u'2497886'),
('1.3.6.1.4.1.311.60.2.1.3', u'US'),
('1.3.6.1.4.1.311.60.2.1.2', u'Delaware'),
('countryName', u'US'),
('postalCode', u'94043'),
('stateOrProvinceName', u'California'),
('localityName', u'Mountain View'),
('streetAddress', u'487 East Middlefield Road'),
('organizationName', u'VeriSign, Inc.'),
('organizationalUnitName', u'Production Security Services'),
('organizationalUnitName',
u'Terms of use at www.verisign.com/rpa (c)06'),
('commonName', u'www.verisign.com')),
'version': 2}
Server-side operation
^^^^^^^^^^^^^^^^^^^^^
......@@ -386,3 +393,5 @@ Class :class:`socket.socket`
`Introducing SSL and Certificates using OpenSSL <http://old.pseudonym.org/ssl/wwwj-index.html>`_, by Frederick J. Hirsch
`Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management`, :rfc:`1422`, by Steve Kent
`Internet X.509 Public Key Infrastructure Certificate and CRL Profile`, :rfc:`3280`, Housley et. al.
......@@ -137,18 +137,15 @@ class ConnectedTests(unittest.TestCase):
cert = c2.getpeercert()
if not cert:
raise test_support.TestFailed("Can't get peer certificate.")
if test_support.verbose:
sys.stdout.write(pprint.pformat(cert) + '\n')
if not cert.has_key('subject'):
raise test_support.TestFailed(
"No subject field in certificate: %s." %
pprint.pformat(cert))
if not (cert['subject'].has_key('organizationName')):
raise test_support.TestFailed(
"No 'organizationName' field in certificate subject: %s." %
pprint.pformat(cert))
if (cert['subject']['organizationName'] !=
"Python Software Foundation"):
if not ('organizationName', 'Python Software Foundation') in cert['subject']:
raise test_support.TestFailed(
"Invalid 'organizationName' field in certificate subject; "
"Missing or invalid 'organizationName' field in certificate subject; "
"should be 'Python Software Foundation'.");
c2.close()
......@@ -336,7 +333,7 @@ def create_cert_files(hostname=None):
def test_main(verbose=False):
if skip_expected:
raise test_support.TestSkipped("socket module has no ssl support")
raise test_support.TestSkipped("No SSL support")
global CERTFILE
CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
......
......@@ -437,12 +437,15 @@ PySSL_issuer(PySSLObject *self)
}
static PyObject *
_create_dict_for_X509_NAME (X509_NAME *xname)
_create_tuple_for_X509_NAME (X509_NAME *xname)
{
PyObject *pd = PyDict_New();
PyObject *pt = NULL;
PyObject *entry_tuple = NULL;
int entry_count = X509_NAME_entry_count(xname);
int index_counter;
if (pd == NULL)
pt = PyTuple_New(entry_count);
if (pt == NULL)
return NULL;
for (index_counter = 0;
......@@ -480,18 +483,20 @@ _create_dict_for_X509_NAME (X509_NAME *xname)
Py_DECREF(name_obj);
goto fail0;
}
if (PyDict_SetItem(pd, name_obj, value_obj) < 0) {
entry_tuple = PyTuple_New(2);
if (entry_tuple == NULL) {
Py_DECREF(name_obj);
Py_DECREF(value_obj);
goto fail0;
}
Py_DECREF(name_obj);
Py_DECREF(value_obj);
PyTuple_SET_ITEM(entry_tuple, 0, name_obj);
PyTuple_SET_ITEM(entry_tuple, 1, value_obj);
PyTuple_SET_ITEM(pt, index_counter, entry_tuple);
}
return pd;
return pt;
fail0:
Py_XDECREF(pd);
Py_XDECREF(pt);
return NULL;
}
......@@ -520,7 +525,7 @@ PySSL_peercert(PySSLObject *self)
if ((verification & SSL_VERIFY_PEER) == 0)
return retval;
peer = _create_dict_for_X509_NAME(
peer = _create_tuple_for_X509_NAME(
X509_get_subject_name(self->peer_cert));
if (peer == NULL)
goto fail0;
......@@ -530,7 +535,7 @@ PySSL_peercert(PySSLObject *self)
}
Py_DECREF(peer);
issuer = _create_dict_for_X509_NAME(
issuer = _create_tuple_for_X509_NAME(
X509_get_issuer_name(self->peer_cert));
if (issuer == NULL)
goto fail0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment