LCOV - code coverage report
Current view: | top level - Modules/_ssl - cert.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 0 | 101 | 0.0 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 0 | 10 | 0.0 %
|  |  | Branches: | 0 | 44 | 0.0 %

               Branch data     Line data    Source code
           1                 :            : #include "Python.h"
           2                 :            : #include "../_ssl.h"
           3                 :            :
           4                 :            : #include "openssl/err.h"
           5                 :            : #include "openssl/bio.h"
           6                 :            : #include "openssl/pem.h"
           7                 :            : #include "openssl/x509.h"
           8                 :            :
           9                 :            : /*[clinic input]
          10                 :            : module _ssl
          11                 :            : class _ssl.Certificate "PySSLCertificate *" "PySSLCertificate_Type"
          12                 :            : [clinic start generated code]*/
          13                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=780fc647948cfffc]*/
          14                 :            :
          15                 :            : #include "clinic/cert.c.h"
          16                 :            :
          17                 :            : static PyObject *
          18                 :          0 : newCertificate(PyTypeObject *type, X509 *cert, int upref)
          19                 :            : {
          20                 :            :     PySSLCertificate *self;
          21                 :            :
          22                 :            :     assert(type != NULL && type->tp_alloc != NULL);
          23                 :            :     assert(cert != NULL);
          24                 :            :
          25                 :          0 :     self = (PySSLCertificate *) type->tp_alloc(type, 0);
          26         [ #  # ]:          0 :     if (self == NULL) {
          27                 :          0 :         return NULL;
          28                 :            :     }
          29         [ #  # ]:          0 :     if (upref == 1) {
          30                 :          0 :         X509_up_ref(cert);
          31                 :            :     }
          32                 :          0 :     self->cert = cert;
          33                 :          0 :     self->hash = -1;
          34                 :            :
          35                 :          0 :     return (PyObject *) self;
          36                 :            : }
          37                 :            :
          38                 :            : static PyObject *
          39                 :          0 : _PySSL_CertificateFromX509(_sslmodulestate *state, X509 *cert, int upref)
          40                 :            : {
          41                 :          0 :     return newCertificate(state->PySSLCertificate_Type, cert, upref);
          42                 :            : }
          43                 :            :
          44                 :            : static PyObject*
          45                 :          0 : _PySSL_CertificateFromX509Stack(_sslmodulestate *state, STACK_OF(X509) *stack, int upref)
          46                 :            : {
          47                 :            :     int len, i;
          48                 :          0 :     PyObject *result = NULL;
          49                 :            :
          50                 :          0 :     len = sk_X509_num(stack);
          51                 :          0 :     result = PyList_New(len);
          52         [ #  # ]:          0 :     if (result == NULL) {
          53                 :          0 :         return NULL;
          54                 :            :     }
          55         [ #  # ]:          0 :     for (i = 0; i < len; i++) {
          56                 :          0 :         X509 *cert = sk_X509_value(stack, i);
          57                 :          0 :         PyObject *ocert = _PySSL_CertificateFromX509(state, cert, upref);
          58         [ #  # ]:          0 :         if (ocert == NULL) {
          59                 :          0 :             Py_DECREF(result);
          60                 :          0 :             return NULL;
          61                 :            :         }
          62                 :          0 :         PyList_SetItem(result, i, ocert);
          63                 :            :     }
          64                 :          0 :     return result;
          65                 :            : }
          66                 :            :
          67                 :            : /*[clinic input]
          68                 :            : _ssl.Certificate.public_bytes
          69                 :            :     format: int(c_default="PY_SSL_ENCODING_PEM") = Encoding.PEM
          70                 :            :
          71                 :            : [clinic start generated code]*/
          72                 :            :
          73                 :            : static PyObject *
          74                 :          0 : _ssl_Certificate_public_bytes_impl(PySSLCertificate *self, int format)
          75                 :            : /*[clinic end generated code: output=c01ddbb697429e12 input=4d38c45e874b0e64]*/
          76                 :            : {
          77                 :            :     BIO *bio;
          78                 :            :     int retcode;
          79                 :            :     PyObject *result;
          80                 :          0 :     _sslmodulestate *state = get_state_cert(self);
          81                 :            :
          82                 :          0 :     bio = BIO_new(BIO_s_mem());
          83         [ #  # ]:          0 :     if (bio == NULL) {
          84                 :          0 :         PyErr_SetString(state->PySSLErrorObject,
          85                 :            :                         "failed to allocate BIO");
          86                 :          0 :         return NULL;
          87                 :            :     }
          88   [ #  #  #  # ]:          0 :     switch(format) {
          89                 :          0 :     case PY_SSL_ENCODING_PEM:
          90                 :          0 :         retcode = PEM_write_bio_X509(bio, self->cert);
          91                 :          0 :         break;
          92                 :          0 :     case PY_SSL_ENCODING_PEM_AUX:
          93                 :          0 :         retcode = PEM_write_bio_X509_AUX(bio, self->cert);
          94                 :          0 :         break;
          95                 :          0 :     case PY_SSL_ENCODING_DER:
          96                 :          0 :         retcode = i2d_X509_bio(bio, self->cert);
          97                 :          0 :         break;
          98                 :          0 :     default:
          99                 :          0 :         PyErr_SetString(PyExc_ValueError, "Unsupported format");
         100                 :          0 :         BIO_free(bio);
         101                 :          0 :         return NULL;
         102                 :            :     }
         103         [ #  # ]:          0 :     if (retcode != 1) {
         104                 :          0 :         BIO_free(bio);
         105                 :          0 :         _setSSLError(state, NULL, 0, __FILE__, __LINE__);
         106                 :          0 :         return NULL;
         107                 :            :     }
         108         [ #  # ]:          0 :     if (format == PY_SSL_ENCODING_DER) {
         109                 :          0 :         result = _PySSL_BytesFromBIO(state, bio);
         110                 :            :     } else {
         111                 :          0 :         result = _PySSL_UnicodeFromBIO(state, bio, "error");
         112                 :            :     }
         113                 :          0 :     BIO_free(bio);
         114                 :          0 :     return result;
         115                 :            : }
         116                 :            :
         117                 :            :
         118                 :            : /*[clinic input]
         119                 :            : _ssl.Certificate.get_info
         120                 :            :
         121                 :            : [clinic start generated code]*/
         122                 :            :
         123                 :            : static PyObject *
         124                 :          0 : _ssl_Certificate_get_info_impl(PySSLCertificate *self)
         125                 :            : /*[clinic end generated code: output=0f0deaac54f4408b input=ba2c1694b39d0778]*/
         126                 :            : {
         127                 :          0 :     return _decode_certificate(get_state_cert(self), self->cert);
         128                 :            : }
         129                 :            :
         130                 :            : static PyObject*
         131                 :          0 : _x509name_print(_sslmodulestate *state, X509_NAME *name, int indent, unsigned long flags)
         132                 :            : {
         133                 :            :     PyObject *res;
         134                 :            :     BIO *biobuf;
         135                 :            :
         136                 :          0 :     biobuf = BIO_new(BIO_s_mem());
         137         [ #  # ]:          0 :     if (biobuf == NULL) {
         138                 :          0 :         PyErr_SetString(PyExc_MemoryError, "failed to allocate BIO");
         139                 :          0 :         return NULL;
         140                 :            :     }
         141                 :            :
         142         [ #  # ]:          0 :     if (X509_NAME_print_ex(biobuf, name, indent, flags) <= 0) {
         143                 :          0 :         _setSSLError(state, NULL, 0, __FILE__, __LINE__);
         144                 :          0 :         BIO_free(biobuf);
         145                 :          0 :         return NULL;
         146                 :            :     }
         147                 :          0 :     res = _PySSL_UnicodeFromBIO(state, biobuf, "strict");
         148                 :          0 :     BIO_free(biobuf);
         149                 :          0 :     return res;
         150                 :            : }
         151                 :            :
         152                 :            : /* ************************************************************************
         153                 :            :  * PySSLCertificate_Type
         154                 :            :  */
         155                 :            :
         156                 :            : static PyObject *
         157                 :          0 : certificate_repr(PySSLCertificate *self)
         158                 :            : {
         159                 :            :     PyObject *osubject, *result;
         160                 :            :
         161                 :            :     /* subject string is ASCII encoded, UTF-8 chars are quoted */
         162                 :          0 :     osubject = _x509name_print(
         163                 :          0 :         get_state_cert(self),
         164                 :          0 :         X509_get_subject_name(self->cert),
         165                 :            :         0,
         166                 :            :         XN_FLAG_RFC2253
         167                 :            :     );
         168         [ #  # ]:          0 :     if (osubject == NULL)
         169                 :          0 :         return NULL;
         170                 :          0 :     result = PyUnicode_FromFormat(
         171                 :            :         "<%s '%U'>",
         172                 :          0 :         Py_TYPE(self)->tp_name, osubject
         173                 :            :     );
         174                 :          0 :     Py_DECREF(osubject);
         175                 :          0 :     return result;
         176                 :            : }
         177                 :            :
         178                 :            : static Py_hash_t
         179                 :          0 : certificate_hash(PySSLCertificate *self)
         180                 :            : {
         181         [ #  # ]:          0 :     if (self->hash == (Py_hash_t)-1) {
         182                 :            :         unsigned long hash;
         183                 :          0 :         hash = X509_subject_name_hash(self->cert);
         184         [ #  # ]:          0 :         if ((Py_hash_t)hash == (Py_hash_t)-1) {
         185                 :          0 :             self->hash = -2;
         186                 :            :         } else {
         187                 :          0 :             self->hash = (Py_hash_t)hash;
         188                 :            :         }
         189                 :            :     }
         190                 :          0 :     return self->hash;
         191                 :            : }
         192                 :            :
         193                 :            : static PyObject *
         194                 :          0 : certificate_richcompare(PySSLCertificate *self, PyObject *other, int op)
         195                 :            : {
         196                 :            :     int cmp;
         197                 :          0 :     _sslmodulestate *state = get_state_cert(self);
         198                 :            :
         199         [ #  # ]:          0 :     if (Py_TYPE(other) != state->PySSLCertificate_Type) {
         200                 :          0 :         Py_RETURN_NOTIMPLEMENTED;
         201                 :            :     }
         202                 :            :     /* only support == and != */
         203   [ #  #  #  # ]:          0 :     if ((op != Py_EQ) && (op != Py_NE)) {
         204                 :          0 :         Py_RETURN_NOTIMPLEMENTED;
         205                 :            :     }
         206                 :          0 :     cmp = X509_cmp(self->cert, ((PySSLCertificate*)other)->cert);
         207   [ #  #  #  #  :          0 :     if (((op == Py_EQ) && (cmp == 0)) || ((op == Py_NE) && (cmp != 0))) {
                 #  #  #  # ]
         208                 :          0 :         Py_RETURN_TRUE;
         209                 :            :     } else {
         210                 :          0 :         Py_RETURN_FALSE;
         211                 :            :     }
         212                 :            : }
         213                 :            :
         214                 :            : static void
         215                 :          0 : certificate_dealloc(PySSLCertificate *self)
         216                 :            : {
         217                 :          0 :     PyTypeObject *tp = Py_TYPE(self);
         218                 :          0 :     X509_free(self->cert);
         219                 :          0 :     Py_TYPE(self)->tp_free(self);
         220                 :          0 :     Py_DECREF(tp);
         221                 :          0 : }
         222                 :            :
         223                 :            : static PyMethodDef certificate_methods[] = {
         224                 :            :     /* methods */
         225                 :            :     _SSL_CERTIFICATE_PUBLIC_BYTES_METHODDEF
         226                 :            :     _SSL_CERTIFICATE_GET_INFO_METHODDEF
         227                 :            :     {NULL, NULL}
         228                 :            : };
         229                 :            :
         230                 :            : static PyType_Slot PySSLCertificate_slots[] = {
         231                 :            :     {Py_tp_dealloc, certificate_dealloc},
         232                 :            :     {Py_tp_repr, certificate_repr},
         233                 :            :     {Py_tp_hash, certificate_hash},
         234                 :            :     {Py_tp_richcompare, certificate_richcompare},
         235                 :            :     {Py_tp_methods, certificate_methods},
         236                 :            :     {0, 0},
         237                 :            : };
         238                 :            :
         239                 :            : static PyType_Spec PySSLCertificate_spec = {
         240                 :            :     "_ssl.Certificate",
         241                 :            :     sizeof(PySSLCertificate),
         242                 :            :     0,
         243                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE,
         244                 :            :     PySSLCertificate_slots,
         245                 :            : };

Generated by: LCOV version 1.14