Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fb04691

Browse files
committed
Issue #10022: The dictionary returned by the getpeercert() method
of SSL sockets now has additional items such as `issuer` and `notBefore`.
1 parent 859c4ef commit fb04691

4 files changed

Lines changed: 63 additions & 59 deletions

File tree

Doc/library/ssl.rst

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -433,11 +433,9 @@ They also have the following additional methods and attributes:
433433
certificate was not validated, the dict is empty. If the certificate was
434434
validated, it returns a dict with the keys ``subject`` (the principal for
435435
which the certificate was issued), and ``notAfter`` (the time after which the
436-
certificate should not be trusted). The certificate was already validated,
437-
so the ``notBefore`` and ``issuer`` fields are not returned. If a
438-
certificate contains an instance of the *Subject Alternative Name* extension
439-
(see :rfc:`3280`), there will also be a ``subjectAltName`` key in the
440-
dictionary.
436+
certificate should not be trusted). If a certificate contains an instance
437+
of the *Subject Alternative Name* extension (see :rfc:`3280`), there will
438+
also be a ``subjectAltName`` key in the dictionary.
441439

442440
The "subject" field is a tuple containing the sequence of relative
443441
distinguished names (RDNs) given in the certificate's data structure for the
@@ -459,6 +457,10 @@ They also have the following additional methods and attributes:
459457
been validated, but if :const:`CERT_NONE` was used to establish the
460458
connection, the certificate, if present, will not have been validated.
461459

460+
.. versionchanged:: 3.2
461+
The returned dictionary includes additional items such as ``issuer``
462+
and ``notBefore``.
463+
462464
.. method:: SSLSocket.cipher()
463465

464466
Returns a three-value tuple containing the name of the cipher being used, the

Lib/test/test_ssl.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def test_parse_cert(self):
109109
# note that this uses an 'unofficial' function in _ssl.c,
110110
# provided solely for this test, to exercise the certificate
111111
# parsing code
112-
p = ssl._ssl._test_decode_cert(CERTFILE, False)
112+
p = ssl._ssl._test_decode_cert(CERTFILE)
113113
if support.verbose:
114114
sys.stdout.write("\n" + pprint.pformat(p) + "\n")
115115

@@ -1059,6 +1059,11 @@ def test_getpeercert(self):
10591059
self.fail(
10601060
"Missing or invalid 'organizationName' field in certificate subject; "
10611061
"should be 'Python Software Foundation'.")
1062+
self.assertIn('notBefore', cert)
1063+
self.assertIn('notAfter', cert)
1064+
before = ssl.cert_time_to_seconds(cert['notBefore'])
1065+
after = ssl.cert_time_to_seconds(cert['notAfter'])
1066+
self.assertLess(before, after)
10621067
s.close()
10631068
finally:
10641069
server.stop()

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ Core and Builtins
6060
Library
6161
-------
6262

63+
- Issue #10022: The dictionary returned by the ``getpeercert()`` method
64+
of SSL sockets now has additional items such as ``issuer`` and ``notBefore``.
65+
6366
- ``usenetrc`` is now false by default for NNTP objects.
6467

6568
- Issue #1926: Add support for NNTP over SSL on port 563, as well as

Modules/_ssl.c

Lines changed: 47 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ _get_peer_alt_names (X509 *certificate) {
700700
}
701701

