/*****************************************************************************/ /* */ /* 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // 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 PKCS7_MESSAGE 9 #define CMS_MESSAGE 10 // Asymmetric ciphers #define RSA_CIPHER 1 #define DSA_CIPHER 2 #define DH_CIPHER 3 //#define NO_DSA //#define NO_DH // Digests #define MD2_DIGEST 1 #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_pkcs7_Check(op) ((op)->ob_type == &pkcs7type) #define X_cms_Check(op) ((op)->ob_type == &cmstype) static char pow_module__doc__ [] = "\n" "
\n" " POW\n" " Peter Shannon\n" "
\n" " \n" " \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 directoryNames and\n" " generalNames. 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" " certificatePolicies coding coding routines in C\n" " to handle the data proved laborous and ultimately error prone.\n" " \n" " \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" " Name 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" " \n" " \n" " functionality have been plugged. The Ssl 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" " \n" " \n" "
\n" ; /*========== Pre-definitions ==========*/ static PyObject *SSLErrorObject; static PyTypeObject x509type; static PyTypeObject x509_storetype; static PyTypeObject x509_crltype; static PyTypeObject x509_revokedtype; static PyTypeObject asymmetrictype; static PyTypeObject symmetrictype; static PyTypeObject digesttype; static PyTypeObject hmactype; static PyTypeObject ssltype; static PyTypeObject pkcs7type; static PyTypeObject cmstype; /*========== Pre-definitions ==========*/ /*========== C stucts ==========*/ 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; } ssl_object; typedef struct { PyObject_HEAD PKCS7 *pkcs7; } pkcs7_object; typedef struct { PyObject_HEAD CMS_ContentInfo *cms; } cms_object; /*========== C structs ==========*/ /*========== helper functions ==========*/ /* Simple function to install a constant in the module name space. */ static void install_int_const( PyObject *d, char *name, long value ) { PyObject *v = PyInt_FromLong(value); if (!v || PyDict_SetItemString(d, name, v) ) PyErr_Clear(); Py_XDECREF(v); } int docset_helper_add(PyObject *set, char *v) { PyObject *value=NULL; if ( !(value = PyString_FromString(v) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( PyList_Append( set, value ) != 0) goto error; return 1; error: Py_XDECREF(value); return 0; } /* Generate an encrypion envelope. Saves a lot of space having thie 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; } } static PyObject * ssl_err_factory(int err) { switch(err) { case SSL_ERROR_NONE: return Py_BuildValue( "(is)", SSL_ERROR_NONE, "SSL_ERROR_NONE" ); case SSL_ERROR_ZERO_RETURN: return Py_BuildValue( "(is)", SSL_ERROR_ZERO_RETURN, "SSL_ERROR_ZERO_RETURN" ); case SSL_ERROR_WANT_READ: return Py_BuildValue( "(is)", SSL_ERROR_WANT_READ, "SSL_ERROR_WANT_READ" ); case SSL_ERROR_WANT_WRITE: return Py_BuildValue( "(is)", SSL_ERROR_WANT_WRITE, "SSL_ERROR_WANT_WRITE" ); case SSL_ERROR_WANT_X509_LOOKUP: return Py_BuildValue( "(is)", SSL_ERROR_WANT_X509_LOOKUP, "SSL_ERROR_WANT_X509_LOOKUP" ); case SSL_ERROR_SYSCALL: return Py_BuildValue( "(is)", SSL_ERROR_SYSCALL, "SSL_ERROR_SYSCALL" ); case SSL_ERROR_SSL: return Py_BuildValue( "(is)", SSL_ERROR_SSL, "SSL_ERROR_SSL" ); default: return Py_BuildValue( "(is)", err, "UNKOWN_SSL_ERROR" ); } } 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; char *valueptr = NULL, *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) ) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } if ( PySequence_Size(pair) != 2 ) { PyErr_SetString( SSLErrorObject, "each name entry must have 2 elements" ); goto error; } if ( !(type = PySequence_GetItem( pair, 0 ) ) ) { PyErr_SetString( PyExc_TypeError, "could not get type string" ); goto error; } if ( !PyString_Check(type) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } if ( !( value = PySequence_GetItem( pair, 1 ) ) ) { PyErr_SetString( PyExc_TypeError, "could not get value string" ); goto error; } if ( !PyString_Check(value) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } typeptr = PyString_AsString(type); valueptr = PyString_AsString(value); str_type = ASN1_PRINTABLE_type( valueptr, -1 ); if ( !(nid = OBJ_ln2nid(typeptr)) ) if ( !(nid = OBJ_sn2nid(typeptr)) ) { PyErr_SetString( SSLErrorObject, "unknown ASN1 object" ); goto error; } if ( !X509_NAME_add_entry_by_NID( name, nid, str_type, valueptr, strlen(valueptr), -1, 0 ) ) { PyErr_SetString( SSLErrorObject, "unable to add name entry" ); goto error; } Py_DECREF(pair); Py_DECREF(type); Py_DECREF(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 ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } for(i=0; ivalue->length + 1 > value_len) { if (value) free(value); if ( !(value = malloc( entry->value->length + 1 ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } 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) ) ) { PyErr_SetString( SSLErrorObject, "could not object name" ); goto error; } if ( format == SHORTNAME_FORMAT ) { nid = OBJ_ln2nid( long_name ); short_name = OBJ_nid2sn( nid ); py_type = PyString_FromString(short_name); } else if ( format == LONGNAME_FORMAT ) py_type = PyString_FromString(long_name); else { PyErr_SetString( SSLErrorObject, "unkown name format" ); goto error; } py_value = PyString_FromString(value); if ( !(pair = PyTuple_New( 2 ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } 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_DECREF( py_value ); } } } Py_XDECREF(py_type); Py_XDECREF(py_value); Py_XDECREF(result_list); return NULL; } static void set_openssl_pyerror(const char *msg) { char *buf = NULL; BIO *bio = NULL; int len; if (!(bio = BIO_new(BIO_s_mem()))) goto error; BIO_puts(bio, msg); BIO_puts(bio, ":\n"); ERR_print_errors(bio); if (!(len = BIO_ctrl_pending(bio))) goto error; if (!(buf = malloc(len + 1))) goto error; if (BIO_read(bio, buf, len) != len) goto error; buf[len] = '\0'; PyErr_SetString(SSLErrorObject, buf); /* fall through */ error: if (bio) BIO_free(bio); if (buf) free(buf); } static STACK_OF(X509) * x509_helper_sequence_to_stack(PyObject *x509_sequence) { x509_object *tmpX509 = 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) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } if (!(x509_stack = sk_X509_new_null() ) ) { PyErr_SetString( SSLErrorObject, "could not create new x509 stack" ); goto error; } if ( x509_sequence != Py_None ) { size = PySequence_Size( x509_sequence ); for (i=0; i < size; i++) { if ( !( tmpX509 = (x509_object*)PySequence_GetItem( x509_sequence, i ) ) ) goto error; if ( !X_X509_Check( tmpX509 ) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } if (!sk_X509_push( x509_stack, tmpX509->x509 ) ) { PyErr_SetString( SSLErrorObject, "could not add x509 to stack" ); goto error; } Py_DECREF(tmpX509); tmpX509 = NULL; } } return x509_stack; error: if(x509_stack) sk_X509_free(x509_stack); Py_XDECREF(tmpX509); return NULL; } /*========== 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 ) ) ) goto error; if( !(self->x509 = PEM_read_bio_X509( in, NULL, NULL, NULL ) ) ) { PyErr_SetString( SSLErrorObject, "could not load PEM encoded certificate" ); goto error; } return self; error: Py_XDECREF(self); return NULL; } static x509_object * X509_object_der_read(char *src, int len) { x509_object *self; unsigned char *ptr = src; if ( !(self = PyObject_New( x509_object, &x509type ) ) ) goto error; self->x509 = X509_new(); if( !(d2i_X509( &self->x509, (const unsigned char **) &ptr, len ) ) ) { PyErr_SetString( SSLErrorObject, "could not load PEM encoded certificate" ); goto error; } 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()); if (format == DER_FORMAT) { if (!i2d_X509_bio(out_bio, self->x509) ) { PyErr_SetString( SSLErrorObject, "unable to write certificate" ); goto error; } } else if (format == PEM_FORMAT) { if (!PEM_write_bio_X509(out_bio, self->x509) ) { PyErr_SetString( SSLErrorObject, "unable to write certificate" ); goto error; } } else { PyErr_SetString( SSLErrorObject, "internal error, unkown output format" ); goto error; } if ( !(len = BIO_ctrl_pending(out_bio) ) ) { PyErr_SetString( SSLErrorObject, "unable to get bytes stored in bio" ); goto error; } if ( !(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( BIO_read( out_bio, buf, len ) != len ) { PyErr_SetString( SSLErrorObject, "unable to write out cert" ); goto error; } 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__[] = "\n" "
\n" " X509\n" " pemWrite\n" "
\n" " \n" " \n" " This method returns a PEM encoded certificate as a\n" " string.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " X509\n" " derWrite\n" "
\n" " \n" " \n" " This method returns a DER encoded certificate as a\n" " string.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " X509\n" " setPublicKey\n" " key\n" "
\n" " \n" " \n" " This method sets the public key for this certificate object. The\n" " parameter key should be an instance of\n" " Asymmetric containing a public key.\n" " \n" " \n" "
\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() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !(EVP_PKEY_assign_RSA(pkey, asym->cipher) ) ) { PyErr_SetString( SSLErrorObject, "EVP_PKEY assignment error" ); goto error; } if ( !(X509_set_pubkey(self->x509,pkey) ) ) { PyErr_SetString( SSLErrorObject, "could not set certificate's public key" ); goto error; } return Py_BuildValue(""); error: if (pkey) EVP_PKEY_free(pkey); return NULL; } static char X509_object_sign__doc__[] = "\n" "
\n" " X509\n" " sign\n" " key\n" " digest=MD5_DIGEST\n" "
\n" " \n" " \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. key should be an instance of\n" " Asymmetric containing a private key.\n" " The optional parameter digest indicates \n" " which digest function should be used to compute the hash to be \n" " signed, it should be one of the following:\n" " \n" " \n" " MD2_DIGEST\n" " MD5_DIGEST\n" " SHA_DIGEST\n" " SHA1_DIGEST\n" " RIPEMD160_DIGEST\n" " SHA256_DIGEST\n" " SHA384_DIGEST\n" " SHA512_DIGEST\n" " \n" " \n" "
\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() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if (asym->key_type != RSA_PRIVATE_KEY) { PyErr_SetString( SSLErrorObject, "cannot use this type of key" ); goto error; } if ( !(EVP_PKEY_assign_RSA(pkey, asym->cipher) ) ) { PyErr_SetString( SSLErrorObject, "EVP_PKEY assignment error" ); goto error; } switch (digest) { case MD5_DIGEST: { if (!X509_sign(self->x509, pkey, EVP_md5() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case MD2_DIGEST: { if (!X509_sign(self->x509, pkey, EVP_md2() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA_DIGEST: { if (!X509_sign(self->x509, pkey, EVP_sha() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA1_DIGEST: { if (!X509_sign(self->x509, pkey, EVP_sha1() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case RIPEMD160_DIGEST: { if (!X509_sign(self->x509, pkey, EVP_ripemd160() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA256_DIGEST: { if (!X509_sign(self->x509, pkey, EVP_sha256() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA384_DIGEST: { if (!X509_sign(self->x509, pkey, EVP_sha384() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA512_DIGEST: { if (!X509_sign(self->x509, pkey, EVP_sha512() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } } return Py_BuildValue(""); error: if (pkey) EVP_PKEY_free(pkey); return NULL; } static char X509_object_get_version__doc__[] = "\n" "
\n" " X509\n" " getVersion\n" "
\n" " \n" " \n" " This method returns the version number from the version field of\n" " this certificate. \n" " \n" " \n" "
\n" ; static PyObject * X509_object_get_version(x509_object *self, PyObject *args) { long version=0; if (!PyArg_ParseTuple(args, "")) goto error; if ( !(version = X509_get_version( self->x509 ) ) ) { PyErr_SetString( SSLErrorObject, "could not get certificate version" ); goto error; } return Py_BuildValue("l", version); error: return NULL; } static char X509_object_set_version__doc__[] = "\n" "
\n" " X509\n" " setVersion\n" " version\n" "
\n" " \n" " \n" " This method sets the version number in the version field of\n" " this certificate. version should be an\n" " integer.\n" " \n" " \n" "
\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 ) ) { PyErr_SetString( SSLErrorObject, "could not set certificate version" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char X509_object_get_serial__doc__[] = "\n" "
\n" " X509\n" " getSerial\n" "
\n" " \n" " \n" " This method get the serial number in the serial field of\n" " this certificate.\n" " \n" " \n" "
\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 ) ) ) { PyErr_SetString( SSLErrorObject, "could not get serial number" ); goto error; } if ( (serial = ASN1_INTEGER_get(asn1i) ) == -1 ) { PyErr_SetString( SSLErrorObject, "could not convert ASN1 Integer to long" ); goto error; } return Py_BuildValue("l", serial); error: return NULL; } static char X509_object_set_serial__doc__[] = "\n" "
\n" " X509\n" " setSerial\n" " serial\n" "
\n" " \n" " \n" " This method sets the serial number in the serial field of\n" " this certificate. serial should ba an\n" " integer.\n" " \n" " \n" "
\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() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !ASN1_INTEGER_set( asn1i, serial ) ) { PyErr_SetString( SSLErrorObject, "could not set ASN1 integer" ); goto error; } if ( !X509_set_serialNumber( self->x509, asn1i ) ) { PyErr_SetString( SSLErrorObject, "could not set certificate serial" ); goto error; } ASN1_INTEGER_free(asn1i); return Py_BuildValue(""); error: if (asn1i) ASN1_INTEGER_free(asn1i); return NULL; } static char X509_object_get_issuer__doc__[] = "\n" "
\n" " X509\n" " getIssuer\n" " format=SHORTNAME_FORMAT\n" "
\n" " \n" " \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" " \n" " \n" " c or countryName\n" " st or stateOrProvinceName\n" " o or organizationName\n" " l or localityName\n" " ou or organizationalUnitName\n" " cn or commonName\n" " \n" " \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" " \n" " \n" "
\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 ) ) ) { PyErr_SetString( SSLErrorObject, "could not get issuers name" ); goto error; } if ( !(result_list = X509_object_helper_get_name(name, format) ) ) { PyErr_SetString( SSLErrorObject, "failed to produce name list" ); goto error; } return result_list; error: return NULL; } static char X509_object_get_subject__doc__[] = "\n" "
\n" " X509\n" " getSubject\n" " format=SHORTNAME_FORMAT\n" "
\n" " \n" " \n" " This method returns a tuple containing the subjects name. See\n" " getIssuer for a description of the returned\n" " object's format.\n" " \n" " \n" "
\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 ) ) ) { PyErr_SetString( SSLErrorObject, "could not get issuers name" ); goto error; } if ( !(result_list = X509_object_helper_get_name(name, format) ) ) { PyErr_SetString( SSLErrorObject, "failed to produce name list" ); goto error; } return result_list; error: return NULL; } static char X509_object_set_subject__doc__[] = "\n" "
\n" " X509\n" " setSubject\n" " name\n" "
\n" " \n" " \n" " This method is used to set the subjects name.\n" " name can be comprised of lists or tuples in\n" " the format described in the getIssuer method.\n" " \n" " \n" "
\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) ) ) { PyErr_SetString( PyExc_TypeError, "Inapropriate type" ); goto error; } if ( !(name = X509_NAME_new() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !X509_object_helper_set_name(name, name_sequence) ) { PyErr_SetString( SSLErrorObject, "unable to set new name" ); goto error; } if ( !X509_set_subject_name(self->x509,name) ) { PyErr_SetString( SSLErrorObject, "unable to set name" ); goto error; } X509_NAME_free(name); return Py_BuildValue(""); error: return NULL; } static char X509_object_set_issuer__doc__[] = "\n" "
\n" " X509\n" " setIssuer\n" " name\n" "
\n" " \n" " \n" " This method is used to set the issuers name.\n" " name can be comprised of lists or tuples in\n" " the format described in the getissuer method.\n" " \n" " \n" "
\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) ) ) { PyErr_SetString( PyExc_TypeError, "Inapropriate type" ); goto error; } if ( !(name = X509_NAME_new() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !X509_object_helper_set_name(name, name_sequence) ) { PyErr_SetString( SSLErrorObject, "unable to set new name" ); goto error; } if ( !X509_set_issuer_name(self->x509,name) ) { PyErr_SetString( SSLErrorObject, "unable to set name" ); goto error; } X509_NAME_free(name); return Py_BuildValue(""); error: if (name) X509_NAME_free(name); return NULL; } static char X509_object_get_not_before__doc__[] = "\n" "
\n" " X509\n" " getNotBefore\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * X509_object_get_not_before (x509_object *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) goto error; return Py_BuildValue("s", self->x509->cert_info->validity->notBefore->data); error: return NULL; } static char X509_object_get_not_after__doc__[] = "\n" "
\n" " X509\n" " getNotAfter\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * X509_object_get_not_after (x509_object *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) goto error; return Py_BuildValue("s", self->x509->cert_info->validity->notAfter->data); error: return NULL; } static char X509_object_set_not_after__doc__[] = "\n" "
\n" " X509\n" " setNotAfter\n" " time\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * X509_object_set_not_after (x509_object *self, PyObject *args) { //int new_time = 0; char *new_time=NULL; if (!PyArg_ParseTuple(args, "s", &new_time)) goto error; if ( !ASN1_UTCTIME_set_string(self->x509->cert_info->validity->notAfter, new_time) ) { PyErr_SetString( SSLErrorObject, "could not set time" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char X509_object_set_not_before__doc__[] = "\n" "
\n" " X509\n" " setNotBefore\n" " time\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * X509_object_set_not_before (x509_object *self, PyObject *args) { //int new_time = 0; char *new_time=NULL; if (!PyArg_ParseTuple(args, "s", &new_time)) goto error; if ( !ASN1_UTCTIME_set_string(self->x509->cert_info->validity->notBefore, new_time) ) { PyErr_SetString( SSLErrorObject, "could not set time" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char X509_object_add_extension__doc__[] = "\n" "
\n" " X509\n" " addExtension\n" " extensionName\n" " critical\n" " extensionValue\n" "
\n" " \n" " \n" " This method adds an extension to this certificate.\n" " extensionName should be the of the\n" " extension. critical should an integer, 1\n" " for true and 0 for false. extensionValue\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 objects.h header file, part of\n" " the OpenSSL source distribution. In the majority of cases they\n" " are the same as those defined in POW._oids\n" " but if you do encounter problems is may be worth checking.\n" " \n" " \n" " <function>addExtension</function> method usage\n" " \n" " basic = POW.pkix.BasicConstraints()\n" " basic.set([1,5]) \n" " serverCert.addExtension( 'basicConstraints', 0, basic.toString())\n" " \n" " \n" " \n" "
\n" ; static PyObject * X509_object_add_extension(x509_object *self, PyObject *args) { int critical=0, nid=0, len=0; char *name=NULL, *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() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !ASN1_OCTET_STRING_set(octetString, buf, len) ) { PyErr_SetString( SSLErrorObject, "could not set ASN1 Octect string" ); goto error; } if ( NID_undef == (nid = OBJ_txt2nid(name) ) ) { PyErr_SetString( SSLErrorObject, "extension has unknown object identifier" ); goto error; } if ( !( extn = X509_EXTENSION_create_by_NID(NULL, nid, critical, octetString) ) ) { PyErr_SetString( SSLErrorObject, "unable to create ASN1 X509 Extension object" ); goto error; } if (!self->x509->cert_info->extensions) if ( !(self->x509->cert_info->extensions = sk_X509_EXTENSION_new_null() ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( !sk_X509_EXTENSION_push(self->x509->cert_info->extensions, extn) ) { PyErr_SetString( SSLErrorObject, "unable to add extension" ); goto error; } return Py_BuildValue(""); error: if(extn) X509_EXTENSION_free(extn); return NULL; } static char X509_object_clear_extensions__doc__[] = "\n" "
\n" " X509\n" " clearExtensions\n" "
\n" " \n" " \n" " This method clears the structure which holds the extension for\n" " this certificate.\n" " \n" " \n" "
\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; } return Py_BuildValue(""); error: return NULL; } static char X509_object_count_extensions__doc__[] = "\n" "
\n" " X509\n" " countExtensions\n" "
\n" " \n" " \n" " This method returns the size of the structure which holds the\n" " extension for this certificate.\n" " \n" " \n" "
\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); } else return Py_BuildValue("i", 0); error: return NULL; } static char X509_object_get_extension__doc__[] = "\n" "
\n" " X509\n" " getExtension\n" " index\n" "
\n" " \n" " \n" " This method returns a tuple equivalent the parameters of\n" " addExtension.\n" " \n" " \n" "
\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 [] = "unkown"; 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); } else num = 0; if (index >= num) { PyErr_SetString( SSLErrorObject, "certificate does not have that many extensions" ); goto error; } if ( !(ext = sk_X509_EXTENSION_value(self->x509->cert_info->extensions, index) ) ) { PyErr_SetString( SSLErrorObject, "could not get extension" ); goto error; } if ( NID_undef == (ext_nid = OBJ_obj2nid(ext->object) ) ) { PyErr_SetString( SSLErrorObject, "extension has unknown object identifier" ); goto error; } if ( NULL == (ext_ln = OBJ_nid2sn(ext_nid) ) ) 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__[] = "\n" "
\n" " X509\n" " pprint\n" "
\n" " \n" " \n" " This method returns a formatted string showing the information\n" " held in the certificate.\n" " \n" " \n" "
\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) ) { PyErr_SetString( SSLErrorObject, "unable to write crl" ); goto error; } if ( !(len = BIO_ctrl_pending(out_bio) ) ) { PyErr_SetString( SSLErrorObject, "unable to get bytes stored in bio" ); goto error; } if ( !(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( (ret = BIO_read( out_bio, buf, len ) ) != len ) { PyErr_SetString( SSLErrorObject, "unable to write out cert" ); goto error; } 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, 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__[] = "\n" "
\n" " X509\n" "
\n" " \n" " \n" " This class provides access to a significant proportion of X509 \n" " functionality of OpenSSL.\n" " \n" "\n" " \n" " <classname>x509</classname> class usage\n" " \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" " \n" " \n" "\n" " \n" "
\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; self = PyObject_New( x509_store_object, &x509_storetype ); if (self == NULL) goto error; self->store = X509_STORE_new(); return self; error: Py_XDECREF(self); return NULL; } static char x509_store_object_verify__doc__[] = "\n" "
\n" " X509Store\n" " verify\n" " certificate\n" "
\n" " \n" " \n" " The X509Store method\n" " verify is based on the\n" " X509_verify_cert. It handles certain aspects\n" " of verification but not others. The certificate will be verified\n" " against notBefore, \n" " notAfter 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" " \n" " \n" "
\n" ; static PyObject * x509_store_object_verify(x509_store_object *self, PyObject *args) { X509_STORE_CTX csc; x509_object *x509=NULL; int result=0; if (!PyArg_ParseTuple(args, "O!", &x509type, &x509)) goto error; X509_STORE_CTX_init( &csc, self->store, x509->x509, NULL ); result = X509_verify_cert( &csc ); X509_STORE_CTX_cleanup( &csc ); return Py_BuildValue("i", result); error: return NULL; } static char x509_store_object_verify_chain__doc__[] = "\n" "
\n" " X509Store\n" " verifyChain\n" " certificate\n" " chain\n" "
\n" " \n" " \n" " The X509Store method verifyChain \n" " is based on the X509_verify_cert but is initialised \n" " with a X509 object to verify and list of \n" " X509 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 notBefore, \n" " notAfter 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" " \n" " \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" " \n" " \n" "
\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 result = 0; if (!PyArg_ParseTuple(args, "O!O", &x509type, &x509, &x509_sequence)) goto error; if ( !(x509_stack = x509_helper_sequence_to_stack(x509_sequence)) ) goto error; X509_STORE_CTX_init( &csc, self->store, x509->x509, x509_stack ); result = X509_verify_cert( &csc ); X509_STORE_CTX_cleanup( &csc ); sk_X509_free(x509_stack); return Py_BuildValue("i", result); error: if(x509_stack) sk_X509_free(x509_stack); return NULL; } static char x509_store_object_add_trust__doc__[] = "\n" "
\n" " X509Store\n" " addTrust\n" " cert\n" "
\n" " \n" " \n" " This method adds a new certificate to the store to be used in the\n" " verification process. cert should be an\n" " instance of X509. 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" " \n" " \n" "
\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 ); return Py_BuildValue(""); error: return NULL; } static char x509_store_object_add_crl__doc__[] = "\n" "
\n" " X509Store\n" " addCrl\n" " crl\n" "
\n" " \n" " \n" " This method adds a CRL to a store to be used for verification.\n" " crl should be an instance of\n" " X509Crl.\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" " \n" " \n" "
\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 ); return Py_BuildValue(""); 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}, {"addTrust", (PyCFunction)x509_store_object_add_trust, METH_VARARGS, NULL}, {"addCrl", (PyCFunction)x509_store_object_add_crl, METH_VARARGS, NULL}, {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__[] = "\n" "
\n" " X509Store\n" "
\n" " \n" " \n" " This class provides preliminary access to OpenSSL X509 verification\n" " facilities.\n" " \n" "\n" " \n" " <classname>x509_store</classname> class usage\n" " \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" " \n" " \n" " \n" "
\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; self = PyObject_New( x509_crl_object, &x509_crltype ); if (self == NULL) goto error; if( !(self->crl = PEM_read_bio_X509_CRL( in, NULL, NULL, NULL ) ) ) { PyErr_SetString( SSLErrorObject, "could not load certificate" ); goto error; } return self; error: Py_XDECREF(self); return NULL; } static x509_crl_object * x509_crl_object_der_read(char *src, int len) { x509_crl_object *self; unsigned char* ptr = src; if ( !(self = PyObject_New( x509_crl_object, &x509_crltype ) ) ) goto error; self->crl = X509_CRL_new(); if( !(d2i_X509_CRL( &self->crl, (const unsigned char **) &ptr, len ) ) ) { PyErr_SetString( SSLErrorObject, "could not load PEM encoded CRL" ); goto error; } return self; error: Py_XDECREF(self); return NULL; } static char x509_crl_object_get_version__doc__[] = "\n" "
\n" " X509Crl\n" " getVersion\n" "
\n" " \n" " \n" " This method returns the version number from the version field of\n" " this CRL. \n" " \n" " \n" "
\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 ) { PyErr_SetString( SSLErrorObject, "could not get crl version" ); goto error; } return Py_BuildValue("l", version); error: return NULL; } static char x509_crl_object_set_version__doc__[] = "\n" "
\n" " X509Crl\n" " setVersion\n" " version\n" "
\n" " \n" " \n" " This method sets the version number in the version field of\n" " this CRL. version should be an\n" " integer.\n" " \n" " \n" "
\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() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !ASN1_INTEGER_set( asn1_version, version ) ) { PyErr_SetString( SSLErrorObject, "could not get set version" ); goto error; } self->crl->crl->version = asn1_version; return Py_BuildValue(""); error: if (asn1_version) ASN1_INTEGER_free(asn1_version); return NULL; } static char x509_crl_object_get_issuer__doc__[] = "\n" "
\n" " X509Crl\n" " getIssuer\n" " format=SHORTNAME_FORMAT\n" "
\n" " \n" " \n" " This method returns a tuple containing the issuers name. See the\n" " getIssuer method of\n" " X509 for more details.\n" " \n" " \n" "
\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) ) ) { PyErr_SetString( SSLErrorObject, "failed to produce name list" ); goto error; } return result_list; error: return NULL; } static char x509_crl_object_set_issuer__doc__[] = "\n" "
\n" " X509Crl\n" " setIssuer\n" " name\n" "
\n" " \n" " \n" " This method is used to set the issuers name.\n" " name can be comprised of lists or tuples in\n" " the format described in the getIssuer method\n" " of X509.\n" " \n" " \n" "
\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) ) ) { PyErr_SetString( PyExc_TypeError, "Inapropriate type" ); goto error; } if ( !(name = X509_NAME_new() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !X509_object_helper_set_name(name, name_sequence) ) { PyErr_SetString( SSLErrorObject, "unable to set new name" ); goto error; } if ( !X509_NAME_set(&self->crl->crl->issuer,name ) ) { PyErr_SetString( SSLErrorObject, "unable to set name" ); goto error; } X509_NAME_free(name); return Py_BuildValue(""); error: if (name) X509_NAME_free(name); return NULL; } static char x509_crl_object_set_this_update__doc__[] = "\n" "
\n" " X509Crl\n" " setThisUpdate\n" " time\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * x509_crl_object_set_this_update (x509_crl_object *self, PyObject *args) { //int new_time = 0; char *new_time=NULL; if (!PyArg_ParseTuple(args, "s", &new_time)) goto error; if ( !ASN1_UTCTIME_set_string(self->crl->crl->lastUpdate,new_time) ) { PyErr_SetString( SSLErrorObject, "could not set time" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char x509_crl_object_get_this_update__doc__[] = "\n" "
\n" " X509Crl\n" " getThisUpdate\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * x509_crl_object_get_this_update (x509_crl_object *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) goto error; return Py_BuildValue("s", self->crl->crl->lastUpdate->data); error: return NULL; } static char x509_crl_object_set_next_update__doc__[] = "\n" "
\n" " X509Crl\n" " setNextUpdate\n" " time\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * x509_crl_object_set_next_update (x509_crl_object *self, PyObject *args) { //int new_time = 0; char *new_time=NULL; ASN1_UTCTIME *time=NULL; if (!PyArg_ParseTuple(args, "s", &new_time)) goto error; if (self->crl->crl->nextUpdate == NULL) if ( !(time = ASN1_UTCTIME_new() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } self->crl->crl->nextUpdate = time; if (!ASN1_UTCTIME_set_string(time, new_time) ) { PyErr_SetString( SSLErrorObject, "could not set next update" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char x509_crl_object_get_next_update__doc__[] = "\n" "
\n" " X509Crl\n" " getNextUpdate\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * x509_crl_object_get_next_update (x509_crl_object *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) goto error; return Py_BuildValue("s", self->crl->crl->nextUpdate->data); error: return NULL; } static char x509_crl_object_set_revoked__doc__[] = "\n" "
\n" " X509Crl\n" " setRevoked\n" " revoked\n" "
\n" " \n" " \n" " This method sets the sequence of revoked certificates in this CRL.\n" " revoked should be a list or tuple of \n" " X509Revoked.\n" " \n" " \n" " <function>setRevoked</function> function usage\n" " \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" " \n" " \n" "\n" " \n" "
\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) ) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } size = PySequence_Size( revoked_sequence ); for (i=0; i < size; i++) { if ( !( revoked = (x509_revoked_object*)PySequence_GetItem( revoked_sequence, i ) ) ) goto error; if ( !X_X509_revoked_Check( revoked ) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } if ( !(tmp_revoked = X509_REVOKED_dup( revoked->revoked ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if (!X509_CRL_add0_revoked( self->crl, tmp_revoked ) ) { PyErr_SetString( SSLErrorObject, "could not add revokation to stack" ); goto error; } Py_DECREF(revoked); revoked = NULL; } return Py_BuildValue(""); error: Py_XDECREF(revoked); return NULL; } static PyObject * x509_crl_object_helper_get_revoked(STACK_OF(X509_REVOKED) *revoked) { int no_entries=0, inlist=0, i=0; X509_REVOKED *revoke_tmp=NULL; x509_revoked_object *revoke_obj=NULL; PyObject *item=NULL, *result_list=NULL, *result_tuple=NULL; no_entries = sk_X509_REVOKED_num( revoked ); if ( !(result_list = PyList_New(0) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } for(i=0; irevoked = revoke_tmp; if ( PyList_Append( result_list, (PyObject*)revoke_obj ) != 0) goto error; revoke_obj = NULL; revoke_tmp = NULL; } result_tuple = PyList_AsTuple( result_list ); Py_DECREF(result_list); return Py_BuildValue("O", result_tuple); error: if (result_list) { inlist = PyList_Size( result_list ); for (i=0; i < inlist; i++) { item = PyList_GetItem( result_list, i ); Py_DECREF(item); } Py_DECREF(result_list); } return NULL; } static char x509_crl_object_get_revoked__doc__[] = "\n" "
\n" " X509Crl\n" " getRevoked\n" "
\n" " \n" " \n" " This method returns a tuple of X509Revoked\n" " objects described in the CRL.\n" " \n" " \n" " <function>getRevoked</function> function usage\n" " \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" " \n" " \n" "\n" " \n" "
\n" ; static PyObject * x509_crl_object_get_revoked(x509_crl_object *self, PyObject *args) { PyObject *revoked = NULL; if (!PyArg_ParseTuple(args, "")) goto error; revoked = x509_crl_object_helper_get_revoked( X509_CRL_get_REVOKED(self->crl) ); return revoked; error: return NULL; } static char X509_crl_object_add_extension__doc__[] = "\n" "
\n" " X509Crl\n" " addExtension\n" " extensionName\n" " critical\n" " extensionValue\n" "
\n" " \n" " \n" " This method adds an extension to this CRL.\n" " extensionName should be the of the\n" " extension. critical should an integer, 1\n" " for true and 0 for clase. extensionValue\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 objects.h header file, part of\n" " the OpenSSL source distrobution. In the majority of cases they\n" " are the same as those defined in POW._oids\n" " but if you do encounter problems is may be worth checking.\n" " \n" " \n" " <function>addExtension</function> method usage\n" " \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" " \n" " \n" " \n" "
\n" ; static PyObject * X509_crl_object_add_extension(x509_crl_object *self, PyObject *args) { int critical=0, nid=0, len=0; char *name=NULL, *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() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !ASN1_OCTET_STRING_set(octetString, buf, len) ) { PyErr_SetString( SSLErrorObject, "could not set ASN1 Octect string" ); goto error; } if ( NID_undef == (nid = OBJ_txt2nid(name) ) ) { PyErr_SetString( SSLErrorObject, "extension has unknown object identifier" ); goto error; } if ( !( extn = X509_EXTENSION_create_by_NID(NULL, nid, critical, octetString) ) ) { PyErr_SetString( SSLErrorObject, "unable to create ASN1 X509 Extension object" ); goto error; } if (!self->crl->crl->extensions) if ( !(self->crl->crl->extensions = sk_X509_EXTENSION_new_null() ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( !sk_X509_EXTENSION_push(self->crl->crl->extensions, extn) ) { PyErr_SetString( SSLErrorObject, "unable to add extension" ); goto error; } return Py_BuildValue(""); error: if(extn) X509_EXTENSION_free(extn); return NULL; } static char X509_crl_object_clear_extensions__doc__[] = "\n" "
\n" " X509Crl\n" " clearExtensions\n" "
\n" " \n" " \n" " This method clears the structure which holds the extension for\n" " this CRL.\n" " \n" " \n" "
\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; } return Py_BuildValue(""); error: return NULL; } static char X509_crl_object_count_extensions__doc__[] = "\n" "
\n" " X509Crl\n" " countExtensions\n" "
\n" " \n" " \n" " This method returns the size of the structure which holds the\n" " extension for this CRL.\n" " \n" " \n" "
\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); } else return Py_BuildValue("i", 0); error: return NULL; } static char X509_crl_object_get_extension__doc__[] = "\n" "
\n" " X509Crl\n" " getExtension\n" " index\n" "
\n" " \n" " \n" " This method returns a tuple equivalent the parameters of\n" " addExtension.\n" " \n" " \n" "
\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 [] = "unkown"; 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); } else num = 0; if (index >= num) { PyErr_SetString( SSLErrorObject, "certificate does not have that many extensions" ); goto error; } if ( !(ext = sk_X509_EXTENSION_value(self->crl->crl->extensions, index) ) ) { PyErr_SetString( SSLErrorObject, "could not get extension" ); goto error; } if ( NID_undef == (ext_nid = OBJ_obj2nid(ext->object) ) ) { PyErr_SetString( SSLErrorObject, "extension has unknown object identifier" ); goto error; } if ( NULL == (ext_ln = OBJ_nid2sn(ext_nid) ) ) 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__[] = "\n" "
\n" " X509Crl\n" " sign\n" " key\n" " digest=MD5_DIGEST\n" "
\n" " \n" " \n" " key should be an instance of\n" " Asymmetric and contain a private key.\n" " digest indicates \n" " which digest function should be used to compute the hash to be \n" " signed, it should be one of the following:\n" " \n" " \n" " MD2_DIGEST\n" " MD5_DIGEST\n" " SHA_DIGEST\n" " SHA1_DIGEST\n" " RIPEMD160_DIGEST\n" " SHA256_DIGEST\n" " SHA384_DIGEST\n" " SHA512_DIGEST\n" " \n" " \n" "
\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() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if (asym->key_type != RSA_PRIVATE_KEY) { PyErr_SetString( SSLErrorObject, "cannot use this type of key" ); goto error; } if ( !(EVP_PKEY_assign_RSA(pkey, asym->cipher) ) ) { PyErr_SetString( SSLErrorObject, "EVP_PKEY assignment error" ); goto error; } switch (digest) { case MD5_DIGEST: { if (!X509_CRL_sign(self->crl, pkey, EVP_md5() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case MD2_DIGEST: { if (!X509_CRL_sign(self->crl, pkey, EVP_md2() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA_DIGEST: { if (!X509_CRL_sign(self->crl, pkey, EVP_sha() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA1_DIGEST: { if (!X509_CRL_sign(self->crl, pkey, EVP_sha1() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case RIPEMD160_DIGEST: { if (!X509_CRL_sign(self->crl, pkey, EVP_ripemd160() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA256_DIGEST: { if (!X509_CRL_sign(self->crl, pkey, EVP_sha256() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA384_DIGEST: { if (!X509_CRL_sign(self->crl, pkey, EVP_sha384() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } case SHA512_DIGEST: { if (!X509_CRL_sign(self->crl, pkey, EVP_sha512() ) ) { PyErr_SetString( SSLErrorObject, "could not sign certificate" ); goto error; } break; } } return Py_BuildValue(""); error: if (pkey) EVP_PKEY_free(pkey); return NULL; } static char x509_crl_object_verify__doc__[] = "\n" "
\n" " X509Crl\n" " verify\n" " key\n" "
\n" " \n" " \n" " The X509Crl method\n" " verify is based on the\n" " X509_CRL_verify function. Unlike the\n" " X509 function of the same name, this\n" " function simply checks the CRL was signed with the private key\n" " which corresponds the parameter key.\n" " key should be an instance of\n" " Asymmetric and contain a public key.\n" " \n" " \n" "
\n" ; static PyObject * x509_crl_object_verify(x509_crl_object *self, PyObject *args) { int result=0; EVP_PKEY *pkey=NULL; asymmetric_object *asym; if (!PyArg_ParseTuple(args, "O!", &asymmetrictype, &asym)) goto error; if ( !(pkey = EVP_PKEY_new() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !(EVP_PKEY_assign_RSA(pkey, asym->cipher) ) ) { PyErr_SetString( SSLErrorObject, "EVP_PKEY assignment error" ); goto error; } result = X509_CRL_verify(self->crl,pkey); return Py_BuildValue("i", result); 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()); if (format == DER_FORMAT) { if (!i2d_X509_CRL_bio(out_bio, self->crl) ) { PyErr_SetString( SSLErrorObject, "unable to write certificate" ); goto error; } } else if (format == PEM_FORMAT) { if (!PEM_write_bio_X509_CRL(out_bio, self->crl) ) { PyErr_SetString( SSLErrorObject, "unable to write certificate" ); goto error; } } else { PyErr_SetString( SSLErrorObject, "internal error, unkown output format" ); goto error; } if ( !(len = BIO_ctrl_pending(out_bio) ) ) { PyErr_SetString( SSLErrorObject, "unable to get bytes stored in bio" ); goto error; } if ( !(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( (ret = BIO_read( out_bio, buf, len ) ) != len ) { PyErr_SetString( SSLErrorObject, "unable to write out cert" ); goto error; } 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__[] = "\n" "
\n" " X509Crl\n" " pemWrite\n" "
\n" " \n" " \n" " This method returns a PEM encoded CRL as a\n" " string.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " X509Crl\n" " derWrite\n" "
\n" " \n" " \n" " This method returns a DER encoded CRL as a string.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " X509Crl\n" " pprint\n" "
\n" " \n" " \n" " This method returns a formatted string showing the information\n" " held in the CRL.\n" " \n" " \n" "
\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) ) { PyErr_SetString( SSLErrorObject, "unable to write crl" ); goto error; } if ( !(len = BIO_ctrl_pending(out_bio) ) ) { PyErr_SetString( SSLErrorObject, "unable to get bytes stored in bio" ); goto error; } if ( !(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( (ret = BIO_read( out_bio, buf, len ) ) != len ) { PyErr_SetString( SSLErrorObject, "unable to write out cert" ); goto error; } 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, 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__[] = "\n" "
\n" " X509Crl\n" "
\n" " \n" " \n" " This class provides access to OpenSSL X509 CRL management\n" " facilities.\n" " \n" " \n" "
\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 ) ) ) goto error; self->revoked = X509_REVOKED_new(); return self; error: Py_XDECREF(self); return NULL; } static char x509_revoked_object_set_serial__doc__[] = "\n" "
\n" " X509Revoked\n" " setSerial\n" " serial\n" "
\n" " \n" " \n" " This method sets the serial number in the serial field of\n" " this object. serial should be an\n" " integer.\n" " \n" " \n" "
\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 ) ) { PyErr_SetString( SSLErrorObject, "unable to set serial number" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char x509_revoked_object_get_serial__doc__[] = "\n" "
\n" " X509Revoked\n" " getSerial\n" "
\n" " \n" " \n" " This method gets the serial number in the serial field of\n" " this object.\n" " \n" " \n" "
\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 ) { PyErr_SetString( SSLErrorObject, "unable to get serial number" ); goto error; } return Py_BuildValue("i", serial); error: return NULL; } static char x509_revoked_object_get_date__doc__[] = "\n" "
\n" " X509Revoked\n" " getDate\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\n" ; static PyObject * x509_revoked_object_get_date(x509_revoked_object *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) goto error; return Py_BuildValue("s", self->revoked->revocationDate->data); error: return NULL; } static char x509_revoked_object_set_date__doc__[] = "\n" "
\n" " X509Revoked\n" " setDate\n" " time\n" "
\n" " \n" " \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 time2utc to convert to a\n" " string if you like and utc2time to back.\n" " \n" " \n" "
\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 (!ASN1_UTCTIME_set_string( self->revoked->revocationDate, time )) { PyErr_SetString( PyExc_TypeError, "could not set revocationDate" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char X509_revoked_object_add_extension__doc__[] = "\n" "
\n" " X509Revoked\n" " addExtension\n" " extensionName\n" " critical\n" " extensionValue\n" "
\n" " \n" " \n" " This method adds an extension to this revocation.\n" " extensionName should be the of the\n" " extension. critical should an integer, 1\n" " for true and 0 for clase. extensionValue\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 objects.h header file, part of\n" " the OpenSSL source distrobution. In the majority of cases they\n" " are the same as those defined in POW._oids\n" " but if you do encounter problems is may be worth checking.\n" " \n" " \n" " <function>addExtension</function> method usage\n" " \n" " reason = POW.pkix.CrlReason()\n" " reason.set(1) \n" " revocation.addExtension( 'CRLReason', 0, reason.toString() )\n" " \n" " \n" " \n" "
\n" ; static PyObject * X509_revoked_object_add_extension(x509_revoked_object *self, PyObject *args) { int critical=0, nid=0, len=0; char *name=NULL, *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() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !ASN1_OCTET_STRING_set(octetString, buf, strlen(buf)) ) { PyErr_SetString( SSLErrorObject, "could not set ASN1 Octect string" ); goto error; } if ( NID_undef == (nid = OBJ_txt2nid(name) ) ) { PyErr_SetString( SSLErrorObject, "extension has unknown object identifier" ); goto error; } if ( !( extn = X509_EXTENSION_create_by_NID(NULL, nid, critical, octetString) ) ) { PyErr_SetString( SSLErrorObject, "unable to create ASN1 X509 Extension object" ); goto error; } if (!self->revoked->extensions) if ( !(self->revoked->extensions = sk_X509_EXTENSION_new_null() ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( !sk_X509_EXTENSION_push(self->revoked->extensions, extn) ) { PyErr_SetString( SSLErrorObject, "unable to add extension" ); goto error; } return Py_BuildValue(""); error: if(extn) X509_EXTENSION_free(extn); return NULL; } static char X509_revoked_object_clear_extensions__doc__[] = "\n" "
\n" " X509Revoked\n" " clearExtensions\n" "
\n" " \n" " \n" " This method clears the structure which holds the extension for\n" " this revocation.\n" " \n" " \n" "
\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; } return Py_BuildValue(""); error: return NULL; } static char X509_revoked_object_count_extensions__doc__[] = "\n" "
\n" " X509Revoked\n" " countExtensions\n" "
\n" " \n" " \n" " This method returns the size of the structure which holds the\n" " extension for this revocation.\n" " \n" " \n" "
\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); } else return Py_BuildValue("i", 0); error: return NULL; } static char X509_revoked_object_get_extension__doc__[] = "\n" "
\n" " X509Revoked\n" " getExtension\n" " index\n" "
\n" " \n" " \n" " This method returns a tuple equivalent the parameters of\n" " addExtension.\n" " \n" " \n" "
\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 [] = "unkown"; X509_EXTENSION *ext; if (!PyArg_ParseTuple(args, "i", &index)) goto error; if (self->revoked->extensions) { num = sk_X509_EXTENSION_num(self->revoked->extensions); } else num = 0; if (index >= num) { PyErr_SetString( SSLErrorObject, "certificate does not have that many extensions" ); goto error; } if ( !(ext = sk_X509_EXTENSION_value(self->revoked->extensions, index) ) ) { PyErr_SetString( SSLErrorObject, "could not get extension" ); goto error; } if ( NID_undef == (ext_nid = OBJ_obj2nid(ext->object) ) ) { PyErr_SetString( SSLErrorObject, "extension has unknown object identifier" ); goto error; } if ( NULL == (ext_ln = OBJ_nid2sn(ext_nid) ) ) 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, 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__[] = "\n" "
\n" " X509Revoked\n" "
\n" " \n" " \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" " X509Revoked existing as an object in its\n" " own right will make adding this support easier, while avoiding\n" " backwards compatibility issues.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " Ssl\n" " useCertificate\n" " cert\n" "
\n" " \n" " \n" " The parameter cert must be an\n" " instance of the X590 class and must be\n" " called before setFd. \n" " \n" " \n" "
\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) { PyErr_SetString( SSLErrorObject, "cannot be called after setFd()" ); goto error; } if ( !SSL_CTX_use_certificate(self->ctx, x509->x509) ) { PyErr_SetString( SSLErrorObject, "could not use certificate" ); goto error; } return Py_BuildValue(""); 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) { PyErr_SetString( SSLErrorObject, "cannot be called after setFd()" ); goto error; } if ( !(x = X509_dup(x509->x509)) ) { PyErr_SetString( SSLErrorObject, "could not duplicate X509 object" ); goto error; } if ( !SSL_CTX_add_extra_chain_cert(self->ctx, x) ) { set_openssl_pyerror( "could not add certificate" ); goto error; } x = NULL; return Py_BuildValue(""); error: if (x) X509_free(x); return NULL; } static char ssl_object_use_key__doc__[] = "\n" "
\n" " Ssl\n" " useKey\n" " key\n" "
\n" " \n" " \n" " The parameter key must be an\n" " instance of the Asymmetric class and\n" " must contain the private key. This function cannot be called \n" " after useKey.\n" " \n" " \n" "
\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) { PyErr_SetString( SSLErrorObject, "cannot be called after setFd()" ); goto error; } if ( !(pkey = EVP_PKEY_new() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if (asym->key_type != RSA_PRIVATE_KEY) { PyErr_SetString( SSLErrorObject, "cannot use this type of key" ); goto error; } if ( !EVP_PKEY_assign_RSA(pkey, asym->cipher) ) { PyErr_SetString( SSLErrorObject, "EVP_PKEY assignment error" ); goto error; } if ( !SSL_CTX_use_PrivateKey(self->ctx, pkey) ) { PyErr_SetString( SSLErrorObject, "ctx key assignment error" ); goto error; } return Py_BuildValue(""); error: if(pkey) EVP_PKEY_free(pkey); return NULL; } static char ssl_object_check_key__doc__[] = "\n" "
\n" " Ssl\n" " checkKey\n" "
\n" " \n" " \n" " This simple method will return 1 if the public key, contained in\n" " the X509 certificate this Ssl instance is using,\n" " matches the private key this Ssl instance is using.\n" " Otherwise it will return 0.\n" " \n" " \n" "
\n" ; static PyObject * ssl_object_check_key(ssl_object *self, PyObject *args) { if ( SSL_CTX_check_private_key(self->ctx) ) return Py_BuildValue("i", 1); else return Py_BuildValue("i", 0); } static char ssl_object_set_fd__doc__[] = "\n" "
\n" " Ssl\n" " setFd\n" " descriptor\n" "
\n" " \n" " \n" " This function is used to associate a file descriptor with a\n" " Ssl object. The file descriptor should\n" " belong to an open TCP connection. Once this function has\n" " been called, calling useKey or\n" " useCertificate will, fail rasing exceptions.\n" " \n" " \n" "
\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 ) ) ) { PyErr_SetString( SSLErrorObject, "unable to create ssl sturcture" ); goto error; } if ( !SSL_set_fd( self->ssl, fd ) ) { PyErr_SetString( SSLErrorObject, "unable to set file descriptor" ); goto error; } 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 { PyErr_SetString( SSLErrorObject, "unable to create ex data index" ); goto error; } self->ctxset = 1; return Py_BuildValue(""); error: return NULL; } static char ssl_object_accept__doc__[] = "\n" "
\n" " Ssl\n" " accept\n" "
\n" " \n" " \n" " This function will attempt the SSL level accept with a\n" " client. The Ssl object must have been\n" " created using a XXXXX_SERVER_METHOD or\n" " a XXXXX_METHOD and this function should only be\n" " called after useKey,\n" " useCertificate and\n" " setFd functions have been called.\n" " \n" "\n" " \n" " <function>accept</function> function usage\n" " \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" " \n" " \n" " \n" "
\n" ; static PyObject * ssl_object_accept(ssl_object *self, PyObject *args) { int ret=0, err=0; if (!PyArg_ParseTuple(args, "")) goto error; Py_BEGIN_ALLOW_THREADS ret = SSL_accept( self->ssl ); Py_END_ALLOW_THREADS if (ret <= 0) { err = SSL_get_error( self->ssl, ret ); PyErr_SetObject(SSLErrorObject, ssl_err_factory( err ) ); goto error; } return Py_BuildValue(""); error: return NULL; } static char ssl_object_connect__doc__[] = "\n" "
\n" " Ssl\n" " connect\n" "
\n" " \n" " \n" " This function will attempt the SSL level connection with a\n" " server. The Ssl object must have been\n" " created using a XXXXX_CLIENT_METHOD or\n" " a XXXXX_METHOD and this function should only be\n" " called after setFd has already been\n" " called.\n" " \n" "\n" " \n" " <function>connect</function> function usage\n" " \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" " \n" " \n" " \n" "
\n" ; static PyObject * ssl_object_connect(ssl_object *self, PyObject *args) { int ret, err=0; if (!PyArg_ParseTuple(args, "")) goto error; Py_BEGIN_ALLOW_THREADS ret = SSL_connect( self->ssl ); Py_END_ALLOW_THREADS if (ret <= 0) { err = SSL_get_error( self->ssl, ret ); PyErr_SetObject(SSLErrorObject, ssl_err_factory( err ) ); goto error; } return Py_BuildValue(""); error: return NULL; } static char ssl_object_write__doc__[] = "\n" "
\n" " Ssl\n" " write\n" " string\n" "
\n" " \n" " \n" " This method writes the string to the\n" " Ssl object, to be read by it's peer. This\n" " function is analogous to the socket\n" " classes write function.\n" " \n" " \n" "
\n" ; static PyObject * ssl_object_write(ssl_object *self, PyObject *args) { char *msg; int length=0, ret=0, err=0; if (!PyArg_ParseTuple(args, "s#", &msg, &length)) goto error; Py_BEGIN_ALLOW_THREADS ret = SSL_write( self->ssl, msg, length ); Py_END_ALLOW_THREADS if (ret <= 0) { err = SSL_get_error( self->ssl, ret ); PyErr_SetObject(SSLErrorObject, ssl_err_factory( err ) ); goto error; } return Py_BuildValue("i", ret); error: return NULL; } static char ssl_object_read__doc__[] = "\n" "
\n" " Ssl\n" " read\n" " amount=1024\n" "
\n" " \n" " \n" " This method reads up to amount characters from the\n" " Ssl object. This\n" " function is analogous to the socket\n" " classes read function.\n" " \n" " \n" "
\n" ; static PyObject * ssl_object_read(ssl_object *self, PyObject *args) { PyObject *data; char *msg=NULL; int len = 1024, ret=0, err=0; if (!PyArg_ParseTuple(args, "|i", &len)) goto error; if ( !(msg = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } Py_BEGIN_ALLOW_THREADS ret = SSL_read( self->ssl, msg, len ); Py_END_ALLOW_THREADS if (ret <= 0) { err = SSL_get_error( self->ssl, ret ); PyErr_SetObject(SSLErrorObject, ssl_err_factory( err ) ); goto error; } data = Py_BuildValue("s#", msg, ret); free(msg); return data; error: if (msg) free(msg); return NULL; } static char ssl_object_peer_certificate__doc__[] = "\n" "
\n" " Ssl\n" " peerCertificate\n" "
\n" " \n" " \n" " This method returns any peer certificate presented in the initial\n" " SSL negotiation or None. If a certificate is\n" " returned, it will be an instance of X509.\n" " \n" " \n" "
\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 ( !(x509_obj = X509_object_new() ) ) { PyErr_SetString( SSLErrorObject, "could not create x509 object" ); goto error; } x509 = SSL_get_peer_certificate( self->ssl ); if (x509) { X509_free( x509_obj->x509 ); if ( !(x509_obj->x509 = x509 ) ) { PyErr_SetString( SSLErrorObject, "could not create x509 object" ); goto error; } return Py_BuildValue("O", x509_obj); } else { Py_XDECREF( x509_obj ); return Py_BuildValue(""); } error: if (x509) X509_free(x509); Py_XDECREF( x509_obj ); return NULL; } static char ssl_object_clear__doc__[] = "\n" "
\n" " Ssl\n" " clear\n" "
\n" " \n" " \n" " This method will clear the SSL session ready for\n" " a new SSL connection. It will not effect the underlying socket.\n" " \n" " \n" "
\n" ; static PyObject * ssl_object_clear(ssl_object *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) goto error; if (!SSL_clear( self->ssl ) ) { PyErr_SetString( SSLErrorObject, "failed to clear ssl connection" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char ssl_object_shutdown__doc__[] = "\n" "
\n" " Ssl\n" " shutdown\n" "
\n" " \n" " \n" " This method will issue a shutdown 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" " shutdown must be called again. If no\n" " exception is raised, the handshake is complete. \n" " \n" " \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" " \n" " \n" "
\n" ; static PyObject * ssl_object_shutdown(ssl_object *self, PyObject *args) { int ret=0, err=0; if (!PyArg_ParseTuple(args, "")) goto error; ret = SSL_shutdown(self->ssl); if (ret <= 0) { err = SSL_get_error( self->ssl, ret ); PyErr_SetObject(SSLErrorObject, ssl_err_factory( err ) ); goto error; } return Py_BuildValue(""); error: return NULL; } static char ssl_object_get_shutdown__doc__[] = "\n" "
\n" " Ssl\n" " getShutdown\n" "
\n" " \n" " \n" " This function returns an integer indicating the state of the\n" " SSL connection. SSL_RECIEVED_SHUTDOWN\n" " will be set the if it's peer sends a shutdown\n" " signal or the underlying socket\n" " receives a close notify . The possible values are:\n" " \n" " \n" " SSL_NO_SHUTDOWN\n" " SSL_SENT_SHUTDOWN\n" " SSL_RECIEVED_SHUTDOWN\n" " SSL_SENT_SHUTDOWN | SSL_RECIEVED_SHUTDOWN\n" " \n" " \n" "
\n" ; static PyObject * ssl_object_get_shutdown(ssl_object *self, PyObject *args) { int state=0; if (!PyArg_ParseTuple(args, "")) goto error; state = SSL_get_shutdown(self->ssl); return Py_BuildValue("i", state); error: return NULL; } static char ssl_object_get_ciphers__doc__[] = "\n" "
\n" " Ssl\n" " getCiphers\n" "
\n" " \n" " \n" " This function returns a list of available ciphers ordered from\n" " most favored to least. This function must be called after\n" " setFd. \n" " \n" " \n" "
\n" ; static PyObject * ssl_object_get_ciphers(ssl_object *self, PyObject *args) { int inlist=0, i=0; const char *cipher=NULL; PyObject *list=NULL, *name=NULL; if (!PyArg_ParseTuple(args, "")) goto error; if (!self->ctxset) { PyErr_SetString( SSLErrorObject, "cannot be called before setFd()" ); goto error; } list = PyList_New(0); cipher = SSL_get_cipher_list(self->ssl, 0); while (cipher) { if ( !(name = PyString_FromString(cipher) ) ) goto error; if ( PyList_Append( list, name ) != 0) goto error; cipher = SSL_get_cipher_list(self->ssl, ++i); } return Py_BuildValue("O", list); error: if (list) { inlist = PyList_Size( list ); for (i=0; i < inlist; i++) { name = PyList_GetItem( list, i ); Py_DECREF(name); } Py_DECREF(list); } return NULL; } static char ssl_object_set_ciphers__doc__[] = "\n" "
\n" " Ssl\n" " setCiphers\n" " ciphers\n" "
\n" " \n" " \n" " setCiphers\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" " ciphers should be a list of strings, as\n" " produced by getCiphers and described in the\n" " OpenSSL man page ciphers. setCiphers should\n" " only be called after setFd.\n" " \n" " \n" "
\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)) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } if (!self->ctxset) { PyErr_SetString( SSLErrorObject, "cannot be called before setFd()" ); goto error; } cipherstr = malloc(8); //very bogus, realloc dosn't work with out 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 ) ) ) goto error; if ( !PyString_Check(cipher) ) { PyErr_SetString( PyExc_TypeError, "inapropriate type" ); goto error; } cipherstrlen = strlen(cipherstr); nextstrlen = strlen( PyString_AsString(cipher) ); if ( !(cipherstr = realloc( cipherstr, cipherstrlen + nextstrlen + 2)) ) { PyErr_SetString( PyExc_TypeError, "could allocate memory" ); goto error; } if (cipherstrlen) strcat( cipherstr, ":\0" ); strcat( cipherstr, PyString_AsString(cipher) ); Py_DECREF(cipher); cipher = NULL; } SSL_set_cipher_list( self->ssl, cipherstr ); free(cipherstr); return Py_BuildValue(""); error: if (cipherstr) free(cipherstr); Py_XDECREF(cipher); return NULL; } static char ssl_object_get_cipher__doc__[] = "\n" "
\n" " Ssl\n" " getCipher\n" "
\n" " \n" " \n" " This function returns the current cipher in use.\n" " \n" " \n" "
\n" ; static PyObject * ssl_object_get_cipher(ssl_object *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) goto error; if (!self->ctxset) { PyErr_SetString( SSLErrorObject, "cannot be called before setFd()" ); goto error; } return Py_BuildValue("s", SSL_get_cipher( self->ssl )); error: return NULL; } static int stub_callback(int preverify_ok, X509_STORE_CTX *ctx) { return 1; } static char ssl_object_set_verify_mode__doc__[] = "\n" "
\n" " Ssl\n" " setVerifyMode\n" " mode\n" "
\n" " \n" " \n" " This function sets the behavior of the SSL handshake. The\n" " parameter mode should be one of the\n" " following:\n" " \n" " \n" " SSL_VERIFY_NONE\n" " SSL_VERIFY_PEER\n" " \n" " \n" " See the OpenSSL man page SSL_CTX_set_verify \n" " for details. This function must be called after setfd \n" " has been called.\n" " \n" " \n" "
\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) { PyErr_SetString( SSLErrorObject, "cannot be called after setfd()" ); goto error; } SSL_CTX_set_verify( self->ctx, mode, stub_callback ); return Py_BuildValue(""); 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}, {"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}, {"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, NULL} /* sentinel */ }; static ssl_object * newssl_object(int type) { ssl_object *self; const SSL_METHOD *method; if ( !(self = PyObject_NEW(ssl_object, &ssltype) ) ) goto error; self->ctxset = 0; self->ssl = 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: { PyErr_SetString( SSLErrorObject, "unkown ctx method" ); goto error; } } if ( !(self->ctx = SSL_CTX_new( method ) ) ) { PyErr_SetString( SSLErrorObject, "unable to create new ctx" ); goto error; } 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 ); PyObject_Del(self); } static char ssltype__doc__[] = "\n" "
\n" " Ssl\n" "
\n" " \n" " \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" " \n" " \n" "
\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) { PyErr_SetString( SSLErrorObject, "unsupported cipher" ); goto error; } if ( !(self->cipher = RSA_generate_key(key_size,RSA_F4,NULL,NULL) ) ) { PyErr_SetString( SSLErrorObject, "could not generate key" ); goto error; } 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 ) ) ) { PyErr_SetString( SSLErrorObject, "could not load public key" ); goto error; } 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) ) ) { PyErr_SetString( SSLErrorObject, "could not load private key" ); goto error; } self->key_type = RSA_PRIVATE_KEY; self->cipher_type = RSA_CIPHER; break; } default: { PyErr_SetString( SSLErrorObject, "unkown key type" ); goto error; } } return self; error: Py_XDECREF(self); return NULL; } static asymmetric_object * asymmetric_object_der_read(int key_type, 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 ) ) ) { PyErr_SetString( SSLErrorObject, "could not load public key" ); goto error; } 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 ) ) ) { PyErr_SetString( SSLErrorObject, "could not load private key" ); goto error; } self->key_type = RSA_PRIVATE_KEY; self->cipher_type = RSA_CIPHER; break; } default: { PyErr_SetString( SSLErrorObject, "unkown key type" ); goto error; } } return self; error: Py_XDECREF(self); return NULL; } static char asymmetric_object_pem_write__doc__[] = "\n" "
\n" " Asymmetric\n" " pemWrite\n" " keytype\n" " ciphertype=None\n" " passphrase=None\n" "
\n" " \n" " \n" " This method is used to write Asymmetric\n" " objects out as strings. The first argument should be either\n" " RSA_PUBLIC_KEY or\n" " RSA_PRIVATE_KEY. Private keys are often\n" " saved in encrypted files to offer extra security above access\n" " control mechanisms. If the keytype is\n" " RSA_PRIVATE_KEY a\n" " ciphertype and\n" " passphrase can also be specified. The\n" " ciphertype should be one of those listed in\n" " the Symmetric class section.\n" " \n" " \n" "
\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()) ) ) { PyErr_SetString( SSLErrorObject, "unable to create new BIO" ); goto error; } if ( (kstr && !cipher) || (cipher && !kstr) ) {PyErr_SetString(SSLErrorObject,"cipher type and key string must both be supplied");goto error;} 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) ) { PyErr_SetString( SSLErrorObject, "unable to write key" ); goto error; } } else { if (!PEM_write_bio_RSAPrivateKey(out_bio, self->cipher, NULL, NULL, 0, NULL, NULL) ) { PyErr_SetString( SSLErrorObject, "unable to write key" ); goto error; } } break; } case RSA_PUBLIC_KEY: { if (kstr && cipher) { PyErr_SetString( SSLErrorObject, "public keys should not encrypted" ); goto error; } else { if (!PEM_write_bio_RSA_PUBKEY(out_bio, self->cipher) ) { PyErr_SetString( SSLErrorObject, "unable to write key" ); goto error; } } break; } default: { PyErr_SetString( SSLErrorObject, "unsupported key type" ); goto error; } } if ( !(len = BIO_ctrl_pending(out_bio) ) ) { PyErr_SetString( SSLErrorObject, "unable to get number of bytes in bio" ); goto error; } if ( !(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( (ret = BIO_read( out_bio, buf, len ) ) != len ) { PyErr_SetString( SSLErrorObject, "unable to write out key" ); goto error; } 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__[] = "" "
" " Asymmetric" " derWrite" " keytype" "
" " " " " " This method is used to write Asymmetric" " objects out as strings. The first argument should be either" " RSA_PUBLIC_KEY or " " RSA_PRIVATE_KEY." " " " " "
" ; 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) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } p = buf; if (!i2d_RSAPrivateKey(self->cipher, &buf) ) { PyErr_SetString( SSLErrorObject, "unable to write key" ); goto error; } break; } case RSA_PUBLIC_KEY: { len = i2d_RSA_PUBKEY(self->cipher, NULL); if ( !(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } p = buf; if (!i2d_RSA_PUBKEY(self->cipher, &buf) ) { PyErr_SetString( SSLErrorObject, "unable to write key" ); goto error; } break; } default: { PyErr_SetString( SSLErrorObject, "unsupported key type" ); goto error; } } asymmetric = Py_BuildValue("s#", p, len); free(p); return asymmetric; error: if (p) free(p); return NULL; } static char asymmetric_object_public_encrypt__doc__[] = "\n" "
\n" " Asymmetric\n" " publicEncrypt\n" " plaintext\n" "
\n" " \n" " \n" " This method is used to encrypt the plaintext\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" " \n" " \n" "
\n" ; static PyObject * asymmetric_object_public_encrypt(asymmetric_object *self, PyObject *args) { char *plain_text=NULL, *cipher_text=NULL; int len=0, size=0; PyObject *obj=NULL; switch( self->cipher_type ) { case RSA_CIPHER: { if (!PyArg_ParseTuple(args, "s#", &plain_text, &len)) goto error; size = RSA_size(self->cipher); if ( len > size ) { PyErr_SetString( SSLErrorObject, "plain text is too long" ); goto error; } if ( !(cipher_text = malloc( size + 16 ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( (len = RSA_public_encrypt( len, plain_text, cipher_text, self->cipher, RSA_PKCS1_PADDING ) ) < 0 ) { PyErr_SetString( SSLErrorObject, "could not encrypt plain text" ); goto error; } break; } default: { PyErr_SetString( SSLErrorObject, "unsupported cipher type" ); goto error; } } 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__[] = "\n" "
\n" " Asymmetric\n" " privateEncrypt\n" " plaintext\n" "
\n" " \n" " \n" " This method is used to encrypt the plaintext\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" " \n" " \n" "
\n" ; static PyObject * asymmetric_object_private_encrypt(asymmetric_object *self, PyObject *args) { char *plain_text=NULL, *cipher_text=NULL; int len=0, size=0; PyObject *obj=NULL; if ( !(self->key_type == RSA_PRIVATE_KEY) ) { PyErr_SetString( SSLErrorObject, "cannot perform private encryption with this key" ); goto error; } if (!PyArg_ParseTuple(args, "s#", &plain_text, &len) ) goto error; size = RSA_size(self->cipher); if ( len > size ) { PyErr_SetString( SSLErrorObject, "plain text is too long" ); goto error; } if ( !(cipher_text = malloc( size + 16 ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( (len = RSA_private_encrypt( len, plain_text, cipher_text, self->cipher, RSA_PKCS1_PADDING ) ) < 0 ) { PyErr_SetString( SSLErrorObject, "could not encrypt plain text" ); goto error; } 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__[] = "\n" "
\n" " Asymmetric\n" " publicDecrypt\n" " ciphertext\n" "
\n" " \n" " \n" " This method is used to decrypt the\n" " ciphertext which has been encrypted\n" " using the corresponding private key and the\n" " privateEncrypt function. \n" " \n" " \n" "
\n" ; static PyObject * asymmetric_object_public_decrypt(asymmetric_object *self, PyObject *args) { char *plain_text=NULL, *cipher_text=NULL; int len=0, size=0; PyObject *obj=NULL; switch( self->cipher_type ) { case RSA_CIPHER: { if (!PyArg_ParseTuple(args, "s#", &cipher_text, &len)) goto error; size = RSA_size(self->cipher); if ( len > size ) { PyErr_SetString( SSLErrorObject, "cipher text is too long" ); goto error; } if ( !(plain_text = malloc( size + 16 ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( (len = RSA_public_decrypt( len, cipher_text, plain_text, self->cipher, RSA_PKCS1_PADDING ) ) < 0 ) { PyErr_SetString( SSLErrorObject, "could not decrypt cipher text" ); goto error; } break; } default: { PyErr_SetString( SSLErrorObject, "unsupported cipher type" ); goto error; } } 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__[] = "\n" "
\n" " Asymmetric\n" " privateDecrypt\n" " ciphertext\n" "
\n" " \n" " \n" " This method is used to decrypt ciphertext which has been encrypted\n" " using the corresponding public key and the\n" " publicEncrypt function. \n" " \n" " \n" "
\n" ; static PyObject * asymmetric_object_private_decrypt(asymmetric_object *self, PyObject *args) { char *plain_text=NULL, *cipher_text=NULL; int len=0, size=0; PyObject *obj=NULL; if ( !(self->key_type == RSA_PRIVATE_KEY) ) { PyErr_SetString( SSLErrorObject, "cannot perform private decryption with this key" ); goto error; } if (!PyArg_ParseTuple(args, "s#", &cipher_text, &len)) goto error; size = RSA_size(self->cipher); if ( len > size ) { PyErr_SetString( SSLErrorObject, "cipher text is too long" ); goto error; } if ( !(plain_text = malloc( size + 16 ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( (len = RSA_private_decrypt( len, cipher_text, plain_text, self->cipher, RSA_PKCS1_PADDING ) ) < 0 ) { PyErr_SetString( SSLErrorObject, "could not decrypt cipher text" ); goto error; } 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__[] = "\n" "
\n" " Asymmetric\n" " sign\n" " digesttext\n" " digesttype\n" "
\n" " \n" " \n" " This method is used to produce a signed digest text. \n" " This instance of\n" " Asymmetric should be a private key used for\n" " signing. The parameter\n" " digesttext should be a digest of the \n" " data to protect against alteration and\n" " finally digesttype should be one of the\n" " following:\n" " \n" " \n" " MD2_DIGEST\n" " MD5_DIGEST\n" " SHA_DIGEST\n" " SHA1_DIGEST\n" " RIPEMD160_DIGEST\n" " SHA256_DIGEST\n" " SHA384_DIGEST\n" " SHA512_DIGEST\n" " \n" " \n" " If the procedure was successful, a string containing the signed\n" " digest is returned. \n" " \n" " \n" "
\n" ; static PyObject * asymmetric_object_sign(asymmetric_object *self, PyObject *args) { char *digest_text=NULL, *signed_text=NULL; 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) { PyErr_SetString( SSLErrorObject, "unsupported key type" ); goto error; } if ( !(signed_text = malloc( RSA_size(self->cipher) ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } switch(digest_type) { case MD2_DIGEST: { digest_nid = NID_md2; digest_len = MD2_DIGEST_LENGTH; break; } 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: { PyErr_SetString( SSLErrorObject, "unsupported digest" ); goto error; } } if ( !(RSA_sign( digest_nid, digest_text, digest_len, signed_text, &signed_len, self->cipher ) ) ) { PyErr_SetString( SSLErrorObject, "could not sign digest" ); goto error; } 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__[] = "\n" "
\n" " Asymmetric\n" " verify\n" " signedtext\n" " digesttext\n" " digesttype\n" "
\n" " \n" " \n" " This method is used to verify a signed digest text. \n" " \n" " \n" " <function>verify</function> method usage\n" " \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" " \n" " \n" " \n" " The parameter signedtext should be a \n" " signed digest text. This instance of\n" " Asymmetric should correspond to the private\n" " key used to sign the digest. The parameter\n" " digesttext should be a digest of the same\n" " data used to produce the signedtext and\n" " finally digesttype should be one of the\n" " following:\n" " \n" " \n" " MD2_DIGEST\n" " MD5_DIGEST\n" " SHA_DIGEST\n" " SHA1_DIGEST\n" " RIPEMD160_DIGEST\n" " SHA256_DIGEST\n" " SHA384_DIGEST\n" " SHA512_DIGEST\n" " \n" " \n" " If the procedure was successful, 1 is returned, otherwise 0 is\n" " returned.\n" " \n" " \n" "
\n" ; static PyObject * asymmetric_object_verify(asymmetric_object *self, PyObject *args) { char *digest_text=NULL, *signed_text=NULL; int digest_len=0, digest_type=0, digest_nid=0, signed_len=0, result=0; if (!PyArg_ParseTuple(args, "s#s#i", &signed_text, &signed_len, &digest_text, &digest_len, &digest_type)) goto error; switch(digest_type) { case MD2_DIGEST: { digest_len = MD2_DIGEST_LENGTH; digest_nid = NID_md2; break; } 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: { PyErr_SetString( SSLErrorObject, "unsupported digest" ); goto error; } } result = RSA_verify( digest_nid, digest_text, digest_len, signed_text, signed_len, self->cipher ); return Py_BuildValue("i", result); 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, 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__[] = "\n" "
\n" " Asymmetric\n" "
\n" " \n" " \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" " \n" " \n" "
\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; self = PyObject_New( symmetric_object, &symmetrictype ); if (self == 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__[] = "\n" "
\n" " Symmetric\n" " encryptInit\n" " key\n" " initialvalue=''\n" "
\n" " \n" " \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 initialvalue serves\n" " a similar purpose the the salt supplied to the Unix\n" " crypt function.\n" " The initialvalue 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" " \n" " \n" "
\n" ; static PyObject * symmetric_object_encrypt_init(symmetric_object *self, PyObject *args) { 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 ) ) ) { PyErr_SetString( SSLErrorObject, "unsupported cipher" ); goto error; } if ( !EVP_EncryptInit( &self->cipher_ctx, cipher, key, iv ) ) { PyErr_SetString( SSLErrorObject, "could not initialise cipher" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char symmetric_object_decrypt_init__doc__[] = "\n" "
\n" " Symmetric\n" " decryptInit\n" " key\n" " initialvalue=''\n" "
\n" " \n" " \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 initialvalue \n" " used to encrypt the data.\n" " \n" " \n" "
\n" ; static PyObject * symmetric_object_decrypt_init(symmetric_object *self, PyObject *args) { 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 ) ) ) { PyErr_SetString( SSLErrorObject, "unsupported cipher" ); goto error; } if ( !EVP_DecryptInit( &self->cipher_ctx, cipher, key, iv ) ) { PyErr_SetString( SSLErrorObject, "could not initialise cipher" ); goto error; } return Py_BuildValue(""); error: return NULL; } static char symmetric_object_update__doc__[] = "\n" "
\n" " Symmetric\n" " update\n" " data\n" "
\n" " \n" " \n" " This method is used to process the bulk of data being encrypted\n" " or decrypted by the cipher object. data\n" " should be a string.\n" " \n" " \n" "
\n" ; static PyObject * symmetric_object_update(symmetric_object *self, PyObject *args) { int inl=0, outl=0; 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) ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !EVP_CipherUpdate( &self->cipher_ctx, out, &outl, in, inl ) ) { PyErr_SetString( SSLErrorObject, "could not update cipher" ); goto error; } if ( !(py_out = Py_BuildValue("s#", out, outl) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } free(out); return py_out; error: if (out) free(out); return NULL; } static char symmetric_object_final__doc__[] = "\n" "
\n" " Symmetric\n" " final\n" " size=1024\n" "
\n" " \n" " \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 size. \n" " \n" " \n" "
\n" ; static PyObject * symmetric_object_final(symmetric_object *self, PyObject *args) { int outl=0, size=1024; 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) ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !EVP_CipherFinal( &self->cipher_ctx, out, &outl ) ) { PyErr_SetString( SSLErrorObject, "could not update cipher" ); goto error; } if ( !(py_out = Py_BuildValue("s#", out, outl) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } 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, 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__[] = "\n" "
\n" " Symmetric\n" "
\n" " \n" " \n" " This class provides access to all the symmetric ciphers in OpenSSL.\n" " Initialisation of the cipher structures is performed late, only\n" " when encryptInit or\n" " decryptInit is called, the\n" " constructor only records the cipher type. It is possible to reuse\n" " the Symmetric objects by calling\n" " encryptInit or decryptInit\n" " again.\n" " \n" " \n" " <classname>Symmetric</classname> class usage\n" " \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" " \n" " \n" " \n" "
\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; self = PyObject_New( digest_object, &digesttype ); if (self == NULL) goto error; switch(digest_type) { case MD2_DIGEST: { self->digest_type = MD2_DIGEST; EVP_DigestInit( &self->digest_ctx, EVP_md2() ); break; } 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: { PyErr_SetString( SSLErrorObject, "unsupported digest" ); goto error; } } return self; error: Py_XDECREF(self); return NULL; } static char digest_object_update__doc__[] = "\n" "
\n" " Digest\n" " update\n" " data\n" "
\n" " \n" " \n" " This method updates the internal structures of the \n" " Digest object with data.\n" " data should be a string.\n" " \n" " \n" "
\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 ); return Py_BuildValue(""); error: return NULL; } static char digest_object_copy__doc__[] = "\n" "
\n" " Digest\n" " copy\n" "
\n" " \n" " \n" " This method returns a copy of the Digest\n" " object.\n" " \n" " \n" "
\n" ; static PyObject * digest_object_copy(digest_object *self, PyObject *args) { digest_object *new=NULL; if ( !(new = PyObject_New( digest_object, &digesttype ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } new->digest_type = self->digest_type; if (!EVP_MD_CTX_copy( &new->digest_ctx, &self->digest_ctx )) { PyErr_SetString( SSLErrorObject, "could not copy digest" ); goto error; } return (PyObject*)new; error: Py_XDECREF(new); return NULL; } static char digest_object_digest__doc__[] = "\n" "
\n" " Digest\n" " digest\n" "
\n" " \n" " \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 digest\n" " object.\n" " \n" " \n" "
\n" ; static PyObject * digest_object_digest(digest_object *self, PyObject *args) { char digest_text[EVP_MAX_MD_SIZE]; void *md_copy=NULL; int digest_len=0; if (!PyArg_ParseTuple(args, "")) goto error; if ( !(md_copy = malloc( sizeof(EVP_MD_CTX) ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if (!EVP_MD_CTX_copy( md_copy, &self->digest_ctx )) { PyErr_SetString( SSLErrorObject, "could not copy digest" ); goto error; } 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, 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__[] = "\n" "
\n" " Digest\n" "
\n" " \n" " \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 hexdigest\n" " function.\n" " \n" " \n" " <classname>digest</classname> class usage\n" " \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" " \n" " \n" " \n" "
\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; self = PyObject_New( hmac_object, &hmactype ); if (self == NULL) goto error; switch(digest_type) { case MD2_DIGEST: { md = EVP_md2(); break; } 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: { PyErr_SetString( SSLErrorObject, "unsupported digest" ); goto error; } } HMAC_Init( &self->hmac_ctx, key, key_len, md ); return self; error: Py_XDECREF(self); return NULL; } static char hmac_object_update__doc__[] = "\n" "
\n" " Hmac\n" " update\n" " data\n" "
\n" " \n" " \n" " This method updates the internal structures of the \n" " Hmac object with data.\n" " data should be a string.\n" " \n" " \n" "
\n" ; static PyObject * hmac_object_update(hmac_object *self, PyObject *args) { char *data=NULL; int len=0; if (!PyArg_ParseTuple(args, "s#", &data, &len)) goto error; HMAC_Update( &self->hmac_ctx, data, len ); return Py_BuildValue(""); error: return NULL; } static char hmac_object_copy__doc__[] = "\n" "
\n" " Hmac\n" " copy\n" "
\n" " \n" " \n" " This method returns a copy of the Hmac\n" " object.\n" " \n" " \n" "
\n" ; static PyObject * hmac_object_copy(hmac_object *self, PyObject *args) { hmac_object *new=NULL; if ( !(new = PyObject_New( hmac_object, &hmactype ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } 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__[] = "\n" "
\n" " Hmac\n" " mac\n" "
\n" " \n" " \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 Hmac\n" " object.\n" " \n" " \n" "
\n" ; static PyObject * hmac_object_mac(hmac_object *self, PyObject *args) { char hmac_text[EVP_MAX_MD_SIZE]; void *hmac_copy=NULL; int hmac_len=0; if (!PyArg_ParseTuple(args, "")) goto error; if ( !(hmac_copy = malloc( sizeof(HMAC_CTX) ) ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } 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, 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__[] = "\n" "
\n" " Hmac\n" "
\n" " \n" " \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" " \n" " \n" "
\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 ==========*/ /*========== PKCS7 code ==========*/ static pkcs7_object * PKCS7_object_new(void) { pkcs7_object *self; self = PyObject_New( pkcs7_object, &pkcs7type ); if (self == NULL) goto error; self->pkcs7 = NULL; return self; error: Py_XDECREF(self); return NULL; } static pkcs7_object * PKCS7_object_pem_read(BIO *in) { pkcs7_object *self; if ( !(self = PyObject_New( pkcs7_object, &pkcs7type ) ) ) goto error; if( !(self->pkcs7 = PEM_read_bio_PKCS7( in, NULL, NULL, NULL ) ) ) { PyErr_SetString( SSLErrorObject, "could not load PEM encoded PKCS7 message" ); goto error; } return self; error: Py_XDECREF(self); return NULL; } static pkcs7_object * PKCS7_object_der_read(char *src, int len) { pkcs7_object *self; BIO *bio = NULL; if ( !(self = PyObject_New( pkcs7_object, &pkcs7type ) ) ) goto error; self->pkcs7 = PKCS7_new(); if ( !(bio = BIO_new_mem_buf(src, len) ) ) goto error; if( !(d2i_PKCS7_bio( bio, &self->pkcs7 ) ) ) { PyErr_SetString( SSLErrorObject, "could not load PEM encoded PKCS7 message" ); goto error; } BIO_free(bio); return self; error: if (bio) BIO_free(bio); Py_XDECREF(self); return NULL; } static PyObject * PKCS7_object_write_helper(pkcs7_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()); if (format == DER_FORMAT) { if (!i2d_PKCS7_bio(out_bio, self->pkcs7) ) { PyErr_SetString( SSLErrorObject, "unable to write certificate" ); goto error; } } else if (format == PEM_FORMAT) { if (!PEM_write_bio_PKCS7(out_bio, self->pkcs7) ) { PyErr_SetString( SSLErrorObject, "unable to write certificate" ); goto error; } } else { PyErr_SetString( SSLErrorObject, "internal error, unkown output format" ); goto error; } if ( !(len = BIO_ctrl_pending(out_bio) ) ) { PyErr_SetString( SSLErrorObject, "unable to get bytes stored in bio" ); goto error; } if ( !(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( BIO_read( out_bio, buf, len ) != len ) { PyErr_SetString( SSLErrorObject, "unable to write out cert" ); goto error; } 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 PKCS7_object_pem_write__doc__[] = "\n" "
\n" " PKCS7\n" " pemWrite\n" "
\n" " \n" " \n" " This method returns a PEM encoded PKCS7 message as a\n" " string.\n" " \n" " \n" "
\n" ; static PyObject * PKCS7_object_pem_write(pkcs7_object *self, PyObject *args) { return PKCS7_object_write_helper(self, args, PEM_FORMAT); } static char PKCS7_object_der_write__doc__[] = "\n" "
\n" " PKCS7\n" " derWrite\n" "
\n" " \n" " \n" " This method returns a DER encoded PKCS7 message as a\n" " string.\n" " \n" " \n" "
\n" ; static PyObject * PKCS7_object_der_write(pkcs7_object *self, PyObject *args) { return PKCS7_object_write_helper(self, args, DER_FORMAT); } static char PKCS7_object_sign__doc__[] = "\n" "
\n" " PKCS7\n" " sign\n" " signcert\n" " key\n" " certs\n" " data\n" " no_certs\n" "
\n" " \n" " \n" " This method signs a message with a private key.\n" " \n" " \n" "
\n" ; static PyObject * PKCS7_object_sign(pkcs7_object *self, PyObject *args) { asymmetric_object *signkey = NULL; x509_object *signcert = NULL; PyObject *x509_sequence = NULL; STACK_OF(X509) *x509_stack = NULL; EVP_PKEY *pkey = NULL; char *buf = NULL; int len, flags = PKCS7_BINARY | PKCS7_NOATTR; BIO *bio = NULL; PKCS7 *p7 = NULL; PyObject *no_certs = Py_False; if (!PyArg_ParseTuple(args, "O!O!Os#|O!", &x509type, &signcert, &asymmetrictype, &signkey, &x509_sequence, &buf, &len, &PyBool_Type, &no_certs)) goto error; if (signkey->key_type != RSA_PRIVATE_KEY) { PyErr_SetString( SSLErrorObject, "unsupported key type" ); goto error; } if ( !(x509_stack = x509_helper_sequence_to_stack(x509_sequence)) ) goto error; if ( !(pkey = EVP_PKEY_new() ) ) { PyErr_SetString( SSLErrorObject, "could not allocate memory" ); goto error; } if ( !(EVP_PKEY_assign_RSA(pkey, signkey->cipher) ) ) { PyErr_SetString( SSLErrorObject, "EVP_PKEY assignment error" ); goto error; } if ( !(bio = BIO_new_mem_buf(buf, len))) goto error; if ( no_certs == Py_True ) flags |= PKCS7_NOCERTS; if ( !(p7 = PKCS7_sign(signcert->x509, pkey, x509_stack, bio, flags))) { set_openssl_pyerror( "could not sign PKCS7 message" ); goto error; } if (self->pkcs7) PKCS7_free(self->pkcs7); self->pkcs7 = p7; p7 = NULL; sk_X509_free(x509_stack); BIO_free(bio); return Py_BuildValue(""); error: if (p7) PKCS7_free(p7); if (bio) BIO_free(bio); if (x509_stack) sk_X509_free(x509_stack); if (pkey) EVP_PKEY_free(pkey); return NULL; } static char PKCS7_object_verify__doc__[] = "\n" "
\n" " PKCS7\n" " verify\n" " store\n" " certs\n" "
\n" " \n" " \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" " \n" " \n" "
\n" ; static PyObject * PKCS7_object_verify(pkcs7_object *self, PyObject *args) { x509_store_object *store = NULL; PyObject *result = NULL, *certs_sequence = Py_None; STACK_OF(X509) *certs_stack = NULL; char *buf = NULL; BIO *bio = NULL; int len; if (!(bio = BIO_new(BIO_s_mem()))) goto error; if (!PyArg_ParseTuple(args, "O!|O", &x509_storetype, &store, &certs_sequence)) goto error; if (certs_sequence != Py_None && !(certs_stack = x509_helper_sequence_to_stack(certs_sequence))) goto error; if (PKCS7_verify(self->pkcs7, certs_stack, store->store, NULL, bio, 0) <= 0) { set_openssl_pyerror( "could not verify PKCS7 message" ); goto error; } if (!(len = BIO_ctrl_pending(bio))) { PyErr_SetString( SSLErrorObject, "unable to get bytes stored in bio" ); goto error; } if (!(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if (BIO_read( bio, buf, len ) != len) { PyErr_SetString( SSLErrorObject, "unable to write out PKCS7 content" ); goto error; } result = Py_BuildValue("s#", buf, len); if (certs_stack) sk_X509_free(certs_stack); BIO_free(bio); free(buf); return result; error: if (certs_stack) sk_X509_free(certs_stack); if (bio) BIO_free(bio); if (buf) free(buf); return NULL; } static struct PyMethodDef PKCS7_object_methods[] = { {"pemWrite", (PyCFunction)PKCS7_object_pem_write, METH_VARARGS, NULL}, {"derWrite", (PyCFunction)PKCS7_object_der_write, METH_VARARGS, NULL}, {"sign", (PyCFunction)PKCS7_object_sign, METH_VARARGS, NULL}, {"verify", (PyCFunction)PKCS7_object_verify, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ }; static PyObject * PKCS7_object_getattr(pkcs7_object *self, char *name) { return Py_FindMethod(PKCS7_object_methods, (PyObject *)self, name); } static void PKCS7_object_dealloc(pkcs7_object *self, char *name) { PKCS7_free( self->pkcs7 ); PyObject_Del(self); } static char pkcs7type__doc__[] = "\n" "
\n" " PKCS7\n" "
\n" " \n" " \n" " This class provides basic access OpenSSL's PKCS7 functionality.\n" " \n" " \n" "
\n" ; static PyTypeObject pkcs7type = { PyObject_HEAD_INIT(0) 0, /*ob_size*/ "PKCS7", /*tp_name*/ sizeof(pkcs7_object), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)PKCS7_object_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)PKCS7_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, pkcs7type__doc__ /* Documentation string */ }; /*========== PKCS7 Code ==========*/ /*========== CMS code ==========*/ static cms_object * CMS_object_new(void) { cms_object *self; self = PyObject_New( cms_object, &cmstype ); if (self == 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 ) ) ) goto error; if( !(self->cms = PEM_read_bio_CMS( in, NULL, NULL, NULL ) ) ) { PyErr_SetString( SSLErrorObject, "could not load PEM encoded CMS message" ); goto error; } 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 ) ) ) goto error; self->cms = CMS_ContentInfo_new(); if ( !(bio = BIO_new_mem_buf(src, len) ) ) goto error; if( !(d2i_CMS_bio( bio, &self->cms ) ) ) { PyErr_SetString( SSLErrorObject, "could not load PEM encoded CMS message" ); goto error; } 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()); if (format == DER_FORMAT) { if (!i2d_CMS_bio(out_bio, self->cms) ) { PyErr_SetString( SSLErrorObject, "unable to write certificate" ); goto error; } } else if (format == PEM_FORMAT) { if (!PEM_write_bio_CMS(out_bio, self->cms) ) { PyErr_SetString( SSLErrorObject, "unable to write certificate" ); goto error; } } else { PyErr_SetString( SSLErrorObject, "internal error, unkown output format" ); goto error; } if ( !(len = BIO_ctrl_pending(out_bio) ) ) { PyErr_SetString( SSLErrorObject, "unable to get bytes stored in bio" ); goto error; } if ( !(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if ( BIO_read( out_bio, buf, len ) != len ) { PyErr_SetString( SSLErrorObject, "unable to write out cert" ); goto error; } 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__[] = "\n" "
\n" " CMS\n" " pemWrite\n" "
\n" " \n" " \n" " This method returns a PEM encoded CMS message as a\n" " string.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " CMS\n" " derWrite\n" "
\n" " \n" " \n" " This method returns a DER encoded CMS message as a\n" " string.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " CMS\n" " sign\n" " signcert\n" " key\n" " certs\n" " data\n" " \n" " eContentType\n" " flags\n" " \n" "
\n" " \n" " \n" " This method signs a message with a private key.\n" " Supported flags: CMS_NOCERTS, CMS_NOATTR.\n" " \n" " \n" "
\n" ; static PyObject * CMS_object_sign(cms_object *self, PyObject *args) { asymmetric_object *signkey = NULL; x509_object *signcert = NULL; PyObject *x509_sequence = NULL; STACK_OF(X509) *x509_stack = NULL; EVP_PKEY *pkey = NULL; char *buf = NULL, *oid = NULL; int i, len, flags = 0; BIO *bio = NULL; CMS_ContentInfo *cms = NULL; ASN1_OBJECT *econtent_type = NULL; if (!PyArg_ParseTuple(args, "O!O!Os#|si", &x509type, &signcert, &asymmetrictype, &signkey, &x509_sequence, &buf, &len, &oid, &flags)) goto error; flags &= CMS_NOCERTS | CMS_NOATTR; flags |= CMS_BINARY | CMS_NOSMIMECAP | CMS_PARTIAL | CMS_USE_KEYID; if (signkey->key_type != RSA_PRIVATE_KEY) { PyErr_SetString( SSLErrorObject, "unsupported key type" ); goto error; } if ( !(x509_stack = x509_helper_sequence_to_stack(x509_sequence)) ) goto error; if ( !(pkey = EVP_PKEY_new() ) ) { set_openssl_pyerror( "could not allocate memory" ); goto error; } if ( !(EVP_PKEY_assign_RSA(pkey, signkey->cipher) ) ) { set_openssl_pyerror( "EVP_PKEY assignment error" ); goto error; } if ( !(bio = BIO_new_mem_buf(buf, len))) goto error; if ( oid && (econtent_type = OBJ_txt2obj(oid, 0)) == NULL ) { set_openssl_pyerror( "could not parse OID" ); goto error; } if ( !(cms = CMS_sign(NULL, NULL, NULL, bio, flags))) { set_openssl_pyerror( "could not create CMS message" ); goto error; } for ( i = 0; i < sk_X509_num(x509_stack); i++ ) if ( !CMS_add1_cert(cms, sk_X509_value(x509_stack, i))) { set_openssl_pyerror( "could not add cert to CMS message" ); goto error; } if (econtent_type) CMS_set1_eContentType(cms, econtent_type); if ( !CMS_add1_signer(cms, signcert->x509, pkey, EVP_sha256(), flags)) { set_openssl_pyerror( "could not sign CMS message" ); goto error; } if ( !CMS_final(cms, bio, NULL, flags)) { set_openssl_pyerror( "could not finalize CMS signatures" ); goto error; } if (self->cms) CMS_ContentInfo_free(self->cms); self->cms = cms; cms = NULL; sk_X509_free(x509_stack); BIO_free(bio); if (econtent_type) ASN1_OBJECT_free(econtent_type); return Py_BuildValue(""); error: 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); return NULL; } static char CMS_object_verify__doc__[] = "\n" "
\n" " CMS\n" " verify\n" " store\n" " certs\n" "
\n" " \n" " \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" " \n" " \n" "
\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; char *buf = NULL; BIO *bio = NULL; int len; if (!(bio = BIO_new(BIO_s_mem()))) goto error; if (!PyArg_ParseTuple(args, "O!|O", &x509_storetype, &store, &certs_sequence)) goto error; if (certs_sequence != Py_None && !(certs_stack = x509_helper_sequence_to_stack(certs_sequence))) goto error; if (CMS_verify(self->cms, certs_stack, store->store, NULL, bio, 0) <= 0) { set_openssl_pyerror( "could not verify CMS message" ); goto error; } if (!(len = BIO_ctrl_pending(bio))) { PyErr_SetString( SSLErrorObject, "unable to get bytes stored in bio" ); goto error; } if (!(buf = malloc(len) ) ) { PyErr_SetString( SSLErrorObject, "unable to allocate memory" ); goto error; } if (BIO_read( bio, buf, len ) != len) { PyErr_SetString( SSLErrorObject, "unable to write out CMS content" ); goto error; } result = Py_BuildValue("s#", buf, len); if (certs_stack) sk_X509_free(certs_stack); BIO_free(bio); free(buf); return result; error: if (certs_stack) sk_X509_free(certs_stack); if (bio) BIO_free(bio); if (buf) free(buf); return NULL; } static char CMS_object_eContentType__doc__[] = "\n" "
\n" " CMS\n" " get_eContentType\n" "
\n" " \n" " \n" " This method returns the eContentType of a CMS message.\n" " \n" " \n" "
\n" ; static PyObject * CMS_object_eContentType(cms_object *self, PyObject *args) { const ASN1_OBJECT *oid = NULL; char buf[512]; if (!PyArg_ParseTuple(args, "")) return NULL; if ( !(oid = CMS_get0_eContentType(self->cms))) { set_openssl_pyerror("Could not extract eContentType from CMS message"); return NULL; } OBJ_obj2txt(buf, sizeof(buf), oid, 1); return Py_BuildValue("s", buf); } 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}, {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__[] = "\n" "
\n" " CMS\n" "
\n" " \n" " \n" " This class provides basic access OpenSSL's CMS functionality.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " Ssl\n" " protocol=SSLV23METHOD\n" "
\n" " \n" " \n" " This constructor creates a new Ssl object which will behave as a client\n" " or server, depending on the protocol value passed. The\n" " protocol also determines the protocol type\n" " and version and should be one of the following:\n" " \n" "\n" " \n" " SSLV2_SERVER_METHOD\n" " SSLV2_CLIENT_METHOD\n" " SSLV2_METHOD\n" " SSLV3_SERVER_METHOD\n" " SSLV3_CLIENT_METHOD\n" " SSLV3_METHOD\n" " TLSV1_SERVER_METHOD\n" " TLSV1_CLIENT_METHOD\n" " TLSV1_METHOD\n" " SSLV23_SERVER_METHOD\n" " SSLV23_CLIENT_METHOD\n" " SSLV23_METHOD\n" " \n" " \n" "
\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) ) ) goto error; return (PyObject*)ssl; error: return NULL; } static char pow_module_new_x509__doc__[] = "\n" "
\n" " X509\n" "
\n" " \n" " \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" " \n" " \n" "
\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() ) ) { PyErr_SetString( SSLErrorObject, "could not create new x509 object" ); goto error; } return (PyObject*)x509; error: return NULL; } static char pow_module_new_asymmetric__doc__[] = "\n" "
\n" " Asymmetric\n" " ciphertype=RSA_CIPHER\n" " keylength=1024\n" "
\n" " \n" " \n" " This constructor builds a new cipher object. Only RSA ciphers\n" " are currently support, so the first argument should always be\n" " RSA_CIPHER. The second argument,\n" " keylength,\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" " \n" " \n" " <classname>asymmetric</classname> class usage\n" " \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" " \n" " \n" " \n" "
\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__[] = "\n" "
\n" " Digest\n" " type\n" "
\n" " \n" " \n" " This constructor creates a new Digest\n" " object. The parameter type specifies what kind\n" " of digest to create and should be one of the following: \n" " \n" " \n" " MD2_DIGEST\n" " MD5_DIGEST\n" " SHA_DIGEST\n" " SHA1_DIGEST\n" " RIPEMD160_DIGEST\n" " SHA256_DIGEST\n" " SHA384_DIGEST\n" " SHA512_DIGEST\n" " \n" " \n" "
\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__[] = "\n" "
\n" " Hmac\n" " type\n" " key\n" "
\n" " \n" " \n" " This constructor creates a new Hmac\n" " object. The parameter key should be a\n" " string and type should be one of the following: \n" " \n" " \n" " MD2_DIGEST\n" " MD5_DIGEST\n" " SHA_DIGEST\n" " SHA1_DIGEST\n" " RIPEMD160_DIGEST\n" " SHA256_DIGEST\n" " SHA384_DIGEST\n" " SHA512_DIGEST\n" " \n" " \n" "
\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_pkcs7__doc__[] = "\n" "
\n" " PKCS7\n" "
\n" " \n" " \n" " This constructor creates a skeletal PKCS7 object.\n" " \n" " \n" "
\n" ; static PyObject * pow_module_new_pkcs7 (PyObject *self, PyObject *args) { pkcs7_object *pkcs7 = NULL; if (!PyArg_ParseTuple(args, "")) goto error; if ( !(pkcs7 = PKCS7_object_new() ) ) { PyErr_SetString( SSLErrorObject, "could not create new PKCS7 object" ); goto error; } return (PyObject*)pkcs7; error: return NULL; } static char pow_module_new_cms__doc__[] = "\n" "
\n" " CMS\n" "
\n" " \n" " \n" " This constructor creates a skeletal CMS object.\n" " \n" " \n" "
\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() ) ) { PyErr_SetString( SSLErrorObject, "could not create new CMS object" ); goto error; } return (PyObject*)cms; error: return NULL; } static char pow_module_pem_read__doc__[] = "\n" "
\n" " pemRead\n" " type\n" " string\n" " pass=None\n" "
\n" " \n" " \n" " This function attempts to parse the string according to the PEM\n" " type passed. type should be one of the\n" " following:\n" " \n" " \n" " RSA_PUBLIC_KEY\n" " RSA_PRIVATE_KEY\n" " X509_CERTIFICATE\n" " X509_CRL\n" " PKCS7_MESSAGE\n" " CMS_MESSAGE\n" " \n" " \n" " pass should only be provided if an encrypted\n" " Asymmetric 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 Asymmetric, \n" " X509, X509Crl,\n" " PKCS7, or CMS.\n" " \n" " \n" "
\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, -1) ) ) { PyErr_SetString( SSLErrorObject, "unable to create new BIO" ); goto error; } if ( !BIO_write( in, src, len ) ) { PyErr_SetString( SSLErrorObject, "unable to write to BIO" ); goto error; } 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 PKCS7_MESSAGE: { obj = (PyObject*)PKCS7_object_pem_read( in ); break ; } case CMS_MESSAGE: { obj = (PyObject*)CMS_object_pem_read( in ); break ; } default: { PyErr_SetString( SSLErrorObject, "unknown pem encoding" ); goto error; } } BIO_free(in); if (obj) return obj; error: return NULL; } static char pow_module_der_read__doc__[] = "\n" "
\n" " derRead\n" " type\n" " string\n" "
\n" " \n" " \n" " This function attempts to parse the string according to the PEM\n" " type passed. type should be one of the\n" " following:\n" " \n" " \n" " RSA_PUBLIC_KEY\n" " RSA_PRIVATE_KEY\n" " X509_CERTIFICATE\n" " X509_CRL\n" " PKCS7_MESSAGE\n" " CMS_MESSAGE\n" " \n" " \n" " As with the PEM operations, the object returned will be and instance \n" " of Asymmetric, X509,\n" " X509Crl, PKCS7,\n" " or CMS.\n" " \n" " \n" "
\n" ; static PyObject * pow_module_der_read (PyObject *self, PyObject *args) { PyObject *obj=NULL; int object_type=0, len=0; 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 PKCS7_MESSAGE: { obj = (PyObject*)PKCS7_object_der_read( src, len ); break ; } case CMS_MESSAGE: { obj = (PyObject*)CMS_object_der_read( src, len ); break ; } default: { PyErr_SetString( SSLErrorObject, "unknown der encoding" ); goto error; } } if (obj) return obj; error: return NULL; } static char pow_module_new_x509_store__doc__[] = "\n" "
\n" " X509Store\n" "
\n" " \n" " \n" " This constructor takes no arguments. The\n" " X509Store returned cannot be used for\n" " verifying certificates until at least one trusted certificate has been\n" " added.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " Symmetric\n" " type\n" "
\n" " \n" " \n" " This constructor creates a new Symmetric\n" " object. The parameter type specifies which kind\n" " of cipher to create. type should be one of the following: \n" " \n" " \n" " DES_ECB \n" " DES_EDE\n" " DES_EDE3 \n" " DES_CFB \n" " DES_EDE_CFB \n" " DES_EDE3_CFB\n" " DES_OFB\n" " DES_EDE_OFB\n" " DES_EDE3_OFB\n" " DES_CBC\n" " DES_EDE_CBC\n" " DES_EDE3_CBC\n" " DESX_CBC\n" " RC4\n" " RC4_40\n" " IDEA_ECB\n" " IDEA_CFB\n" " IDEA_OFB\n" " IDEA_CBC\n" " RC2_ECB\n" " RC2_CBC\n" " RC2_40_CBC\n" " RC2_CFB\n" " RC2_OFB\n" " BF_ECB\n" " BF_CBC\n" " BF_CFB\n" " BF_OFB\n" " CAST5_ECB\n" " CAST5_CBC\n" " CAST5_CFB\n" " CAST5_OFB\n" " RC5_32_12_16_CBC\n" " RC5_32_12_16_CFB\n" " RC5_32_12_16_ECB\n" " RC5_32_12_16_OFB\n" " \n" " \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" " \n" " \n" "
\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__[] = "\n" "
\n" " x509_crl\n" "
\n" " \n" " \n" " This constructor builds an empty CRL.\n" " \n" " \n" "
\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__[] = "\n" "
\n" " X509Revoked\n" " serial\n" " date\n" "
\n" " \n" " \n" " This constructor builds a X509 Revoked structure. serial\n" " should be an integer and date should be and\n" " UTCTime string.\n" " \n" " \n" "
\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) if ( !ASN1_INTEGER_set( revoke->revoked->serialNumber, serial ) ) { PyErr_SetString( SSLErrorObject, "unable to set serial number" ); goto error; } if (date != NULL) if (!ASN1_UTCTIME_set_string( revoke->revoked->revocationDate, date )) { PyErr_SetString( PyExc_TypeError, "could not set revocationDate" ); goto error; } return (PyObject*)revoke; error: return NULL; } static char pow_module_add_object__doc__[] = "\n" "
\n" " addObject\n" " oid\n" " shortName\n" " longName\n" "
\n" " \n" " \n" " This function can be used to dynamically add new objects to\n" " OpenSSL. The oid should be a string of space separated numbers\n" " and shortName and\n" " longName are the names of the object, ie\n" " 'cn' and 'commonName'.\n" " \n" " \n" "
\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) ) {PyErr_SetString(SSLErrorObject, "unable to add object"); goto error;} return Py_BuildValue(""); error: return NULL; } static char pow_module_get_error__doc__[] = "\n" "
\n" " getError\n" "
\n" " \n" " \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" " \n" " \n" "
\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__[] = "\n" "
\n" " clearError\n" "
\n" " \n" " \n" " Removes all errors from the global error stack.\n" " \n" " \n" "
\n" ; static PyObject * pow_module_clear_error(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) goto error; ERR_clear_error(); return Py_BuildValue(""); error: return NULL; } static char pow_module_seed__doc__[] = "\n" "
\n" " seed\n" " data\n" "
\n" " \n" " \n" " The seed 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 seed and add are very\n" " similar, except the entropy of the data is assumed to be equal to\n" " the length for seed. I 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" " \n" " \n" "
\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 ); return Py_BuildValue(""); error: return NULL; } static char pow_module_add__doc__[] = "\n" "
\n" " add\n" " data\n" " entropy\n" "
\n" " \n" " \n" " The add function adds data to OpenSSLs PRNG\n" " state. data should be data obtained from a\n" " random source and entropy is an estimation of the number of random\n" " bytes in data.\n" " \n" " \n" "
\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 ); return Py_BuildValue(""); error: return NULL; } static char pow_module_write_random_file__doc__[] = "\n" "
\n" " writeRandomFile\n" " filename\n" "
\n" " \n" " \n" " This function writes the current random state to a file. Clearly\n" " this function should be used in conjunction with\n" " readRandomFile.\n" " \n" " \n" "
\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 ) {PyErr_SetString(SSLErrorObject, "could not write random file"); goto error;} return Py_BuildValue(""); error: return NULL; } static char pow_module_read_random_file__doc__[] = "\n" "
\n" " readRandomFile\n" " filename\n" "
\n" " \n" " \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" " add function, with data from other\n" " suitable random sources.\n" " \n" " \n" "
\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 ) ) {PyErr_SetString(SSLErrorObject, "could not load random file"); goto error;} return Py_BuildValue(""); 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_pkcs7__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_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_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__ ); // pkcs7 documentation docset_helper_add( docset, PKCS7_object_pem_write__doc__ ); docset_helper_add( docset, PKCS7_object_der_write__doc__ ); docset_helper_add( docset, PKCS7_object_sign__doc__ ); docset_helper_add( docset, PKCS7_object_verify__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__ ); // 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 Py_BuildValue("O", 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}, {"PKCS7", (PyCFunction)pow_module_new_pkcs7, 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, (PyCFunction)NULL, 0, NULL} /* sentinel */ }; /*========== module functions ==========*/ /*==========================================================================*/ void init_POW(void) { PyObject *m, *d; 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; pkcs7type.ob_type = &PyType_Type; cmstype.ob_type = &PyType_Type; m = Py_InitModule4("_POW", pow_module_methods, pow_module__doc__, (PyObject*)NULL,PYTHON_API_VERSION); d = PyModule_GetDict(m); SSLErrorObject = PyErr_NewException("POW.SSLError", NULL, NULL); PyDict_SetItemString(d, "SSLError", SSLErrorObject); // constants for SSL_get_error() install_int_const( d, "SSL_ERROR_NONE", SSL_ERROR_NONE ); install_int_const( d, "SSL_ERROR_ZERO_RETURN", SSL_ERROR_ZERO_RETURN ); install_int_const( d, "SSL_ERROR_WANT_READ", SSL_ERROR_WANT_READ ); install_int_const( d, "SSL_ERROR_WANT_WRITE", SSL_ERROR_WANT_WRITE ); install_int_const( d, "SSL_ERROR_WANT_X509_LOOKUP",SSL_ERROR_WANT_X509_LOOKUP ); install_int_const( d, "SSL_ERROR_SYSCALL", SSL_ERROR_SYSCALL ); install_int_const( d, "SSL_ERROR_SSL", SSL_ERROR_SSL ); // constants for different types of connection methods install_int_const( d, "SSLV2_SERVER_METHOD", SSLV2_SERVER_METHOD ); install_int_const( d, "SSLV2_CLIENT_METHOD", SSLV2_CLIENT_METHOD ); install_int_const( d, "SSLV2_METHOD", SSLV2_METHOD ); install_int_const( d, "SSLV3_SERVER_METHOD", SSLV3_SERVER_METHOD ); install_int_const( d, "SSLV3_CLIENT_METHOD", SSLV3_CLIENT_METHOD ); install_int_const( d, "SSLV3_METHOD", SSLV3_METHOD ); install_int_const( d, "SSLV23_SERVER_METHOD", SSLV23_SERVER_METHOD ); install_int_const( d, "SSLV23_CLIENT_METHOD", SSLV23_CLIENT_METHOD ); install_int_const( d, "SSLV23_METHOD", SSLV23_METHOD ); install_int_const( d, "TLSV1_SERVER_METHOD", TLSV1_SERVER_METHOD ); install_int_const( d, "TLSV1_CLIENT_METHOD", TLSV1_CLIENT_METHOD ); install_int_const( d, "TLSV1_METHOD", TLSV1_METHOD ); install_int_const( d, "SSL_NO_SHUTDOWN", 0 ); install_int_const( d, "SSL_SENT_SHUTDOWN", SSL_SENT_SHUTDOWN ); install_int_const( d, "SSL_RECIEVED_SHUTDOWN", SSL_RECEIVED_SHUTDOWN ); // ssl verification mode install_int_const( d, "SSL_VERIFY_NONE", SSL_VERIFY_NONE ); install_int_const( d, "SSL_VERIFY_PEER", SSL_VERIFY_PEER ); // object format types install_int_const( d, "LONGNAME_FORMAT", LONGNAME_FORMAT ); install_int_const( d, "SHORTNAME_FORMAT", SHORTNAME_FORMAT ); // PEM encoded types #ifndef OPENSSL_NO_RSA install_int_const( d, "RSA_PUBLIC_KEY", RSA_PUBLIC_KEY ); install_int_const( d, "RSA_PRIVATE_KEY", RSA_PRIVATE_KEY ); #endif #ifndef OPENSSL_NO_DSA install_int_const( d, "DSA_PUBLIC_KEY", DSA_PUBLIC_KEY ); install_int_const( d, "DSA_PRIVATE_KEY", DSA_PRIVATE_KEY ); #endif #ifndef OPENSSL_NO_DH install_int_const( d, "DH_PUBLIC_KEY", DH_PUBLIC_KEY ); install_int_const( d, "DH_PRIVATE_KEY", DH_PRIVATE_KEY ); #endif install_int_const( d, "X509_CERTIFICATE", X509_CERTIFICATE ); install_int_const( d, "X509_CRL", X_X509_CRL ); install_int_const( d, "PKCS7_MESSAGE", PKCS7_MESSAGE ); install_int_const( d, "CMS_MESSAGE", CMS_MESSAGE ); // asymmetric ciphers #ifndef OPENSSL_NO_RSA install_int_const( d, "RSA_CIPHER", RSA_CIPHER ); #endif #ifndef OPENSSL_NO_DSA install_int_const( d, "DSA_CIPHER", DSA_CIPHER ); #endif #ifndef OPENSSL_NO_DH install_int_const( d, "DH_CIPHER", DH_CIPHER ); #endif // symmetric ciphers #ifndef OPENSSL_NO_DES install_int_const( d, "DES_ECB", DES_ECB ); install_int_const( d, "DES_EDE", DES_EDE ); install_int_const( d, "DES_EDE3", DES_EDE3 ); install_int_const( d, "DES_CFB", DES_CFB ); install_int_const( d, "DES_EDE_CFB", DES_EDE_CFB ); install_int_const( d, "DES_EDE3_CFB", DES_EDE3_CFB ); install_int_const( d, "DES_OFB", DES_OFB ); install_int_const( d, "DES_EDE_OFB", DES_EDE_OFB ); install_int_const( d, "DES_EDE3_OFB", DES_EDE3_OFB ); install_int_const( d, "DES_CBC", DES_CBC ); install_int_const( d, "DES_EDE_CBC", DES_EDE_CBC ); install_int_const( d, "DES_EDE3_CBC", DES_EDE3_CBC ); install_int_const( d, "DESX_CBC", DESX_CBC ); #endif #ifndef OPENSSL_NO_RC4 install_int_const( d, "RC4", RC4 ); install_int_const( d, "RC4_40", RC4_40 ); #endif #ifndef OPENSSL_NO_IDEA install_int_const( d, "IDEA_ECB", IDEA_ECB ); install_int_const( d, "IDEA_CFB", IDEA_CFB ); install_int_const( d, "IDEA_OFB", IDEA_OFB ); install_int_const( d, "IDEA_CBC", IDEA_CBC ); #endif #ifndef OPENSSL_NO_RC2 install_int_const( d, "RC2_ECB", RC2_ECB ); install_int_const( d, "RC2_CBC", RC2_CBC ); install_int_const( d, "RC2_40_CBC", RC2_40_CBC ); install_int_const( d, "RC2_CFB", RC2_CFB ); install_int_const( d, "RC2_OFB", RC2_OFB ); #endif #ifndef OPENSSL_NO_BF install_int_const( d, "BF_ECB", BF_ECB ); install_int_const( d, "BF_CBC", BF_CBC ); install_int_const( d, "BF_CFB", BF_CFB ); install_int_const( d, "BF_OFB", BF_OFB ); #endif install_int_const( d, "CAST5_ECB", CAST5_ECB ); install_int_const( d, "CAST5_CBC", CAST5_CBC ); install_int_const( d, "CAST5_CFB", CAST5_CFB ); install_int_const( d, "CAST5_OFB", CAST5_OFB ); #ifndef OPENSSL_NO_RC5 install_int_const( d, "RC5_32_12_16_CBC", RC5_32_12_16_CBC ); install_int_const( d, "RC5_32_12_16_CFB", RC5_32_12_16_CFB ); install_int_const( d, "RC5_32_12_16_ECB", RC5_32_12_16_ECB ); install_int_const( d, "RC5_32_12_16_OFB", RC5_32_12_16_OFB ); #endif // message digests install_int_const( d, "MD2_DIGEST", MD2_DIGEST ); install_int_const( d, "MD5_DIGEST", MD5_DIGEST ); install_int_const( d, "SHA_DIGEST", SHA_DIGEST ); install_int_const( d, "SHA1_DIGEST", SHA1_DIGEST ); install_int_const( d, "RIPEMD160_DIGEST", RIPEMD160_DIGEST ); install_int_const( d, "SHA256_DIGEST", SHA256_DIGEST ); install_int_const( d, "SHA384_DIGEST", SHA384_DIGEST ); install_int_const( d, "SHA512_DIGEST", SHA512_DIGEST ); // general name install_int_const( d, "GEN_OTHERNAME", GEN_OTHERNAME ); install_int_const( d, "GEN_EMAIL", GEN_EMAIL ); install_int_const( d, "GEN_DNS", GEN_DNS ); install_int_const( d, "GEN_X400", GEN_X400 ); install_int_const( d, "GEN_DIRNAME", GEN_DIRNAME ); install_int_const( d, "GEN_EDIPARTY", GEN_EDIPARTY ); install_int_const( d, "GEN_URI", GEN_URI ); install_int_const( d, "GEN_IPADD", GEN_IPADD ); install_int_const( d, "GEN_RID", GEN_RID ); // CMS flags install_int_const( d, "CMS_NOCERTS", CMS_NOCERTS ); install_int_const( d, "CMS_NOATTR", CMS_NOATTR ); install_int_const( d, "CMS_NOINTERN", CMS_NOINTERN ); install_int_const( d, "CMS_NOCRL", CMS_NOCRL ); install_int_const( d, "CMS_NO_SIGNER_CERT_VERIFY", CMS_NO_SIGNER_CERT_VERIFY ); install_int_const( d, "CMS_NO_ATTR_VERIFY", CMS_NO_ATTR_VERIFY ); install_int_const( d, "CMS_NO_CONTENT_VERIFY", CMS_NO_CONTENT_VERIFY ); // 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: */