cert.c 6.1 KB

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