aboutsummaryrefslogtreecommitdiff
path: root/pow/POW.c
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2011-01-20 00:25:27 +0000
committerRob Austein <sra@hactrn.net>2011-01-20 00:25:27 +0000
commit0fb7ecdb829e5941ecfadc06812e1c4a51f18d1e (patch)
tree1e5225d05d2812242c0b6bd41f67e6ec70cf343f /pow/POW.c
parent4b77848f92101ba05ac564dc3f91f3600661423f (diff)
Move POW extension module into rpkid directory and use distutils to
build it. svn path=/configure; revision=3610
Diffstat (limited to 'pow/POW.c')
-rw-r--r--pow/POW.c8564
1 files changed, 0 insertions, 8564 deletions
diff --git a/pow/POW.c b/pow/POW.c
deleted file mode 100644
index 666a8919..00000000
--- a/pow/POW.c
+++ /dev/null
@@ -1,8564 +0,0 @@
-/*****************************************************************************/
-/* */
-/* Copyright (c) 2001, 2002, Peter Shannon */
-/* All rights reserved. */
-/* */
-/* Redistribution and use in source and binary forms, with or without */
-/* modification, are permitted provided that the following conditions */
-/* are met: */
-/* */
-/* * Redistributions of source code must retain the above */
-/* copyright notice, this list of conditions and the following */
-/* disclaimer. */
-/* */
-/* * Redistributions in binary form must reproduce the above */
-/* copyright notice, this list of conditions and the following */
-/* disclaimer in the documentation and/or other materials */
-/* provided with the distribution. */
-/* */
-/* * The name of the contributors may be used to endorse or promote */
-/* products derived from this software without specific prior */
-/* written permission. */
-/* */
-/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
-/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
-/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
-/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS */
-/* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
-/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
-/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
-/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
-/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
-/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
-/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
-/* */
-/*****************************************************************************/
-
-#include <Python.h>
-
-#include <openssl/opensslconf.h>
-#include <openssl/crypto.h>
-#include <openssl/rand.h>
-#include <openssl/asn1.h>
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-#include <openssl/pem.h>
-#include <openssl/ssl.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include <openssl/md5.h>
-#ifndef OPENSSL_NO_MD2
-#include <openssl/md2.h>
-#endif
-#include <openssl/sha.h>
-#include <openssl/hmac.h>
-#include <openssl/ripemd.h>
-#include <openssl/cms.h>
-
-#include <time.h>
-
-// Symmetric ciphers
-#define DES_ECB 1
-#define DES_EDE 2
-#define DES_EDE3 3
-#define DES_CFB 4
-#define DES_EDE_CFB 5
-#define DES_EDE3_CFB 6
-#define DES_OFB 7
-#define DES_EDE_OFB 8
-#define DES_EDE3_OFB 9
-#define DES_CBC 10
-#define DES_EDE_CBC 11
-#define DES_EDE3_CBC 12
-#define DESX_CBC 13
-#define RC4 14
-#define RC4_40 15
-#define IDEA_ECB 16
-#define IDEA_CFB 17
-#define IDEA_OFB 18
-#define IDEA_CBC 19
-#define RC2_ECB 20
-#define RC2_CBC 21
-#define RC2_40_CBC 22
-#define RC2_CFB 23
-#define RC2_OFB 24
-#define BF_ECB 25
-#define BF_CBC 26
-#define BF_CFB 27
-#define BF_OFB 28
-#define CAST5_ECB 29
-#define CAST5_CBC 30
-#define CAST5_CFB 31
-#define CAST5_OFB 32
-#define RC5_32_12_16_CBC 33
-#define RC5_32_12_16_CFB 34
-#define RC5_32_12_16_ECB 35
-#define RC5_32_12_16_OFB 36
-
-// SSL connection methods
-#define SSLV2_SERVER_METHOD 1
-#define SSLV2_CLIENT_METHOD 2
-#define SSLV2_METHOD 3
-#define SSLV3_SERVER_METHOD 4
-#define SSLV3_CLIENT_METHOD 5
-#define SSLV3_METHOD 6
-#define TLSV1_SERVER_METHOD 7
-#define TLSV1_CLIENT_METHOD 8
-#define TLSV1_METHOD 9
-#define SSLV23_SERVER_METHOD 10
-#define SSLV23_CLIENT_METHOD 11
-#define SSLV23_METHOD 12
-
-// SSL connection states
-
-// PEM encoded data types
-#define RSA_PUBLIC_KEY 1
-#define RSA_PRIVATE_KEY 2
-#define DSA_PUBLIC_KEY 3
-#define DSA_PRIVATE_KEY 4
-#define DH_PUBLIC_KEY 5
-#define DH_PRIVATE_KEY 6
-#define X509_CERTIFICATE 7
-#define X_X509_CRL 8 // X509_CRL already used by OpenSSL library
-#define CMS_MESSAGE 9
-
-// Asymmetric ciphers
-#define RSA_CIPHER 1
-#define DSA_CIPHER 2
-#define DH_CIPHER 3
-//#define NO_DSA
-//#define NO_DH
-
-// Digests
-#ifndef OPENSSL_NO_MD2
-#define MD2_DIGEST 1
-#endif
-#define MD5_DIGEST 2
-#define SHA_DIGEST 3
-#define SHA1_DIGEST 4
-#define RIPEMD160_DIGEST 5
-#define SHA256_DIGEST 6
-#define SHA384_DIGEST 7
-#define SHA512_DIGEST 8
-
-// Object format
-#define SHORTNAME_FORMAT 1
-#define LONGNAME_FORMAT 2
-
-// Output format
-#define PEM_FORMAT 1
-#define DER_FORMAT 2
-
-// Object check functions
-#define X_X509_Check(op) ((op)->ob_type == &x509type)
-#define X_X509_store_Check(op) ((op)->ob_type == &x509_storetype)
-#define X_X509_crl_Check(op) ((op)->ob_type == &x509_crltype)
-#define X_X509_revoked_Check(op) ((op)->ob_type == &x509_revokedtype)
-#define X_asymmetric_Check(op) ((op)->ob_type == &asymmetrictype)
-#define X_symmetric_Check(op) ((op)->ob_type == &symmetrictype)
-#define X_digest_Check(op) ((op)->ob_type == &digesttype)
-#define X_hmac_Check(op) ((op)->ob_type == &hmactype)
-#define X_ssl_Check(op) ((op)->ob_type == &ssltype)
-#define X_cms_Check(op) ((op)->ob_type == &cmstype)
-
-// Symbolic representation of "no SSL shutdown mode requested"
-#define SSL_NO_SHUTDOWN 0
-
-static char pow_module__doc__ [] =
-"<moduleDescription>\n"
-" <header>\n"
-" <name>POW</name>\n"
-" <author>Peter Shannon</author>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This third major release of POW addresses the most critical missing\n"
-" parts of functionality, X509v3 support. Initially I thought adding\n"
-" support via the OpenSSL code would be the easiest option but this\n"
-" proved to be incorrect mainly due to the way I have chosen to handle\n"
-" the complex data such as <classname>directoryNames</classname> and\n"
-" <classname>generalNames</classname>. It is easier in python to\n"
-" construct complex sets of data using lists and dictionaries than\n"
-" coordinate large numbers of objects and method calls. This is no\n"
-" criticism, it is just extremely easy. Coding complex data such as the\n"
-" <classname>certificatePolicies</classname> coding coding routines in C\n"
-" to handle the data proved laborous and ultimately error prone.\n"
-" </para>\n"
-" <para>\n"
-" PKIX structures are supported by a few operations on the relevant POW\n"
-" objects and through a Python library which is modelled on the DER\n"
-" encoding rules. Modeling DER does expose some of the complexities of\n"
-" the ASN1 specifications but avoids coding many assumptions into the\n"
-" data structures and the interface for the objects. For an example of\n"
-" overly complex definitions take a look at the\n"
-" <classname>Name</classname> object in RFC3280. It is equally\n"
-" important that modeling DER in the way leads to a library which is\n"
-" trivial to extend to support new objects - simple objects are one\n"
-" liners and complex objects only require the definition of a new\n"
-" constructor.\n"
-" </para>\n"
-" <para>\n"
-" functionality have been plugged. The <classname>Ssl</classname> class has received\n"
-" several new features relating to security. Other areas have been\n"
-" improved: PRNG support, certificate and CRL signing, certificate chain\n"
-" and client verification. Many bugs have been fixed, and certain\n"
-" parts of code re-written where necessary. I hope you enjoy using POW\n"
-" and please feel free to send me feature requests and bug reports.\n"
-" </para>\n"
-" </body>\n"
-"</moduleDescription>\n"
-;
-
-/*========== Pre-definitions ==========*/
-static PyObject
- *ErrorObject,
- *SSLErrorObject,
- *ZeroReturnErrorObject,
- *WantReadErrorObject,
- *WantWriteErrorObject,
- *SSLSyscallErrorObject,
- *SSLErrorSSLErrorObject,
- *SSLSyscallSSLErrorObject,
- *SSLUnexpectedEOFErrorObject,
- *SSLOtherErrorObject;
-
-static PyTypeObject
- x509type,
- x509_storetype,
- x509_crltype,
- x509_revokedtype,
- asymmetrictype,
- symmetrictype,
- digesttype,
- hmactype,
- ssltype,
- cmstype;
-/*========== Pre-definitions ==========*/
-
-/*========== C structs ==========*/
-typedef struct {
- PyObject_HEAD
- X509 *x509;
-} x509_object;
-
-typedef struct {
- PyObject_HEAD
- X509_STORE *store;
-} x509_store_object;
-
-typedef struct {
- PyObject_HEAD
- X509_CRL *crl;
-} x509_crl_object;
-
-typedef struct {
- PyObject_HEAD
- X509_REVOKED *revoked;
-} x509_revoked_object;
-
-typedef struct {
- PyObject_HEAD
- void *cipher;
- int key_type;
- int cipher_type;
-} asymmetric_object;
-
-typedef struct {
- PyObject_HEAD
- EVP_CIPHER_CTX cipher_ctx;
- int cipher_type;
-} symmetric_object;
-
-typedef struct {
- PyObject_HEAD
- EVP_MD_CTX digest_ctx;
- int digest_type;
-} digest_object;
-
-typedef struct {
- PyObject_HEAD
- HMAC_CTX hmac_ctx;
-} hmac_object;
-
-typedef struct {
- PyObject_HEAD
- int ctxset;
- SSL *ssl;
- SSL_CTX *ctx;
- STACK_OF(X509) *trusted_certs;
- char *x509_cb_err;
-} ssl_object;
-
-typedef struct {
- PyObject_HEAD
- CMS_ContentInfo *cms;
-} cms_object;
-
-/*========== C structs ==========*/
-
-/*========== helper functions ==========*/
-
-/*
- * Minimal intervention debug-by-printf() hack, use only for good.
- */
-
-#if 0
-#define KVETCH(_msg_) write(2, _msg_ "\n", sizeof(_msg_))
-#else
-#define KVETCH(_msg_)
-#endif
-
-/*
- * Error handling macros. These macros make two assumptions:
- *
- * 1) All the macros assume that there's a cleanup label named
- * "error" which these macros can use as a goto target.
- *
- * 2) assert_no_unhandled_openssl_errors() assumes that the return
- * value is stored in a PyObject* variable named "result".
- *
- * These are icky assumptions, but they make it easier to provide
- * uniform error handling and make the code easier to read, not to
- * mention making it easier to track down obscure OpenSSL errors.
- */
-
-#define lose(_msg_) \
- do { \
- PyErr_SetString(ErrorObject, (_msg_)); \
- goto error; \
- } while (0)
-
-#define lose_type_error(_msg_) \
- do { \
- PyErr_SetString(PyExc_TypeError, (_msg_)); \
- goto error; \
- } while (0)
-
-#define lose_openssl_error(_msg_) \
- do { \
- set_openssl_exception(ErrorObject, (_msg_)); \
- goto error; \
- } while (0)
-
-#define lose_ssl_error(_self_, _code_) \
- do { \
- set_openssl_ssl_exception(_self_, _code_); \
- goto error; \
- } while (0)
-
-#define assert_no_unhandled_openssl_errors() \
- do { \
- if (ERR_peek_error()) { \
- if (result) { \
- Py_XDECREF(result); \
- result = NULL; \
- } \
- lose_openssl_error(assert_helper(__LINE__)); \
- } \
- } while (0)
-
-static char *
-assert_helper(int line)
-{
- static const char fmt[] = "Unhandled OpenSSL error at " __FILE__ ":%d!";
- static char msg[sizeof(fmt) + 10];
-
- snprintf(msg, sizeof(msg), fmt, line);
- return msg;
-}
-
-static int
-docset_helper_add(PyObject *set, char *v)
-{
- PyObject *value = NULL;
-
- if ((value = PyString_FromString(v)) == NULL)
- lose("could not allocate memory");
-
- if (PyList_Append(set, value) != 0)
- goto error;
-
- Py_XDECREF(value);
- return 1;
-
- error:
-
- Py_XDECREF(value);
- return 0;
-}
-
-/*
- * Generate an encrypion envelope. Saves a lot of space having this case
- * statement in one place.
- */
-static const EVP_CIPHER *
-evp_cipher_factory(int cipher_type)
-{
- switch(cipher_type) {
-#ifndef OPENSSL_NO_DES
- case DES_ECB: return EVP_des_ecb();
- case DES_EDE: return EVP_des_ede();
- case DES_EDE3: return EVP_des_ede3();
- case DES_CFB: return EVP_des_cfb();
- case DES_EDE_CFB: return EVP_des_ede_cfb();
- case DES_EDE3_CFB: return EVP_des_ede3_cfb();
- case DES_OFB: return EVP_des_ofb();
- case DES_EDE_OFB: return EVP_des_ede_ofb();
- case DES_EDE3_OFB: return EVP_des_ede3_ofb();
- case DES_CBC: return EVP_des_cbc();
- case DES_EDE_CBC: return EVP_des_ede_cbc();
- case DES_EDE3_CBC: return EVP_des_ede3_cbc();
- case DESX_CBC: return EVP_desx_cbc();
-#endif
-#ifndef OPENSSL_NO_RC4
- case RC4: return EVP_rc4();
- case RC4_40: return EVP_rc4_40();
-#endif
-#ifndef OPENSSL_NO_IDEA
- case IDEA_ECB: return EVP_idea_ecb();
- case IDEA_CFB: return EVP_idea_cfb();
- case IDEA_OFB: return EVP_idea_ofb();
- case IDEA_CBC: return EVP_idea_cbc();
-#endif
-#ifndef OPENSSL_NO_RC2
- case RC2_ECB: return EVP_rc2_ecb();
- case RC2_CBC: return EVP_rc2_cbc();
- case RC2_40_CBC: return EVP_rc2_40_cbc();
- case RC2_CFB: return EVP_rc2_cfb();
- case RC2_OFB: return EVP_rc2_ofb();
-#endif
-#ifndef OPENSSL_NO_BF
- case BF_ECB: return EVP_bf_ecb();
- case BF_CBC: return EVP_bf_cbc();
- case BF_CFB: return EVP_bf_cfb();
- case BF_OFB: return EVP_bf_ofb();
-#endif
-#ifndef OPENSSL_NO_CAST5
- case CAST5_ECB: return EVP_cast5_ecb();
- case CAST5_CBC: return EVP_cast5_cbc();
- case CAST5_CFB: return EVP_cast5_cfb();
- case CAST5_OFB: return EVP_cast5_ofb();
-#endif
-#ifndef OPENSSL_NO_RC5
- case RC5_32_12_16_CBC: return EVP_rc5_32_12_16_cbc();
- case RC5_32_12_16_CFB: return EVP_rc5_32_12_16_cfb();
- case RC5_32_12_16_ECB: return EVP_rc5_32_12_16_ecb();
- case RC5_32_12_16_OFB: return EVP_rc5_32_12_16_ofb();
-#endif
- default: return NULL;
- }
-}
-
-/*
- * Raise an exception with data pulled from the OpenSSL error stack.
- * Exception value is a tuple with some internal structure. If a
- * string error message is supplied, that string is the first element
- * of the exception value tuple. Remainder of exception value tuple
- * is zero or more tuples, each representing one error from the stack.
- * Each error tuple contains six slots:
- * - the numeric error code
- * - string translation of numeric error code ("reason")
- * - name of library in which error occurred
- * - name of function in which error occurred
- * - name of file in which error occurred
- * - line number in file where error occurred
- */
-
-static void
-set_openssl_exception(PyObject *error_class, const char *msg)
-{
- PyObject *errors;
- unsigned long err;
- const char *file;
- int line;
-
- errors = PyList_New(0);
-
- if (msg) {
- PyObject *s = Py_BuildValue("s", msg);
- (void) PyList_Append(errors, s);
- Py_XDECREF(s);
- }
-
- while ((err = ERR_get_error_line(&file, &line)) != 0) {
- PyObject *t = Py_BuildValue("(issssi)",
- err,
- ERR_reason_error_string(err),
- ERR_lib_error_string(err),
- ERR_func_error_string(err),
- file,
- line);
- (void) PyList_Append(errors, t);
- Py_XDECREF(t);
- }
-
- PyErr_SetObject(error_class, PyList_AsTuple(errors));
- Py_XDECREF(errors);
-}
-
-static void
-set_openssl_ssl_exception(const ssl_object *self, const int ret)
-{
- int err = SSL_get_error(self->ssl, ret);
- const char *s = NULL;
-
- switch(err) {
-
- /*
- * These three get their own exceptions.
- */
-
- case SSL_ERROR_ZERO_RETURN:
- PyErr_SetNone(ZeroReturnErrorObject);
- break;
- case SSL_ERROR_WANT_READ:
- PyErr_SetNone(WantReadErrorObject);
- break;
- case SSL_ERROR_WANT_WRITE:
- PyErr_SetNone(WantWriteErrorObject);
- break;
-
- case SSL_ERROR_SYSCALL:
- /*
- * Horrible jumbled mess of I/O related errors. I'd ask what they
- * were thinking, except that it's pretty clear that they weren't.
- */
- if (ERR_peek_error())
- set_openssl_exception(SSLSyscallSSLErrorObject, NULL);
- else if (ret)
- PyErr_SetFromErrno(SSLSyscallErrorObject);
- else
- PyErr_SetNone(SSLUnexpectedEOFErrorObject);
- break;
-
- case SSL_ERROR_SSL:
- /*
- * Generic OpenSSL error during an SSL call. I think.
- */
- set_openssl_exception(SSLErrorSSLErrorObject, self->x509_cb_err);
- break;
-
- /*
- * All other SSL errors are returned as a (number, string) tuple.
- */
-
- case SSL_ERROR_NONE:
- s = "SSL_ERROR_NONE";
- break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- s = "SSL_ERROR_WANT_X509_LOOKUP";
- break;
- case SSL_ERROR_WANT_CONNECT:
- s = "SSL_ERROR_WANT_CONNECT";
- break;
- case SSL_ERROR_WANT_ACCEPT:
- s = "SSL_ERROR_WANT_ACCEPT";
- break;
- default:
- s = "UNKNOWN_SSL_ERROR";
- }
-
- if (s)
- PyErr_SetObject(SSLOtherErrorObject, Py_BuildValue("(is)", err, s));
-}
-
-static PyObject *
-X509_object_helper_set_name(X509_NAME *name, PyObject *name_sequence)
-{
- PyObject *pair = NULL; PyObject *type = NULL; PyObject *value = NULL;
- int no_pairs = 0, i = 0, str_type = 0, nid;
- unsigned char *valueptr = NULL;
- char *typeptr = NULL;
-
- no_pairs = PySequence_Size(name_sequence);
- for (i = 0; i < no_pairs; i++) {
- if ((pair = PySequence_GetItem(name_sequence, i)) == NULL)
- return NULL;
-
- if (!PyTuple_Check(pair) && !PyList_Check(pair))
- lose_type_error("inapropriate type");
-
- if (PySequence_Size(pair) != 2)
- lose("each name entry must have 2 elements");
-
- if ((type = PySequence_GetItem(pair, 0)) == NULL)
- lose_type_error("could not get type string");
-
- if (!PyString_Check(type))
- lose_type_error("inapropriate type");
-
- if ((value = PySequence_GetItem(pair, 1)) == NULL)
- lose_type_error("could not get value string");
-
- if (!PyString_Check(value))
- lose_type_error("inapropriate type");
-
- typeptr = PyString_AsString(type);
- valueptr = (unsigned char *) PyString_AsString(value);
-
- str_type = ASN1_PRINTABLE_type(valueptr, -1);
- if ((nid = OBJ_ln2nid(typeptr)) == 0 &&
- (nid = OBJ_sn2nid(typeptr)) == 0)
- lose("unknown ASN1 object");
-
- if (!X509_NAME_add_entry_by_NID(name, nid, str_type, valueptr,
- strlen((char *) valueptr), -1, 0))
- lose("unable to add name entry");
-
- Py_XDECREF(pair);
- Py_XDECREF(type);
- Py_XDECREF(value);
- pair = NULL;
- type = NULL;
- value = NULL;
- }
- return name_sequence;
-
- error:
-
- Py_XDECREF(pair);
- Py_XDECREF(type);
- Py_XDECREF(value);
-
- return NULL;
-}
-
-static PyObject *
-X509_object_helper_get_name(X509_NAME *name, int format)
-{
- int no_entries = 0, no_pairs = 0, i = 0, j = 0, value_len = 0, nid = 0;
- X509_NAME_ENTRY *entry = NULL;
- char *value = NULL, long_name[512];
- const char *short_name;
-
- PyObject *result_list = NULL;
- PyObject *pair = NULL;
- PyObject *py_type = NULL;
- PyObject *py_value = NULL;
-
- no_entries = X509_NAME_entry_count(name);
-
- if ((result_list = PyTuple_New(no_entries)) == NULL)
- lose("could not allocate memory");
-
- for(i = 0; i < no_entries; i++) {
- if ((entry = X509_NAME_get_entry(name, i)) == NULL)
- lose("could not get certificate name");
-
- if (entry->value->length + 1 > value_len) {
- if (value)
- free(value);
-
- if ((value = malloc(entry->value->length + 1)) == NULL)
- lose("could not allocate memory");
-
- value_len = entry->value->length + 1;
- }
- memcpy(value, entry->value->data, entry->value->length);
- value[entry->value->length] = 0;
-
- if (!i2t_ASN1_OBJECT(long_name, sizeof(long_name), entry->object))
- lose("could not find object name");
-
- switch (format) {
- case SHORTNAME_FORMAT:
- nid = OBJ_ln2nid(long_name);
- short_name = OBJ_nid2sn(nid);
- py_type = PyString_FromString(short_name);
- break;
- case LONGNAME_FORMAT:
- py_type = PyString_FromString(long_name);
- break;
- default:
- lose("unknown name format");
- }
-
- py_value = PyString_FromString(value);
-
- if ((pair = PyTuple_New(2)) == NULL)
- lose("could not allocate memory");
-
- PyTuple_SetItem(pair, 0, py_type);
- PyTuple_SetItem(pair, 1, py_value);
- PyTuple_SetItem(result_list, i, pair);
- }
-
- if (value)
- free(value);
-
- return result_list;
-
- error:
-
- if (value)
- free(value);
-
- if (result_list) {
- no_pairs = PyTuple_Size(result_list);
- for (i = 0; i < no_pairs; i++) {
- pair = PyTuple_GetItem(result_list, i);
- no_entries = PyTuple_Size(result_list);
- for (j = 0; j < no_entries; j++) {
- py_value = PyTuple_GetItem(pair, i);
- Py_XDECREF(py_value);
- }
- }
- }
-
- Py_XDECREF(py_type);
- Py_XDECREF(py_value);
- Py_XDECREF(result_list);
- return NULL;
-}
-
-static STACK_OF(X509) *
-x509_helper_sequence_to_stack(PyObject *x509_sequence)
-{
- x509_object *x509obj = NULL;
- STACK_OF(X509) *x509_stack = NULL;
- int size = 0, i = 0;
-
- if (x509_sequence != Py_None && !PyTuple_Check(x509_sequence) && !PyList_Check(x509_sequence))
- lose_type_error("Inapropriate type");
-
- if ((x509_stack = sk_X509_new_null()) == NULL)
- lose("Couldn't create new X509 stack");
-
- if (x509_sequence != Py_None) {
- size = PySequence_Size(x509_sequence);
-
- for (i = 0; i < size; i++) {
- if ((x509obj = (x509_object*) PySequence_GetItem(x509_sequence, i)) == NULL)
- goto error;
-
- if (!X_X509_Check(x509obj))
- lose_type_error("Inapropriate type");
-
- if (!sk_X509_push(x509_stack, x509obj->x509))
- lose("Couldn't add X509 object to stack");
-
- Py_XDECREF(x509obj);
- x509obj = NULL;
- }
- }
-
- return x509_stack;
-
- error:
-
- if (x509_stack)
- sk_X509_free(x509_stack);
-
- Py_XDECREF(x509obj);
-
- return NULL;
-}
-
-static PyObject *
-stack_to_tuple_helper(_STACK *sk, PyObject *(*handler)(void *))
-{
- PyObject *result_list = NULL, *result_tuple = NULL, *obj = NULL;
-
- if ((result_list = PyList_New(0)) == NULL)
- lose("could not allocate memory");
-
- while (sk_num(sk)) {
-
- if ((obj = handler(sk_value(sk, 0))) == NULL)
- lose("could not allocate memory");
-
- sk_shift(sk);
-
- if (PyList_Append(result_list, obj) != 0)
- goto error;
-
- Py_XDECREF(obj);
- obj = NULL;
- }
-
- result_tuple = PyList_AsTuple(result_list);
- Py_XDECREF(result_list);
-
- return result_tuple;
-
- error:
-
- Py_XDECREF(obj);
- Py_XDECREF(result_list);
- return NULL;
-}
-
-/*
- * Time conversion functions. These follow RFC 5280, but use a single
- * text encoding that looks like GeneralizedTime as restricted by RFC
- * 5280; conversion to and from UTCTime is handled internally
- * according to the RFC 5280 rules. The intent is to hide the
- * horrible short-sighted mess from Python code entirely.
- */
-
-static PyObject *
-ASN1_TIME_to_Python(ASN1_TIME *t)
-{
- ASN1_GENERALIZEDTIME *g = ASN1_TIME_to_generalizedtime(t, NULL);
- PyObject *result = NULL;
- if (g) {
- result = Py_BuildValue("s", g->data);
- ASN1_GENERALIZEDTIME_free(g);
- }
- return result;
-}
-
-static int
-python_ASN1_TIME_set_string(ASN1_TIME *t, const char *s)
-{
- if (t == NULL || s == NULL || strlen(s) < 10)
- return 0;
- if ((s[0] == '1' && s[1] == '9' && s[2] > '4') ||
- (s[0] == '2' && s[1] == '0' && s[2] < '5'))
- return ASN1_UTCTIME_set_string(t, s + 2);
- else
- return ASN1_GENERALIZEDTIME_set_string(t, s);
-}
-
-/*========== helper funcitons ==========*/
-
-/*========== X509 code ==========*/
-static x509_object *
-X509_object_new(void)
-{
- x509_object *self;
-
- self = PyObject_New(x509_object, &x509type);
- if (self == NULL)
- goto error;
-
- self->x509 = X509_new();
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-/*
- * This function is pretty dumb. Most of the work is done by the module
- * function pow_module_pem_read().
- */
-static x509_object *
-X509_object_pem_read(BIO *in)
-{
- x509_object *self;
-
- if ((self = PyObject_New(x509_object, &x509type)) == NULL)
- goto error;
-
- if ((self->x509 = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
- lose("could not load PEM encoded certificate");
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static x509_object *
-X509_object_der_read(unsigned char *src, int len)
-{
- x509_object *self;
- unsigned char *ptr = src;
-
- if ((self = PyObject_New(x509_object, &x509type)) == NULL)
- goto error;
-
- self->x509 = X509_new();
-
- if(!d2i_X509(&self->x509, (const unsigned char **) &ptr, len))
- lose("could not load PEM encoded certificate");
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-/*
- * Unlike the previous function this creates the BIO itself. The BIO_s_mem
- * is used as a buffer which the certificate is read into, from this buffer
- * it is read into a char[] and returned as a string.
- */
-static PyObject *
-X509_object_write_helper(x509_object *self, PyObject *args, int format)
-{
- int len = 0;
- char *buf = NULL;
- BIO *out_bio = NULL;
- PyObject *cert = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- out_bio = BIO_new(BIO_s_mem());
-
- switch (format) {
-
- case DER_FORMAT:
- if (!i2d_X509_bio(out_bio, self->x509))
- lose("unable to write certificate");
- break;
-
- case PEM_FORMAT:
- if (!PEM_write_bio_X509(out_bio, self->x509))
- lose("unable to write certificate");
- break;
-
- default:
- lose("internal error, unknown output format");
- }
-
- if ((len = BIO_ctrl_pending(out_bio)) == 0)
- lose("unable to get bytes stored in bio");
-
- if ((buf = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- if (BIO_read(out_bio, buf, len) != len)
- lose("unable to write out cert");
-
- cert = Py_BuildValue("s#", buf, len);
-
- BIO_free(out_bio);
- free(buf);
- return cert;
-
- error:
-
- if (out_bio)
- BIO_free(out_bio);
-
- if (buf)
- free(buf);
-
- Py_XDECREF(cert);
- return NULL;
-}
-
-static char X509_object_pem_write__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>pemWrite</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a PEM encoded certificate as a\n"
-" string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_pem_write(x509_object *self, PyObject *args)
-{
- return X509_object_write_helper(self, args, PEM_FORMAT);
-}
-
-static char X509_object_der_write__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>derWrite</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a DER encoded certificate as a\n"
-" string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_der_write(x509_object *self, PyObject *args)
-{
- return X509_object_write_helper(self, args, DER_FORMAT);
-}
-
-/*
- * Currently this function only supports RSA keys.
- */
-static char X509_object_set_public_key__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>setPublicKey</name>\n"
-" <parameter>key</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method sets the public key for this certificate object. The\n"
-" parameter <parameter>key</parameter> should be an instance of\n"
-" <classname>Asymmetric</classname> containing a public key.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-
-static PyObject *
-X509_object_set_public_key(x509_object *self, PyObject *args)
-{
- EVP_PKEY *pkey = NULL;
- asymmetric_object *asym;
-
- if (!PyArg_ParseTuple(args, "O!", &asymmetrictype, &asym))
- goto error;
-
- if ((pkey = EVP_PKEY_new()) == NULL)
- lose("could not allocate memory");
-
- if (!EVP_PKEY_assign_RSA(pkey, asym->cipher))
- lose("EVP_PKEY assignment error");
-
- if (!X509_set_pubkey(self->x509,pkey))
- lose("could not set certificate's public key");
-
- Py_RETURN_NONE;
-
- error:
-
- if (pkey)
- EVP_PKEY_free(pkey);
-
- return NULL;
-
-}
-
-static char X509_object_sign__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>sign</name>\n"
-" <parameter>key</parameter>\n"
-" <optional><parameter>digest = MD5_DIGEST</parameter></optional>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method signs a certificate with a private key. See the\n"
-" example for the methods which should be invoked before signing a\n"
-" certificate. <parameter>key</parameter> should be an instance of\n"
-" <classname>Asymmetric</classname> containing a private key.\n"
-" The optional parameter <parameter>digest</parameter> indicates\n"
-" which digest function should be used to compute the hash to be\n"
-" signed, it should be one of the following:\n"
-" </para>\n"
-" <simplelist>\n"
-#ifndef OPENSSL_NO_MD2
-" <member><constant>MD2_DIGEST</constant></member>\n"
-#endif
-" <member><constant>MD5_DIGEST</constant></member>\n"
-" <member><constant>SHA_DIGEST</constant></member>\n"
-" <member><constant>SHA1_DIGEST</constant></member>\n"
-" <member><constant>RIPEMD160_DIGEST</constant></member>\n"
-" <member><constant>SHA256_DIGEST</constant></member>\n"
-" <member><constant>SHA384_DIGEST</constant></member>\n"
-" <member><constant>SHA512_DIGEST</constant></member>\n"
-" </simplelist>\n"
-" </body>\n"
-"</method>\n"
-;
-
-
-static PyObject *
-X509_object_sign(x509_object *self, PyObject *args)
-{
- EVP_PKEY *pkey = NULL;
- asymmetric_object *asym;
- int digest = MD5_DIGEST;
-
- if (!PyArg_ParseTuple(args, "O!|i", &asymmetrictype, &asym, &digest))
- goto error;
-
- if ((pkey = EVP_PKEY_new()) == NULL)
- lose("could not allocate memory");
-
- if (asym->key_type != RSA_PRIVATE_KEY)
- lose("cannot use this type of key");
-
- if (!EVP_PKEY_assign_RSA(pkey, asym->cipher))
- lose("EVP_PKEY assignment error");
-
- switch (digest) {
- case MD5_DIGEST:
- if (!X509_sign(self->x509, pkey, EVP_md5()))
- lose("could not sign certificate");
- break;
-
-#ifndef OPENSSL_NO_MD2
- case MD2_DIGEST:
- if (!X509_sign(self->x509, pkey, EVP_md2()))
- lose("could not sign certificate");
- break;
-#endif
-
- case SHA_DIGEST:
- if (!X509_sign(self->x509, pkey, EVP_sha()))
- lose("could not sign certificate");
- break;
-
- case SHA1_DIGEST:
- if (!X509_sign(self->x509, pkey, EVP_sha1()))
- lose("could not sign certificate");
- break;
-
- case RIPEMD160_DIGEST:
- if (!X509_sign(self->x509, pkey, EVP_ripemd160()))
- lose("could not sign certificate");
- break;
-
- case SHA256_DIGEST:
- if (!X509_sign(self->x509, pkey, EVP_sha256()))
- lose("could not sign certificate");
- break;
-
- case SHA384_DIGEST:
- if (!X509_sign(self->x509, pkey, EVP_sha384()))
- lose("could not sign certificate");
- break;
-
- case SHA512_DIGEST:
- if (!X509_sign(self->x509, pkey, EVP_sha512()))
- lose("could not sign certificate");
- break;
- }
-
- Py_RETURN_NONE;
-
- error:
-
- if (pkey)
- EVP_PKEY_free(pkey);
-
- return NULL;
-
-}
-
-static char X509_object_get_version__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>getVersion</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the version number from the version field of\n"
-" this certificate.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-
-static PyObject *
-X509_object_get_version(x509_object *self, PyObject *args)
-{
- long version = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- version = X509_get_version(self->x509);
-
- return Py_BuildValue("l", version);
-
- error:
-
- return NULL;
-}
-
-static char X509_object_set_version__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>setVersion</name>\n"
-" <parameter>version</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method sets the version number in the version field of\n"
-" this certificate. <parameter>version</parameter> should be an\n"
-" integer.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_set_version(x509_object *self, PyObject *args)
-{
- long version = 0;
-
- if (!PyArg_ParseTuple(args, "l", &version))
- goto error;
-
- if (!X509_set_version(self->x509, version))
- lose("could not set certificate version");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char X509_object_get_serial__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>getSerial</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method get the serial number in the serial field of\n"
-" this certificate.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_get_serial(x509_object *self, PyObject *args)
-{
- long serial = 0;
- ASN1_INTEGER *asn1i = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((asn1i = X509_get_serialNumber(self->x509)) == NULL)
- lose("could not get serial number");
-
- if ((serial = ASN1_INTEGER_get(asn1i)) == -1)
- lose("could not convert ASN1 Integer to long");
-
- return Py_BuildValue("l", serial);
-
- error:
-
- return NULL;
-}
-
-static char X509_object_set_serial__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>setSerial</name>\n"
-" <parameter>serial</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method sets the serial number in the serial field of\n"
-" this certificate. <parameter>serial</parameter> should ba an\n"
-" integer.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_set_serial(x509_object *self, PyObject *args)
-{
- long serial = 0;
- ASN1_INTEGER *asn1i = NULL;
-
- if (!PyArg_ParseTuple(args, "l", &serial))
- goto error;
-
- if ((asn1i = ASN1_INTEGER_new()) == NULL)
- lose("could not allocate memory");
-
- if (!ASN1_INTEGER_set(asn1i, serial))
- lose("could not set ASN1 integer");
-
- if (!X509_set_serialNumber(self->x509, asn1i))
- lose("could not set certificate serial");
-
- ASN1_INTEGER_free(asn1i);
-
- Py_RETURN_NONE;
-
- error:
-
- if (asn1i)
- ASN1_INTEGER_free(asn1i);
-
- return NULL;
-}
-
-static char X509_object_get_issuer__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>getIssuer</name>\n"
-" <parameter>format = SHORTNAME_FORMAT</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a tuple containing the issuers name. Each\n"
-" element of the tuple is a tuple with 2 elements. The first tuple\n"
-" is an object name and the second is it's value. Both issuer and\n"
-" subject are names distinguished normally composed of a small\n"
-" number of objects:\n"
-" </para>\n"
-" <simplelist>\n"
-" <member><constant>c</constant> or <constant>countryName</constant></member>\n"
-" <member><constant>st</constant> or <constant>stateOrProvinceName</constant></member>\n"
-" <member><constant>o</constant> or <constant>organizationName</constant></member>\n"
-" <member><constant>l</constant> or <constant>localityName</constant></member>\n"
-" <member><constant>ou</constant> or <constant>organizationalUnitName</constant></member>\n"
-" <member><constant>cn</constant> or <constant>commonName</constant></member>\n"
-" </simplelist>\n"
-" <para>\n"
-" The data type varies from one object to another, however, all the\n"
-" common objects are strings. It would be possible to specify any\n"
-" kind of object but that would certainly adversely effect\n"
-" portability and is not recommended.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_get_issuer(x509_object *self, PyObject *args)
-{
- PyObject *result_list = NULL;
- X509_NAME *name = NULL;
- int format = SHORTNAME_FORMAT;
-
- if (!PyArg_ParseTuple(args, "|i", &format))
- goto error;
-
- if ((name = X509_get_issuer_name(self->x509)) == NULL)
- lose("could not get issuers name");
-
- if ((result_list = X509_object_helper_get_name(name, format)) == NULL)
- lose("failed to produce name list");
-
- return result_list;
-
- error:
-
- return NULL;
-}
-
-static char X509_object_get_subject__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>getSubject</name>\n"
-" <parameter>format = SHORTNAME_FORMAT</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a tuple containing the subjects name. See\n"
-" <function>getIssuer</function> for a description of the returned\n"
-" object's format.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_get_subject(x509_object *self, PyObject *args)
-{
- PyObject *result_list = NULL;
- X509_NAME *name = NULL;
- int format = SHORTNAME_FORMAT;
-
- if (!PyArg_ParseTuple(args, "|i", &format))
- goto error;
-
- if ((name = X509_get_subject_name(self->x509)) == NULL)
- lose("could not get issuers name");
-
- if ((result_list = X509_object_helper_get_name(name, format)) == NULL)
- lose("failed to produce name list");
-
- return result_list;
-
- error:
-
- return NULL;
-}
-
-static char X509_object_set_subject__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>setSubject</name>\n"
-" <parameter>name</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to set the subjects name.\n"
-" <parameter>name</parameter> can be comprised of lists or tuples in\n"
-" the format described in the <function>getIssuer</function> method.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_set_subject(x509_object *self, PyObject *args)
-{
- PyObject *name_sequence = NULL;
- X509_NAME *name = NULL;
-
- if (!PyArg_ParseTuple(args, "O", &name_sequence))
- goto error;
-
- if (!PyTuple_Check(name_sequence) && !PyList_Check(name_sequence))
- lose_type_error("Inapropriate type");
-
- if ((name = X509_NAME_new()) == NULL)
- lose("could not allocate memory");
-
- if (!X509_object_helper_set_name(name, name_sequence))
- lose("unable to set new name");
-
- if (!X509_set_subject_name(self->x509, name))
- lose("unable to set name");
-
- X509_NAME_free(name);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char X509_object_set_issuer__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>setIssuer</name>\n"
-" <parameter>name</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to set the issuers name.\n"
-" <parameter>name</parameter> can be comprised of lists or tuples in\n"
-" the format described in the <function>getissuer</function> method.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_set_issuer(x509_object *self, PyObject *args)
-{
- PyObject *name_sequence = NULL;
- X509_NAME *name = NULL;
-
- if (!PyArg_ParseTuple(args, "O", &name_sequence))
- goto error;
-
- if (!PyTuple_Check(name_sequence) && !PyList_Check(name_sequence))
- lose_type_error("Inapropriate type");
-
- if ((name = X509_NAME_new()) == NULL)
- lose("could not allocate memory");
-
- if (!X509_object_helper_set_name(name, name_sequence))
- lose("unable to set new name");
-
- if (!X509_set_issuer_name(self->x509,name))
- lose("unable to set name");
-
- X509_NAME_free(name);
-
- Py_RETURN_NONE;
-
- error:
-
- if (name)
- X509_NAME_free(name);
-
- return NULL;
-}
-
-static char X509_object_get_not_before__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>getNotBefore</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this function returns a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-
-;
-
-static PyObject *
-X509_object_get_not_before (x509_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- return ASN1_TIME_to_Python(self->x509->cert_info->validity->notBefore);
-
- error:
-
- return NULL;
-}
-
-static char X509_object_get_not_after__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>getNotAfter</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this function returns a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_get_not_after (x509_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- return ASN1_TIME_to_Python(self->x509->cert_info->validity->notAfter);
-
- error:
-
- return NULL;
-}
-
-static char X509_object_set_not_after__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>setNotAfter</name>\n"
-" <parameter>time</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this accepts one parameter, a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_set_not_after (x509_object *self, PyObject *args)
-{
- char *new_time = NULL;
-
- if (!PyArg_ParseTuple(args, "s", &new_time))
- goto error;
-
- if (!python_ASN1_TIME_set_string(self->x509->cert_info->validity->notAfter, new_time))
- lose("Could not set notAfter");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char X509_object_set_not_before__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>setNotBefore</name>\n"
-" <parameter>time</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this accepts one parameter, a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_set_not_before (x509_object *self, PyObject *args)
-{
- char *new_time = NULL;
-
- if (!PyArg_ParseTuple(args, "s", &new_time))
- goto error;
-
- if (!python_ASN1_TIME_set_string(self->x509->cert_info->validity->notBefore, new_time))
- lose("Could not set notBefore");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char X509_object_add_extension__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>addExtension</name>\n"
-" <parameter>extensionName</parameter>\n"
-" <parameter>critical</parameter>\n"
-" <parameter>extensionValue</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method adds an extension to this certificate.\n"
-" <parameter>extensionName</parameter> should be the of the\n"
-" extension. <parameter>critical</parameter> should an integer, 1\n"
-" for true and 0 for false. <parameter>extensionValue</parameter>\n"
-" should be a string, DER encoded value of the extension. The name\n"
-" of the extension must be correct according to OpenSSL and can be\n"
-" checked in the <constant>objects.h</constant> header file, part of\n"
-" the OpenSSL source distribution. In the majority of cases they\n"
-" are the same as those defined in <constant>POW._oids</constant>\n"
-" but if you do encounter problems is may be worth checking.\n"
-" </para>\n"
-" <example>\n"
-" <title><function>addExtension</function> method usage</title>\n"
-" <programlisting>\n"
-" basic = POW.pkix.BasicConstraints()\n"
-" basic.set([1,5])\n"
-" serverCert.addExtension('basicConstraints', 0, basic.toString())\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_add_extension(x509_object *self, PyObject *args)
-{
- int critical = 0, nid = 0, len = 0;
- char *name = NULL;
- unsigned char *buf = NULL;
- ASN1_OCTET_STRING *octetString = NULL;
- X509_EXTENSION *extn = NULL;
-
- if (!PyArg_ParseTuple(args, "sis#", &name, &critical, &buf, &len))
- goto error;
-
- if ((octetString = M_ASN1_OCTET_STRING_new()) == NULL)
- lose("could not allocate memory");
-
- if (!ASN1_OCTET_STRING_set(octetString, buf, len))
- lose("could not set ASN1 Octect string");
-
- if ((nid = OBJ_txt2nid(name)) == NID_undef)
- lose("extension has unknown object identifier");
-
- if ((extn = X509_EXTENSION_create_by_NID(NULL, nid, critical, octetString)) == NULL)
- lose("unable to create ASN1 X509 Extension object");
-
- if (!self->x509->cert_info->extensions &&
- (self->x509->cert_info->extensions = sk_X509_EXTENSION_new_null()) == NULL)
- lose("unable to allocate memory");
-
- if (!sk_X509_EXTENSION_push(self->x509->cert_info->extensions, extn))
- lose("unable to add extension");
-
- Py_RETURN_NONE;
-
- error:
-
- if (extn)
- X509_EXTENSION_free(extn);
-
- return NULL;
-}
-
-static char X509_object_clear_extensions__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>clearExtensions</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method clears the structure which holds the extension for\n"
-" this certificate.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_clear_extensions(x509_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (self->x509->cert_info->extensions) {
- sk_X509_EXTENSION_free(self->x509->cert_info->extensions);
- self->x509->cert_info->extensions = NULL;
- }
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char X509_object_count_extensions__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>countExtensions</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the size of the structure which holds the\n"
-" extension for this certificate.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_count_extensions(x509_object *self, PyObject *args)
-{
- int num = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (self->x509->cert_info->extensions)
- num = sk_X509_EXTENSION_num(self->x509->cert_info->extensions);
-
- return Py_BuildValue("i", num);
-
- error:
-
- return NULL;
-}
-
-static char X509_object_get_extension__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>getExtension</name>\n"
-" <parameter>index</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a tuple equivalent the parameters of\n"
-" <function>addExtension</function>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_object_get_extension(x509_object *self, PyObject *args)
-{
- int num = 0, index = 0, ext_nid = 0;
- char const *ext_ln = NULL;
- char unknown_ext [] = "unknown";
- X509_EXTENSION *ext;
-
- if (!PyArg_ParseTuple(args, "i", &index))
- goto error;
-
- if (self->x509->cert_info->extensions)
- num = sk_X509_EXTENSION_num(self->x509->cert_info->extensions);
-
- if (index >= num)
- lose("certificate does not have that many extensions");
-
- if ((ext = sk_X509_EXTENSION_value(self->x509->cert_info->extensions, index)) == NULL)
- lose("could not get extension");
-
- if ((ext_nid = OBJ_obj2nid(ext->object)) == NID_undef)
- lose("extension has unknown object identifier");
-
- if ((ext_ln = OBJ_nid2sn(ext_nid)) == NULL)
- ext_ln = unknown_ext;
-
- return Py_BuildValue("sis#", ext_ln, ext->critical, ext->value->data, ext->value->length);
-
- error:
-
- return NULL;
-}
-
-static char x509_object_pprint__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" <name>pprint</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a formatted string showing the information\n"
-" held in the certificate.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_object_pprint(x509_object *self, PyObject *args)
-{
- int len = 0, ret = 0;
- char *buf = NULL;
- BIO *out_bio = NULL;
- PyObject *cert = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- out_bio = BIO_new(BIO_s_mem());
-
- if (!X509_print(out_bio, self->x509))
- lose("unable to write crl");
-
- if ((len = BIO_ctrl_pending(out_bio)) == 0)
- lose("unable to get bytes stored in bio");
-
- if ((buf = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- if ((ret = BIO_read(out_bio, buf, len)) != len)
- lose("unable to write out cert");
-
- cert = Py_BuildValue("s#", buf, len);
-
- BIO_free(out_bio);
- free(buf);
- return cert;
-
- error:
-
- if (out_bio)
- BIO_free(out_bio);
-
- if (buf)
- free(buf);
-
- return NULL;
-
-}
-
-static struct PyMethodDef X509_object_methods[] = {
- {"pemWrite", (PyCFunction)X509_object_pem_write, METH_VARARGS, NULL},
- {"derWrite", (PyCFunction)X509_object_der_write, METH_VARARGS, NULL},
- {"sign", (PyCFunction)X509_object_sign, METH_VARARGS, NULL},
- {"setPublicKey", (PyCFunction)X509_object_set_public_key, METH_VARARGS, NULL},
- {"getVersion", (PyCFunction)X509_object_get_version, METH_VARARGS, NULL},
- {"setVersion", (PyCFunction)X509_object_set_version, METH_VARARGS, NULL},
- {"getSerial", (PyCFunction)X509_object_get_serial, METH_VARARGS, NULL},
- {"setSerial", (PyCFunction)X509_object_set_serial, METH_VARARGS, NULL},
- {"getIssuer", (PyCFunction)X509_object_get_issuer, METH_VARARGS, NULL},
- {"setIssuer", (PyCFunction)X509_object_set_issuer, METH_VARARGS, NULL},
- {"getSubject", (PyCFunction)X509_object_get_subject, METH_VARARGS, NULL},
- {"setSubject", (PyCFunction)X509_object_set_subject, METH_VARARGS, NULL},
- {"getNotBefore", (PyCFunction)X509_object_get_not_before, METH_VARARGS, NULL},
- {"getNotAfter", (PyCFunction)X509_object_get_not_after, METH_VARARGS, NULL},
- {"setNotAfter", (PyCFunction)X509_object_set_not_after, METH_VARARGS, NULL},
- {"setNotBefore", (PyCFunction)X509_object_set_not_before, METH_VARARGS, NULL},
- {"addExtension", (PyCFunction)X509_object_add_extension, METH_VARARGS, NULL},
- {"clearExtensions", (PyCFunction)X509_object_clear_extensions, METH_VARARGS, NULL},
- {"countExtensions", (PyCFunction)X509_object_count_extensions, METH_VARARGS, NULL},
- {"getExtension", (PyCFunction)X509_object_get_extension, METH_VARARGS, NULL},
- {"pprint", (PyCFunction)x509_object_pprint, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-X509_object_getattr(x509_object *self, char *name)
-{
- return Py_FindMethod(X509_object_methods, (PyObject *)self, name);
-}
-
-static void
-X509_object_dealloc(x509_object *self, char *name)
-{
- X509_free(self->x509);
- PyObject_Del(self);
-}
-
-static char x509type__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>X509</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides access to a significant proportion of X509\n"
-" functionality of OpenSSL.\n"
-" </para>\n"
-"\n"
-" <example>\n"
-" <title><classname>x509</classname> class usage</title>\n"
-" <programlisting>\n"
-" privateFile = open('test/private.key', 'r')\n"
-" publicFile = open('test/public.key', 'r')\n"
-" certFile = open('test/cacert.pem', 'w')\n"
-"\n"
-" publicKey = POW.pemRead(POW.RSA_PUBLIC_KEY, publicFile.read())\n"
-" privateKey = POW.pemRead(POW.RSA_PRIVATE_KEY, privateFile.read(), 'pass')\n"
-"\n"
-" c = POW.X509()\n"
-"\n"
-" name = [ ['C', 'GB'], ['ST', 'Hertfordshire'],\n"
-" ['O','The House'], ['CN', 'Peter Shannon'] ]\n"
-"\n"
-" c.setIssuer(name)\n"
-" c.setSubject(name)\n"
-" c.setSerial(0)\n"
-" t1 = POW.pkix.time2utc(time.time())\n"
-" t2 = POW.pkix.time2utc(time.time() + 60*60*24*365)\n"
-" c.setNotBefore(t1)\n"
-" c.setNotAfter(t2)\n"
-" c.setPublicKey(publicKey)\n"
-" c.sign(privateKey)\n"
-"\n"
-" certFile.write(c.pemWrite())\n"
-"\n"
-" privateFile.close()\n"
-" publicFile.close()\n"
-" certFile.close()\n"
-" </programlisting>\n"
-" </example>\n"
-"\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject x509type = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "X509", /*tp_name*/
- sizeof(x509_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)X509_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)X509_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- x509type__doc__ /* Documentation string */
-};
-/*========== X509 Code ==========*/
-
-/*========== x509 store Code ==========*/
-static x509_store_object *
-x509_store_object_new(void)
-{
- x509_store_object *self = NULL;
-
- if ((self = PyObject_New(x509_store_object, &x509_storetype)) == NULL)
- goto error;
-
- self->store = X509_STORE_new();
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static char x509_store_object_verify__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Store</memberof>\n"
-" <name>verify</name>\n"
-" <parameter>certificate</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" The <classname>X509Store</classname> method\n"
-" <function>verify</function> is based on the\n"
-" <function>X509_verify_cert</function>. It handles certain aspects\n"
-" of verification but not others. The certificate will be verified\n"
-" against <constant>notBefore</constant>,\n"
-" <constant>notAfter</constant> and trusted certificates.\n"
-" It crucially will not handle checking the certificate against\n"
-" CRLs. This functionality will probably make it into OpenSSL\n"
-" 0.9.7.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_store_object_verify(x509_store_object *self, PyObject *args)
-{
- X509_STORE_CTX csc;
- x509_object *x509 = NULL;
- int ok;
-
- if (!PyArg_ParseTuple(args, "O!", &x509type, &x509))
- goto error;
-
- X509_STORE_CTX_init(&csc, self->store, x509->x509, NULL);
- ok = X509_verify_cert(&csc) == 1;
- X509_STORE_CTX_cleanup(&csc);
-
- return PyBool_FromLong(ok);
-
- error:
-
- return NULL;
-}
-
-static char x509_store_object_verify_chain__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Store</memberof>\n"
-" <name>verifyChain</name>\n"
-" <parameter>certificate</parameter>\n"
-" <parameter>chain</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" The <classname>X509Store</classname> method <function>verifyChain</function>\n"
-" is based on the <function>X509_verify_cert</function> but is initialised\n"
-" with a <classname>X509</classname> object to verify and list of\n"
-" <classname>X509</classname> objects which form a chain to a trusted\n"
-" certificate. Certain aspects of the verification are handled but not others.\n"
-" The certificates will be verified against <constant>notBefore</constant>,\n"
-" <constant>notAfter</constant> and trusted certificates. It crucially will\n"
-" not handle checking the certificate against CRLs. This functionality will\n"
-" probably make it into OpenSSL 0.9.7.\n"
-" </para>\n"
-" <para>\n"
-" This may all sound quite straight forward but determining the\n"
-" certificate associated with the signature on another certificate\n"
-" can be very time consuming. The management aspects of\n"
-" certificates are addressed by various V3 extensions which are not\n"
-" currently supported.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_store_object_verify_chain(x509_store_object *self, PyObject *args)
-{
- PyObject *x509_sequence = NULL;
- X509_STORE_CTX csc;
- x509_object *x509 = NULL;
- STACK_OF(X509) *x509_stack = NULL;
- int ok;
-
- if (!PyArg_ParseTuple(args, "O!O", &x509type, &x509, &x509_sequence))
- goto error;
-
- if ((x509_stack = x509_helper_sequence_to_stack(x509_sequence)) == NULL)
- goto error;
-
- X509_STORE_CTX_init(&csc, self->store, x509->x509, x509_stack);
-
- ok = X509_verify_cert(&csc) == 1;
-
- X509_STORE_CTX_cleanup(&csc);
- sk_X509_free(x509_stack);
-
- return PyBool_FromLong(ok);
-
- error:
-
- if (x509_stack)
- sk_X509_free(x509_stack);
-
- return NULL;
-}
-
-static char x509_store_object_verify_detailed__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Store</memberof>\n"
-" <name>verifyDetailed</name>\n"
-" <parameter>certificate</parameter>\n"
-" <optional>\n"
-" <parameter>chain</parameter>\n"
-" </optional>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" The <classname>X509Store</classname> method <function>verifyDetailed</function>\n"
-" is based on the <function>X509_verify_cert</function> but is initialised\n"
-" with a <classname>X509</classname> object to verify and list of\n"
-" <classname>X509</classname> objects which form a chain to a trusted\n"
-" certificate. Certain aspects of the verification are handled but not others.\n"
-" The certificates will be verified against <constant>notBefore</constant>,\n"
-" <constant>notAfter</constant> and trusted certificates. It crucially will\n"
-" not handle checking the certificate against CRLs. This functionality will\n"
-" probably make it into OpenSSL 0.9.7.\n"
-" </para>\n"
-" <para>\n"
-" This may all sound quite straight forward but determining the\n"
-" certificate associated with the signature on another certificate\n"
-" can be very time consuming. The management aspects of\n"
-" certificates are addressed by various V3 extensions which are not\n"
-" currently supported.\n"
-" </para>\n"
-" <para>\n"
-" Unlike the <function>verify</function> and <function>verifyChain</function>\n"
-" methods, <function>verifyDetailed</function> returns some information about\n"
-" what went wrong when verification fails. The return value is currently a 3-tuple:\n"
-" the first value is the return value from X509_verify_cert(), the second and third\n"
-" are the error and error_depth values from the X509_STORE_CTX.\n"
-" Other values may added to this tuple later.\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_store_object_verify_detailed(x509_store_object *self, PyObject *args)
-{
- PyObject *x509_sequence = Py_None;
- X509_STORE_CTX csc;
- x509_object *x509 = NULL;
- STACK_OF(X509) *x509_stack = NULL;
- PyObject *result = NULL;
- int ok;
-
- if (!PyArg_ParseTuple(args, "O!|O", &x509type, &x509, &x509_sequence))
- goto error;
-
- if (x509_sequence && !(x509_stack = x509_helper_sequence_to_stack(x509_sequence)))
- goto error;
-
- X509_STORE_CTX_init(&csc, self->store, x509->x509, x509_stack);
-
- ok = X509_verify_cert(&csc) == 1;
-
- result = Py_BuildValue("(iii)", ok, csc.error, csc.error_depth);
-
- X509_STORE_CTX_cleanup(&csc);
-
- error: /* fall through */
-
- if (x509_stack)
- sk_X509_free(x509_stack);
-
- return result;
-}
-
-static char x509_store_object_add_trust__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Store</memberof>\n"
-" <name>addTrust</name>\n"
-" <parameter>cert</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method adds a new certificate to the store to be used in the\n"
-" verification process. <parameter>cert</parameter> should be an\n"
-" instance of <classname>X509</classname>. Using trusted certificates to manage\n"
-" verification is relatively primitive, more sophisticated systems\n"
-" can be constructed at an application level by by constructing\n"
-" certificate chains to verify.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_store_object_add_trust(x509_store_object *self, PyObject *args)
-{
- x509_object *x509 = NULL;
-
- if (!PyArg_ParseTuple(args, "O!", &x509type, &x509))
- goto error;
-
- X509_STORE_add_cert(self->store, x509->x509);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char x509_store_object_add_crl__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Store</memberof>\n"
-" <name>addCrl</name>\n"
-" <parameter>crl</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method adds a CRL to a store to be used for verification.\n"
-" <parameter>crl</parameter> should be an instance of\n"
-" <classname>X509Crl</classname>.\n"
-" Unfortunately, the current stable release of OpenSSL does not\n"
-" support CRL checking for certificate verification.\n"
-" This functionality will probably make it into OpenSSL 0.9.7, until\n"
-" it does this function is useless and CRL verification must be\n"
-" implemented by the application.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_store_object_add_crl(x509_store_object *self, PyObject *args)
-{
- x509_crl_object *crl = NULL;
-
- if (!PyArg_ParseTuple(args, "O!", &x509_crltype, &crl))
- goto error;
-
- X509_STORE_add_crl(self->store, crl->crl);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static struct PyMethodDef x509_store_object_methods[] = {
- {"verify", (PyCFunction)x509_store_object_verify, METH_VARARGS, NULL},
- {"verifyChain", (PyCFunction)x509_store_object_verify_chain, METH_VARARGS, NULL},
- {"verifyDetailed", (PyCFunction)x509_store_object_verify_detailed, METH_VARARGS, NULL},
- {"addTrust", (PyCFunction)x509_store_object_add_trust, METH_VARARGS, NULL},
- {"addCrl", (PyCFunction)x509_store_object_add_crl, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-x509_store_object_getattr(x509_store_object *self, char *name)
-{
- return Py_FindMethod(x509_store_object_methods, (PyObject *)self, name);
-}
-
-static void
-x509_store_object_dealloc(x509_store_object *self, char *name)
-{
- X509_STORE_free(self->store);
- PyObject_Del(self);
-}
-
-static char x509_storetype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>X509Store</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides preliminary access to OpenSSL X509 verification\n"
-" facilities.\n"
-" </para>\n"
-"\n"
-" <example>\n"
-" <title><classname>x509_store</classname> class usage</title>\n"
-" <programlisting>\n"
-" store = POW.X509Store()\n"
-"\n"
-" caFile = open('test/cacert.pem', 'r')\n"
-" ca = POW.pemRead(POW.X509_CERTIFICATE, caFile.read())\n"
-" caFile.close()\n"
-"\n"
-" store.addTrust(ca)\n"
-"\n"
-" certFile = open('test/foocom.cert', 'r')\n"
-" x509 = POW.pemRead(POW.X509_CERTIFICATE, certFile.read())\n"
-" certFile.close()\n"
-"\n"
-" print x509.pprint()\n"
-"\n"
-" if store.verify(x509):\n"
-" print 'Verified certificate!.'\n"
-" else:\n"
-" print 'Failed to verify certificate!.'\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject x509_storetype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "X509Store", /*tp_name*/
- sizeof(x509_store_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)x509_store_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)x509_store_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- x509_storetype__doc__ /* Documentation string */
-};
-/*========== x509 store Code ==========*/
-
-/*========== x509 crl Code ==========*/
-static x509_crl_object *
-x509_crl_object_new(void)
-{
- x509_crl_object *self = NULL;
-
- self = PyObject_New(x509_crl_object, &x509_crltype);
- if (self == NULL)
- goto error;
-
- self->crl = X509_CRL_new();
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static x509_crl_object *
-x509_crl_object_pem_read(BIO *in)
-{
- x509_crl_object *self;
-
- if ((self = PyObject_New(x509_crl_object, &x509_crltype)) == NULL)
- goto error;
-
- if ((self->crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL)) == NULL)
- lose("could not load certificate");
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static x509_crl_object *
-x509_crl_object_der_read(unsigned char *src, int len)
-{
- x509_crl_object *self;
- unsigned char* ptr = src;
-
- if ((self = PyObject_New(x509_crl_object, &x509_crltype)) == NULL)
- goto error;
-
- self->crl = X509_CRL_new();
-
- if (!d2i_X509_CRL(&self->crl, (const unsigned char **) &ptr, len))
- lose("could not load PEM encoded CRL");
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static char x509_crl_object_get_version__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>getVersion</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the version number from the version field of\n"
-" this CRL.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_get_version(x509_crl_object *self, PyObject *args)
-{
- long version = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((version = ASN1_INTEGER_get(self->crl->crl->version)) == -1)
- lose("could not get crl version");
-
- return Py_BuildValue("l", version);
-
- error:
-
- return NULL;
-}
-
-static char x509_crl_object_set_version__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>setVersion</name>\n"
-" <parameter>version</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method sets the version number in the version field of\n"
-" this CRL. <parameter>version</parameter> should be an\n"
-" integer.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_set_version(x509_crl_object *self, PyObject *args)
-{
- long version = 0;
- ASN1_INTEGER *asn1_version = NULL;
-
- if (!PyArg_ParseTuple(args, "i", &version))
- goto error;
-
- if ((asn1_version = ASN1_INTEGER_new()) == NULL)
- lose("could not allocate memory");
-
- if (!ASN1_INTEGER_set(asn1_version, version))
- lose("could not get set version");
-
- self->crl->crl->version = asn1_version;
-
- Py_RETURN_NONE;
-
- error:
-
- if (asn1_version)
- ASN1_INTEGER_free(asn1_version);
-
- return NULL;
-}
-
-static char x509_crl_object_get_issuer__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>getIssuer</name>\n"
-" <parameter>format = SHORTNAME_FORMAT</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a tuple containing the issuers name. See the\n"
-" <function>getIssuer</function> method of\n"
-" <classname>X509</classname> for more details.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_get_issuer(x509_crl_object *self, PyObject *args)
-{
- PyObject *result_list = NULL;
- int format = SHORTNAME_FORMAT;
-
- if (!PyArg_ParseTuple(args, "|i", &format))
- goto error;
-
- if ((result_list = X509_object_helper_get_name(self->crl->crl->issuer, format)) == NULL)
- lose("failed to produce name list");
-
- return result_list;
-
- error:
-
- return NULL;
-}
-
-static char x509_crl_object_set_issuer__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>setIssuer</name>\n"
-" <parameter>name</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to set the issuers name.\n"
-" <parameter>name</parameter> can be comprised of lists or tuples in\n"
-" the format described in the <function>getIssuer</function> method\n"
-" of <classname>X509</classname>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_set_issuer(x509_crl_object *self, PyObject *args)
-{
- PyObject *name_sequence = NULL;
- X509_NAME *name = NULL;
-
- if (!PyArg_ParseTuple(args, "O", &name_sequence))
- goto error;
-
- if (!PyTuple_Check(name_sequence) && !PyList_Check(name_sequence))
- lose_type_error("Inapropriate type");
-
- if ((name = X509_NAME_new()) == NULL)
- lose("could not allocate memory");
-
- if (!X509_object_helper_set_name(name, name_sequence))
- lose("unable to set new name");
-
- if (!X509_NAME_set(&self->crl->crl->issuer, name))
- lose("unable to set name");
-
- X509_NAME_free(name);
-
- Py_RETURN_NONE;
-
- error:
-
- if (name)
- X509_NAME_free(name);
-
- return NULL;
-}
-
-static char x509_crl_object_set_this_update__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>setThisUpdate</name>\n"
-" <parameter>time</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this accepts one parameter, a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_set_this_update (x509_crl_object *self, PyObject *args)
-{
- char *new_time = NULL;
-
- if (!PyArg_ParseTuple(args, "s", &new_time))
- goto error;
-
- if (!python_ASN1_TIME_set_string(self->crl->crl->lastUpdate, new_time))
- lose("Could not set lastUpdate");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char x509_crl_object_get_this_update__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>getThisUpdate</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this function returns a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_get_this_update (x509_crl_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- return ASN1_TIME_to_Python(self->crl->crl->lastUpdate);
-
- error:
-
- return NULL;
-}
-
-static char x509_crl_object_set_next_update__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>setNextUpdate</name>\n"
-" <parameter>time</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this accepts one parameter, a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_set_next_update (x509_crl_object *self, PyObject *args)
-{
- char *new_time = NULL;
- ASN1_UTCTIME *time = NULL;
-
- if (!PyArg_ParseTuple(args, "s", &new_time))
- goto error;
-
- if (self->crl->crl->nextUpdate == NULL && (time = ASN1_UTCTIME_new()) == NULL)
- lose("could not allocate memory");
-
- self->crl->crl->nextUpdate = time;
-
- if (!python_ASN1_TIME_set_string(time, new_time))
- lose("Could not set nextUpdate");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char x509_crl_object_get_next_update__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>getNextUpdate</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this function returns a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_get_next_update (x509_crl_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- return ASN1_TIME_to_Python(self->crl->crl->nextUpdate);
-
- error:
-
- return NULL;
-}
-
-static char x509_crl_object_set_revoked__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>setRevoked</name>\n"
-" <parameter>revoked</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method sets the sequence of revoked certificates in this CRL.\n"
-" <parameter>revoked</parameter> should be a list or tuple of\n"
-" <classname>X509Revoked</classname>.\n"
-" </para>\n"
-" <example>\n"
-" <title><function>setRevoked</function> function usage</title>\n"
-" <programlisting>\n"
-" privateFile = open('test/private.key', 'r')\n"
-" publicFile = open('test/public.key', 'r')\n"
-" crlFile = open('test/crl.pem', 'w')\n"
-"\n"
-" publicKey = POW.pemRead(POW.RSA_PUBLIC_KEY, publicFile.read())\n"
-" privateKey = POW.pemRead(POW.RSA_PRIVATE_KEY, privateFile.read(), 'pass')\n"
-"\n"
-" crl = POW.X509Crl()\n"
-"\n"
-" name = [ ['C', 'GB'], ['ST', 'Hertfordshire'],\n"
-" ['O','The House'], ['CN', 'Peter Shannon'] ]\n"
-"\n"
-" t1 = POW.pkix.time2utc(time.time())\n"
-" t2 = POW.pkix.time2utc(time.time() + 60*60*24*365)\n"
-" crl.setIssuer(name)\n"
-" rev = [ POW.X509Revoked(3, t1),\n"
-" POW.X509Revoked(4, t1),\n"
-" POW.X509Revoked(5, t1) ]\n"
-"\n"
-" crl.setRevoked(rev)\n"
-" crl.setThisUpdate(t1)\n"
-" crl.setNextUpdate(t2)\n"
-" crl.sign(privateKey)\n"
-"\n"
-" crlFile.write(crl.pemWrite())\n"
-"\n"
-" privateFile.close()\n"
-" publicFile.close()\n"
-" crlFile.close()\n"
-" </programlisting>\n"
-" </example>\n"
-"\n"
-" </body>\n"
-"</method>\n"
-;
-
-// added because we don't already have one!
-static X509_REVOKED *
-X509_REVOKED_dup(X509_REVOKED *rev)
-{
- return((X509_REVOKED *)ASN1_dup((i2d_of_void *) i2d_X509_REVOKED,
- (d2i_of_void *) d2i_X509_REVOKED,
- (char *) rev));
-}
-
-static PyObject *
-x509_crl_object_set_revoked(x509_crl_object *self, PyObject *args)
-{
- PyObject *revoked_sequence = NULL;
- x509_revoked_object *revoked = NULL;
- X509_REVOKED *tmp_revoked = NULL;
- int i = 0,size = 0;
-
- if (!PyArg_ParseTuple(args, "O", &revoked_sequence))
- goto error;
-
- if (!PyTuple_Check(revoked_sequence) && !PyList_Check(revoked_sequence))
- lose_type_error("inapropriate type");
-
- size = PySequence_Size(revoked_sequence);
- for (i = 0; i < size; i++) {
- if ((revoked = (x509_revoked_object*) PySequence_GetItem(revoked_sequence, i)) == NULL)
- goto error;
-
- if (!X_X509_revoked_Check(revoked))
- lose_type_error("inapropriate type");
-
- if ((tmp_revoked = X509_REVOKED_dup(revoked->revoked)) == NULL)
- lose("could not allocate memory");
-
- if (!X509_CRL_add0_revoked(self->crl, tmp_revoked))
- lose("could not add revokation to stack");
-
- Py_XDECREF(revoked);
- revoked = NULL;
- }
-
- Py_RETURN_NONE;
-
- error:
-
- Py_XDECREF(revoked);
-
- return NULL;
-}
-
-static PyObject *
-x509_crl_object_helper_get_revoked(STACK_OF(X509_REVOKED) *revoked)
-{
- int no_entries = 0, i = 0;
- x509_revoked_object *revoke_obj = NULL;
- PyObject *result_list = NULL, *result_tuple = NULL;
-
- no_entries = sk_X509_REVOKED_num(revoked);
-
- if ((result_list = PyList_New(0)) == NULL)
- lose("could not allocate memory");
-
- for (i = 0; i < no_entries; i++) {
- if ((revoke_obj = PyObject_New(x509_revoked_object, &x509_revokedtype)) == NULL)
- lose("could not allocate memory");
-
- if ((revoke_obj->revoked = X509_REVOKED_dup(sk_X509_REVOKED_value(revoked, i))) == NULL)
- lose("could not get revocation");
-
- if (PyList_Append(result_list, (PyObject*) revoke_obj) != 0)
- goto error;
-
- Py_XDECREF(revoke_obj);
- revoke_obj = NULL;
- }
-
- result_tuple = PyList_AsTuple(result_list);
- Py_XDECREF(result_list);
-
- return result_tuple;
-
- error:
-
- Py_XDECREF(revoke_obj);
- Py_XDECREF(result_list);
- return NULL;
-}
-
-static char x509_crl_object_get_revoked__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>getRevoked</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a tuple of <classname>X509Revoked</classname>\n"
-" objects described in the CRL.\n"
-" </para>\n"
-" <example>\n"
-" <title><function>getRevoked</function> function usage</title>\n"
-" <programlisting>\n"
-" publicFile = open('test/public.key', 'r')\n"
-" crlFile = open('test/crl.pem', 'r')\n"
-"\n"
-" publicKey = POW.pemRead(POW.RSA_PUBLIC_KEY, publicFile.read())\n"
-"\n"
-" crl = POW.pemRead(POW.X509_CRL, crlFile.read())\n"
-"\n"
-" print crl.pprint()\n"
-" if crl.verify(publicKey):\n"
-" print 'signature ok!'\n"
-" else:\n"
-" print 'signature not ok!'\n"
-"\n"
-" revocations = crl.getRevoked()\n"
-" for revoked in revocations:\n"
-" print 'serial number:', revoked.getSerial()\n"
-" print 'date:', time.ctime(revoked.getDate()[0])\n"
-"\n"
-" publicFile.close()\n"
-" crlFile.close()\n"
-" </programlisting>\n"
-" </example>\n"
-"\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_get_revoked(x509_crl_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- return x509_crl_object_helper_get_revoked(X509_CRL_get_REVOKED(self->crl));
-
- error:
-
- return NULL;
-}
-
-static char X509_crl_object_add_extension__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>addExtension</name>\n"
-" <parameter>extensionName</parameter>\n"
-" <parameter>critical</parameter>\n"
-" <parameter>extensionValue</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method adds an extension to this CRL.\n"
-" <parameter>extensionName</parameter> should be the of the\n"
-" extension. <parameter>critical</parameter> should an integer, 1\n"
-" for true and 0 for clase. <parameter>extensionValue</parameter>\n"
-" should be a string, DER encoded value of the extension. The name\n"
-" of the extension must be correct according to OpenSSL and can be\n"
-" checkd in the <constant>objects.h</constant> header file, part of\n"
-" the OpenSSL source distrobution. In the majority of cases they\n"
-" are the same as those defined in <constant>POW._oids</constant>\n"
-" but if you do encounter problems is may be worth checking.\n"
-" </para>\n"
-" <example>\n"
-" <title><function>addExtension</function> method usage</title>\n"
-" <programlisting>\n"
-" oids = POW.pkix.OidData()\n"
-" o2i = oids.obj2oid\n"
-"\n"
-" n1 = ('directoryName', (((o2i('countryName'), ('printableString', 'UK')),),\n"
-" ((o2i('stateOrProvinceName'), ('printableString', 'Herts')),),\n"
-" ((o2i('organizationName'), ('printableString', 'The House')),),\n"
-" ((o2i('commonName'), ('printableString', 'Shannon Works')),)))\n"
-"\n"
-" n2 = ('rfc822Name', 'peter_shannon@yahoo.com')\n"
-" n3 = ('uri', 'http://www.p-s.org.uk')\n"
-" n4 = ('iPAddress', (192,168,100,51))\n"
-"\n"
-" issuer = POW.pkix.IssuerAltName()\n"
-" issuer.set([n1,n2,n3,n4])\n"
-" crl.addExtension('issuerAltName', 0, issuer.toString())\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_crl_object_add_extension(x509_crl_object *self, PyObject *args)
-{
- int critical = 0, nid = 0, len = 0;
- char *name = NULL;
- unsigned char *buf = NULL;
- ASN1_OCTET_STRING *octetString = NULL;
- X509_EXTENSION *extn = NULL;
-
- if (!PyArg_ParseTuple(args, "sis#", &name, &critical, &buf, &len))
- goto error;
-
- if ((octetString = M_ASN1_OCTET_STRING_new()) == NULL)
- lose("could not allocate memory");
-
- if (!ASN1_OCTET_STRING_set(octetString, buf, len))
- lose("could not set ASN1 Octect string");
-
- if ((nid = OBJ_txt2nid(name)) == NID_undef)
- lose("extension has unknown object identifier");
-
- if ((extn = X509_EXTENSION_create_by_NID(NULL, nid, critical, octetString)) == NULL)
- lose("unable to create ASN1 X509 Extension object");
-
- if (!self->crl->crl->extensions &&
- (self->crl->crl->extensions = sk_X509_EXTENSION_new_null()) == NULL)
- lose("unable to allocate memory");
-
- if (!sk_X509_EXTENSION_push(self->crl->crl->extensions, extn))
- lose("unable to add extension");
-
- Py_RETURN_NONE;
-
- error:
-
- if (extn)
- X509_EXTENSION_free(extn);
-
- return NULL;
-}
-
-static char X509_crl_object_clear_extensions__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>clearExtensions</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method clears the structure which holds the extension for\n"
-" this CRL.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_crl_object_clear_extensions(x509_crl_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (self->crl->crl->extensions) {
- sk_X509_EXTENSION_free(self->crl->crl->extensions);
- self->crl->crl->extensions = NULL;
- }
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char X509_crl_object_count_extensions__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>countExtensions</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the size of the structure which holds the\n"
-" extension for this CRL.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_crl_object_count_extensions(x509_crl_object *self, PyObject *args)
-{
- int num = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (self->crl->crl->extensions)
- num = sk_X509_EXTENSION_num(self->crl->crl->extensions);
-
- return Py_BuildValue("i", num);
-
- error:
-
- return NULL;
-}
-
-static char X509_crl_object_get_extension__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>getExtension</name>\n"
-" <parameter>index</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a tuple equivalent the parameters of\n"
-" <function>addExtension</function>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_crl_object_get_extension(x509_crl_object *self, PyObject *args)
-{
- int num = 0, index = 0, ext_nid = 0;
- char const *ext_ln = NULL;
- char unknown_ext [] = "unknown";
- X509_EXTENSION *ext;
-
- if (!PyArg_ParseTuple(args, "i", &index))
- goto error;
-
- if (self->crl->crl->extensions)
- num = sk_X509_EXTENSION_num(self->crl->crl->extensions);
-
-
- if (index >= num)
- lose("certificate does not have that many extensions");
-
- if ((ext = sk_X509_EXTENSION_value(self->crl->crl->extensions, index)) == NULL)
- lose("could not get extension");
-
- if ((ext_nid = OBJ_obj2nid(ext->object)) == NID_undef)
- lose("extension has unknown object identifier");
-
- if ((ext_ln = OBJ_nid2sn(ext_nid)) == NULL)
- ext_ln = unknown_ext;
-
- return Py_BuildValue("sis#", ext_ln, ext->critical, ext->value->data, ext->value->length);
-
- error:
-
- return NULL;
-}
-
-static char x509_crl_object_sign__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>sign</name>\n"
-" <parameter>key</parameter>\n"
-" <parameter>digest = MD5_DIGEST</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" <parameter>key</parameter> should be an instance of\n"
-" <classname>Asymmetric</classname> and contain a private key.\n"
-" <parameter>digest</parameter> indicates\n"
-" which digest function should be used to compute the hash to be\n"
-" signed, it should be one of the following:\n"
-" </para>\n"
-" <simplelist>\n"
-#ifndef OPENSSL_NO_MD2
-" <member><constant>MD2_DIGEST</constant></member>\n"
-#endif
-" <member><constant>MD5_DIGEST</constant></member>\n"
-" <member><constant>SHA_DIGEST</constant></member>\n"
-" <member><constant>SHA1_DIGEST</constant></member>\n"
-" <member><constant>RIPEMD160_DIGEST</constant></member>\n"
-" <member><constant>SHA256_DIGEST</constant></member>\n"
-" <member><constant>SHA384_DIGEST</constant></member>\n"
-" <member><constant>SHA512_DIGEST</constant></member>\n"
-" </simplelist>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_sign(x509_crl_object *self, PyObject *args)
-{
- EVP_PKEY *pkey = NULL;
- asymmetric_object *asym;
- int digest = MD5_DIGEST;
-
- if (!PyArg_ParseTuple(args, "O!|i", &asymmetrictype, &asym, &digest))
- goto error;
-
- if ((pkey = EVP_PKEY_new()) == NULL)
- lose("could not allocate memory");
-
- if (asym->key_type != RSA_PRIVATE_KEY)
- lose("cannot use this type of key");
-
- if (!EVP_PKEY_assign_RSA(pkey, asym->cipher))
- lose("EVP_PKEY assignment error");
-
- switch (digest) {
- case MD5_DIGEST:
- if (!X509_CRL_sign(self->crl, pkey, EVP_md5()))
- lose("could not sign CRL");
- break;
-
-#ifndef OPENSSL_NO_MD2
- case MD2_DIGEST:
- if (!X509_CRL_sign(self->crl, pkey, EVP_md2()))
- lose("could not sign CRL");
- break;
-#endif
-
- case SHA_DIGEST:
- if (!X509_CRL_sign(self->crl, pkey, EVP_sha()))
- lose("could not sign CRL");
- break;
-
- case SHA1_DIGEST:
- if (!X509_CRL_sign(self->crl, pkey, EVP_sha1()))
- lose("could not sign CRL");
- break;
-
- case RIPEMD160_DIGEST:
- if (!X509_CRL_sign(self->crl, pkey, EVP_ripemd160()))
- lose("could not sign CRL");
- break;
-
- case SHA256_DIGEST:
- if (!X509_CRL_sign(self->crl, pkey, EVP_sha256()))
- lose("could not sign CRL");
- break;
-
- case SHA384_DIGEST:
- if (!X509_CRL_sign(self->crl, pkey, EVP_sha384()))
- lose("could not sign CRL");
- break;
-
- case SHA512_DIGEST:
- if (!X509_CRL_sign(self->crl, pkey, EVP_sha512()))
- lose("could not sign CRL");
- break;
- }
-
- Py_RETURN_NONE;
-
- error:
-
- if (pkey)
- EVP_PKEY_free(pkey);
-
- return NULL;
-
-}
-
-static char x509_crl_object_verify__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>verify</name>\n"
-" <parameter>key</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" The <classname>X509Crl</classname> method\n"
-" <function>verify</function> is based on the\n"
-" <function>X509_CRL_verify</function> function. Unlike the\n"
-" <classname>X509</classname> function of the same name, this\n"
-" function simply checks the CRL was signed with the private key\n"
-" which corresponds the parameter <parameter>key</parameter>.\n"
-" <parameter>key</parameter> should be an instance of\n"
-" <classname>Asymmetric</classname> and contain a public key.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_verify(x509_crl_object *self, PyObject *args)
-{
- EVP_PKEY *pkey = NULL;
- asymmetric_object *asym;
- int ok;
-
- if (!PyArg_ParseTuple(args, "O!", &asymmetrictype, &asym))
- goto error;
-
- if ((pkey = EVP_PKEY_new()) == NULL)
- lose("could not allocate memory");
-
- if (!EVP_PKEY_assign_RSA(pkey, asym->cipher))
- lose("EVP_PKEY assignment error");
-
- ok = X509_CRL_verify(self->crl, pkey);
-
- return PyBool_FromLong(ok);
-
- error:
-
- if (pkey)
- EVP_PKEY_free(pkey);
-
- return NULL;
-
-}
-
-static PyObject *
-x509_crl_object_write_helper(x509_crl_object *self, PyObject *args, int format)
-{
- int len = 0, ret = 0;
- char *buf = NULL;
- BIO *out_bio = NULL;
- PyObject *cert = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- out_bio = BIO_new(BIO_s_mem());
-
- switch (format) {
-
- case DER_FORMAT:
- if (!i2d_X509_CRL_bio(out_bio, self->crl))
- lose("unable to write certificate");
- break;
-
- case PEM_FORMAT:
- if (!PEM_write_bio_X509_CRL(out_bio, self->crl))
- lose("unable to write certificate");
-
- default:
- lose("internal error, unknown output format");
- }
-
- if ((len = BIO_ctrl_pending(out_bio)) == 0)
- lose("unable to get bytes stored in bio");
-
- if ((buf = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- if ((ret = BIO_read(out_bio, buf, len)) != len)
- lose("unable to write out cert");
-
- cert = Py_BuildValue("s#", buf, len);
-
- BIO_free(out_bio);
- free(buf);
- return cert;
-
- error:
-
- if (out_bio)
- BIO_free(out_bio);
-
- if (buf)
- free(buf);
-
- return NULL;
-}
-
-static char x509_crl_object_pem_write__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>pemWrite</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a PEM encoded CRL as a\n"
-" string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_pem_write(x509_crl_object *self, PyObject *args)
-{
- return x509_crl_object_write_helper(self, args, PEM_FORMAT);
-}
-
-static char x509_crl_object_der_write__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>derWrite</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a DER encoded CRL as a string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_der_write(x509_crl_object *self, PyObject *args)
-{
- return x509_crl_object_write_helper(self, args, DER_FORMAT);
-}
-
-static char x509_crl_object_pprint__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Crl</memberof>\n"
-" <name>pprint</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a formatted string showing the information\n"
-" held in the CRL.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_crl_object_pprint(x509_crl_object *self, PyObject *args)
-{
- int len = 0, ret = 0;
- char *buf = NULL;
- BIO *out_bio = NULL;
- PyObject *crl = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- out_bio = BIO_new(BIO_s_mem());
-
- if (!X509_CRL_print(out_bio, self->crl))
- lose("unable to write crl");
-
- if ((len = BIO_ctrl_pending(out_bio)) == 0)
- lose("unable to get bytes stored in bio");
-
- if ((buf = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- if ((ret = BIO_read(out_bio, buf, len)) != len)
- lose("unable to write out cert");
-
- crl = Py_BuildValue("s#", buf, len);
-
- BIO_free(out_bio);
- free(buf);
- return crl;
-
- error:
-
- if (out_bio)
- BIO_free(out_bio);
-
- if (buf)
- free(buf);
-
- return NULL;
-
-}
-
-static struct PyMethodDef x509_crl_object_methods[] = {
- {"sign", (PyCFunction)x509_crl_object_sign, METH_VARARGS, NULL},
- {"verify", (PyCFunction)x509_crl_object_verify, METH_VARARGS, NULL},
- {"getVersion", (PyCFunction)x509_crl_object_get_version, METH_VARARGS, NULL},
- {"setVersion", (PyCFunction)x509_crl_object_set_version, METH_VARARGS, NULL},
- {"getIssuer", (PyCFunction)x509_crl_object_get_issuer, METH_VARARGS, NULL},
- {"setIssuer", (PyCFunction)x509_crl_object_set_issuer, METH_VARARGS, NULL},
- {"getThisUpdate", (PyCFunction)x509_crl_object_get_this_update, METH_VARARGS, NULL},
- {"setThisUpdate", (PyCFunction)x509_crl_object_set_this_update, METH_VARARGS, NULL},
- {"getNextUpdate", (PyCFunction)x509_crl_object_get_next_update, METH_VARARGS, NULL},
- {"setNextUpdate", (PyCFunction)x509_crl_object_set_next_update, METH_VARARGS, NULL},
- {"setRevoked", (PyCFunction)x509_crl_object_set_revoked, METH_VARARGS, NULL},
- {"getRevoked", (PyCFunction)x509_crl_object_get_revoked, METH_VARARGS, NULL},
- {"addExtension", (PyCFunction)X509_crl_object_add_extension, METH_VARARGS, NULL},
- {"clearExtensions", (PyCFunction)X509_crl_object_clear_extensions, METH_VARARGS, NULL},
- {"countExtensions", (PyCFunction)X509_crl_object_count_extensions, METH_VARARGS, NULL},
- {"getExtension", (PyCFunction)X509_crl_object_get_extension, METH_VARARGS, NULL},
- {"pemWrite", (PyCFunction)x509_crl_object_pem_write, METH_VARARGS, NULL},
- {"derWrite", (PyCFunction)x509_crl_object_der_write, METH_VARARGS, NULL},
- {"pprint", (PyCFunction)x509_crl_object_pprint, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-x509_crl_object_getattr(x509_crl_object *self, char *name)
-{
- return Py_FindMethod(x509_crl_object_methods, (PyObject *)self, name);
-}
-
-static void
-x509_crl_object_dealloc(x509_crl_object *self, char *name)
-{
- X509_CRL_free(self->crl);
- PyObject_Del(self);
-}
-
-static char x509_crltype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>X509Crl</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides access to OpenSSL X509 CRL management\n"
-" facilities.\n"
-" </para>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject x509_crltype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "X509Crl", /*tp_name*/
- sizeof(x509_crl_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)x509_crl_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)x509_crl_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- x509_crltype__doc__ /* Documentation string */
-};
-/*========== x509 crl Code ==========*/
-
-/*========== revoked Code ==========*/
-x509_revoked_object* x509_revoked_object_new(void)
-{
- x509_revoked_object *self = NULL;
-
- if ((self = PyObject_New(x509_revoked_object, &x509_revokedtype)) == NULL)
- goto error;
-
- self->revoked = X509_REVOKED_new();
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static char x509_revoked_object_set_serial__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <name>setSerial</name>\n"
-" <parameter>serial</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method sets the serial number in the serial field of\n"
-" this object. <parameter>serial</parameter> should be an\n"
-" integer.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_revoked_object_set_serial(x509_revoked_object *self, PyObject *args)
-{
- int serial = 0;
-
- if (!PyArg_ParseTuple(args, "i", &serial))
- goto error;
-
- if (!ASN1_INTEGER_set(self->revoked->serialNumber, serial))
- lose("unable to set serial number");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char x509_revoked_object_get_serial__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <name>getSerial</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method gets the serial number in the serial field of\n"
-" this object.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_revoked_object_get_serial(x509_revoked_object *self, PyObject *args)
-{
- int serial = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((serial = ASN1_INTEGER_get(self->revoked->serialNumber)) == -1)
- lose("unable to get serial number");
-
- return Py_BuildValue("i", serial);
-
- error:
-
- return NULL;
-}
-
-static char x509_revoked_object_get_date__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <name>getDate</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this function returns a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_revoked_object_get_date(x509_revoked_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- return ASN1_TIME_to_Python(self->revoked->revocationDate);
-
- error:
-
- return NULL;
-}
-
-static char x509_revoked_object_set_date__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <name>setDate</name>\n"
-" <parameter>time</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" In a change from previous releases, for reasons of portability\n"
-" and to avoid hard to fix issues with problems in unreliable time\n"
-" functions, this accepts one parameter, a UTCTime string. You\n"
-" can use the function <function>time2utc</function> to convert to a\n"
-" string if you like and <function>utc2time</function> to back.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-x509_revoked_object_set_date(x509_revoked_object *self, PyObject *args)
-{
- char *time = NULL;
-
- if (!PyArg_ParseTuple(args, "s", &time))
- goto error;
-
- if (!python_ASN1_TIME_set_string(self->revoked->revocationDate, time))
- lose_type_error("Could not set revocationDate");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char X509_revoked_object_add_extension__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <name>addExtension</name>\n"
-" <parameter>extensionName</parameter>\n"
-" <parameter>critical</parameter>\n"
-" <parameter>extensionValue</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method adds an extension to this revocation.\n"
-" <parameter>extensionName</parameter> should be the of the\n"
-" extension. <parameter>critical</parameter> should an integer, 1\n"
-" for true and 0 for clase. <parameter>extensionValue</parameter>\n"
-" should be a string, DER encoded value of the extension. The name\n"
-" of the extension must be correct according to OpenSSL and can be\n"
-" checkd in the <constant>objects.h</constant> header file, part of\n"
-" the OpenSSL source distrobution. In the majority of cases they\n"
-" are the same as those defined in <constant>POW._oids</constant>\n"
-" but if you do encounter problems is may be worth checking.\n"
-" </para>\n"
-" <example>\n"
-" <title><function>addExtension</function> method usage</title>\n"
-" <programlisting>\n"
-" reason = POW.pkix.CrlReason()\n"
-" reason.set(1)\n"
-" revocation.addExtension('CRLReason', 0, reason.toString())\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_revoked_object_add_extension(x509_revoked_object *self, PyObject *args)
-{
- int critical = 0, nid = 0, len = 0;
- char *name = NULL;
- unsigned char *buf = NULL;
- ASN1_OCTET_STRING *octetString = NULL;
- X509_EXTENSION *extn = NULL;
-
- if (!PyArg_ParseTuple(args, "sis#", &name, &critical, &buf, &len))
- goto error;
-
- if ((octetString = M_ASN1_OCTET_STRING_new()) == NULL)
- lose("could not allocate memory");
-
- if (!ASN1_OCTET_STRING_set(octetString, buf, strlen((char *) buf)))
- lose("could not set ASN1 Octect string");
-
- if ((nid = OBJ_txt2nid(name)) == NID_undef)
- lose("extension has unknown object identifier");
-
- if ((extn = X509_EXTENSION_create_by_NID(NULL, nid, critical, octetString)) == NULL)
- lose("unable to create ASN1 X509 Extension object");
-
- if (!self->revoked->extensions && (self->revoked->extensions = sk_X509_EXTENSION_new_null()) == NULL)
- lose("unable to allocate memory");
-
- if (!sk_X509_EXTENSION_push(self->revoked->extensions, extn))
- lose("unable to add extension");
-
- Py_RETURN_NONE;
-
- error:
-
- if (extn)
- X509_EXTENSION_free(extn);
-
- return NULL;
-}
-
-static char X509_revoked_object_clear_extensions__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <name>clearExtensions</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method clears the structure which holds the extension for\n"
-" this revocation.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_revoked_object_clear_extensions(x509_revoked_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (self->revoked->extensions) {
- sk_X509_EXTENSION_free(self->revoked->extensions);
- self->revoked->extensions = NULL;
- }
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char X509_revoked_object_count_extensions__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <name>countExtensions</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the size of the structure which holds the\n"
-" extension for this revocation.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_revoked_object_count_extensions(x509_revoked_object *self, PyObject *args)
-{
- int num = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (self->revoked->extensions)
- num = sk_X509_EXTENSION_num(self->revoked->extensions);
-
- return Py_BuildValue("i", num);
-
- error:
-
- return NULL;
-}
-
-static char X509_revoked_object_get_extension__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <name>getExtension</name>\n"
-" <parameter>index</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a tuple equivalent the parameters of\n"
-" <function>addExtension</function>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-X509_revoked_object_get_extension(x509_revoked_object *self, PyObject *args)
-{
- int num = 0, index = 0, ext_nid = 0;
- char const *ext_ln = NULL;
- char unknown_ext [] = "unknown";
- X509_EXTENSION *ext;
-
- if (!PyArg_ParseTuple(args, "i", &index))
- goto error;
-
- if (self->revoked->extensions)
- num = sk_X509_EXTENSION_num(self->revoked->extensions);
-
- if (index >= num)
- lose("certificate does not have that many extensions");
-
- if ((ext = sk_X509_EXTENSION_value(self->revoked->extensions, index)) == NULL)
- lose("could not get extension");
-
- if ((ext_nid = OBJ_obj2nid(ext->object)) == NID_undef)
- lose("extension has unknown object identifier");
-
- if ((ext_ln = OBJ_nid2sn(ext_nid)) == NULL)
- ext_ln = unknown_ext;
-
- return Py_BuildValue("sis#", ext_ln, ext->critical, ext->value->data, ext->value->length);
-
- error:
-
- return NULL;
-}
-
-static struct PyMethodDef x509_revoked_object_methods[] = {
- {"getSerial", (PyCFunction)x509_revoked_object_get_serial, METH_VARARGS, NULL},
- {"setSerial", (PyCFunction)x509_revoked_object_set_serial, METH_VARARGS, NULL},
- {"getDate", (PyCFunction)x509_revoked_object_get_date, METH_VARARGS, NULL},
- {"setDate", (PyCFunction)x509_revoked_object_set_date, METH_VARARGS, NULL},
- {"addExtension", (PyCFunction)X509_revoked_object_add_extension, METH_VARARGS, NULL},
- {"clearExtensions", (PyCFunction)X509_revoked_object_clear_extensions, METH_VARARGS, NULL},
- {"countExtensions", (PyCFunction)X509_revoked_object_count_extensions, METH_VARARGS, NULL},
- {"getExtension", (PyCFunction)X509_revoked_object_get_extension, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-x509_revoked_object_getattr(x509_revoked_object *self, char *name)
-{
- return Py_FindMethod(x509_revoked_object_methods, (PyObject *) self, name);
-}
-
-static void
-x509_revoked_object_dealloc(x509_revoked_object *self, char *name)
-{
- X509_REVOKED_free(self->revoked);
- PyObject_Del(self);
-}
-
-static char x509_revokedtype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>X509Revoked</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides a container for details of a revoked\n"
-" certificate. It normally would only be used in association with\n"
-" a CRL, its not much use by itself. Indeed the only reason this\n"
-" class exists is because in the future POW is likely to be extended\n"
-" to support extensions for certificates, CRLs and revocations.\n"
-" <classname>X509Revoked</classname> existing as an object in its\n"
-" own right will make adding this support easier, while avoiding\n"
-" backwards compatibility issues.\n"
-" </para>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject x509_revokedtype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "X509Revoked", /*tp_name*/
- sizeof(x509_revoked_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)x509_revoked_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)x509_revoked_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- x509_revokedtype__doc__ /* Documentation string */
-};
-/*========== x509 revoked Code ==========*/
-
-/*========== ssl Code ==========*/
-static char ssl_object_use_certificate__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>useCertificate</name>\n"
-" <parameter>cert</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" The parameter <parameter>cert</parameter> must be an\n"
-" instance of the <classname>X590</classname> class and must be\n"
-" called before <function>setFd</function>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_use_certificate(ssl_object *self, PyObject *args)
-{
- x509_object *x509 = NULL;
-
- if (!PyArg_ParseTuple(args, "O!", &x509type, &x509))
- goto error;
-
- if (self->ctxset)
- lose("cannot be called after setFd()");
-
- if (!SSL_CTX_use_certificate(self->ctx, x509->x509))
- lose("could not use certificate");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static PyObject *
-ssl_object_add_certificate(ssl_object *self, PyObject *args)
-{
- x509_object *x509 = NULL;
- X509 *x = NULL;
-
- if (!PyArg_ParseTuple(args, "O!", &x509type, &x509))
- goto error;
-
- if (self->ctxset)
- lose("cannot be called after setFd()");
-
- if ((x = X509_dup(x509->x509)) == NULL)
- lose("could not duplicate X509 object");
-
- if (!SSL_CTX_add_extra_chain_cert(self->ctx, x))
- lose_openssl_error("Could not add certificate");
-
- x = NULL;
-
- Py_RETURN_NONE;
-
- error:
-
- if (x)
- X509_free(x);
-
- return NULL;
-}
-
-static PyObject *
-ssl_object_add_trust(ssl_object *self, PyObject *args)
-{
- x509_object *x509 = NULL;
- X509 *x = NULL;
-
- if (!PyArg_ParseTuple(args, "O!", &x509type, &x509))
- goto error;
-
- if (self->ctxset)
- lose("Cannot be called after setFd()");
-
- if (self->trusted_certs == NULL &&
- (self->trusted_certs = sk_X509_new_null()) == NULL)
- lose("Couldn't allocate trusted certificate stack");
-
- if ((x = X509_dup(x509->x509)) == NULL)
- lose("Couldn't duplicate X509 object");
-
- if (!sk_X509_push(self->trusted_certs, x))
- lose("Couldn't push cert onto trusted certificate stack");
-
- x = NULL;
-
- Py_RETURN_NONE;
-
- error:
-
- if (x)
- X509_free(x);
-
- return NULL;
-}
-
-static char ssl_object_use_key__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>useKey</name>\n"
-" <parameter>key</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" The parameter <parameter>key</parameter> must be an\n"
-" instance of the <classname>Asymmetric</classname> class and\n"
-" must contain the private key. This function cannot be called\n"
-" after <function>useKey</function>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_use_key(ssl_object *self, PyObject *args)
-{
- asymmetric_object *asym = NULL;
- EVP_PKEY *pkey = NULL;
-
- if (!PyArg_ParseTuple(args, "O!", &asymmetrictype, &asym))
- goto error;
-
- if (self->ctxset)
- lose("cannot be called after setFd()");
-
- if ((pkey = EVP_PKEY_new()) == NULL)
- lose("could not allocate memory");
-
- if (asym->key_type != RSA_PRIVATE_KEY)
- lose("cannot use this type of key");
-
- if (!EVP_PKEY_set1_RSA(pkey, asym->cipher))
- lose("EVP_PKEY assignment error");
-
- if (!SSL_CTX_use_PrivateKey(self->ctx, pkey))
- lose("ctx key assignment error");
-
- Py_RETURN_NONE;
-
- error:
-
- if(pkey)
- EVP_PKEY_free(pkey);
-
- return NULL;
-}
-
-static char ssl_object_check_key__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>checkKey</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This simple method will return 1 if the public key, contained in\n"
-" the X509 certificate this <classname>Ssl</classname> instance is using,\n"
-" matches the private key this <classname>Ssl</classname> instance is using.\n"
-" Otherwise it will return 0.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_check_key(ssl_object *self, PyObject *args)
-{
- return PyBool_FromLong(SSL_CTX_check_private_key(self->ctx));
-}
-
-static char ssl_object_set_fd__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>setFd</name>\n"
-" <parameter>descriptor</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function is used to associate a file descriptor with a\n"
-" <classname>Ssl</classname> object. The file descriptor should\n"
-" belong to an open TCP connection. Once this function has\n"
-" been called, calling <function>useKey</function> or\n"
-" <function>useCertificate</function> will, fail rasing exceptions.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_set_fd(ssl_object *self, PyObject *args)
-{
- int fd = 0, self_index = 0;
-
- if (!PyArg_ParseTuple(args, "i", &fd))
- goto error;
-
- if ((self->ssl = SSL_new(self->ctx)) == NULL)
- lose("Unable to create ssl structure");
-
- SSL_set_mode(self->ssl, (SSL_MODE_ENABLE_PARTIAL_WRITE |
- SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER));
-
- if (!SSL_set_fd(self->ssl, fd))
- lose("Unable to set file descriptor");
-
- if ((self_index = SSL_get_ex_new_index(0, "self_index", NULL, NULL, NULL)) != -1)
- SSL_set_ex_data(self->ssl, self_index, self);
- else
- lose("Unable to create ex data index");
-
- self->ctxset = 1;
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char ssl_object_fileno__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>fileno</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function is used to extract the file descriptor associated\n"
-" with a <classname>Ssl</classname> object.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_fileno(ssl_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- return Py_BuildValue("i", SSL_get_fd(self->ssl));
-
- error:
-
- return NULL;
-}
-
-static char ssl_object_accept__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>accept</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function will attempt the SSL level accept with a\n"
-" client. The <classname>Ssl</classname> object must have been\n"
-" created using a <constant>XXXXX_SERVER_METHOD</constant> or\n"
-" a <constant>XXXXX_METHOD</constant> and this function should only be\n"
-" called after <function>useKey</function>,\n"
-" <function>useCertificate</function> and\n"
-" <function>setFd</function> functions have been called.\n"
-" </para>\n"
-"\n"
-" <example>\n"
-" <title><function>accept</function> function usage</title>\n"
-" <programlisting>\n"
-" keyFile = open('test/private.key', 'r')\n"
-" certFile = open('test/cacert.pem', 'r')\n"
-"\n"
-" rsa = POW.pemRead(POW.RSA_PRIVATE_KEY, keyFile.read(), 'pass')\n"
-" x509 = POW.pemRead(POW.X509_CERTIFICATE, certFile.read())\n"
-"\n"
-" keyFile.close()\n"
-" certFile.close()\n"
-"\n"
-" sl = POW.Ssl(POW.SSLV23_SERVER_METHOD)\n"
-" sl.useCertificate(x509)\n"
-" sl.useKey(rsa)\n"
-"\n"
-" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n"
-" s.bind(('localhost', 1111))\n"
-" s.listen(5)\n"
-" s2, addr = s.accept()\n"
-"\n"
-" s.close()\n"
-"\n"
-" sl.setFd(s2.fileno())\n"
-" sl.accept()\n"
-" print sl.read(1024)\n"
-" sl.write('Message from server to client...')\n"
-"\n"
-" s2.close()\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_accept(ssl_object *self, PyObject *args)
-{
- int ret = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- Py_BEGIN_ALLOW_THREADS;
- ret = SSL_accept(self->ssl);
- Py_END_ALLOW_THREADS;
-
- if (ret <= 0)
- lose_ssl_error(self, ret);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char ssl_object_connect__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>connect</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function will attempt the SSL level connection with a\n"
-" server. The <classname>Ssl</classname> object must have been\n"
-" created using a <constant>XXXXX_CLIENT_METHOD</constant> or\n"
-" a <constant>XXXXX_METHOD</constant> and this function should only be\n"
-" called after <function>setFd</function> has already been\n"
-" called.\n"
-" </para>\n"
-"\n"
-" <example>\n"
-" <title><function>connect</function> function usage</title>\n"
-" <programlisting>\n"
-" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n"
-" s.connect(('localhost', 1111))\n"
-"\n"
-" sl = POW.Ssl(POW.SSLV23_CLIENT_METHOD)\n"
-" sl.setFd(s.fileno())\n"
-" sl.connect()\n"
-" sl.write('Message from client to server...')\n"
-" print sl.read(1024)\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_connect(ssl_object *self, PyObject *args)
-{
- int ret;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- Py_BEGIN_ALLOW_THREADS;
- ret = SSL_connect(self->ssl);
- Py_END_ALLOW_THREADS;
-
- if (ret <= 0)
- lose_ssl_error(self, ret);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char ssl_object_write__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>write</name>\n"
-" <parameter>string</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method writes the <parameter>string</parameter> to the\n"
-" <classname>Ssl</classname> object, to be read by it's peer. This\n"
-" function is analogous to the <classname>socket</classname>\n"
-" classes <function>write</function> function.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_write(ssl_object *self, PyObject *args)
-{
- char *msg;
- int length = 0, ret = 0;
-
- if (!PyArg_ParseTuple(args, "s#", &msg, &length))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- Py_BEGIN_ALLOW_THREADS;
- ret = SSL_write(self->ssl, msg, length);
- Py_END_ALLOW_THREADS;
-
- if (ret <= 0)
- lose_ssl_error(self, ret);
-
- return Py_BuildValue("i", ret);
-
- error:
-
- return NULL;
-}
-
-static char ssl_object_read__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>read</name>\n"
-" <parameter>amount = 1024</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method reads up to <parameter>amount</parameter> characters from the\n"
-" <classname>Ssl</classname> object. This\n"
-" function is analogous to the <classname>socket</classname>\n"
-" classes <function>read</function> function.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_read(ssl_object *self, PyObject *args)
-{
- PyObject *data;
- char *msg = NULL;
- int len = 1024, ret = 0;
-
- if (!PyArg_ParseTuple(args, "|i", &len))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- if ((msg = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- Py_BEGIN_ALLOW_THREADS;
- ret = SSL_read(self->ssl, msg, len);
- Py_END_ALLOW_THREADS;
-
- if (ret <= 0)
- lose_ssl_error(self, ret);
-
- data = Py_BuildValue("s#", msg, ret);
-
- free(msg);
- return data;
-
- error:
-
- if (msg)
- free(msg);
-
- return NULL;
-}
-
-static char ssl_object_peer_certificate__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>peerCertificate</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns any peer certificate presented in the initial\n"
-" SSL negotiation or <constant>None</constant>. If a certificate is\n"
-" returned, it will be an instance of <classname>X509</classname>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_peer_certificate(ssl_object *self, PyObject *args)
-{
- X509 *x509 = NULL;
- x509_object *x509_obj = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- if ((x509_obj = X509_object_new()) == NULL)
- lose("could not create x509 object");
-
- x509 = SSL_get_peer_certificate(self->ssl);
-
- if (x509) {
- X509_free(x509_obj->x509);
- x509_obj->x509 = x509;
- return (PyObject *) x509_obj;
- }
- else {
- Py_XDECREF(x509_obj);
- Py_RETURN_NONE;
- }
-
- error:
-
- if (x509)
- X509_free(x509);
-
- Py_XDECREF(x509_obj);
- return NULL;
-}
-
-static char ssl_object_clear__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>clear</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method will clear the SSL session ready for\n"
-" a new SSL connection. It will not effect the underlying socket.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_clear(ssl_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- if (!SSL_clear(self->ssl))
- lose("failed to clear ssl connection");
-
- if (self->x509_cb_err) {
- free(self->x509_cb_err);
- self->x509_cb_err = NULL;
- }
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char ssl_object_shutdown__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>shutdown</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method will issue a <constant>shutdown</constant> signal to it's peer.\n"
-" If this connection's peer has already initiated a shutdown this call\n"
-" will succeed, otherwise it will raise and exception. In order to\n"
-" check the shutdown handshake was successful,\n"
-" <function>shutdown</function> must be called again. If no\n"
-" exception is raised, the handshake is complete.\n"
-" </para>\n"
-" <para>\n"
-" The odd\n"
-" implementation of this function reflects the underlying OpenSSL\n"
-" function, which reflects the SSL protocol. Although rasing an\n"
-" exception is a bit annoying, the alternative, returning true all\n"
-" false will not tell you why the call failed and the exception\n"
-" will, at least that is the theory. Look up the exact meaning\n"
-" of the exceptions in the OpenSSL man page SSL_get_error.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_shutdown(ssl_object *self, PyObject *args)
-{
- int ret = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- ret = SSL_shutdown(self->ssl);
-
- /*
- * The original POW behavior here seems nuts to me. SSL_shutdown()
- * returns a tristate:
- *
- * 1: fully closed
- * 0: close notification sent, waiting for peer
- * -1: error, WANT_READ, or WANT_WRITE
- *
- * Doc claims the protocol allows us to bail on 0 return if we don't
- * want to wait. So the "obvious" thing to do here is return boolean
- * for 1 or 0 and raise an exception for -1. Original author's explanation
- * for why he didn't do that makes no sense to me, so I've changed it.
- */
-
- if (ret < 0)
- lose_ssl_error(self, ret);
-
- return PyBool_FromLong(ret);
-
- error:
-
- return NULL;
-}
-
-static char ssl_object_get_shutdown__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>getShutdown</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function returns an integer indicating the state of the\n"
-" SSL connection. <constant>SSL_RECEIVED_SHUTDOWN</constant>\n"
-" will be set the if it's peer sends a <constant>shutdown</constant>\n"
-" signal or the underlying socket\n"
-" receives a close notify . The possible values are:\n"
-" </para>\n"
-" <simplelist>\n"
-" <member><constant>SSL_NO_SHUTDOWN</constant></member>\n"
-" <member><constant>SSL_SENT_SHUTDOWN</constant></member>\n"
-" <member><constant>SSL_RECEIVED_SHUTDOWN</constant></member>\n"
-" <member><constant>SSL_SENT_SHUTDOWN</constant> | <constant>SSL_RECEIVED_SHUTDOWN</constant></member>\n"
-" </simplelist>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_get_shutdown(ssl_object *self, PyObject *args)
-{
- int state = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- state = SSL_get_shutdown(self->ssl);
-
- return Py_BuildValue("i", state);
-
- error:
-
- return NULL;
-}
-
-static char ssl_object_get_ciphers__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>getCiphers</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function returns a list of available ciphers ordered from\n"
-" most favored to least. This function must be called after\n"
-" <function>setFd</function>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_get_ciphers(ssl_object *self, PyObject *args)
-{
- int i = 0;
- const char *cipher = NULL;
- PyObject *list = NULL, *name = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- list = PyList_New(0);
-
- cipher = SSL_get_cipher_list(self->ssl, 0);
- while (cipher) {
- if ((name = PyString_FromString(cipher)) == NULL)
- goto error;
- if (PyList_Append(list, name) != 0)
- goto error;
- Py_XDECREF(name);
- name = NULL;
- cipher = SSL_get_cipher_list(self->ssl, ++i);
- }
- return list;
-
- error:
-
- Py_XDECREF(name);
- Py_XDECREF(list);
- return NULL;
-}
-
-static char ssl_object_set_ciphers__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>setCiphers</name>\n"
-" <parameter>ciphers</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" <function>setCiphers</function>\n"
-" can help protect against certain types of attacks which try to\n"
-" coerce the server, client or both to negotiate a weak cipher.\n"
-" <parameter>ciphers</parameter> should be a list of strings, as\n"
-" produced by <function>getCiphers</function> and described in the\n"
-" OpenSSL man page ciphers. <function>setCiphers</function> should\n"
-" only be called after <function>setFd</function>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_set_ciphers(ssl_object *self, PyObject *args)
-{
- PyObject *ciphers = NULL;
- PyObject *cipher = NULL;
- int size = 0, cipherstrlen = 0, nextstrlen = 0, i = 0;
- char *cipherstr = NULL;
-
- if (!PyArg_ParseTuple(args, "O", &ciphers))
- goto error;
-
- if (!PyList_Check(ciphers) && !PyTuple_Check(ciphers))
- lose_type_error("inapropriate type");
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- cipherstr = malloc(8); // Very bogus, realloc() dosn't work without some
- // previously allocated memory! Really should.
- memset(cipherstr, 0, 8);
- size = PySequence_Size(ciphers);
- for (i = 0; i < size; i++) {
- if ((cipher = PySequence_GetItem(ciphers, i)) == NULL)
- goto error;
-
- if (!PyString_Check(cipher))
- lose_type_error("inapropriate type");
-
- cipherstrlen = strlen(cipherstr);
- nextstrlen = strlen(PyString_AsString(cipher));
-
- if ((cipherstr = realloc(cipherstr, cipherstrlen + nextstrlen + 2)) == NULL)
- lose_type_error("could allocate memory");
-
- if (cipherstrlen)
- strcat(cipherstr, ":\0");
-
- strcat(cipherstr, PyString_AsString(cipher));
- Py_XDECREF(cipher);
- cipher = NULL;
- }
- SSL_set_cipher_list(self->ssl, cipherstr);
- free(cipherstr);
- Py_RETURN_NONE;
-
- error:
-
- if (cipherstr)
- free(cipherstr);
-
- Py_XDECREF(cipher);
-
- return NULL;
-}
-
-static char ssl_object_get_cipher__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>getCipher</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function returns the current cipher in use.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_get_cipher(ssl_object *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if (!self->ctxset)
- lose("cannot be called before setFd()");
-
- return Py_BuildValue("s", SSL_get_cipher(self->ssl));
-
- error:
-
- return NULL;
-}
-
-static int ssl_object_verify_callback(X509_STORE_CTX *ctx, void *arg)
-{
- ssl_object *self = arg;
- int ok;
-
- if (self->trusted_certs)
- X509_STORE_CTX_trusted_stack(ctx, self->trusted_certs);
-
- if (self->x509_cb_err) {
- free(self->x509_cb_err);
- self->x509_cb_err = NULL;
- }
-
- ok = X509_verify_cert(ctx) == 1;
-
- if (!ok) {
-
- /*
- * We probably should be pushing out structured Python data here
- * rather than a string, but we're pretty deep in the OpenSSL call
- * chain at this point and I'd rather not risk whacky interactions
- * with the Python garbage collector. Try this kludge initially,
- * rewrite as something better later if it looks worth the effort.
- */
-
- BIO *b = BIO_new(BIO_s_mem());
- char *buf = NULL;
- int len;
-
- if (!b)
- goto fail;
-
- BIO_puts(b, "TLS validation failure:\n\n");
-
- if (self->trusted_certs) {
- int i;
- BIO_puts(b, "Trusted cert stack\n");
- for (i = 0; i < sk_X509_num(self->trusted_certs); i++) {
- X509 *x = sk_X509_value(self->trusted_certs, i);
- BIO_printf(b, "[%d] ", i);
- if (x)
- X509_print(b, x);
- else
- BIO_puts(b, "<NULL>!\n");
- }
- } else {
- BIO_puts(b, "No trusted cert stack\n");
- }
-
- BIO_printf(b,
- "\nX509_verify_cert() error: error depth %d error %d current_cert %p current_issuer %p current_crl %p: %s\n",
- ctx->error_depth,
- ctx->error,
- ctx->current_cert,
- ctx->current_issuer,
- ctx->current_crl,
- X509_verify_cert_error_string(ctx->error));
- if (ctx->current_cert)
- X509_print(b, ctx->current_cert);
-
- /* This seems to be returning garbage, don't know why */
- if (ctx->current_issuer)
- X509_print(b, ctx->current_issuer);
-
- if ((len = BIO_ctrl_pending(b)) == 0 || (buf = malloc(len + 1)) == NULL)
- goto fail;
-
- if (BIO_read(b, buf, len) == len) {
- buf[len] = '\0';
- self->x509_cb_err = buf;
- } else {
- free(buf);
- }
-
- fail:
- BIO_free(b);
- }
-
- return ok;
-}
-
-static char ssl_object_set_verify_mode__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <name>setVerifyMode</name>\n"
-" <parameter>mode</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function sets the behavior of the SSL handshake. The\n"
-" parameter <parameter>mode</parameter> should be one of the\n"
-" following:\n"
-" </para>\n"
-" <simplelist>\n"
-" <member><constant>SSL_VERIFY_NONE</constant></member>\n"
-" <member><constant>SSL_VERIFY_PEER</constant></member>\n"
-" <member><constant>SSL_VERIFY_PEER</constant> |\n"
-" <constant>SSL_VERIFY_FAIL_IF_NO_PEER_CERT</constant></member>\n"
-" </simplelist>\n"
-" <para>\n"
-" See the OpenSSL man page <function>SSL_CTX_set_verify</function>\n"
-" for details. This function must be called after <function>setfd</function>\n"
-" has been called.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-ssl_object_set_verify_mode(ssl_object *self, PyObject *args)
-{
- int mode = 0;
-
- if (!PyArg_ParseTuple(args, "i", &mode))
- goto error;
-
- if (self->ctxset)
- lose("cannot be called after setfd()");
-
- SSL_CTX_set_verify(self->ctx, mode, NULL);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static struct PyMethodDef ssl_object_methods[] = {
- {"useCertificate", (PyCFunction)ssl_object_use_certificate, METH_VARARGS, NULL},
- {"addCertificate", (PyCFunction)ssl_object_add_certificate, METH_VARARGS, NULL},
- {"addTrust", (PyCFunction)ssl_object_add_trust, METH_VARARGS, NULL},
- {"useKey", (PyCFunction)ssl_object_use_key, METH_VARARGS, NULL},
- {"checkKey", (PyCFunction)ssl_object_check_key, METH_VARARGS, NULL},
- {"setFd", (PyCFunction)ssl_object_set_fd, METH_VARARGS, NULL},
- {"fileno", (PyCFunction)ssl_object_fileno, METH_VARARGS, NULL},
- {"connect", (PyCFunction)ssl_object_connect, METH_VARARGS, NULL},
- {"accept", (PyCFunction)ssl_object_accept, METH_VARARGS, NULL},
- {"write", (PyCFunction)ssl_object_write, METH_VARARGS, NULL},
- {"read", (PyCFunction)ssl_object_read, METH_VARARGS, NULL},
- {"peerCertificate", (PyCFunction)ssl_object_peer_certificate, METH_VARARGS, NULL},
- {"clear", (PyCFunction)ssl_object_clear, METH_VARARGS, NULL},
- {"shutdown", (PyCFunction)ssl_object_shutdown, METH_VARARGS, NULL},
- {"getShutdown", (PyCFunction)ssl_object_get_shutdown, METH_VARARGS, NULL},
- {"getCiphers", (PyCFunction)ssl_object_get_ciphers, METH_VARARGS, NULL},
- {"setCiphers", (PyCFunction)ssl_object_set_ciphers, METH_VARARGS, NULL},
- {"getCipher", (PyCFunction)ssl_object_get_cipher, METH_VARARGS, NULL},
- {"setVerifyMode", (PyCFunction)ssl_object_set_verify_mode, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static ssl_object *
-newssl_object(int type)
-{
- ssl_object *self;
- const SSL_METHOD *method;
-
-
- if ((self = PyObject_NEW(ssl_object, &ssltype)) == NULL)
- goto error;
-
- self->ctxset = 0;
- self->ssl = NULL;
- self->trusted_certs = NULL;
- self->x509_cb_err = NULL;
-
- switch (type) {
- case SSLV2_SERVER_METHOD: method = SSLv2_server_method(); break;
- case SSLV2_CLIENT_METHOD: method = SSLv2_client_method(); break;
- case SSLV2_METHOD: method = SSLv2_method(); break;
- case SSLV3_SERVER_METHOD: method = SSLv3_server_method(); break;
- case SSLV3_CLIENT_METHOD: method = SSLv3_client_method(); break;
- case SSLV3_METHOD: method = SSLv3_method(); break;
- case TLSV1_SERVER_METHOD: method = TLSv1_server_method(); break;
- case TLSV1_CLIENT_METHOD: method = TLSv1_client_method(); break;
- case TLSV1_METHOD: method = TLSv1_method(); break;
- case SSLV23_SERVER_METHOD: method = SSLv23_server_method(); break;
- case SSLV23_CLIENT_METHOD: method = SSLv23_client_method(); break;
- case SSLV23_METHOD: method = SSLv23_method(); break;
-
- default:
- lose("unknown ctx method");
- }
-
- if ((self->ctx = SSL_CTX_new(method)) == NULL)
- lose("unable to create new ctx");
-
- SSL_CTX_set_cert_verify_callback(self->ctx, ssl_object_verify_callback, self);
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static PyObject *
-ssl_object_getattr(ssl_object *self, char *name)
-{
- return Py_FindMethod(ssl_object_methods, (PyObject *)self, name);
-}
-
-static void
-ssl_object_dealloc(ssl_object *self)
-{
- SSL_free(self->ssl);
- SSL_CTX_free(self->ctx);
- if (self->trusted_certs)
- sk_X509_pop_free(self->trusted_certs, X509_free);
- if (self->x509_cb_err)
- free(self->x509_cb_err);
- PyObject_Del(self);
-}
-
-static char ssltype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>Ssl</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides access to the Secure Socket Layer\n"
-" functionality of OpenSSL. It is designed to be a simple as\n"
-" possible to use and is not designed for high performance\n"
-" applications which handle many simultaneous connections. The\n"
-" original motivation for writing this library was to provide a\n"
-" security layer for network agents written in Python, for this\n"
-" application, good performance with multiple concurrent connections\n"
-" is not an issue.\n"
-" </para>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject ssltype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "Ssl", /*tp_name*/
- sizeof(ssl_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)ssl_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)ssl_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- ssltype__doc__ /* Documentation string */
-};
-/*========== ssl Object ==========*/
-
-/*========== asymmetric Object ==========*/
-static asymmetric_object *
-asymmetric_object_new(int cipher_type, int key_size)
-{
- asymmetric_object *self = NULL;
-
- self = PyObject_New(asymmetric_object, &asymmetrictype);
- if (self == NULL)
- goto error;
-
- if (cipher_type != RSA_CIPHER)
- lose("unsupported cipher");
-
- if ((self->cipher = RSA_generate_key(key_size,RSA_F4,NULL,NULL)) == NULL)
- lose("could not generate key");
-
- self->key_type = RSA_PRIVATE_KEY;
- self->cipher_type = RSA_CIPHER;
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static asymmetric_object *
-asymmetric_object_pem_read(int key_type, BIO *in, char *pass)
-{
- asymmetric_object *self = NULL;
-
- self = PyObject_New(asymmetric_object, &asymmetrictype);
- if (self == NULL)
- goto error;
-
- switch (key_type) {
-
- case RSA_PUBLIC_KEY:
- if ((self->cipher = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL)) == NULL)
- lose("could not load public key");
- self->key_type = RSA_PUBLIC_KEY;
- self->cipher_type = RSA_CIPHER;
- break;
-
- case RSA_PRIVATE_KEY:
- if ((self->cipher = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, pass)) == NULL)
- lose("could not load private key");
- self->key_type = RSA_PRIVATE_KEY;
- self->cipher_type = RSA_CIPHER;
- break;
-
- default:
- lose("unknown key type");
- }
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static asymmetric_object *
-asymmetric_object_der_read(int key_type, unsigned char *src, int len)
-{
- asymmetric_object *self = NULL;
- unsigned char *ptr = src;
-
- self = PyObject_New(asymmetric_object, &asymmetrictype);
- if (self == NULL)
- goto error;
-
- switch (key_type) {
- case RSA_PUBLIC_KEY:
-
- if ((self->cipher = d2i_RSA_PUBKEY(NULL, (const unsigned char **) &ptr, len)) == NULL)
- lose("could not load public key");
-
- self->key_type = RSA_PUBLIC_KEY;
- self->cipher_type = RSA_CIPHER;
- break;
-
- case RSA_PRIVATE_KEY:
-
- if ((self->cipher = d2i_RSAPrivateKey(NULL, (const unsigned char **) &ptr, len)) == NULL)
- lose("could not load private key");
-
- self->key_type = RSA_PRIVATE_KEY;
- self->cipher_type = RSA_CIPHER;
- break;
-
- default:
- lose("unknown key type");
- }
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static char asymmetric_object_pem_write__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Asymmetric</memberof>\n"
-" <name>pemWrite</name>\n"
-" <parameter>keytype</parameter>\n"
-" <parameter>ciphertype = None</parameter>\n"
-" <parameter>passphrase = None</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to write <classname>Asymmetric</classname>\n"
-" objects out as strings. The first argument should be either\n"
-" <constant>RSA_PUBLIC_KEY</constant> or\n"
-" <constant>RSA_PRIVATE_KEY</constant>. Private keys are often\n"
-" saved in encrypted files to offer extra security above access\n"
-" control mechanisms. If the <parameter>keytype</parameter> is\n"
-" <constant>RSA_PRIVATE_KEY</constant> a\n"
-" <parameter>ciphertype</parameter> and\n"
-" <parameter>passphrase</parameter> can also be specified. The\n"
-" <parameter>ciphertype</parameter> should be one of those listed in\n"
-" the <classname>Symmetric</classname> class section.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-asymmetric_object_pem_write(asymmetric_object *self, PyObject *args)
-{
- int key_type = 0, cipher = 0, len = 0, ret = 0;
- char *kstr = NULL, *buf = NULL;
- BIO *out_bio = NULL;
- PyObject *asymmetric = NULL;
-
- if (!PyArg_ParseTuple(args, "|iis", &key_type, &cipher, &kstr))
- goto error;
-
- if (key_type == 0)
- key_type = self->key_type;
-
- if ((out_bio = BIO_new(BIO_s_mem())) == NULL)
- lose("unable to create new BIO");
-
- if ((kstr && !cipher) || (cipher && !kstr))
- lose("cipher type and key string must both be supplied");
-
- switch(key_type) {
-
- case RSA_PRIVATE_KEY:
- if (kstr && cipher) {
- if (!PEM_write_bio_RSAPrivateKey(out_bio, self->cipher, evp_cipher_factory(cipher), NULL, 0, NULL, kstr))
- lose("unable to write key");
- }
- else {
- if (!PEM_write_bio_RSAPrivateKey(out_bio, self->cipher, NULL, NULL, 0, NULL, NULL))
- lose("unable to write key");
- }
- break;
-
- case RSA_PUBLIC_KEY:
- if (kstr && cipher)
- lose("public keys should not encrypted");
- else {
- if (!PEM_write_bio_RSA_PUBKEY(out_bio, self->cipher))
- lose("unable to write key");
- }
- break;
-
- default:
- lose("unsupported key type");
- }
-
- if ((len = BIO_ctrl_pending(out_bio)) == 0)
- lose("unable to get number of bytes in bio");
-
- if ((buf = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- if ((ret = BIO_read(out_bio, buf, len)) != len)
- lose("unable to write out key");
-
- asymmetric = Py_BuildValue("s#", buf, len);
-
- BIO_free(out_bio);
- free(buf);
- return asymmetric;
-
- error:
-
- if (out_bio);
- BIO_free(out_bio);
-
- if (buf)
- free(buf);
-
- return NULL;
-}
-
-static char asymmetric_object_der_write__doc__[] =
-"<method>"
-" <header>"
-" <memberof>Asymmetric</memberof>"
-" <name>derWrite</name>"
-" <parameter>keytype</parameter>"
-" </header>"
-" <body>"
-" <para>"
-" This method is used to write <classname>Asymmetric</classname>"
-" objects out as strings. The first argument should be either"
-" <constant>RSA_PUBLIC_KEY</constant> or "
-" <constant>RSA_PRIVATE_KEY</constant>."
-" </para>"
-" </body>"
-"</method>"
-;
-
-static PyObject *
-asymmetric_object_der_write(asymmetric_object *self, PyObject *args)
-{
- int len = 0, key_type = 0;
- unsigned char *buf = NULL, *p = NULL;
- PyObject *asymmetric = NULL;
-
- if (!PyArg_ParseTuple(args, "|i", &key_type))
- goto error;
-
- if (key_type == 0)
- key_type = self->key_type;
-
- switch(key_type) {
-
- case RSA_PRIVATE_KEY:
- len = i2d_RSAPrivateKey(self->cipher, NULL);
- if ((buf = malloc(len)) == NULL)
- lose("could not allocate memory");
- p = buf;
- if (!i2d_RSAPrivateKey(self->cipher, &buf))
- lose("unable to write key");
- break;
-
- case RSA_PUBLIC_KEY:
- len = i2d_RSA_PUBKEY(self->cipher, NULL);
- if ((buf = malloc(len)) == NULL)
- lose("could not allocate memory");
- p = buf;
- if (!i2d_RSA_PUBKEY(self->cipher, &buf))
- lose("unable to write key");
- break;
-
- default:
- lose("unsupported key type");
- }
-
- asymmetric = Py_BuildValue("s#", p, len);
-
- free(p);
- return asymmetric;
-
- error:
-
- if (p)
- free(p);
-
- return NULL;
-}
-
-static char asymmetric_object_public_encrypt__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Asymmetric</memberof>\n"
-" <name>publicEncrypt</name>\n"
-" <parameter>plaintext</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to encrypt the <parameter>plaintext</parameter>\n"
-" using a public key. It should be noted; in practice this\n"
-" function would be used almost exclusively to encrypt symmetric cipher\n"
-" keys and not data since asymmetric cipher operations are very slow.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-asymmetric_object_public_encrypt(asymmetric_object *self, PyObject *args)
-{
- unsigned char *plain_text = NULL, *cipher_text = NULL;
- int len = 0, size = 0;
- PyObject *obj = NULL;
-
- if (self->cipher_type != RSA_CIPHER)
- lose("unsupported cipher type");
-
- if (!PyArg_ParseTuple(args, "s#", &plain_text, &len))
- goto error;
-
- size = RSA_size(self->cipher);
- if (len > size)
- lose("plain text is too long");
-
- if ((cipher_text = malloc(size + 16)) == NULL)
- lose("could not allocate memory");
-
- if ((len = RSA_public_encrypt(len, plain_text, cipher_text, self->cipher, RSA_PKCS1_PADDING)) < 0)
- lose("could not encrypt plain text");
-
- obj = Py_BuildValue("s#", cipher_text, len);
- free(cipher_text);
- return obj;
-
- error:
-
- if (cipher_text)
- free(cipher_text);
-
- return NULL;
-}
-
-static char asymmetric_object_private_encrypt__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Asymmetric</memberof>\n"
-" <name>privateEncrypt</name>\n"
-" <parameter>plaintext</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to encrypt the <parameter>plaintext</parameter>\n"
-" using a private key. It should be noted; in practice this\n"
-" function would be used almost exclusively to encrypt symmetric cipher\n"
-" keys and not data since asymmetric cipher operations are very slow.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-asymmetric_object_private_encrypt(asymmetric_object *self, PyObject *args)
-{
- unsigned char *plain_text = NULL, *cipher_text = NULL;
- int len = 0, size = 0;
- PyObject *obj = NULL;
-
- if (self->key_type != RSA_PRIVATE_KEY)
- lose("cannot perform private encryption with this key");
-
- if (!PyArg_ParseTuple(args, "s#", &plain_text, &len))
- goto error;
-
- size = RSA_size(self->cipher);
- if (len > size)
- lose("plain text is too long");
-
- if ((cipher_text = malloc(size + 16)) == NULL)
- lose("could not allocate memory");
-
- if ((len = RSA_private_encrypt(len, plain_text, cipher_text, self->cipher, RSA_PKCS1_PADDING)) < 0)
- lose("could not encrypt plain text");
-
- obj = Py_BuildValue("s#", cipher_text, len);
- free(cipher_text);
- return obj;
-
- error:
-
- if (cipher_text)
- free(cipher_text);
-
- return NULL;
-}
-
-static char asymmetric_object_public_decrypt__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Asymmetric</memberof>\n"
-" <name>publicDecrypt</name>\n"
-" <parameter>ciphertext</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to decrypt the\n"
-" <parameter>ciphertext</parameter> which has been encrypted\n"
-" using the corresponding private key and the\n"
-" <function>privateEncrypt</function> function.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-asymmetric_object_public_decrypt(asymmetric_object *self, PyObject *args)
-{
- unsigned char *plain_text = NULL, *cipher_text = NULL;
- int len = 0, size = 0;
- PyObject *obj = NULL;
-
- if (self->cipher_type != RSA_CIPHER)
- lose("unsupported cipher type");
-
- if (!PyArg_ParseTuple(args, "s#", &cipher_text, &len))
- goto error;
-
- size = RSA_size(self->cipher);
- if (len > size)
- lose("cipher text is too long");
-
- if ((plain_text = malloc(size + 16)) == NULL)
- lose("could not allocate memory");
-
- if ((len = RSA_public_decrypt(len, cipher_text, plain_text, self->cipher, RSA_PKCS1_PADDING)) < 0)
- lose("could not decrypt cipher text");
-
- obj = Py_BuildValue("s#", plain_text, len);
- free(plain_text);
- return obj;
-
- error:
-
- if (plain_text)
- free(plain_text);
-
- return NULL;
-}
-
-static char asymmetric_object_private_decrypt__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Asymmetric</memberof>\n"
-" <name>privateDecrypt</name>\n"
-" <parameter>ciphertext</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to decrypt ciphertext which has been encrypted\n"
-" using the corresponding public key and the\n"
-" <function>publicEncrypt</function> function.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-asymmetric_object_private_decrypt(asymmetric_object *self, PyObject *args)
-{
- unsigned char *plain_text = NULL, *cipher_text = NULL;
- int len = 0, size = 0;
- PyObject *obj = NULL;
-
- if (self->key_type != RSA_PRIVATE_KEY)
- lose("cannot perform private decryption with this key");
-
- if (!PyArg_ParseTuple(args, "s#", &cipher_text, &len))
- goto error;
-
- size = RSA_size(self->cipher);
- if (len > size)
- lose("cipher text is too long");
-
- if ((plain_text = malloc(size + 16)) == NULL)
- lose("could not allocate memory");
-
- if ((len = RSA_private_decrypt(len, cipher_text, plain_text, self->cipher, RSA_PKCS1_PADDING)) < 0)
- lose("could not decrypt cipher text");
-
- obj = Py_BuildValue("s#", plain_text, len);
- free(plain_text);
- return obj;
-
- error:
-
- if (plain_text)
- free(plain_text);
- return NULL;
-}
-
-static char asymmetric_object_sign__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Asymmetric</memberof>\n"
-" <name>sign</name>\n"
-" <parameter>digesttext</parameter>\n"
-" <parameter>digesttype</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to produce a signed digest text.\n"
-" This instance of\n"
-" <classname>Asymmetric</classname> should be a private key used for\n"
-" signing. The parameter\n"
-" <parameter>digesttext</parameter> should be a digest of the\n"
-" data to protect against alteration and\n"
-" finally <parameter>digesttype</parameter> should be one of the\n"
-" following:\n"
-" </para>\n"
-" <simplelist>\n"
-#ifndef OPENSSL_NO_MD2
-" <member><constant>MD2_DIGEST</constant></member>\n"
-#endif
-" <member><constant>MD5_DIGEST</constant></member>\n"
-" <member><constant>SHA_DIGEST</constant></member>\n"
-" <member><constant>SHA1_DIGEST</constant></member>\n"
-" <member><constant>RIPEMD160_DIGEST</constant></member>\n"
-" <member><constant>SHA256_DIGEST</constant></member>\n"
-" <member><constant>SHA384_DIGEST</constant></member>\n"
-" <member><constant>SHA512_DIGEST</constant></member>\n"
-" </simplelist>\n"
-" <para>\n"
-" If the procedure was successful, a string containing the signed\n"
-" digest is returned.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-asymmetric_object_sign(asymmetric_object *self, PyObject *args)
-{
- unsigned char *digest_text = NULL, *signed_text = NULL;
- unsigned int digest_len = 0, digest_type = 0, digest_nid = 0, signed_len = 0;
- PyObject *obj = NULL;
-
- if (!PyArg_ParseTuple(args, "s#i", &digest_text, &digest_len, &digest_type))
- goto error;
-
- if (self->key_type != RSA_PRIVATE_KEY)
- lose("unsupported key type");
-
- if ((signed_text = malloc(RSA_size(self->cipher))) == NULL)
- lose("could not allocate memory");
-
- switch(digest_type) {
-#ifndef OPENSSL_NO_MD2
- case MD2_DIGEST:
- digest_nid = NID_md2;
- digest_len = MD2_DIGEST_LENGTH;
- break;
-#endif
- case MD5_DIGEST:
- digest_nid = NID_md5;
- digest_len = MD5_DIGEST_LENGTH;
- break;
- case SHA_DIGEST:
- digest_nid = NID_sha;
- digest_len = SHA_DIGEST_LENGTH;
- break;
- case SHA1_DIGEST:
- digest_nid = NID_sha1;
- digest_len = SHA_DIGEST_LENGTH;
- break;
- case RIPEMD160_DIGEST:
- digest_nid = NID_ripemd160;
- digest_len = RIPEMD160_DIGEST_LENGTH;
- break;
- case SHA256_DIGEST:
- digest_nid = NID_sha256;
- digest_len = SHA256_DIGEST_LENGTH;
- break;
- case SHA384_DIGEST:
- digest_nid = NID_sha384;
- digest_len = SHA384_DIGEST_LENGTH;
- break;
- case SHA512_DIGEST:
- digest_nid = NID_sha512;
- digest_len = SHA512_DIGEST_LENGTH;
- break;
- default:
- lose("unsupported digest");
- }
-
- if (!RSA_sign(digest_nid, digest_text, digest_len, signed_text, &signed_len, self->cipher))
- lose("could not sign digest");
-
- obj = Py_BuildValue("s#", signed_text, signed_len);
- free(signed_text);
- return obj;
-
- error:
-
- if (signed_text)
- free(signed_text);
-
- return NULL;
-}
-
-static char asymmetric_object_verify__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Asymmetric</memberof>\n"
-" <name>verify</name>\n"
-" <parameter>signedtext</parameter>\n"
-" <parameter>digesttext</parameter>\n"
-" <parameter>digesttype</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to verify a signed digest text.\n"
-" </para>\n"
-" <example>\n"
-" <title><function>verify</function> method usage</title>\n"
-" <programlisting>\n"
-" plain_text = 'Hello World!'\n"
-" print '\tPlain text:', plain_text\n"
-" digest = POW.Digest(POW.RIPEMD160_DIGEST)\n"
-" digest.update(plain_text)\n"
-" print '\tDigest text:', digest.digest()\n"
-"\n"
-" privateFile = open('test/private.key', 'r')\n"
-" privateKey = POW.pemRead(POW.RSA_PRIVATE_KEY, privateFile.read(), 'pass')\n"
-" privateFile.close()\n"
-" signed_text = privateKey.sign(digest.digest(), POW.RIPEMD160_DIGEST)\n"
-" print '\tSigned text:', signed_text\n"
-"\n"
-" digest2 = POW.Digest(POW.RIPEMD160_DIGEST)\n"
-" digest2.update(plain_text)\n"
-" publicFile = open('test/public.key', 'r')\n"
-" publicKey = POW.pemRead(POW.RSA_PUBLIC_KEY, publicFile.read())\n"
-" publicFile.close()\n"
-" if publicKey.verify(signed_text, digest2.digest(), POW.RIPEMD160_DIGEST):\n"
-" print 'Signing verified!'\n"
-" else:\n"
-" print 'Signing gone wrong!'\n"
-" </programlisting>\n"
-" </example>\n"
-" <para>\n"
-" The parameter <parameter>signedtext</parameter> should be a\n"
-" signed digest text. This instance of\n"
-" <classname>Asymmetric</classname> should correspond to the private\n"
-" key used to sign the digest. The parameter\n"
-" <parameter>digesttext</parameter> should be a digest of the same\n"
-" data used to produce the <parameter>signedtext</parameter> and\n"
-" finally <parameter>digesttype</parameter> should be one of the\n"
-" following:\n"
-" </para>\n"
-" <simplelist>\n"
-#ifndef OPENSSL_NO_MD2
-" <member><constant>MD2_DIGEST</constant></member>\n"
-#endif
-" <member><constant>MD5_DIGEST</constant></member>\n"
-" <member><constant>SHA_DIGEST</constant></member>\n"
-" <member><constant>SHA1_DIGEST</constant></member>\n"
-" <member><constant>RIPEMD160_DIGEST</constant></member>\n"
-" <member><constant>SHA256_DIGEST</constant></member>\n"
-" <member><constant>SHA384_DIGEST</constant></member>\n"
-" <member><constant>SHA512_DIGEST</constant></member>\n"
-" </simplelist>\n"
-" <para>\n"
-" If the procedure was successful, 1 is returned, otherwise 0 is\n"
-" returned.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-asymmetric_object_verify(asymmetric_object *self, PyObject *args)
-{
- unsigned char *digest_text = NULL, *signed_text = NULL;
- int digest_len = 0, digest_type = 0, digest_nid = 0, signed_len = 0;
-
- if (!PyArg_ParseTuple(args, "s#s#i", &signed_text, &signed_len, &digest_text, &digest_len, &digest_type))
- goto error;
-
- switch (digest_type) {
-#ifndef OPENSSL_NO_MD2
- case MD2_DIGEST:
- digest_len = MD2_DIGEST_LENGTH;
- digest_nid = NID_md2;
- break;
-#endif
- case MD5_DIGEST:
- digest_len = MD5_DIGEST_LENGTH;
- digest_nid = NID_md5;
- break;
- case SHA_DIGEST:
- digest_len = SHA_DIGEST_LENGTH;
- digest_nid = NID_sha;
- break;
- case SHA1_DIGEST:
- digest_len = SHA_DIGEST_LENGTH;
- digest_nid = NID_sha1;
- break;
- case RIPEMD160_DIGEST:
- digest_len = RIPEMD160_DIGEST_LENGTH;
- digest_nid = NID_ripemd160;
- break;
- case SHA256_DIGEST:
- digest_len = SHA256_DIGEST_LENGTH;
- digest_nid = NID_sha256;
- break;
- case SHA384_DIGEST:
- digest_len = SHA384_DIGEST_LENGTH;
- digest_nid = NID_sha384;
- break;
- case SHA512_DIGEST:
- digest_len = SHA512_DIGEST_LENGTH;
- digest_nid = NID_sha512;
- break;
- default:
- lose("unsupported digest");
- }
-
- return PyBool_FromLong(RSA_verify(digest_nid, digest_text, digest_len, signed_text, signed_len, self->cipher));
-
- error:
-
- return NULL;
-}
-
-static struct PyMethodDef asymmetric_object_methods[] = {
- {"pemWrite", (PyCFunction)asymmetric_object_pem_write, METH_VARARGS, NULL},
- {"derWrite", (PyCFunction)asymmetric_object_der_write, METH_VARARGS, NULL},
- {"publicEncrypt", (PyCFunction)asymmetric_object_public_encrypt, METH_VARARGS, NULL},
- {"privateEncrypt", (PyCFunction)asymmetric_object_private_encrypt, METH_VARARGS, NULL},
- {"privateDecrypt", (PyCFunction)asymmetric_object_private_decrypt, METH_VARARGS, NULL},
- {"publicDecrypt", (PyCFunction)asymmetric_object_public_decrypt, METH_VARARGS, NULL},
- {"sign", (PyCFunction)asymmetric_object_sign, METH_VARARGS, NULL},
- {"verify", (PyCFunction)asymmetric_object_verify, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-asymmetric_object_getattr(asymmetric_object *self, char *name)
-{
- return Py_FindMethod(asymmetric_object_methods, (PyObject *)self, name);
-}
-
-static void
-asymmetric_object_dealloc(asymmetric_object *self, char *name)
-{
- switch(self->cipher_type) {
- case RSA_CIPHER:
- RSA_free(self->cipher);
- break;
- }
- PyObject_Del(self);
-}
-
-static char asymmetrictype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>Asymmetric</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides access to RSA asymmetric ciphers in OpenSSL.\n"
-" Other ciphers will probably be supported in the future but this is\n"
-" not a priority.\n"
-" </para>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject asymmetrictype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "Asymmetric", /*tp_name*/
- sizeof(asymmetric_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)asymmetric_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)asymmetric_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- asymmetrictype__doc__ /* Documentation string */
-};
-/*========== asymmetric Code ==========*/
-
-/*========== symmetric Code ==========*/
-static symmetric_object *
-symmetric_object_new(int cipher_type)
-{
- symmetric_object *self = NULL;
-
- if ((self = PyObject_New(symmetric_object, &symmetrictype)) == NULL)
- goto error;
-
- self->cipher_type = cipher_type;
- EVP_CIPHER_CTX_init(&self->cipher_ctx);
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static char symmetric_object_encrypt_init__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Symmetric</memberof>\n"
-" <name>encryptInit</name>\n"
-" <parameter>key</parameter>\n"
-" <parameter>initialvalue = ''</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method sets up the cipher object to start encrypting a stream\n"
-" of data. The first parameter is the key used to encrypt the\n"
-" data. The second, the <parameter>initialvalue</parameter> serves\n"
-" a similar purpose the the salt supplied to the Unix\n"
-" <function>crypt</function> function.\n"
-" The <parameter>initialvalue</parameter> is normally chosen at random and\n"
-" often transmitted with the encrypted data, its purpose is to prevent\n"
-" two identical plain texts resulting in two identical cipher texts.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-symmetric_object_encrypt_init(symmetric_object *self, PyObject *args)
-{
- unsigned char *key = NULL, *iv = NULL, nulliv [] = "";
- const EVP_CIPHER *cipher = NULL;
-
- if (!PyArg_ParseTuple(args, "s|s", &key, &iv))
- goto error;
-
- if (!iv)
- iv = nulliv;
-
- if ((cipher = evp_cipher_factory(self->cipher_type)) == NULL)
- lose("unsupported cipher");
-
- if (!EVP_EncryptInit(&self->cipher_ctx, cipher, key, iv))
- lose("could not initialise cipher");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char symmetric_object_decrypt_init__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Symmetric</memberof>\n"
-" <name>decryptInit</name>\n"
-" <parameter>key</parameter>\n"
-" <parameter>initialvalue = ''</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method sets up the cipher object to start decrypting a stream\n"
-" of data. The first value must be the key used to encrypt the\n"
-" data. The second parameter is the <parameter>initialvalue</parameter>\n"
-" used to encrypt the data.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-symmetric_object_decrypt_init(symmetric_object *self, PyObject *args)
-{
- unsigned char *key = NULL, *iv = NULL, nulliv [] = "";
- const EVP_CIPHER *cipher = NULL;
-
- if (!PyArg_ParseTuple(args, "s|s", &key, &iv))
- goto error;
-
- if (!iv)
- iv = nulliv;
-
- if ((cipher = evp_cipher_factory(self->cipher_type)) == NULL)
- lose("unsupported cipher");
-
- if (!EVP_DecryptInit(&self->cipher_ctx, cipher, key, iv))
- lose("could not initialise cipher");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char symmetric_object_update__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Symmetric</memberof>\n"
-" <name>update</name>\n"
-" <parameter>data</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method is used to process the bulk of data being encrypted\n"
-" or decrypted by the cipher object. <parameter>data</parameter>\n"
-" should be a string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-symmetric_object_update(symmetric_object *self, PyObject *args)
-{
- int inl = 0, outl = 0;
- unsigned char *in = NULL, *out = NULL;
- PyObject *py_out = NULL;
-
- if (!PyArg_ParseTuple(args, "s#", &in, &inl))
- goto error;
-
- if ((out = malloc(inl + EVP_CIPHER_CTX_block_size(&self->cipher_ctx))) == NULL)
- lose("could not allocate memory");
-
- if (!EVP_CipherUpdate(&self->cipher_ctx, out, &outl, in, inl))
- lose("could not update cipher");
-
- if ((py_out = Py_BuildValue("s#", out, outl)) == NULL)
- lose("could not allocate memory");
-
- free(out);
- return py_out;
-
- error:
-
- if (out)
- free(out);
-
- return NULL;
-}
-
-static char symmetric_object_final__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Symmetric</memberof>\n"
-" <name>final</name>\n"
-" <parameter>size = 1024</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" Most ciphers are block ciphers, that is they encrypt or decrypt a block of\n"
-" data at a time. Often the data being processed will not fill an\n"
-" entire block, this method processes these half-empty blocks. A\n"
-" string is returned of a maximum length <parameter>size</parameter>.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-symmetric_object_final(symmetric_object *self, PyObject *args)
-{
- int outl = 0, size = 1024;
- unsigned char *out = NULL;
- PyObject *py_out = NULL;
-
- if (!PyArg_ParseTuple(args, "|i", &size))
- goto error;
-
- if ((out = malloc(size + EVP_CIPHER_CTX_block_size(&self->cipher_ctx))) == NULL)
- lose("could not allocate memory");
-
- if (!EVP_CipherFinal(&self->cipher_ctx, out, &outl))
- lose("could not update cipher");
-
- if ((py_out = Py_BuildValue("s#", out, outl)) == NULL)
- lose("could not allocate memory");
-
- free(out);
- return py_out;
-
- error:
-
- if (out)
- free(out);
-
- return NULL;
-}
-
-static struct PyMethodDef symmetric_object_methods[] = {
- {"encryptInit", (PyCFunction)symmetric_object_encrypt_init, METH_VARARGS, NULL},
- {"decryptInit", (PyCFunction)symmetric_object_decrypt_init, METH_VARARGS, NULL},
- {"update", (PyCFunction)symmetric_object_update, METH_VARARGS, NULL},
- {"final", (PyCFunction)symmetric_object_final, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-symmetric_object_getattr(symmetric_object *self, char *name)
-{
- return Py_FindMethod(symmetric_object_methods, (PyObject *)self, name);
-}
-
-static void
-symmetric_object_dealloc(symmetric_object *self, char *name)
-{
- PyObject_Del(self);
-}
-
-static char symmetrictype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>Symmetric</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides access to all the symmetric ciphers in OpenSSL.\n"
-" Initialisation of the cipher structures is performed late, only\n"
-" when <function>encryptInit</function> or\n"
-" <function>decryptInit</function> is called, the\n"
-" constructor only records the cipher type. It is possible to reuse\n"
-" the <classname>Symmetric</classname> objects by calling\n"
-" <function>encryptInit</function> or <function>decryptInit</function>\n"
-" again.\n"
-" </para>\n"
-" <example>\n"
-" <title><classname>Symmetric</classname> class usage</title>\n"
-" <programlisting>\n"
-" passphrase = 'my silly passphrase'\n"
-" md5 = POW.Digest(POW.MD5_DIGEST)\n"
-" md5.update(passphrase)\n"
-" password = md5.digest()[:8]\n"
-"\n"
-" plaintext = 'cast test message'\n"
-" cast = POW.Symmetric(POW.CAST5_CFB)\n"
-" cast.encryptInit(password)\n"
-" ciphertext = cast.update(plaintext) + cast.final()\n"
-" print 'Cipher text:', ciphertext\n"
-"\n"
-" cast.decryptInit(password)\n"
-" out = cast.update(ciphertext) + cast.final()\n"
-" print 'Deciphered text:', out\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject symmetrictype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "Symmetric", /*tp_name*/
- sizeof(symmetric_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)symmetric_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)symmetric_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- symmetrictype__doc__ /* Documentation string */
-};
-/*========== symmetric Code ==========*/
-
-/*========== digest Code ==========*/
-static digest_object *
-digest_object_new(int digest_type)
-{
- digest_object *self = NULL;
-
- if ((self = PyObject_New(digest_object, &digesttype)) == NULL)
- goto error;
-
- switch(digest_type) {
-#ifndef OPENSSL_NO_MD2
- case MD2_DIGEST:
- self->digest_type = MD2_DIGEST;
- EVP_DigestInit(&self->digest_ctx, EVP_md2());
- break;
-#endif
- case MD5_DIGEST:
- self->digest_type = MD5_DIGEST;
- EVP_DigestInit(&self->digest_ctx, EVP_md5());
- break;
- case SHA_DIGEST:
- self->digest_type = SHA_DIGEST;
- EVP_DigestInit(&self->digest_ctx, EVP_sha());
- break;
- case SHA1_DIGEST:
- self->digest_type = SHA1_DIGEST;
- EVP_DigestInit(&self->digest_ctx, EVP_sha1());
- break;
- case RIPEMD160_DIGEST:
- self->digest_type = RIPEMD160_DIGEST;
- EVP_DigestInit(&self->digest_ctx, EVP_ripemd160());
- break;
- case SHA256_DIGEST:
- self->digest_type = SHA256_DIGEST;
- EVP_DigestInit(&self->digest_ctx, EVP_sha256());
- break;
- case SHA384_DIGEST:
- self->digest_type = SHA384_DIGEST;
- EVP_DigestInit(&self->digest_ctx, EVP_sha384());
- break;
- case SHA512_DIGEST:
- self->digest_type = SHA512_DIGEST;
- EVP_DigestInit(&self->digest_ctx, EVP_sha512());
- break;
- default:
- lose("unsupported digest");
- }
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static char digest_object_update__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Digest</memberof>\n"
-" <name>update</name>\n"
-" <parameter>data</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method updates the internal structures of the\n"
-" <classname>Digest</classname> object with <parameter>data</parameter>.\n"
-" <parameter>data</parameter> should be a string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-digest_object_update(digest_object *self, PyObject *args)
-{
- char *data = NULL;
- int len = 0;
-
- if (!PyArg_ParseTuple(args, "s#", &data, &len))
- goto error;
-
- EVP_DigestUpdate(&self->digest_ctx, data, len);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char digest_object_copy__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Digest</memberof>\n"
-" <name>copy</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a copy of the <classname>Digest</classname>\n"
-" object.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-digest_object_copy(digest_object *self, PyObject *args)
-{
- digest_object *new = NULL;
-
- if ((new = PyObject_New(digest_object, &digesttype)) == NULL)
- lose("could not allocate memory");
-
- new->digest_type = self->digest_type;
- if (!EVP_MD_CTX_copy(&new->digest_ctx, &self->digest_ctx))
- lose("could not copy digest");
-
- return (PyObject*)new;
-
- error:
-
- Py_XDECREF(new);
- return NULL;
-}
-
-static char digest_object_digest__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Digest</memberof>\n"
-" <name>digest</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the digest of all the data which has been\n"
-" processed. This function can be called at any time and will not\n"
-" effect the internal structure of the <classname>digest</classname>\n"
-" object.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-digest_object_digest(digest_object *self, PyObject *args)
-{
- unsigned char digest_text[EVP_MAX_MD_SIZE];
- void *md_copy = NULL;
- unsigned digest_len = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((md_copy = malloc(sizeof(EVP_MD_CTX))) == NULL)
- lose("could not allocate memory");
-
- if (!EVP_MD_CTX_copy(md_copy, &self->digest_ctx))
- lose("could not copy digest");
-
- EVP_DigestFinal(md_copy, digest_text, &digest_len);
-
- free(md_copy);
-
- return Py_BuildValue("s#", digest_text, digest_len);
-
- error:
-
- if (md_copy)
- free(md_copy);
-
- return NULL;
-}
-
-static struct PyMethodDef digest_object_methods[] = {
- {"update", (PyCFunction)digest_object_update, METH_VARARGS, NULL},
- {"digest", (PyCFunction)digest_object_digest, METH_VARARGS, NULL},
- {"copy", (PyCFunction)digest_object_copy, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-digest_object_getattr(digest_object *self, char *name)
-{
- return Py_FindMethod(digest_object_methods, (PyObject *)self, name);
-}
-
-static void
-digest_object_dealloc(digest_object *self, char *name)
-{
- EVP_MD_CTX_cleanup(&self->digest_ctx);
- PyObject_Del(self);
-}
-
-static char digesttype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>Digest</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides access to the digest functionality of OpenSSL.\n"
-" It emulates the digest modules in the Python Standard Library but\n"
-" does not currently support the <function>hexdigest</function>\n"
-" function.\n"
-" </para>\n"
-" <example>\n"
-" <title><classname>digest</classname> class usage</title>\n"
-" <programlisting>\n"
-" plain_text = 'Hello World!'\n"
-" sha1 = POW.Digest(POW.SHA1_DIGEST)\n"
-" sha1.update(plain_text)\n"
-" print '\tPlain text: Hello World! =>', sha1.digest()\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject digesttype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "Digest", /*tp_name*/
- sizeof(digest_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)digest_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)digest_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- digesttype__doc__ /* Documentation string */
-};
-/*========== digest Code ==========*/
-
-/*========== hmac Code ==========*/
-static hmac_object *
-hmac_object_new(int digest_type, char *key, int key_len)
-{
- hmac_object *self = NULL;
- const EVP_MD *md = NULL;
-
- if ((self = PyObject_New(hmac_object, &hmactype)) == NULL)
- goto error;
-
- switch (digest_type) {
-#ifndef OPENSSL_NO_MD2
- case MD2_DIGEST:
- md = EVP_md2();
- break;
-#endif
- case MD5_DIGEST:
- md = EVP_md5();
- break;
- case SHA_DIGEST:
- md = EVP_sha();
- break;
- case SHA1_DIGEST:
- md = EVP_sha1();
- break;
- case RIPEMD160_DIGEST:
- md = EVP_ripemd160();
- break;
- case SHA256_DIGEST:
- md = EVP_sha256();
- break;
- case SHA384_DIGEST:
- md = EVP_sha384();
- break;
- case SHA512_DIGEST:
- md = EVP_sha512();
- break;
- default:
- lose("unsupported digest");
- }
-
- HMAC_Init(&self->hmac_ctx, key, key_len, md);
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static char hmac_object_update__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Hmac</memberof>\n"
-" <name>update</name>\n"
-" <parameter>data</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method updates the internal structures of the\n"
-" <classname>Hmac</classname> object with <parameter>data</parameter>.\n"
-" <parameter>data</parameter> should be a string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-hmac_object_update(hmac_object *self, PyObject *args)
-{
- unsigned char *data = NULL;
- int len = 0;
-
- if (!PyArg_ParseTuple(args, "s#", &data, &len))
- goto error;
-
- HMAC_Update(&self->hmac_ctx, data, len);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char hmac_object_copy__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Hmac</memberof>\n"
-" <name>copy</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a copy of the <classname>Hmac</classname>\n"
-" object.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-hmac_object_copy(hmac_object *self, PyObject *args)
-{
- hmac_object *new = NULL;
-
- if ((new = PyObject_New(hmac_object, &hmactype)) == NULL)
- lose("could not allocate memory");
-
- memcpy(&new->hmac_ctx, &self->hmac_ctx, sizeof(HMAC_CTX));
-
- return (PyObject*) new;
-
- error:
-
- Py_XDECREF(new);
- return NULL;
-}
-
-static char hmac_object_mac__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>Hmac</memberof>\n"
-" <name>mac</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the MAC of all the data which has been\n"
-" processed. This function can be called at any time and will not\n"
-" effect the internal structure of the <classname>Hmac</classname>\n"
-" object.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-hmac_object_mac(hmac_object *self, PyObject *args)
-{
- unsigned char hmac_text[EVP_MAX_MD_SIZE];
- void *hmac_copy = NULL;
- unsigned int hmac_len = 0;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((hmac_copy = malloc(sizeof(HMAC_CTX))) == NULL)
- lose("could not allocate memory");
-
- memcpy(hmac_copy, &self->hmac_ctx, sizeof(HMAC_CTX));
- HMAC_Final(hmac_copy, hmac_text, &hmac_len);
-
- free(hmac_copy);
- return Py_BuildValue("s#", hmac_text, hmac_len);
-
- error:
-
- if (hmac_copy)
- free(hmac_copy);
-
- return NULL;
-}
-
-
-static struct PyMethodDef hmac_object_methods[] = {
- {"update", (PyCFunction)hmac_object_update, METH_VARARGS, NULL},
- {"mac", (PyCFunction)hmac_object_mac, METH_VARARGS, NULL},
- {"copy", (PyCFunction)hmac_object_copy, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-hmac_object_getattr(hmac_object *self, char *name)
-{
- return Py_FindMethod(hmac_object_methods, (PyObject *)self, name);
-}
-
-static void
-hmac_object_dealloc(hmac_object *self, char *name)
-{
- PyObject_Del(self);
-}
-
-static char hmactype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>Hmac</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides access to the HMAC functionality of OpenSSL.\n"
-" HMAC's are a variant on digest based MACs, which have the\n"
-" interesting property of a provable level of security. HMAC is\n"
-" discussed further in RFC 2104.\n"
-" </para>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject hmactype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "Hmac", /*tp_name*/
- sizeof(hmac_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)hmac_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)hmac_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- hmactype__doc__ /* Documentation string */
-};
-/*========== hmac Code ==========*/
-
-/*========== CMS code ==========*/
-static cms_object *
-CMS_object_new(void)
-{
- cms_object *self;
-
- if ((self = PyObject_New(cms_object, &cmstype)) == NULL)
- goto error;
-
- self->cms = NULL;
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static cms_object *
-CMS_object_pem_read(BIO *in)
-{
- cms_object *self;
-
- if ((self = PyObject_New(cms_object, &cmstype)) == NULL)
- goto error;
-
- if ((self->cms = PEM_read_bio_CMS(in, NULL, NULL, NULL)) == NULL)
- lose("could not load PEM encoded CMS message");
-
- return self;
-
- error:
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static cms_object *
-CMS_object_der_read(char *src, int len)
-{
- cms_object *self;
- BIO *bio = NULL;
-
- if ((self = PyObject_New(cms_object, &cmstype)) == NULL)
- goto error;
-
- self->cms = CMS_ContentInfo_new();
-
- if ((bio = BIO_new_mem_buf(src, len)) == NULL)
- goto error;
-
- if (!d2i_CMS_bio(bio, &self->cms))
- lose("could not load DER encoded CMS message");
-
- BIO_free(bio);
-
- return self;
-
- error:
-
- if (bio)
- BIO_free(bio);
-
- Py_XDECREF(self);
- return NULL;
-}
-
-static PyObject *
-CMS_object_write_helper(cms_object *self, PyObject *args, int format)
-{
- int len = 0;
- char *buf = NULL;
- BIO *out_bio = NULL;
- PyObject *cert = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- out_bio = BIO_new(BIO_s_mem());
-
- switch (format) {
-
- case DER_FORMAT:
- if (!i2d_CMS_bio(out_bio, self->cms))
- lose("unable to write certificate");
- break;
-
- case PEM_FORMAT:
- if (!PEM_write_bio_CMS(out_bio, self->cms))
- lose("unable to write certificate");
- break;
-
- default:
- lose("internal error, unknown output format");
- }
-
- if ((len = BIO_ctrl_pending(out_bio)) == 0)
- lose("unable to get bytes stored in bio");
-
- if ((buf = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- if (BIO_read(out_bio, buf, len) != len)
- lose("unable to write out cert");
-
- cert = Py_BuildValue("s#", buf, len);
-
- BIO_free(out_bio);
- free(buf);
- return cert;
-
- error:
-
- if (out_bio)
- BIO_free(out_bio);
-
- if (buf)
- free(buf);
-
- Py_XDECREF(cert);
- return NULL;
-}
-
-static char CMS_object_pem_write__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>pemWrite</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a PEM encoded CMS message as a\n"
-" string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_pem_write(cms_object *self, PyObject *args)
-{
- return CMS_object_write_helper(self, args, PEM_FORMAT);
-}
-
-static char CMS_object_der_write__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>derWrite</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a DER encoded CMS message as a\n"
-" string.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_der_write(cms_object *self, PyObject *args)
-{
- return CMS_object_write_helper(self, args, DER_FORMAT);
-}
-
-static char CMS_object_sign__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>sign</name>\n"
-" <parameter>signcert</parameter>\n"
-" <parameter>key</parameter>\n"
-" <parameter>data</parameter>\n"
-" <optional>\n"
-" <parameter>certs</parameter>\n"
-" <parameter>crls</parameter>\n"
-" <parameter>eContentType</parameter>\n"
-" <parameter>flags</parameter>\n"
-" </optional>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method signs a message with a private key.\n"
-" Supported flags: CMS_NOCERTS, CMS_NOATTR.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_sign(cms_object *self, PyObject *args)
-{
- asymmetric_object *signkey = NULL;
- x509_object *signcert = NULL;
- x509_crl_object *crlobj = NULL;
- PyObject *x509_sequence = Py_None, *crl_sequence = Py_None, *result = NULL;
- STACK_OF(X509) *x509_stack = NULL;
- EVP_PKEY *pkey = NULL;
- char *buf = NULL, *oid = NULL;
- int i, n, len;
- unsigned flags = 0;
- BIO *bio = NULL;
- CMS_ContentInfo *cms = NULL;
- ASN1_OBJECT *econtent_type = NULL;
-
- if (!PyArg_ParseTuple(args, "O!O!s#|OOsI",
- &x509type, &signcert,
- &asymmetrictype, &signkey,
- &buf, &len,
- &x509_sequence,
- &crl_sequence,
- &oid,
- &flags))
- goto error;
-
- assert_no_unhandled_openssl_errors();
-
- flags &= CMS_NOCERTS | CMS_NOATTR;
- flags |= CMS_BINARY | CMS_NOSMIMECAP | CMS_PARTIAL | CMS_USE_KEYID;
-
- if (signkey->key_type != RSA_PRIVATE_KEY)
- lose("unsupported key type");
-
- if ((x509_stack = x509_helper_sequence_to_stack(x509_sequence)) == NULL)
- goto error;
-
- assert_no_unhandled_openssl_errors();
-
- if ((pkey = EVP_PKEY_new()) == NULL)
- lose_openssl_error("Could not allocate memory");
-
- assert_no_unhandled_openssl_errors();
-
- if (!EVP_PKEY_assign_RSA(pkey, signkey->cipher))
- lose_openssl_error("EVP_PKEY assignment error");
-
- assert_no_unhandled_openssl_errors();
-
- if ((bio = BIO_new_mem_buf(buf, len)) == NULL)
- goto error;
-
- assert_no_unhandled_openssl_errors();
-
- if (oid && (econtent_type = OBJ_txt2obj(oid, 0)) == NULL)
- lose_openssl_error("Could not parse OID");
-
- assert_no_unhandled_openssl_errors();
-
- if ((cms = CMS_sign(NULL, NULL, x509_stack, bio, flags)) == NULL)
- lose_openssl_error("Could not create CMS message");
-
- assert_no_unhandled_openssl_errors();
-
- if (econtent_type)
- CMS_set1_eContentType(cms, econtent_type);
-
- assert_no_unhandled_openssl_errors();
-
- if (!CMS_add1_signer(cms, signcert->x509, pkey, EVP_sha256(), flags))
- lose_openssl_error("Could not sign CMS message");
-
- pkey = NULL; /* CMS_add1_signer() now owns pkey */
-
- assert_no_unhandled_openssl_errors();
-
- if (crl_sequence != Py_None) {
-
- if (!PyTuple_Check(crl_sequence) && !PyList_Check(crl_sequence))
- lose_type_error("inapropriate type");
-
- n = PySequence_Size(crl_sequence);
-
- for (i = 0; i < n; i++) {
-
- if ((crlobj = (x509_crl_object *) PySequence_GetItem(crl_sequence, i)) == NULL)
- goto error;
-
- if (!X_X509_crl_Check(crlobj))
- lose_type_error("inappropriate type");
-
- if (!crlobj->crl)
- lose("CRL object with null crl field!");
-
- if (!CMS_add1_crl(cms, crlobj->crl))
- lose_openssl_error("Could not add CRL to CMS");
-
- assert_no_unhandled_openssl_errors();
-
- Py_XDECREF(crlobj);
- crlobj = NULL;
- }
- }
-
- if (!CMS_final(cms, bio, NULL, flags))
- lose_openssl_error("Could not finalize CMS signatures");
-
- assert_no_unhandled_openssl_errors();
-
- if (self->cms)
- CMS_ContentInfo_free(self->cms);
- self->cms = cms;
- cms = NULL;
-
- result = Py_BuildValue("");
-
- error: /* fall through */
-
- assert_no_unhandled_openssl_errors();
-
- if (cms)
- CMS_ContentInfo_free(cms);
-
- if (bio)
- BIO_free(bio);
-
- if (x509_stack)
- sk_X509_free(x509_stack);
-
- if (pkey)
- EVP_PKEY_free(pkey);
-
- if (econtent_type)
- ASN1_OBJECT_free(econtent_type);
-
- if (crlobj) {
- Py_XDECREF(crlobj);
- }
-
- return result;
-}
-
-static char CMS_object_verify__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>verify</name>\n"
-" <parameter>store</parameter>\n"
-" <optional>\n"
-" <parameter>certs</parameter>\n"
-" <parameter>flags</parameter>\n"
-" </optional>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method verifies a message against a trusted store.\n"
-" The optional certs parameter is a set of certificates to search\n"
-" for the signer's certificate.\n"
-" Supported flags: CMS_NOINTERN, CMS_NOCRL,\n"
-" CMS_NO_SIGNER_CERT_VERIFY, CMS_NO_ATTR_VERIFY,\n"
-" CMS_NO_CONTENT_VERIFY.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_verify(cms_object *self, PyObject *args)
-{
- x509_store_object *store = NULL;
- PyObject *result = NULL, *certs_sequence = Py_None;
- STACK_OF(X509) *certs_stack = NULL;
- unsigned flags = 0;
- char *buf = NULL;
- BIO *bio = NULL;
- int len;
-
- if (!PyArg_ParseTuple(args, "O!|OI", &x509_storetype, &store, &certs_sequence, &flags))
- goto error;
-
- if ((bio = BIO_new(BIO_s_mem())) == NULL)
- goto error;
-
- assert_no_unhandled_openssl_errors();
-
- flags &= CMS_NOINTERN | CMS_NOCRL | CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY | CMS_NO_CONTENT_VERIFY;
-
- if (certs_sequence != Py_None && (certs_stack = x509_helper_sequence_to_stack(certs_sequence)) == NULL)
- goto error;
-
- assert_no_unhandled_openssl_errors();
-
- if (CMS_verify(self->cms, certs_stack, store->store, NULL, bio, flags) <= 0)
- lose_openssl_error("Could not verify CMS message");
-
- assert_no_unhandled_openssl_errors();
-
- if ((len = BIO_ctrl_pending(bio)) == 0)
- lose("unable to get bytes stored in bio");
-
- assert_no_unhandled_openssl_errors();
-
- if ((buf = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- assert_no_unhandled_openssl_errors();
-
- if (BIO_read(bio, buf, len) != len)
- lose("unable to write out CMS content");
-
- assert_no_unhandled_openssl_errors();
-
- result = Py_BuildValue("s#", buf, len);
-
- error: /* fall through */
-
- assert_no_unhandled_openssl_errors();
-
- if (certs_stack)
- sk_X509_free(certs_stack);
-
- if (bio)
- BIO_free(bio);
-
- if (buf)
- free(buf);
-
- return result;
-}
-
-static char CMS_object_eContentType__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>get_eContentType</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the eContentType of a CMS message.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_eContentType(cms_object *self, PyObject *args)
-{
- const ASN1_OBJECT *oid = NULL;
- PyObject *result = NULL;
- char buf[512];
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- if ((oid = CMS_get0_eContentType(self->cms)) == NULL)
- lose_openssl_error("Could not extract eContentType from CMS message");
-
- OBJ_obj2txt(buf, sizeof(buf), oid, 1);
-
- result = Py_BuildValue("s", buf);
-
- error:
-
- assert_no_unhandled_openssl_errors();
-
- return result;
-}
-
-static char CMS_object_signingTime__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>get_signingTime</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns the signingTime of a CMS message.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_signingTime(cms_object *self, PyObject *args)
-{
- PyObject *result = NULL;
- STACK_OF(CMS_SignerInfo) *sis = NULL;
- CMS_SignerInfo *si = NULL;
- X509_ATTRIBUTE *xa = NULL;
- ASN1_TYPE *so = NULL;
- int i;
-
- if (!PyArg_ParseTuple(args, ""))
- return NULL;
-
- if ((sis = CMS_get0_SignerInfos(self->cms)) == NULL)
- lose("Could not extract signerInfos from CMS message[1]");
-
- if (sk_CMS_SignerInfo_num(sis) != 1)
- lose("Could not extract signerInfos from CMS message[2]");
-
- si = sk_CMS_SignerInfo_value(sis, 0);
-
- if ((i = CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1)) < 0)
- lose("Could not extract signerInfos from CMS message[3]");
-
- if ((xa = CMS_signed_get_attr(si, i)) == NULL)
- lose("Could not extract signerInfos from CMS message[4]");
-
- if (xa->single)
- lose("Could not extract signerInfos from CMS message[5]");
-
- if (sk_ASN1_TYPE_num(xa->value.set) != 1)
- lose("Could not extract signerInfos from CMS message[6]");
-
- if ((so = sk_ASN1_TYPE_value(xa->value.set, 0)) == NULL)
- lose("Could not extract signerInfos from CMS message[7]");
-
- switch (so->type) {
- case V_ASN1_UTCTIME:
- result = ASN1_TIME_to_Python(so->value.utctime);
- break;
- case V_ASN1_GENERALIZEDTIME:
- result = ASN1_TIME_to_Python(so->value.generalizedtime);
- break;
- default:
- lose("Could not extract signerInfos from CMS message[8]");
- }
-
- error:
-
- assert_no_unhandled_openssl_errors();
-
- return result;
-}
-
-static char CMS_object_pprint__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>pprint</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns a formatted string showing the information\n"
-" held in the certificate.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_pprint(cms_object *self, PyObject *args)
-{
- int len = 0, ret = 0;
- char *buf = NULL;
- BIO *bio = NULL;
- PyObject *result = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- bio = BIO_new(BIO_s_mem());
-
- if (!CMS_ContentInfo_print_ctx(bio, self->cms, 0, NULL))
- lose("unable to pprint CMS");
-
- if ((len = BIO_ctrl_pending(bio)) == 0)
- lose("unable to get bytes stored in bio");
-
- if ((buf = malloc(len)) == NULL)
- lose("unable to allocate memory");
-
- if ((ret = BIO_read(bio, buf, len)) != len)
- lose("unable to pprint CMS");
-
- result = Py_BuildValue("s#", buf, len);
-
- error: /* fall through */
-
- assert_no_unhandled_openssl_errors();
-
- if (bio)
- BIO_free(bio);
-
- if (buf)
- free(buf);
-
- return result;
-}
-
-
-static PyObject *
-cms_object_helper_get_cert(void *cert)
-{
- x509_object *obj = PyObject_New(x509_object, &x509type);
-
- if (obj)
- obj->x509 = cert;
-
- return (PyObject *) obj;
-}
-
-static char CMS_object_certs__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>certs</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns any certs embedded in a CMS message.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_certs(cms_object *self, PyObject *args)
-{
- STACK_OF(X509) *certs = NULL;
- PyObject *result = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((certs = CMS_get1_certs(self->cms)) != NULL)
- result = stack_to_tuple_helper(CHECKED_PTR_OF(STACK_OF(X509), certs),
- cms_object_helper_get_cert);
- else if (!ERR_peek_error())
- result = Py_BuildValue("()");
- else
- lose_openssl_error("Could not extract certs from CMS message");
-
- error: /* fall through */
-
- if (certs)
- sk_X509_pop_free(certs, X509_free);
-
- return result;
-}
-
-static PyObject *
-cms_object_helper_get_crl(void *crl)
-{
- x509_crl_object *obj = PyObject_New(x509_crl_object, &x509_crltype);
-
- if (obj)
- obj->crl = crl;
-
- return (PyObject *) obj;
-}
-
-static char CMS_object_crls__doc__[] =
-"<method>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" <name>crls</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This method returns any CRLs embedded in a CMS message.\n"
-" </para>\n"
-" </body>\n"
-"</method>\n"
-;
-
-static PyObject *
-CMS_object_crls(cms_object *self, PyObject *args)
-{
- STACK_OF(X509_CRL) *crls = NULL;
- PyObject *result = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((crls = CMS_get1_crls(self->cms)) != NULL)
- result = stack_to_tuple_helper(CHECKED_PTR_OF(STACK_OF(X509_CRL), crls),
- cms_object_helper_get_crl);
- else if (!ERR_peek_error())
- result = Py_BuildValue("()");
- else
- lose_openssl_error("Could not extract CRLs from CMS message");
-
- error: /* fall through */
-
- if (crls)
- sk_X509_CRL_pop_free(crls, X509_CRL_free);
-
- return result;
-}
-
-static struct PyMethodDef CMS_object_methods[] = {
- {"pemWrite", (PyCFunction)CMS_object_pem_write, METH_VARARGS, NULL},
- {"derWrite", (PyCFunction)CMS_object_der_write, METH_VARARGS, NULL},
- {"sign", (PyCFunction)CMS_object_sign, METH_VARARGS, NULL},
- {"verify", (PyCFunction)CMS_object_verify, METH_VARARGS, NULL},
- {"eContentType", (PyCFunction)CMS_object_eContentType, METH_VARARGS, NULL},
- {"signingTime", (PyCFunction)CMS_object_signingTime, METH_VARARGS, NULL},
- {"pprint", (PyCFunction)CMS_object_pprint, METH_VARARGS, NULL},
- {"certs", (PyCFunction)CMS_object_certs, METH_VARARGS, NULL},
- {"crls", (PyCFunction)CMS_object_crls, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-
-static PyObject *
-CMS_object_getattr(cms_object *self, char *name)
-{
- return Py_FindMethod(CMS_object_methods, (PyObject *)self, name);
-}
-
-static void
-CMS_object_dealloc(cms_object *self, char *name)
-{
- CMS_ContentInfo_free(self->cms);
- PyObject_Del(self);
-}
-
-static char cmstype__doc__[] =
-"<class>\n"
-" <header>\n"
-" <name>CMS</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This class provides basic access OpenSSL's CMS functionality.\n"
-" </para>\n"
-" </body>\n"
-"</class>\n"
-;
-
-static PyTypeObject cmstype = {
- PyObject_HEAD_INIT(0)
- 0, /*ob_size*/
- "CMS", /*tp_name*/
- sizeof(cms_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)CMS_object_dealloc, /*tp_dealloc*/
- (printfunc)0, /*tp_print*/
- (getattrfunc)CMS_object_getattr, /*tp_getattr*/
- (setattrfunc)0, /*tp_setattr*/
- (cmpfunc)0, /*tp_compare*/
- (reprfunc)0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- (hashfunc)0, /*tp_hash*/
- (ternaryfunc)0, /*tp_call*/
- (reprfunc)0, /*tp_str*/
- 0,
- 0,
- 0,
- 0,
- cmstype__doc__ /* Documentation string */
-};
-/*========== CMS Code ==========*/
-
-/*========== module functions ==========*/
-static char pow_module_new_ssl__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>Ssl</memberof>\n"
-" <parameter>protocol = SSLV23METHOD</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor creates a new <classname>Ssl</classname> object which will behave as a client\n"
-" or server, depending on the <parameter>protocol</parameter> value passed. The\n"
-" <parameter>protocol</parameter> also determines the protocol type\n"
-" and version and should be one of the following:\n"
-" </para>\n"
-"\n"
-" <simplelist>\n"
-" <member><constant>SSLV2_SERVER_METHOD</constant></member>\n"
-" <member><constant>SSLV2_CLIENT_METHOD</constant></member>\n"
-" <member><constant>SSLV2_METHOD</constant></member>\n"
-" <member><constant>SSLV3_SERVER_METHOD</constant></member>\n"
-" <member><constant>SSLV3_CLIENT_METHOD</constant></member>\n"
-" <member><constant>SSLV3_METHOD</constant></member>\n"
-" <member><constant>TLSV1_SERVER_METHOD</constant></member>\n"
-" <member><constant>TLSV1_CLIENT_METHOD</constant></member>\n"
-" <member><constant>TLSV1_METHOD</constant></member>\n"
-" <member><constant>SSLV23_SERVER_METHOD</constant></member>\n"
-" <member><constant>SSLV23_CLIENT_METHOD</constant></member>\n"
-" <member><constant>SSLV23_METHOD</constant></member>\n"
-" </simplelist>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_ssl (PyObject *self, PyObject *args)
-{
- ssl_object *ssl = NULL;
- int ctxtype = SSLV23_METHOD;
-
- if (!PyArg_ParseTuple(args, "|i", &ctxtype))
- goto error;
-
- if ((ssl = newssl_object(ctxtype)) == NULL)
- goto error;
-
- return (PyObject*) ssl;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_x509__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>X509</memberof>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor creates a skeletal X509 certificate object.\n"
-" It won't be any use at all until several structures\n"
-" have been created using it's member functions.\n"
-" </para>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_x509 (PyObject *self, PyObject *args)
-{
- x509_object *x509 = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((x509 = X509_object_new()) == NULL)
- lose("could not create new x509 object");
-
- return (PyObject*)x509;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_asymmetric__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>Asymmetric</memberof>\n"
-" <parameter>ciphertype = RSA_CIPHER</parameter>\n"
-" <parameter>keylength = 1024</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor builds a new cipher object. Only RSA ciphers\n"
-" are currently support, so the first argument should always be\n"
-" <constant>RSA_CIPHER</constant>. The second argument,\n"
-" <parameter>keylength</parameter>,\n"
-" is normally 512, 768, 1024 or 2048. Key lengths as short as 512\n"
-" bits are generally considered weak, and can be cracked by\n"
-" determined attackers without tremendous expense.\n"
-" </para>\n"
-" <example>\n"
-" <title><classname>asymmetric</classname> class usage</title>\n"
-" <programlisting>\n"
-" privateFile = open('test/private.key', 'w')\n"
-" publicFile = open('test/public.key', 'w')\n"
-"\n"
-" passphrase = 'my silly passphrase'\n"
-" md5 = POW.Digest(POW.MD5_DIGEST)\n"
-" md5.update(passphrase)\n"
-" password = md5.digest()\n"
-"\n"
-" rsa = POW.Asymmetric(POW.RSA_CIPHER, 1024)\n"
-" privateFile.write(rsa.pemWrite(\n"
-" POW.RSA_PRIVATE_KEY, POW.DES_EDE3_CFB, password))\n"
-" publicFile.write(rsa.pemWrite(POW.RSA_PUBLIC_KEY))\n"
-"\n"
-" privateFile.close()\n"
-" publicFile.close()\n"
-" </programlisting>\n"
-" </example>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_asymmetric (PyObject *self, PyObject *args)
-{
- int cipher_type = RSA_CIPHER, key_size = 1024;
-
- if (!PyArg_ParseTuple(args, "|ii", &cipher_type, &key_size))
- goto error;
-
- return (PyObject*) asymmetric_object_new(cipher_type, key_size);
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_digest__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>Digest</memberof>\n"
-" <parameter>type</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor creates a new <classname>Digest</classname>\n"
-" object. The parameter <parameter>type</parameter> specifies what kind\n"
-" of digest to create and should be one of the following:\n"
-" </para>\n"
-" <simplelist>\n"
-#ifndef OPENSSL_NO_MD2
-" <member><constant>MD2_DIGEST</constant></member>\n"
-#endif
-" <member><constant>MD5_DIGEST</constant></member>\n"
-" <member><constant>SHA_DIGEST</constant></member>\n"
-" <member><constant>SHA1_DIGEST</constant></member>\n"
-" <member><constant>RIPEMD160_DIGEST</constant></member>\n"
-" <member><constant>SHA256_DIGEST</constant></member>\n"
-" <member><constant>SHA384_DIGEST</constant></member>\n"
-" <member><constant>SHA512_DIGEST</constant></member>\n"
-" </simplelist>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_digest (PyObject *self, PyObject *args)
-{
- int digest_type = 0;
-
- if (!PyArg_ParseTuple(args, "i", &digest_type))
- goto error;
-
- return (PyObject*) digest_object_new(digest_type);
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_hmac__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>Hmac</memberof>\n"
-" <parameter>type</parameter>\n"
-" <parameter>key</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor creates a new <classname>Hmac</classname>\n"
-" object. The parameter <parameter>key</parameter> should be a\n"
-" string and <parameter>type</parameter> should be one of the following:\n"
-" </para>\n"
-" <simplelist>\n"
-#ifndef OPENSSL_NO_MD2
-" <member><constant>MD2_DIGEST</constant></member>\n"
-#endif
-" <member><constant>MD5_DIGEST</constant></member>\n"
-" <member><constant>SHA_DIGEST</constant></member>\n"
-" <member><constant>SHA1_DIGEST</constant></member>\n"
-" <member><constant>RIPEMD160_DIGEST</constant></member>\n"
-" <member><constant>SHA256_DIGEST</constant></member>\n"
-" <member><constant>SHA384_DIGEST</constant></member>\n"
-" <member><constant>SHA512_DIGEST</constant></member>\n"
-" </simplelist>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_hmac (PyObject *self, PyObject *args)
-{
- int digest_type = 0, key_len = 0;
- char *key = NULL;
-
- if (!PyArg_ParseTuple(args, "is#", &digest_type, &key, &key_len))
- goto error;
-
- return (PyObject*) hmac_object_new(digest_type, key, key_len);
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_cms__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>CMS</memberof>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor creates a skeletal CMS object.\n"
-" </para>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_cms (PyObject *self, PyObject *args)
-{
- cms_object *cms = NULL;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- if ((cms = CMS_object_new()) == NULL)
- lose("could not create new CMS object");
-
- return (PyObject*)cms;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_pem_read__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>pemRead</name>\n"
-" <parameter>type</parameter>\n"
-" <parameter>string</parameter>\n"
-" <parameter>pass = None</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function attempts to parse the <parameter>string</parameter> according to the PEM\n"
-" type passed. <parameter>type</parameter> should be one of the\n"
-" following:\n"
-" </para>\n"
-" <simplelist>\n"
-" <member><constant>RSA_PUBLIC_KEY</constant></member>\n"
-" <member><constant>RSA_PRIVATE_KEY</constant></member>\n"
-" <member><constant>X509_CERTIFICATE</constant></member>\n"
-" <member><constant>X509_CRL</constant></member>\n"
-" <member><constant>CMS_MESSAGE</constant></member>\n"
-" </simplelist>\n"
-" <para>\n"
-" <parameter>pass</parameter> should only be provided if an encrypted\n"
-" <classname>Asymmetric</classname> is being loaded. If the password\n"
-" is incorrect an exception will be raised, if no password is provided\n"
-" and the PEM file is encrypted the user will be prompted. If this is\n"
-" not desirable, always supply a password. The object returned will be\n"
-" and instance of <classname>Asymmetric</classname>,\n"
-" <classname>X509</classname>, <classname>X509Crl</classname>,\n"
-" or <classname>CMS</classname>.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_pem_read (PyObject *self, PyObject *args)
-{
- BIO *in = NULL;
- PyObject *obj = NULL;
- int object_type = 0, len = 0;
- char *pass = NULL, *src = NULL;
-
- if (!PyArg_ParseTuple(args, "is#|s", &object_type, &src, &len, &pass))
- goto error;
-
- if ((in = BIO_new_mem_buf(src, len)) == NULL)
- lose("unable to create new BIO");
-
- switch(object_type) {
- case RSA_PRIVATE_KEY:
- obj = (PyObject*)asymmetric_object_pem_read(object_type, in, pass);
- break;
- case RSA_PUBLIC_KEY:
- obj = (PyObject*)asymmetric_object_pem_read(object_type, in, pass);
- break;
- case X509_CERTIFICATE:
- obj = (PyObject*)X509_object_pem_read(in);
- break;
- case X_X509_CRL:
- obj = (PyObject*)x509_crl_object_pem_read(in);
- break;
- case CMS_MESSAGE:
- obj = (PyObject*)CMS_object_pem_read(in);
- break;
- default:
- lose("unknown pem encoding");
- }
-
- BIO_free(in);
-
- if (obj)
- return obj;
-
- error:
-
- return NULL;
-}
-
-
-static char pow_module_der_read__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>derRead</name>\n"
-" <parameter>type</parameter>\n"
-" <parameter>string</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function attempts to parse the <parameter>string</parameter> according to the PEM\n"
-" type passed. <parameter>type</parameter> should be one of the\n"
-" following:\n"
-" </para>\n"
-" <simplelist>\n"
-" <member><constant>RSA_PUBLIC_KEY</constant></member>\n"
-" <member><constant>RSA_PRIVATE_KEY</constant></member>\n"
-" <member><constant>X509_CERTIFICATE</constant></member>\n"
-" <member><constant>X509_CRL</constant></member>\n"
-" <member><constant>CMS_MESSAGE</constant></member>\n"
-" </simplelist>\n"
-" <para>\n"
-" As with the PEM operations, the object returned will be and instance\n"
-" of <classname>Asymmetric</classname>, <classname>X509</classname>,\n"
-" <classname>X509Crl</classname>, or <classname>CMS</classname>.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_der_read (PyObject *self, PyObject *args)
-{
- PyObject *obj = NULL;
- int object_type = 0, len = 0;
- unsigned char *src = NULL;
-
- if (!PyArg_ParseTuple(args, "is#", &object_type, &src, &len))
- goto error;
-
- switch(object_type) {
- case RSA_PRIVATE_KEY:
- obj = (PyObject*) asymmetric_object_der_read(object_type, src, len);
- break;
- case RSA_PUBLIC_KEY:
- obj = (PyObject*) asymmetric_object_der_read(object_type, src, len);
- break;
- case X509_CERTIFICATE:
- obj = (PyObject*)X509_object_der_read(src, len);
- break;
- case X_X509_CRL:
- obj = (PyObject*)x509_crl_object_der_read(src, len);
- break;
- case CMS_MESSAGE:
- obj = (PyObject*)CMS_object_der_read((char *) src, len);
- break;
- default:
- lose("unknown der encoding");
- }
-
- if (obj)
- return obj;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_x509_store__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>X509Store</memberof>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor takes no arguments. The\n"
-" <classname>X509Store</classname> returned cannot be used for\n"
-" verifying certificates until at least one trusted certificate has been\n"
-" added.\n"
-" </para>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_x509_store (PyObject *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- return (PyObject *) x509_store_object_new();
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_symmetric__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>Symmetric</memberof>\n"
-" <parameter>type</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor creates a new <classname>Symmetric</classname>\n"
-" object. The parameter <parameter>type</parameter> specifies which kind\n"
-" of cipher to create. <constant>type</constant> should be one of the following:\n"
-" </para>\n"
-" <simplelist columns = \"2\">\n"
-" <member><constant>DES_ECB</constant></member>\n"
-" <member><constant>DES_EDE</constant></member>\n"
-" <member><constant>DES_EDE3</constant></member>\n"
-" <member><constant>DES_CFB</constant></member>\n"
-" <member><constant>DES_EDE_CFB</constant></member>\n"
-" <member><constant>DES_EDE3_CFB</constant></member>\n"
-" <member><constant>DES_OFB</constant></member>\n"
-" <member><constant>DES_EDE_OFB</constant></member>\n"
-" <member><constant>DES_EDE3_OFB</constant></member>\n"
-" <member><constant>DES_CBC</constant></member>\n"
-" <member><constant>DES_EDE_CBC</constant></member>\n"
-" <member><constant>DES_EDE3_CBC</constant></member>\n"
-" <member><constant>DESX_CBC</constant></member>\n"
-" <member><constant>RC4</constant></member>\n"
-" <member><constant>RC4_40</constant></member>\n"
-" <member><constant>IDEA_ECB</constant></member>\n"
-" <member><constant>IDEA_CFB</constant></member>\n"
-" <member><constant>IDEA_OFB</constant></member>\n"
-" <member><constant>IDEA_CBC</constant></member>\n"
-" <member><constant>RC2_ECB</constant></member>\n"
-" <member><constant>RC2_CBC</constant></member>\n"
-" <member><constant>RC2_40_CBC</constant></member>\n"
-" <member><constant>RC2_CFB</constant></member>\n"
-" <member><constant>RC2_OFB</constant></member>\n"
-" <member><constant>BF_ECB</constant></member>\n"
-" <member><constant>BF_CBC</constant></member>\n"
-" <member><constant>BF_CFB</constant></member>\n"
-" <member><constant>BF_OFB</constant></member>\n"
-" <member><constant>CAST5_ECB</constant></member>\n"
-" <member><constant>CAST5_CBC</constant></member>\n"
-" <member><constant>CAST5_CFB</constant></member>\n"
-" <member><constant>CAST5_OFB</constant></member>\n"
-" <member><constant>RC5_32_12_16_CBC</constant></member>\n"
-" <member><constant>RC5_32_12_16_CFB</constant></member>\n"
-" <member><constant>RC5_32_12_16_ECB</constant></member>\n"
-" <member><constant>RC5_32_12_16_OFB</constant></member>\n"
-" </simplelist>\n"
-" <para>\n"
-" Please note your version of OpenSSL might not have been compiled with\n"
-" all the ciphers listed above. If that is the case, which is very\n"
-" likely if you are using a stock binary, the unsuported ciphers will not even\n"
-" be in the module namespace.\n"
-" </para>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_symmetric (PyObject *self, PyObject *args)
-{
- int cipher_type = 0;
-
- if (!PyArg_ParseTuple(args, "i", &cipher_type))
- goto error;
-
- return (PyObject *) symmetric_object_new(cipher_type);
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_x509_crl__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>x509_crl</memberof>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor builds an empty CRL.\n"
-" </para>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_x509_crl (PyObject *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- return (PyObject *) x509_crl_object_new();
-
- error:
-
- return NULL;
-}
-
-static char pow_module_new_x509_revoked__doc__[] =
-"<constructor>\n"
-" <header>\n"
-" <memberof>X509Revoked</memberof>\n"
-" <parameter>serial</parameter>\n"
-" <parameter>date</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This constructor builds a X509 Revoked structure. <parameter>serial</parameter>\n"
-" should be an integer and <parameter>date</parameter> should be and\n"
-" UTCTime string.\n"
-" </para>\n"
-" </body>\n"
-"</constructor>\n"
-;
-
-static PyObject *
-pow_module_new_x509_revoked (PyObject *self, PyObject *args)
-{
- int serial = -1;
- char *date = NULL;
- x509_revoked_object *revoke = NULL;
-
- if (!PyArg_ParseTuple(args, "|is", &serial, &date))
- goto error;
-
- revoke = x509_revoked_object_new();
- if (serial != -1 && !ASN1_INTEGER_set(revoke->revoked->serialNumber, serial))
- lose("unable to set serial number");
-
- if (date != NULL && !python_ASN1_TIME_set_string(revoke->revoked->revocationDate, date))
- lose_type_error("Could not set revocationDate");
-
- return (PyObject*) revoke;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_add_object__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>addObject</name>\n"
-" <parameter>oid</parameter>\n"
-" <parameter>shortName</parameter>\n"
-" <parameter>longName</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function can be used to dynamically add new objects to\n"
-" OpenSSL. The <parameter>oid</parameter> should be a string of space separated numbers\n"
-" and <parameter>shortName</parameter> and\n"
-" <parameter>longName</parameter> are the names of the object, ie\n"
-" 'cn' and 'commonName'.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_add_object(PyObject *self, PyObject *args)
-{
- char *oid = NULL, *sn = NULL, *ln = NULL;
-
- if (!PyArg_ParseTuple(args, "sss", &oid, &sn, &ln))
- goto error;
-
- if (!OBJ_create(oid, sn, ln))
- lose("unable to add object");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_get_error__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>getError</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" Pops an error off the global error stack and returns it as a string.\n"
-" Returns None if the global error stack is empty.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_get_error(PyObject *self, PyObject *args)
-{
- unsigned long error;
- char buf[256];
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- error = ERR_get_error();
-
- if (!error)
- Py_RETURN_NONE;
-
- ERR_error_string_n(error, buf, sizeof(buf));
-
- return Py_BuildValue("s", buf);
-
- error:
-
- return NULL;
-}
-
-static char pow_module_clear_error__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>clearError</name>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" Removes all errors from the global error stack.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_clear_error(PyObject *self, PyObject *args)
-{
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- ERR_clear_error();
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_seed__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>seed</name>\n"
-" <parameter>data</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" The <function>seed</function> function adds data to OpenSSLs PRNG\n"
-" state. It is often said the hardest part of cryptography is\n"
-" getting good random data, after all if you don't have good random\n"
-" data, a 1024 bit key is no better than a 512 bit key and neither\n"
-" would provide protection from a targeted brute force attack.\n"
-" The <function>seed</function> and <function>add</function> are very\n"
-" similar, except the entropy of the data is assumed to be equal to\n"
-" the length for <function>seed</function>. One final point to be aware\n"
-" of, only systems which support /dev/urandom are automatically seeded.\n"
-" If your system does not support /dev/urandom it is your responsibility\n"
-" to seed OpenSSL's PRNG.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_seed(PyObject *self, PyObject *args)
-{
- char *in = NULL;
- int inl = 0;
-
- if (!PyArg_ParseTuple(args, "s#", &in, &inl))
- goto error;
-
- RAND_seed(in, inl);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_add__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>add</name>\n"
-" <parameter>data</parameter>\n"
-" <parameter>entropy</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" The <function>add</function> function adds data to OpenSSLs PRNG\n"
-" state. <parameter>data</parameter> should be data obtained from a\n"
-" random source and <parameter>entropy</parameter> is an estimation of the number of random\n"
-" bytes in <parameter>data</parameter>.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_add(PyObject *self, PyObject *args)
-{
- char *in = NULL;
- int inl = 0;
- double entropy = 0;
-
- if (!PyArg_ParseTuple(args, "s#d", &in, &inl, &entropy))
- goto error;
-
- RAND_add(in, inl, entropy);
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_write_random_file__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>writeRandomFile</name>\n"
-" <parameter>filename</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function writes the current random state to a file. Clearly\n"
-" this function should be used in conjunction with\n"
-" <function>readRandomFile</function>.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_write_random_file(PyObject *self, PyObject *args)
-{
- char *file = NULL;
-
- if (!PyArg_ParseTuple(args, "s", &file))
- goto error;
-
- if (RAND_write_file(file) == -1)
- lose("could not write random file");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static char pow_module_read_random_file__doc__[] =
-"<modulefunction>\n"
-" <header>\n"
-" <name>readRandomFile</name>\n"
-" <parameter>filename</parameter>\n"
-" </header>\n"
-" <body>\n"
-" <para>\n"
-" This function reads a previously saved random state. It can be very\n"
-" useful to improve the quality of random data used by an application.\n"
-" The random data should be added to, using the\n"
-" <function>add</function> function, with data from other\n"
-" suitable random sources.\n"
-" </para>\n"
-" </body>\n"
-"</modulefunction>\n"
-;
-
-static PyObject *
-pow_module_read_random_file(PyObject *self, PyObject *args)
-{
- char *file = NULL;
- int len = -1;
-
- if (!PyArg_ParseTuple(args, "s|i", &file, &len))
- goto error;
-
- if (!RAND_load_file(file, len))
- lose("could not load random file");
-
- Py_RETURN_NONE;
-
- error:
-
- return NULL;
-}
-
-static PyObject *
-pow_module_docset(PyObject *self, PyObject *args)
-{
- PyObject *docset;
-
- if (!PyArg_ParseTuple(args, ""))
- goto error;
-
- docset = PyList_New(0);
-
- // module documentation
- docset_helper_add(docset, pow_module__doc__);
-
- // constructors
- docset_helper_add(docset, pow_module_new_symmetric__doc__);
- docset_helper_add(docset, pow_module_new_asymmetric__doc__);
- docset_helper_add(docset, pow_module_new_digest__doc__);
- docset_helper_add(docset, pow_module_new_hmac__doc__);
- docset_helper_add(docset, pow_module_new_ssl__doc__);
- docset_helper_add(docset, pow_module_new_x509__doc__);
- docset_helper_add(docset, pow_module_new_x509_store__doc__);
- docset_helper_add(docset, pow_module_new_x509_crl__doc__);
- docset_helper_add(docset, pow_module_new_x509_revoked__doc__);
- docset_helper_add(docset, pow_module_new_cms__doc__);
-
- // functions
- docset_helper_add(docset, pow_module_pem_read__doc__);
- docset_helper_add(docset, pow_module_der_read__doc__);
- docset_helper_add(docset, pow_module_seed__doc__);
- docset_helper_add(docset, pow_module_add__doc__);
- docset_helper_add(docset, pow_module_read_random_file__doc__);
- docset_helper_add(docset, pow_module_write_random_file__doc__);
- docset_helper_add(docset, pow_module_get_error__doc__);
- docset_helper_add(docset, pow_module_clear_error__doc__);
- docset_helper_add(docset, pow_module_add_object__doc__);
-
- // ssl documentation
- docset_helper_add(docset, ssltype__doc__);
- docset_helper_add(docset, ssl_object_set_fd__doc__);
- docset_helper_add(docset, ssl_object_fileno__doc__);
- docset_helper_add(docset, ssl_object_accept__doc__);
- docset_helper_add(docset, ssl_object_connect__doc__);
- docset_helper_add(docset, ssl_object_write__doc__);
- docset_helper_add(docset, ssl_object_read__doc__);
- docset_helper_add(docset, ssl_object_peer_certificate__doc__);
- docset_helper_add(docset, ssl_object_use_certificate__doc__);
- docset_helper_add(docset, ssl_object_use_key__doc__);
- docset_helper_add(docset, ssl_object_check_key__doc__);
- docset_helper_add(docset, ssl_object_clear__doc__);
- docset_helper_add(docset, ssl_object_shutdown__doc__);
- docset_helper_add(docset, ssl_object_get_shutdown__doc__);
- docset_helper_add(docset, ssl_object_get_ciphers__doc__);
- docset_helper_add(docset, ssl_object_set_ciphers__doc__);
- docset_helper_add(docset, ssl_object_get_cipher__doc__);
- docset_helper_add(docset, ssl_object_set_verify_mode__doc__);
-
- // x509 documentation
- docset_helper_add(docset, x509type__doc__);
- docset_helper_add(docset, X509_object_pem_write__doc__);
- docset_helper_add(docset, X509_object_der_write__doc__);
- docset_helper_add(docset, X509_object_sign__doc__);
- docset_helper_add(docset, X509_object_set_public_key__doc__);
- docset_helper_add(docset, X509_object_get_version__doc__);
- docset_helper_add(docset, X509_object_set_version__doc__);
- docset_helper_add(docset, X509_object_get_serial__doc__);
- docset_helper_add(docset, X509_object_set_serial__doc__);
- docset_helper_add(docset, X509_object_get_issuer__doc__);
- docset_helper_add(docset, X509_object_set_issuer__doc__);
- docset_helper_add(docset, X509_object_get_subject__doc__);
- docset_helper_add(docset, X509_object_set_subject__doc__);
- docset_helper_add(docset, X509_object_get_not_before__doc__);
- docset_helper_add(docset, X509_object_set_not_before__doc__);
- docset_helper_add(docset, X509_object_get_not_after__doc__);
- docset_helper_add(docset, X509_object_set_not_after__doc__);
- docset_helper_add(docset, X509_object_add_extension__doc__);
- docset_helper_add(docset, X509_object_clear_extensions__doc__);
- docset_helper_add(docset, X509_object_count_extensions__doc__);
- docset_helper_add(docset, X509_object_get_extension__doc__);
- docset_helper_add(docset, x509_object_pprint__doc__);
-
- // x509_crl documentation
- docset_helper_add(docset, x509_crltype__doc__);
- docset_helper_add(docset, x509_crl_object_pem_write__doc__);
- docset_helper_add(docset, x509_crl_object_der_write__doc__);
- docset_helper_add(docset, x509_crl_object_get_version__doc__);
- docset_helper_add(docset, x509_crl_object_set_version__doc__);
- docset_helper_add(docset, x509_crl_object_get_issuer__doc__);
- docset_helper_add(docset, x509_crl_object_set_issuer__doc__);
- docset_helper_add(docset, x509_crl_object_get_this_update__doc__);
- docset_helper_add(docset, x509_crl_object_set_this_update__doc__);
- docset_helper_add(docset, x509_crl_object_get_next_update__doc__);
- docset_helper_add(docset, x509_crl_object_set_next_update__doc__);
- docset_helper_add(docset, x509_crl_object_get_revoked__doc__);
- docset_helper_add(docset, x509_crl_object_set_revoked__doc__);
- docset_helper_add(docset, x509_crl_object_verify__doc__);
- docset_helper_add(docset, x509_crl_object_sign__doc__);
- docset_helper_add(docset, X509_crl_object_add_extension__doc__);
- docset_helper_add(docset, X509_crl_object_clear_extensions__doc__);
- docset_helper_add(docset, X509_crl_object_count_extensions__doc__);
- docset_helper_add(docset, X509_crl_object_get_extension__doc__);
- docset_helper_add(docset, x509_crl_object_pprint__doc__);
-
- // x509_revoked documentation
- docset_helper_add(docset, x509_revokedtype__doc__);
- docset_helper_add(docset, x509_revoked_object_get_date__doc__);
- docset_helper_add(docset, x509_revoked_object_set_date__doc__);
- docset_helper_add(docset, x509_revoked_object_get_serial__doc__);
- docset_helper_add(docset, x509_revoked_object_set_serial__doc__);
- docset_helper_add(docset, X509_revoked_object_add_extension__doc__);
- docset_helper_add(docset, X509_revoked_object_clear_extensions__doc__);
- docset_helper_add(docset, X509_revoked_object_count_extensions__doc__);
- docset_helper_add(docset, X509_revoked_object_get_extension__doc__);
-
- // x509_store documentation
- docset_helper_add(docset, x509_storetype__doc__);
- docset_helper_add(docset, x509_store_object_verify__doc__);
- docset_helper_add(docset, x509_store_object_verify_chain__doc__);
- docset_helper_add(docset, x509_store_object_verify_detailed__doc__);
- docset_helper_add(docset, x509_store_object_add_trust__doc__);
- docset_helper_add(docset, x509_store_object_add_crl__doc__);
-
- // digest documentation
- docset_helper_add(docset, digesttype__doc__);
- docset_helper_add(docset, digest_object_update__doc__);
- docset_helper_add(docset, digest_object_copy__doc__);
- docset_helper_add(docset, digest_object_digest__doc__);
-
- // hmac documentation
- docset_helper_add(docset, hmactype__doc__);
- docset_helper_add(docset, hmac_object_update__doc__);
- docset_helper_add(docset, hmac_object_copy__doc__);
- docset_helper_add(docset, hmac_object_mac__doc__);
-
- // cms documentation
- docset_helper_add(docset, CMS_object_pem_write__doc__);
- docset_helper_add(docset, CMS_object_der_write__doc__);
- docset_helper_add(docset, CMS_object_sign__doc__);
- docset_helper_add(docset, CMS_object_verify__doc__);
- docset_helper_add(docset, CMS_object_eContentType__doc__);
- docset_helper_add(docset, CMS_object_signingTime__doc__);
- docset_helper_add(docset, CMS_object_pprint__doc__);
- docset_helper_add(docset, CMS_object_certs__doc__);
- docset_helper_add(docset, CMS_object_crls__doc__);
-
- // symmetric documentation
- docset_helper_add(docset, symmetrictype__doc__);
- docset_helper_add(docset, symmetric_object_encrypt_init__doc__);
- docset_helper_add(docset, symmetric_object_decrypt_init__doc__);
- docset_helper_add(docset, symmetric_object_update__doc__);
- docset_helper_add(docset, symmetric_object_final__doc__);
-
- // asymmetric documentation
- docset_helper_add(docset, asymmetrictype__doc__);
- docset_helper_add(docset, asymmetric_object_pem_write__doc__);
- docset_helper_add(docset, asymmetric_object_der_write__doc__);
- docset_helper_add(docset, asymmetric_object_public_encrypt__doc__);
- docset_helper_add(docset, asymmetric_object_public_decrypt__doc__);
- docset_helper_add(docset, asymmetric_object_private_encrypt__doc__);
- docset_helper_add(docset, asymmetric_object_private_decrypt__doc__);
- docset_helper_add(docset, asymmetric_object_sign__doc__);
- docset_helper_add(docset, asymmetric_object_verify__doc__);
-
- return docset;
-
- error:
-
- return NULL;
-}
-
-static struct PyMethodDef pow_module_methods[] = {
- {"Ssl", (PyCFunction)pow_module_new_ssl, METH_VARARGS, NULL},
- {"X509", (PyCFunction)pow_module_new_x509, METH_VARARGS, NULL},
- {"pemRead", (PyCFunction)pow_module_pem_read, METH_VARARGS, NULL},
- {"derRead", (PyCFunction)pow_module_der_read, METH_VARARGS, NULL},
- {"Digest", (PyCFunction)pow_module_new_digest, METH_VARARGS, NULL},
- {"Hmac", (PyCFunction)pow_module_new_hmac, METH_VARARGS, NULL},
- {"CMS", (PyCFunction)pow_module_new_cms, METH_VARARGS, NULL},
- {"Asymmetric", (PyCFunction)pow_module_new_asymmetric, METH_VARARGS, NULL},
- {"Symmetric", (PyCFunction)pow_module_new_symmetric, METH_VARARGS, NULL},
- {"X509Store", (PyCFunction)pow_module_new_x509_store, METH_VARARGS, NULL},
- {"X509Crl", (PyCFunction)pow_module_new_x509_crl, METH_VARARGS, NULL},
- {"X509Revoked", (PyCFunction)pow_module_new_x509_revoked, METH_VARARGS, NULL},
- {"getError", (PyCFunction)pow_module_get_error, METH_VARARGS, NULL},
- {"clearError", (PyCFunction)pow_module_clear_error, METH_VARARGS, NULL},
- {"seed", (PyCFunction)pow_module_seed, METH_VARARGS, NULL},
- {"add", (PyCFunction)pow_module_add, METH_VARARGS, NULL},
- {"readRandomFile", (PyCFunction)pow_module_read_random_file, METH_VARARGS, NULL},
- {"writeRandomFile", (PyCFunction)pow_module_write_random_file, METH_VARARGS, NULL},
- {"addObject", (PyCFunction)pow_module_add_object, METH_VARARGS, NULL},
-
- {"_docset", (PyCFunction)pow_module_docset, METH_VARARGS, NULL},
-
- {NULL} /* sentinel */
-};
-/*========== module functions ==========*/
-
-
-/*==========================================================================*/
-void
-init_POW(void)
-{
- PyObject *m;
-
- x509type.ob_type = &PyType_Type;
- x509_storetype.ob_type = &PyType_Type;
- x509_crltype.ob_type = &PyType_Type;
- x509_revokedtype.ob_type = &PyType_Type;
- ssltype.ob_type = &PyType_Type;
- asymmetrictype.ob_type = &PyType_Type;
- symmetrictype.ob_type = &PyType_Type;
- digesttype.ob_type = &PyType_Type;
- hmactype.ob_type = &PyType_Type;
- cmstype.ob_type = &PyType_Type;
-
- m = Py_InitModule3("_POW", pow_module_methods, pow_module__doc__);
-
-#define Define_Exception(__name__, __parent__) \
- PyModule_AddObject(m, #__name__, ((__name__##Object) = PyErr_NewException("POW." #__name__, __parent__, NULL)))
-
- Define_Exception(Error, NULL);
- Define_Exception(SSLError, ErrorObject);
- Define_Exception(ZeroReturnError, SSLErrorObject);
- Define_Exception(WantReadError, SSLErrorObject);
- Define_Exception(WantWriteError, SSLErrorObject);
- Define_Exception(SSLSyscallError, SSLErrorObject);
- Define_Exception(SSLErrorSSLError, SSLErrorObject);
- Define_Exception(SSLSyscallSSLError, SSLErrorObject);
- Define_Exception(SSLUnexpectedEOFError,SSLErrorObject);
- Define_Exception(SSLOtherError, SSLErrorObject);
-
-#undef Define_Exception
-
-#define Define_Integer_Constant(__name__) \
- PyModule_AddIntConstant(m, #__name__, __name__)
-
- // constants for SSL_get_error()
- Define_Integer_Constant(SSL_ERROR_NONE);
- Define_Integer_Constant(SSL_ERROR_ZERO_RETURN);
- Define_Integer_Constant(SSL_ERROR_WANT_READ);
- Define_Integer_Constant(SSL_ERROR_WANT_WRITE);
- Define_Integer_Constant(SSL_ERROR_WANT_X509_LOOKUP);
- Define_Integer_Constant(SSL_ERROR_SYSCALL);
- Define_Integer_Constant(SSL_ERROR_SSL);
- Define_Integer_Constant(SSL_ERROR_WANT_CONNECT);
- Define_Integer_Constant(SSL_ERROR_WANT_ACCEPT);
-
- // constants for different types of connection methods
- Define_Integer_Constant(SSLV2_SERVER_METHOD);
- Define_Integer_Constant(SSLV2_CLIENT_METHOD);
- Define_Integer_Constant(SSLV2_METHOD);
- Define_Integer_Constant(SSLV3_SERVER_METHOD);
- Define_Integer_Constant(SSLV3_CLIENT_METHOD);
- Define_Integer_Constant(SSLV3_METHOD);
- Define_Integer_Constant(SSLV23_SERVER_METHOD);
- Define_Integer_Constant(SSLV23_CLIENT_METHOD);
- Define_Integer_Constant(SSLV23_METHOD);
- Define_Integer_Constant(TLSV1_SERVER_METHOD);
- Define_Integer_Constant(TLSV1_CLIENT_METHOD);
- Define_Integer_Constant(TLSV1_METHOD);
-
- Define_Integer_Constant(SSL_NO_SHUTDOWN);
- Define_Integer_Constant(SSL_SENT_SHUTDOWN);
- Define_Integer_Constant(SSL_RECEIVED_SHUTDOWN);
-
- // ssl verification mode
- Define_Integer_Constant(SSL_VERIFY_NONE);
- Define_Integer_Constant(SSL_VERIFY_PEER);
- Define_Integer_Constant(SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
- Define_Integer_Constant(SSL_VERIFY_CLIENT_ONCE);
-
- // object format types
- Define_Integer_Constant(LONGNAME_FORMAT);
- Define_Integer_Constant(SHORTNAME_FORMAT);
-
- // PEM encoded types
-#ifndef OPENSSL_NO_RSA
- Define_Integer_Constant(RSA_PUBLIC_KEY);
- Define_Integer_Constant(RSA_PRIVATE_KEY);
-#endif
-#ifndef OPENSSL_NO_DSA
- Define_Integer_Constant(DSA_PUBLIC_KEY);
- Define_Integer_Constant(DSA_PRIVATE_KEY);
-#endif
-#ifndef OPENSSL_NO_DH
- Define_Integer_Constant(DH_PUBLIC_KEY);
- Define_Integer_Constant(DH_PRIVATE_KEY);
-#endif
- Define_Integer_Constant(X509_CERTIFICATE);
- PyModule_AddIntConstant(m, "X509_CRL", X_X509_CRL);
- Define_Integer_Constant(CMS_MESSAGE);
-
- // asymmetric ciphers
-#ifndef OPENSSL_NO_RSA
- Define_Integer_Constant(RSA_CIPHER);
-#endif
-#ifndef OPENSSL_NO_DSA
- Define_Integer_Constant(DSA_CIPHER);
-#endif
-#ifndef OPENSSL_NO_DH
- Define_Integer_Constant(DH_CIPHER);
-#endif
-
- // symmetric ciphers
-#ifndef OPENSSL_NO_DES
- Define_Integer_Constant(DES_ECB);
- Define_Integer_Constant(DES_EDE);
- Define_Integer_Constant(DES_EDE3);
- Define_Integer_Constant(DES_CFB);
- Define_Integer_Constant(DES_EDE_CFB);
- Define_Integer_Constant(DES_EDE3_CFB);
- Define_Integer_Constant(DES_OFB);
- Define_Integer_Constant(DES_EDE_OFB);
- Define_Integer_Constant(DES_EDE3_OFB);
- Define_Integer_Constant(DES_CBC);
- Define_Integer_Constant(DES_EDE_CBC);
- Define_Integer_Constant(DES_EDE3_CBC);
- Define_Integer_Constant(DESX_CBC);
-#endif
-#ifndef OPENSSL_NO_RC4
- Define_Integer_Constant(RC4);
- Define_Integer_Constant(RC4_40);
-#endif
-#ifndef OPENSSL_NO_IDEA
- Define_Integer_Constant(IDEA_ECB);
- Define_Integer_Constant(IDEA_CFB);
- Define_Integer_Constant(IDEA_OFB);
- Define_Integer_Constant(IDEA_CBC);
-#endif
-#ifndef OPENSSL_NO_RC2
- Define_Integer_Constant(RC2_ECB);
- Define_Integer_Constant(RC2_CBC);
- Define_Integer_Constant(RC2_40_CBC);
- Define_Integer_Constant(RC2_CFB);
- Define_Integer_Constant(RC2_OFB);
-#endif
-#ifndef OPENSSL_NO_BF
- Define_Integer_Constant(BF_ECB);
- Define_Integer_Constant(BF_CBC);
- Define_Integer_Constant(BF_CFB);
- Define_Integer_Constant(BF_OFB);
-#endif
- Define_Integer_Constant(CAST5_ECB);
- Define_Integer_Constant(CAST5_CBC);
- Define_Integer_Constant(CAST5_CFB);
- Define_Integer_Constant(CAST5_OFB);
-#ifndef OPENSSL_NO_RC5
- Define_Integer_Constant(RC5_32_12_16_CBC);
- Define_Integer_Constant(RC5_32_12_16_CFB);
- Define_Integer_Constant(RC5_32_12_16_ECB);
- Define_Integer_Constant(RC5_32_12_16_OFB);
-#endif
-
- // message digests
-#ifndef OPENSSL_NO_MD2
- Define_Integer_Constant(MD2_DIGEST);
-#endif
- Define_Integer_Constant(MD5_DIGEST);
- Define_Integer_Constant(SHA_DIGEST);
- Define_Integer_Constant(SHA1_DIGEST);
- Define_Integer_Constant(RIPEMD160_DIGEST);
- Define_Integer_Constant(SHA256_DIGEST);
- Define_Integer_Constant(SHA384_DIGEST);
- Define_Integer_Constant(SHA512_DIGEST);
-
- // general name
- Define_Integer_Constant(GEN_OTHERNAME);
- Define_Integer_Constant(GEN_EMAIL);
- Define_Integer_Constant(GEN_DNS);
- Define_Integer_Constant(GEN_X400);
- Define_Integer_Constant(GEN_DIRNAME);
- Define_Integer_Constant(GEN_EDIPARTY);
- Define_Integer_Constant(GEN_URI);
- Define_Integer_Constant(GEN_IPADD);
- Define_Integer_Constant(GEN_RID);
-
- // CMS flags
- Define_Integer_Constant(CMS_NOCERTS);
- Define_Integer_Constant(CMS_NOATTR);
- Define_Integer_Constant(CMS_NOINTERN);
- Define_Integer_Constant(CMS_NOCRL);
- Define_Integer_Constant(CMS_NO_SIGNER_CERT_VERIFY);
- Define_Integer_Constant(CMS_NO_ATTR_VERIFY);
- Define_Integer_Constant(CMS_NO_CONTENT_VERIFY);
-
-#undef Define_Integer_Constant
-
- // initialise library
- SSL_library_init();
- OpenSSL_add_all_algorithms();
- OpenSSL_add_all_ciphers();
- OpenSSL_add_all_digests();
-
- // load error strings
- SSL_load_error_strings();
-
- if (PyErr_Occurred())
- Py_FatalError("Can't initialize module POW");
-}
-/*==========================================================================*/
-
-/*
- * Local Variables:
- * indent-tabs-mode: nil
- * End:
- */