702702
static PyObject *
703-
_decode_certificate (X509 *certificate, int verbose) {
703+
_decode_certificate(X509 *certificate) {
704704

705705
PyObject *retval = NULL;
706706
BIO *biobuf = NULL;
@@ -729,65 +729,60 @@ _decode_certificate (X509 *certificate, int verbose) {
729729
}
730730
Py_DECREF(peer);
731731

732-
if (verbose) {
733-
issuer = _create_tuple_for_X509_NAME(
734-
X509_get_issuer_name(certificate));
735-
if (issuer == NULL)
736-
goto fail0;
737-
if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) {
738-
Py_DECREF(issuer);
739-
goto fail0;
740-
}
732+
issuer = _create_tuple_for_X509_NAME(
733+
X509_get_issuer_name(certificate));
734+
if (issuer == NULL)
735+
goto fail0;
736+
if (PyDict_SetItemString(retval, (const char *)"issuer", issuer) < 0) {
741737
Py_DECREF(issuer);
738+
goto fail0;
739+
}
740+
Py_DECREF(issuer);
742741

743-
version = PyLong_FromLong(X509_get_version(certificate) + 1);
744-
if (PyDict_SetItemString(retval, "version", version) < 0) {
745-
Py_DECREF(version);
746-
goto fail0;
747-
}
742+
version = PyLong_FromLong(X509_get_version(certificate) + 1);
743+
if (PyDict_SetItemString(retval, "version", version) < 0) {
748744
Py_DECREF(version);
745+
goto fail0;
749746
}
747+
Py_DECREF(version);
750748

751749
/* get a memory buffer */
752750
biobuf = BIO_new(BIO_s_mem());
753751

754-
if (verbose) {
755-
756-
(void) BIO_reset(biobuf);
757-
serialNumber = X509_get_serialNumber(certificate);
758-
/* should not exceed 20 octets, 160 bits, so buf is big enough */
759-
i2a_ASN1_INTEGER(biobuf, serialNumber);
760-
len = BIO_gets(biobuf, buf, sizeof(buf)-1);
761-
if (len < 0) {
762-
_setSSLError(NULL, 0, __FILE__, __LINE__);
763-
goto fail1;
764-
}
765-
sn_obj = PyUnicode_FromStringAndSize(buf, len);
766-
if (sn_obj == NULL)
767-
goto fail1;
768-
if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) {
769-
Py_DECREF(sn_obj);
770-
goto fail1;
771-
}
752+
(void) BIO_reset(biobuf);
753+
serialNumber = X509_get_serialNumber(certificate);
754+
/* should not exceed 20 octets, 160 bits, so buf is big enough */
755+
i2a_ASN1_INTEGER(biobuf, serialNumber);
756+
len = BIO_gets(biobuf, buf, sizeof(buf)-1);
757+
if (len < 0) {
758+
_setSSLError(NULL, 0, __FILE__, __LINE__);
759+
goto fail1;
760+
}
761+
sn_obj = PyUnicode_FromStringAndSize(buf, len);
762+
if (sn_obj == NULL)
763+
goto fail1;
764+
if (PyDict_SetItemString(retval, "serialNumber", sn_obj) < 0) {
772765
Py_DECREF(sn_obj);
766+
goto fail1;
767+
}
768+
Py_DECREF(sn_obj);
773769

774-
(void) BIO_reset(biobuf);
775-
notBefore = X509_get_notBefore(certificate);
776-
ASN1_TIME_print(biobuf, notBefore);
777-
len = BIO_gets(biobuf, buf, sizeof(buf)-1);
778-
if (len < 0) {
779-
_setSSLError(NULL, 0, __FILE__, __LINE__);
780-
goto fail1;
781-
}
782-
pnotBefore = PyUnicode_FromStringAndSize(buf, len);
783-
if (pnotBefore == NULL)
784-
goto fail1;
785-
if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) {
786-
Py_DECREF(pnotBefore);
787-
goto fail1;
788-
}
770+
(void) BIO_reset(biobuf);
771+
notBefore = X509_get_notBefore(certificate);
772+
ASN1_TIME_print(biobuf, notBefore);
773+
len = BIO_gets(biobuf, buf, sizeof(buf)-1);
774+
if (len < 0) {
775+
_setSSLError(NULL, 0, __FILE__, __LINE__);
776+
goto fail1;
777+
}
778+
pnotBefore = PyUnicode_FromStringAndSize(buf, len);
779+
if (pnotBefore == NULL)
780+
goto fail1;
781+
if (PyDict_SetItemString(retval, "notBefore", pnotBefore) < 0) {
789782
Py_DECREF(pnotBefore);
783+
goto fail1;
790784
}
785+
Py_DECREF(pnotBefore);
791786

792787
(void) BIO_reset(biobuf);
793788
notAfter = X509_get_notAfter(certificate);
@@ -839,10 +834,9 @@ PySSL_test_decode_certificate (PyObject *mod, PyObject *args) {
839834
PyObject *filename;
840835
X509 *x=NULL;
841836
BIO *cert;
842-
int verbose = 1;
843837

844-
if (!PyArg_ParseTuple(args, "O&|i:test_decode_certificate",
845-
PyUnicode_FSConverter, &filename, &verbose))
838+
if (!PyArg_ParseTuple(args, "O&:test_decode_certificate",
839+
PyUnicode_FSConverter, &filename))
846840
return NULL;
847841

848842
if ((cert=BIO_new(BIO_s_file())) == NULL) {
@@ -864,7 +858,7 @@ PySSL_test_decode_certificate (PyObject *mod, PyObject *args) {
864858
goto fail0;
865859
}
866860

867-
retval = _decode_certificate(x, verbose);
861+
retval = _decode_certificate(x);
868862
X509_free(x);
869863

870864
fail0:
@@ -910,7 +904,7 @@ PySSL_peercert(PySSLSocket *self, PyObject *args)
910904
if ((verification & SSL_VERIFY_PEER) == 0)
911905
return PyDict_New();
912906
else
913-
return _decode_certificate (self->peer_cert, 0);
907+
return _decode_certificate(self->peer_cert);
914908
}
915909
}
916910

0 commit comments

Comments
 (0)