4 * Copyright (C) AB Strakt
5 * Copyright (C) Keyphrene
6 * Copyright (C) Jean-Paul Calderone
7 * See LICENSE for details.
9 * Main file of crypto sub module.
10 * See the file RATIONALE for a short explanation of why this module was written.
19 static char crypto_doc[] = "\n\
20 Main file of crypto sub module.\n\
21 See the file RATIONALE for a short explanation of why this module was written.\n\
26 PyObject *crypto_Error;
28 int crypto_byte_converter(PyObject *input, void* output) {
29 char **message = output;
30 if (input == Py_None) {
32 } else if (PyBytes_CheckExact(input)) {
33 *message = PyBytes_AsString(input);
41 global_passphrase_callback(char *buf, int len, int rwflag, void *cb_arg)
43 PyObject *func, *argv, *ret;
46 func = (PyObject *)cb_arg;
47 argv = Py_BuildValue("(i)", rwflag);
48 ret = PyEval_CallObject(func, argv);
52 if (!PyBytes_Check(ret))
54 PyErr_SetString(PyExc_ValueError, "String expected");
57 nchars = PyBytes_Size(ret);
60 strncpy(buf, PyBytes_AsString(ret), nchars);
64 static char crypto_load_privatekey_doc[] = "\n\
65 Load a private key from a buffer\n\
67 @param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)\n\
68 @param buffer: The buffer the key is stored in\n\
69 @param passphrase: (optional) if encrypted PEM format, this can be\n\
70 either the passphrase to use, or a callback for\n\
71 providing the passphrase.\n\
73 @return: The PKey object\n\
77 crypto_load_privatekey(PyObject *spam, PyObject *args)
79 crypto_PKeyObj *crypto_PKey_New(EVP_PKEY *, int);
83 pem_password_cb *cb = NULL;
88 if (!PyArg_ParseTuple(args, "is#|O:load_privatekey", &type, &buffer, &len, &pw))
93 if (PyBytes_Check(pw))
96 cb_arg = PyBytes_AsString(pw);
98 else if (PyCallable_Check(pw))
100 cb = global_passphrase_callback;
105 PyErr_SetString(PyExc_TypeError, "Last argument must be string or callable");
110 bio = BIO_new_mem_buf(buffer, len);
113 case X509_FILETYPE_PEM:
114 pkey = PEM_read_bio_PrivateKey(bio, NULL, cb, cb_arg);
117 case X509_FILETYPE_ASN1:
118 pkey = d2i_PrivateKey_bio(bio, NULL);
122 PyErr_SetString(PyExc_ValueError, "type argument must be FILETYPE_PEM or FILETYPE_ASN1");
130 exception_from_error_queue(crypto_Error);
134 return (PyObject *)crypto_PKey_New(pkey, 1);
137 static char crypto_dump_privatekey_doc[] = "\n\
138 Dump a private key to a buffer\n\
140 @param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)\n\
141 @param pkey: The PKey to dump\n\
142 @param cipher: (optional) if encrypted PEM format, the cipher to\n\
144 @param passphrase - (optional) if encrypted PEM format, this can be either\n\
145 the passphrase to use, or a callback for providing the\n\
147 @return: The buffer with the dumped key in\n\
152 crypto_dump_privatekey(PyObject *spam, PyObject *args)
154 int type, ret, buf_len;
157 char *cipher_name = NULL;
158 const EVP_CIPHER *cipher = NULL;
160 pem_password_cb *cb = NULL;
164 crypto_PKeyObj *pkey;
166 if (!PyArg_ParseTuple(args, "iO!|sO:dump_privatekey", &type,
167 &crypto_PKey_Type, &pkey, &cipher_name, &pw))
170 if (cipher_name != NULL && pw == NULL)
172 PyErr_SetString(PyExc_ValueError, "Illegal number of arguments");
175 if (cipher_name != NULL)
177 cipher = EVP_get_cipherbyname(cipher_name);
180 PyErr_SetString(PyExc_ValueError, "Invalid cipher name");
183 if (PyBytes_Check(pw))
186 cb_arg = PyBytes_AsString(pw);
188 else if (PyCallable_Check(pw))
190 cb = global_passphrase_callback;
195 PyErr_SetString(PyExc_TypeError, "Last argument must be string or callable");
200 bio = BIO_new(BIO_s_mem());
203 case X509_FILETYPE_PEM:
204 ret = PEM_write_bio_PrivateKey(bio, pkey->pkey, cipher, NULL, 0, cb, cb_arg);
205 if (PyErr_Occurred())
212 case X509_FILETYPE_ASN1:
213 ret = i2d_PrivateKey_bio(bio, pkey->pkey);
216 case X509_FILETYPE_TEXT:
217 rsa = EVP_PKEY_get1_RSA(pkey->pkey);
218 ret = RSA_print(bio, rsa, 0);
223 PyErr_SetString(PyExc_ValueError, "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
231 exception_from_error_queue(crypto_Error);
235 buf_len = BIO_get_mem_data(bio, &temp);
236 buffer = PyBytes_FromStringAndSize(temp, buf_len);
242 static char crypto_load_certificate_doc[] = "\n\
243 Load a certificate from a buffer\n\
245 @param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)\n\
246 buffer - The buffer the certificate is stored in\n\
247 @return: The X509 object\n\
251 crypto_load_certificate(PyObject *spam, PyObject *args)
253 crypto_X509Obj *crypto_X509_New(X509 *, int);
259 if (!PyArg_ParseTuple(args, "is#:load_certificate", &type, &buffer, &len))
262 bio = BIO_new_mem_buf(buffer, len);
265 case X509_FILETYPE_PEM:
266 cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
269 case X509_FILETYPE_ASN1:
270 cert = d2i_X509_bio(bio, NULL);
274 PyErr_SetString(PyExc_ValueError, "type argument must be FILETYPE_PEM or FILETYPE_ASN1");
282 exception_from_error_queue(crypto_Error);
286 return (PyObject *)crypto_X509_New(cert, 1);
289 static char crypto_dump_certificate_doc[] = "\n\
290 Dump a certificate to a buffer\n\
292 @param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)\n\
293 @param cert: The certificate to dump\n\
294 @return: The buffer with the dumped certificate in\n\
298 crypto_dump_certificate(PyObject *spam, PyObject *args)
300 int type, ret, buf_len;
304 crypto_X509Obj *cert;
306 if (!PyArg_ParseTuple(args, "iO!:dump_certificate", &type,
307 &crypto_X509_Type, &cert))
310 bio = BIO_new(BIO_s_mem());
313 case X509_FILETYPE_PEM:
314 ret = PEM_write_bio_X509(bio, cert->x509);
317 case X509_FILETYPE_ASN1:
318 ret = i2d_X509_bio(bio, cert->x509);
321 case X509_FILETYPE_TEXT:
322 ret = X509_print_ex(bio, cert->x509, 0, 0);
326 PyErr_SetString(PyExc_ValueError, "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
334 exception_from_error_queue(crypto_Error);
338 buf_len = BIO_get_mem_data(bio, &temp);
339 buffer = PyBytes_FromStringAndSize(temp, buf_len);
345 static char crypto_load_certificate_request_doc[] = "\n\
346 Load a certificate request from a buffer\n\
348 @param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)\n\
349 buffer - The buffer the certificate request is stored in\n\
350 @return: The X509Req object\n\
354 crypto_load_certificate_request(PyObject *spam, PyObject *args)
356 crypto_X509ReqObj *crypto_X509Req_New(X509_REQ *, int);
362 if (!PyArg_ParseTuple(args, "is#:load_certificate_request", &type, &buffer, &len))
365 bio = BIO_new_mem_buf(buffer, len);
368 case X509_FILETYPE_PEM:
369 req = PEM_read_bio_X509_REQ(bio, NULL, NULL, NULL);
372 case X509_FILETYPE_ASN1:
373 req = d2i_X509_REQ_bio(bio, NULL);
377 PyErr_SetString(PyExc_ValueError, "type argument must be FILETYPE_PEM or FILETYPE_ASN1");
385 exception_from_error_queue(crypto_Error);
389 return (PyObject *)crypto_X509Req_New(req, 1);
392 static char crypto_dump_certificate_request_doc[] = "\n\
393 Dump a certificate request to a buffer\n\
395 @param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)\n\
396 req - The certificate request to dump\n\
397 @return: The buffer with the dumped certificate request in\n\
401 crypto_dump_certificate_request(PyObject *spam, PyObject *args)
403 int type, ret, buf_len;
407 crypto_X509ReqObj *req;
409 if (!PyArg_ParseTuple(args, "iO!:dump_certificate_request", &type,
410 &crypto_X509Req_Type, &req))
413 bio = BIO_new(BIO_s_mem());
416 case X509_FILETYPE_PEM:
417 ret = PEM_write_bio_X509_REQ(bio, req->x509_req);
420 case X509_FILETYPE_ASN1:
421 ret = i2d_X509_REQ_bio(bio, req->x509_req);
424 case X509_FILETYPE_TEXT:
425 ret = X509_REQ_print_ex(bio, req->x509_req, 0, 0);
429 PyErr_SetString(PyExc_ValueError, "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
437 exception_from_error_queue(crypto_Error);
441 buf_len = BIO_get_mem_data(bio, &temp);
442 buffer = PyBytes_FromStringAndSize(temp, buf_len);
448 static char crypto_load_crl_doc[] = "\n\
449 Load a certificate revocation list from a buffer\n\
451 @param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)\n\
452 @param buffer: The buffer the CRL is stored in\n\
454 @return: The PKey object\n\
458 crypto_load_crl(PyObject *spam, PyObject *args) {
464 if (!PyArg_ParseTuple(args, "is#:load_crl", &type, &buffer, &len)) {
468 bio = BIO_new_mem_buf(buffer, len);
470 case X509_FILETYPE_PEM:
471 crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
474 case X509_FILETYPE_ASN1:
475 crl = d2i_X509_CRL_bio(bio, NULL);
479 PyErr_SetString(PyExc_ValueError, "type argument must be FILETYPE_PEM or FILETYPE_ASN1");
486 exception_from_error_queue(crypto_Error);
490 return (PyObject *)crypto_CRL_New(crl);
493 static char crypto_load_pkcs7_data_doc[] = "\n\
494 Load pkcs7 data from a buffer\n\
496 @param type: The file type (one of FILETYPE_PEM or FILETYPE_ASN1)\n\
497 buffer - The buffer with the pkcs7 data.\n\
498 @return: The PKCS7 object\n\
502 crypto_load_pkcs7_data(PyObject *spam, PyObject *args)
509 if (!PyArg_ParseTuple(args, "is#:load_pkcs7_data", &type, &buffer, &len))
513 * Try to read the pkcs7 data from the bio
515 bio = BIO_new_mem_buf(buffer, len);
518 case X509_FILETYPE_PEM:
519 pkcs7 = PEM_read_bio_PKCS7(bio, NULL, NULL, NULL);
522 case X509_FILETYPE_ASN1:
523 pkcs7 = d2i_PKCS7_bio(bio, NULL);
527 PyErr_SetString(PyExc_ValueError,
528 "type argument must be FILETYPE_PEM or FILETYPE_ASN1");
534 * Check if we got a PKCS7 structure
538 exception_from_error_queue(crypto_Error);
542 return (PyObject *)crypto_PKCS7_New(pkcs7, 1);
545 static char crypto_load_pkcs12_doc[] = "\n\
546 Load a PKCS12 object from a buffer\n\
548 @param buffer: The buffer the certificate is stored in\n\
549 passphrase (Optional) - The password to decrypt the PKCS12 lump\n\
550 @returns: The PKCS12 object\n\
554 crypto_load_pkcs12(PyObject *spam, PyObject *args)
557 char *buffer, *passphrase = NULL;
561 if (!PyArg_ParseTuple(args, "s#|s:load_pkcs12", &buffer, &len, &passphrase))
564 bio = BIO_new_mem_buf(buffer, len);
565 if ((p12 = d2i_PKCS12_bio(bio, NULL)) == NULL)
568 exception_from_error_queue(crypto_Error);
573 return (PyObject *)crypto_PKCS12_New(p12, passphrase);
577 static char crypto_X509_verify_cert_error_string_doc[] = "\n\
578 Get X509 verify certificate error string.\n\
580 @param errnum: The error number.\n\
581 @return: Error string as a Python string\n\
585 crypto_X509_verify_cert_error_string(PyObject *spam, PyObject *args)
590 if (!PyArg_ParseTuple(args, "i", &errnum))
593 str = X509_verify_cert_error_string(errnum);
594 return PyText_FromString(str);
597 static char crypto_exception_from_error_queue_doc[] = "\n\
598 Raise an exception from the current OpenSSL error queue.\n\
602 crypto_exception_from_error_queue(PyObject *spam, PyObject *eggs) {
603 exception_from_error_queue(crypto_Error);
607 static char crypto_sign_doc[] = "\n\
608 Sign data with a digest\n\
610 @param pkey: Pkey to sign with\n\
611 @param data: data to be signed\n\
612 @param digest: message digest to use\n\
613 @return: signature\n\
617 crypto_sign(PyObject *spam, PyObject *args) {
619 crypto_PKeyObj *pkey;
623 unsigned int sig_len;
624 const EVP_MD *digest;
626 unsigned char sig_buf[512];
628 if (!PyArg_ParseTuple(
629 args, "O!" BYTESTRING_FMT "s:sign", &crypto_PKey_Type,
630 &pkey, &data, &digest_name)) {
634 if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
635 PyErr_SetString(PyExc_ValueError, "No such digest method");
639 EVP_SignInit(&md_ctx, digest);
640 EVP_SignUpdate(&md_ctx, data, strlen(data));
641 sig_len = sizeof(sig_buf);
642 err = EVP_SignFinal(&md_ctx, sig_buf, &sig_len, pkey->pkey);
645 exception_from_error_queue(crypto_Error);
649 buffer = PyBytes_FromStringAndSize((char*)sig_buf, sig_len);
653 static char crypto_verify_doc[] = "\n\
654 Verify a signature\n\
656 @param cert: signing certificate (X509 object)\n\
657 @param signature: signature returned by sign function\n\
658 @param data: data to be verified\n\
659 @param digest: message digest to use\n\
660 @return: None if the signature is correct, raise exception otherwise\n\
664 crypto_verify(PyObject *spam, PyObject *args) {
665 crypto_X509Obj *cert;
666 unsigned char *signature;
668 char *data, *digest_name;
670 const EVP_MD *digest;
675 if (!PyArg_ParseTuple(args, "O!" BYTESTRING_FMT "#" BYTESTRING_FMT "s:verify", &crypto_X509_Type, &cert, &signature, &sig_len, &data, &digest_name)) {
677 if (!PyArg_ParseTuple(args, "O!t#ss:verify", &crypto_X509_Type, &cert, &signature, &sig_len, &data, &digest_name)) {
682 if ((digest = EVP_get_digestbyname(digest_name)) == NULL){
683 PyErr_SetString(PyExc_ValueError, "No such digest method");
687 pkey = X509_get_pubkey(cert->x509);
689 PyErr_SetString(PyExc_ValueError, "No public key");
693 EVP_VerifyInit(&md_ctx, digest);
694 EVP_VerifyUpdate(&md_ctx, data, strlen((char*)data));
695 err = EVP_VerifyFinal(&md_ctx, signature, sig_len, pkey);
699 exception_from_error_queue(crypto_Error);
707 /* Methods in the OpenSSL.crypto module (i.e. none) */
708 static PyMethodDef crypto_methods[] = {
709 /* Module functions */
710 { "load_privatekey", (PyCFunction)crypto_load_privatekey, METH_VARARGS, crypto_load_privatekey_doc },
711 { "dump_privatekey", (PyCFunction)crypto_dump_privatekey, METH_VARARGS, crypto_dump_privatekey_doc },
712 { "load_certificate", (PyCFunction)crypto_load_certificate, METH_VARARGS, crypto_load_certificate_doc },
713 { "dump_certificate", (PyCFunction)crypto_dump_certificate, METH_VARARGS, crypto_dump_certificate_doc },
714 { "load_certificate_request", (PyCFunction)crypto_load_certificate_request, METH_VARARGS, crypto_load_certificate_request_doc },
715 { "dump_certificate_request", (PyCFunction)crypto_dump_certificate_request, METH_VARARGS, crypto_dump_certificate_request_doc },
716 { "load_crl", (PyCFunction)crypto_load_crl, METH_VARARGS, crypto_load_crl_doc },
717 { "load_pkcs7_data", (PyCFunction)crypto_load_pkcs7_data, METH_VARARGS, crypto_load_pkcs7_data_doc },
718 { "load_pkcs12", (PyCFunction)crypto_load_pkcs12, METH_VARARGS, crypto_load_pkcs12_doc },
719 { "sign", (PyCFunction)crypto_sign, METH_VARARGS, crypto_sign_doc },
720 { "verify", (PyCFunction)crypto_verify, METH_VARARGS, crypto_verify_doc },
721 { "X509_verify_cert_error_string", (PyCFunction)crypto_X509_verify_cert_error_string, METH_VARARGS, crypto_X509_verify_cert_error_string_doc },
722 { "_exception_from_error_queue", (PyCFunction)crypto_exception_from_error_queue, METH_NOARGS, crypto_exception_from_error_queue_doc },
729 #include <pythread.h>
732 * This array will store all of the mutexes available to OpenSSL.
734 static PyThread_type_lock *mutex_buf = NULL;
738 * Callback function supplied to OpenSSL to acquire or release a lock.
741 static void locking_function(int mode, int n, const char * file, int line) {
742 if (mode & CRYPTO_LOCK) {
743 PyThread_acquire_lock(mutex_buf[n], WAIT_LOCK);
745 PyThread_release_lock(mutex_buf[n]);
751 * Initialize OpenSSL for use from multiple threads.
753 * Returns: 0 if initialization fails, 1 otherwise.
755 static int init_openssl_threads(void) {
758 mutex_buf = (PyThread_type_lock *)malloc(
759 CRYPTO_num_locks() * sizeof(PyThread_type_lock));
763 for (i = 0; i < CRYPTO_num_locks(); ++i) {
764 mutex_buf[i] = PyThread_allocate_lock();
766 CRYPTO_set_id_callback((unsigned long (*)(void))PyThread_get_thread_ident);
767 CRYPTO_set_locking_callback(locking_function);
772 /* * Clean up after OpenSSL thread initialization. */
774 /* static int deinit_openssl_threads() { */
777 /* if (!mutex_buf) { */
780 /* CRYPTO_set_id_callback(NULL); */
781 /* CRYPTO_set_locking_callback(NULL); */
782 /* for (i = 0; i < CRYPTO_num_locks(); i++) { */
783 /* PyThread_free_lock(mutex_buf[i]); */
785 /* free(mutex_buf); */
786 /* mutex_buf = NULL; */
793 static struct PyModuleDef cryptomodule = {
794 PyModuleDef_HEAD_INIT,
803 * Initialize crypto sub module
808 PyOpenSSL_MODINIT(crypto) {
810 static void *crypto_API[crypto_API_pointers];
811 PyObject *c_api_object;
815 ERR_load_crypto_strings();
816 OpenSSL_add_all_algorithms();
819 module = PyModule_Create(&cryptomodule);
821 module = Py_InitModule3("crypto", crypto_methods, crypto_doc);
824 if (module == NULL) {
825 PyOpenSSL_MODRETURN(NULL);
829 /* Initialize the C API pointer array */
830 crypto_API[crypto_X509_New_NUM] = (void *)crypto_X509_New;
831 crypto_API[crypto_X509Name_New_NUM] = (void *)crypto_X509Name_New;
832 crypto_API[crypto_X509Req_New_NUM] = (void *)crypto_X509Req_New;
833 crypto_API[crypto_X509Store_New_NUM] = (void *)crypto_X509Store_New;
834 crypto_API[crypto_PKey_New_NUM] = (void *)crypto_PKey_New;
835 crypto_API[crypto_X509Extension_New_NUM] = (void *)crypto_X509Extension_New;
836 crypto_API[crypto_PKCS7_New_NUM] = (void *)crypto_PKCS7_New;
837 crypto_API[crypto_NetscapeSPKI_New_NUM] = (void *)crypto_NetscapeSPKI_New;
838 c_api_object = PyCObject_FromVoidPtr((void *)crypto_API, NULL);
839 if (c_api_object != NULL)
840 PyModule_AddObject(module, "_C_API", c_api_object);
843 crypto_Error = PyErr_NewException("OpenSSL.crypto.Error", NULL, NULL);
844 if (crypto_Error == NULL)
846 if (PyModule_AddObject(module, "Error", crypto_Error) != 0)
849 PyModule_AddIntConstant(module, "FILETYPE_PEM", X509_FILETYPE_PEM);
850 PyModule_AddIntConstant(module, "FILETYPE_ASN1", X509_FILETYPE_ASN1);
851 PyModule_AddIntConstant(module, "FILETYPE_TEXT", X509_FILETYPE_TEXT);
853 PyModule_AddIntConstant(module, "TYPE_RSA", crypto_TYPE_RSA);
854 PyModule_AddIntConstant(module, "TYPE_DSA", crypto_TYPE_DSA);
857 if (!init_openssl_threads())
860 if (!init_crypto_x509(module))
862 if (!init_crypto_x509name(module))
864 if (!init_crypto_x509store(module))
866 if (!init_crypto_x509req(module))
868 if (!init_crypto_pkey(module))
870 if (!init_crypto_x509extension(module))
872 if (!init_crypto_pkcs7(module))
874 if (!init_crypto_pkcs12(module))
876 if (!init_crypto_netscape_spki(module))
878 if (!init_crypto_crl(module))
880 if (!init_crypto_revoked(module))
883 PyOpenSSL_MODRETURN(module);
886 PyOpenSSL_MODRETURN(NULL);