symbian-qemu-0.9.1-12/python-2.6.1/Modules/_hashopenssl.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /* Module that wraps all OpenSSL hash algorithms */
       
     2 
       
     3 /*
       
     4  * Copyright (C) 2005   Gregory P. Smith (greg@krypto.org)
       
     5  * Licensed to PSF under a Contributor Agreement.
       
     6  *
       
     7  * Derived from a skeleton of shamodule.c containing work performed by:
       
     8  *
       
     9  * Andrew Kuchling (amk@amk.ca)
       
    10  * Greg Stein (gstein@lyra.org)
       
    11  *
       
    12  */
       
    13 
       
    14 #define PY_SSIZE_T_CLEAN
       
    15 
       
    16 #include "Python.h"
       
    17 #include "structmember.h"
       
    18 
       
    19 /* EVP is the preferred interface to hashing in OpenSSL */
       
    20 #include <openssl/evp.h>
       
    21 
       
    22 #define MUNCH_SIZE INT_MAX
       
    23 
       
    24 
       
    25 #ifndef HASH_OBJ_CONSTRUCTOR
       
    26 #define HASH_OBJ_CONSTRUCTOR 0
       
    27 #endif
       
    28 
       
    29 typedef struct {
       
    30     PyObject_HEAD
       
    31     PyObject            *name;  /* name of this hash algorithm */
       
    32     EVP_MD_CTX          ctx;    /* OpenSSL message digest context */
       
    33 } EVPobject;
       
    34 
       
    35 
       
    36 static PyTypeObject EVPtype;
       
    37 
       
    38 
       
    39 #define DEFINE_CONSTS_FOR_NEW(Name)  \
       
    40     static PyObject *CONST_ ## Name ## _name_obj; \
       
    41     static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \
       
    42     static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
       
    43 
       
    44 DEFINE_CONSTS_FOR_NEW(md5)
       
    45 DEFINE_CONSTS_FOR_NEW(sha1)
       
    46 DEFINE_CONSTS_FOR_NEW(sha224)
       
    47 DEFINE_CONSTS_FOR_NEW(sha256)
       
    48 DEFINE_CONSTS_FOR_NEW(sha384)
       
    49 DEFINE_CONSTS_FOR_NEW(sha512)
       
    50 
       
    51 
       
    52 static EVPobject *
       
    53 newEVPobject(PyObject *name)
       
    54 {
       
    55     EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
       
    56 
       
    57     /* save the name for .name to return */
       
    58     if (retval != NULL) {
       
    59         Py_INCREF(name);
       
    60         retval->name = name;
       
    61     }
       
    62 
       
    63     return retval;
       
    64 }
       
    65 
       
    66 /* Internal methods for a hash object */
       
    67 
       
    68 static void
       
    69 EVP_dealloc(PyObject *ptr)
       
    70 {
       
    71     EVP_MD_CTX_cleanup(&((EVPobject *)ptr)->ctx);
       
    72     Py_XDECREF(((EVPobject *)ptr)->name);
       
    73     PyObject_Del(ptr);
       
    74 }
       
    75 
       
    76 
       
    77 /* External methods for a hash object */
       
    78 
       
    79 PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object.");
       
    80 
       
    81 static PyObject *
       
    82 EVP_copy(EVPobject *self, PyObject *unused)
       
    83 {
       
    84     EVPobject *newobj;
       
    85 
       
    86     if ( (newobj = newEVPobject(self->name))==NULL)
       
    87         return NULL;
       
    88 
       
    89     EVP_MD_CTX_copy(&newobj->ctx, &self->ctx);
       
    90     return (PyObject *)newobj;
       
    91 }
       
    92 
       
    93 PyDoc_STRVAR(EVP_digest__doc__,
       
    94 "Return the digest value as a string of binary data.");
       
    95 
       
    96 static PyObject *
       
    97 EVP_digest(EVPobject *self, PyObject *unused)
       
    98 {
       
    99     unsigned char digest[EVP_MAX_MD_SIZE];
       
   100     EVP_MD_CTX temp_ctx;
       
   101     PyObject *retval;
       
   102     unsigned int digest_size;
       
   103 
       
   104     EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
       
   105     digest_size = EVP_MD_CTX_size(&temp_ctx);
       
   106     EVP_DigestFinal(&temp_ctx, digest, NULL);
       
   107 
       
   108     retval = PyString_FromStringAndSize((const char *)digest, digest_size);
       
   109     EVP_MD_CTX_cleanup(&temp_ctx);
       
   110     return retval;
       
   111 }
       
   112 
       
   113 PyDoc_STRVAR(EVP_hexdigest__doc__,
       
   114 "Return the digest value as a string of hexadecimal digits.");
       
   115 
       
   116 static PyObject *
       
   117 EVP_hexdigest(EVPobject *self, PyObject *unused)
       
   118 {
       
   119     unsigned char digest[EVP_MAX_MD_SIZE];
       
   120     EVP_MD_CTX temp_ctx;
       
   121     PyObject *retval;
       
   122     char *hex_digest;
       
   123     unsigned int i, j, digest_size;
       
   124 
       
   125     /* Get the raw (binary) digest value */
       
   126     EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
       
   127     digest_size = EVP_MD_CTX_size(&temp_ctx);
       
   128     EVP_DigestFinal(&temp_ctx, digest, NULL);
       
   129 
       
   130     EVP_MD_CTX_cleanup(&temp_ctx);
       
   131 
       
   132     /* Create a new string */
       
   133     /* NOTE: not thread safe! modifying an already created string object */
       
   134     /* (not a problem because we hold the GIL by default) */
       
   135     retval = PyString_FromStringAndSize(NULL, digest_size * 2);
       
   136     if (!retval)
       
   137 	    return NULL;
       
   138     hex_digest = PyString_AsString(retval);
       
   139     if (!hex_digest) {
       
   140 	    Py_DECREF(retval);
       
   141 	    return NULL;
       
   142     }
       
   143 
       
   144     /* Make hex version of the digest */
       
   145     for(i=j=0; i<digest_size; i++) {
       
   146         char c;
       
   147         c = (digest[i] >> 4) & 0xf;
       
   148 	c = (c>9) ? c+'a'-10 : c + '0';
       
   149         hex_digest[j++] = c;
       
   150         c = (digest[i] & 0xf);
       
   151 	c = (c>9) ? c+'a'-10 : c + '0';
       
   152         hex_digest[j++] = c;
       
   153     }
       
   154     return retval;
       
   155 }
       
   156 
       
   157 PyDoc_STRVAR(EVP_update__doc__,
       
   158 "Update this hash object's state with the provided string.");
       
   159 
       
   160 static PyObject *
       
   161 EVP_update(EVPobject *self, PyObject *args)
       
   162 {
       
   163     unsigned char *cp;
       
   164     Py_ssize_t len;
       
   165 
       
   166     if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
       
   167         return NULL;
       
   168 
       
   169     if (len > 0 && len <= MUNCH_SIZE) {
       
   170     EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
       
   171                                                       unsigned int));
       
   172     } else {
       
   173         Py_ssize_t offset = 0;
       
   174         while (len) {
       
   175             unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
       
   176             EVP_DigestUpdate(&self->ctx, cp + offset, process);
       
   177             len -= process;
       
   178             offset += process;
       
   179         }
       
   180     }
       
   181     Py_INCREF(Py_None);
       
   182     return Py_None;
       
   183 }
       
   184 
       
   185 static PyMethodDef EVP_methods[] = {
       
   186     {"update",	  (PyCFunction)EVP_update,    METH_VARARGS, EVP_update__doc__},
       
   187     {"digest",	  (PyCFunction)EVP_digest,    METH_NOARGS,  EVP_digest__doc__},
       
   188     {"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS,  EVP_hexdigest__doc__},
       
   189     {"copy",	  (PyCFunction)EVP_copy,      METH_NOARGS,  EVP_copy__doc__},
       
   190     {NULL,	  NULL}		/* sentinel */
       
   191 };
       
   192 
       
   193 static PyObject *
       
   194 EVP_get_block_size(EVPobject *self, void *closure)
       
   195 {
       
   196     return PyInt_FromLong(EVP_MD_CTX_block_size(&((EVPobject *)self)->ctx));
       
   197 }
       
   198 
       
   199 static PyObject *
       
   200 EVP_get_digest_size(EVPobject *self, void *closure)
       
   201 {
       
   202     return PyInt_FromLong(EVP_MD_CTX_size(&((EVPobject *)self)->ctx));
       
   203 }
       
   204 
       
   205 static PyMemberDef EVP_members[] = {
       
   206     {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")},
       
   207     {NULL}  /* Sentinel */
       
   208 };
       
   209 
       
   210 static PyGetSetDef EVP_getseters[] = {
       
   211     {"digest_size",
       
   212      (getter)EVP_get_digest_size, NULL,
       
   213      NULL,
       
   214      NULL},
       
   215     {"block_size",
       
   216      (getter)EVP_get_block_size, NULL,
       
   217      NULL,
       
   218      NULL},
       
   219     /* the old md5 and sha modules support 'digest_size' as in PEP 247.
       
   220      * the old sha module also supported 'digestsize'.  ugh. */
       
   221     {"digestsize",
       
   222      (getter)EVP_get_digest_size, NULL,
       
   223      NULL,
       
   224      NULL},
       
   225     {NULL}  /* Sentinel */
       
   226 };
       
   227 
       
   228 
       
   229 static PyObject *
       
   230 EVP_repr(PyObject *self)
       
   231 {
       
   232     char buf[100];
       
   233     PyOS_snprintf(buf, sizeof(buf), "<%s HASH object @ %p>",
       
   234             PyString_AsString(((EVPobject *)self)->name), self);
       
   235     return PyString_FromString(buf);
       
   236 }
       
   237 
       
   238 #if HASH_OBJ_CONSTRUCTOR
       
   239 static int
       
   240 EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
       
   241 {
       
   242     static char *kwlist[] = {"name", "string", NULL};
       
   243     PyObject *name_obj = NULL;
       
   244     char *nameStr;
       
   245     unsigned char *cp = NULL;
       
   246     Py_ssize_t len = 0;
       
   247     const EVP_MD *digest;
       
   248 
       
   249     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:HASH", kwlist,
       
   250                                      &name_obj, &cp, &len)) {
       
   251         return -1;
       
   252     }
       
   253 
       
   254     if (!PyArg_Parse(name_obj, "s", &nameStr)) {
       
   255         PyErr_SetString(PyExc_TypeError, "name must be a string");
       
   256         return -1;
       
   257     }
       
   258 
       
   259     digest = EVP_get_digestbyname(nameStr);
       
   260     if (!digest) {
       
   261         PyErr_SetString(PyExc_ValueError, "unknown hash function");
       
   262         return -1;
       
   263     }
       
   264     EVP_DigestInit(&self->ctx, digest);
       
   265 
       
   266     self->name = name_obj;
       
   267     Py_INCREF(self->name);
       
   268 
       
   269     if (cp && len) {
       
   270         if (len > 0 && len <= MUNCH_SIZE) {
       
   271         EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
       
   272                                                           unsigned int));
       
   273         } else {
       
   274             Py_ssize_t offset = 0;
       
   275             while (len) {
       
   276                 unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
       
   277                 EVP_DigestUpdate(&self->ctx, cp + offset, process);
       
   278                 len -= process;
       
   279                 offset += process;
       
   280             }
       
   281         }
       
   282     }
       
   283     
       
   284     return 0;
       
   285 }
       
   286 #endif
       
   287 
       
   288 
       
   289 PyDoc_STRVAR(hashtype_doc,
       
   290 "A hash represents the object used to calculate a checksum of a\n\
       
   291 string of information.\n\
       
   292 \n\
       
   293 Methods:\n\
       
   294 \n\
       
   295 update() -- updates the current digest with an additional string\n\
       
   296 digest() -- return the current digest value\n\
       
   297 hexdigest() -- return the current digest as a string of hexadecimal digits\n\
       
   298 copy() -- return a copy of the current hash object\n\
       
   299 \n\
       
   300 Attributes:\n\
       
   301 \n\
       
   302 name -- the hash algorithm being used by this object\n\
       
   303 digest_size -- number of bytes in this hashes output\n");
       
   304 
       
   305 static PyTypeObject EVPtype = {
       
   306     PyVarObject_HEAD_INIT(NULL, 0)
       
   307     "_hashlib.HASH",    /*tp_name*/
       
   308     sizeof(EVPobject),	/*tp_basicsize*/
       
   309     0,			/*tp_itemsize*/
       
   310     /* methods */
       
   311     EVP_dealloc,	/*tp_dealloc*/
       
   312     0,			/*tp_print*/
       
   313     0,                  /*tp_getattr*/
       
   314     0,                  /*tp_setattr*/
       
   315     0,                  /*tp_compare*/
       
   316     EVP_repr,           /*tp_repr*/
       
   317     0,                  /*tp_as_number*/
       
   318     0,                  /*tp_as_sequence*/
       
   319     0,                  /*tp_as_mapping*/
       
   320     0,                  /*tp_hash*/
       
   321     0,                  /*tp_call*/
       
   322     0,                  /*tp_str*/
       
   323     0,                  /*tp_getattro*/
       
   324     0,                  /*tp_setattro*/
       
   325     0,                  /*tp_as_buffer*/
       
   326     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
       
   327     hashtype_doc,       /*tp_doc*/
       
   328     0,                  /*tp_traverse*/
       
   329     0,			/*tp_clear*/
       
   330     0,			/*tp_richcompare*/
       
   331     0,			/*tp_weaklistoffset*/
       
   332     0,			/*tp_iter*/
       
   333     0,			/*tp_iternext*/
       
   334     EVP_methods,	/* tp_methods */
       
   335     EVP_members,	/* tp_members */
       
   336     EVP_getseters,      /* tp_getset */
       
   337 #if 1
       
   338     0,                  /* tp_base */
       
   339     0,                  /* tp_dict */
       
   340     0,                  /* tp_descr_get */
       
   341     0,                  /* tp_descr_set */
       
   342     0,                  /* tp_dictoffset */
       
   343 #endif
       
   344 #if HASH_OBJ_CONSTRUCTOR
       
   345     (initproc)EVP_tp_init, /* tp_init */
       
   346 #endif
       
   347 };
       
   348 
       
   349 static PyObject *
       
   350 EVPnew(PyObject *name_obj,
       
   351        const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
       
   352        const unsigned char *cp, Py_ssize_t len)
       
   353 {
       
   354     EVPobject *self;
       
   355 
       
   356     if (!digest && !initial_ctx) {
       
   357         PyErr_SetString(PyExc_ValueError, "unsupported hash type");
       
   358         return NULL;
       
   359     }
       
   360 
       
   361     if ((self = newEVPobject(name_obj)) == NULL)
       
   362         return NULL;
       
   363 
       
   364     if (initial_ctx) {
       
   365         EVP_MD_CTX_copy(&self->ctx, initial_ctx);
       
   366     } else {
       
   367         EVP_DigestInit(&self->ctx, digest);
       
   368     }
       
   369 
       
   370     if (cp && len) {
       
   371         if (len > 0 && len <= MUNCH_SIZE) {
       
   372             EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
       
   373                                                               unsigned int));
       
   374         } else {
       
   375             Py_ssize_t offset = 0;
       
   376             while (len) {
       
   377                 unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
       
   378                 EVP_DigestUpdate(&self->ctx, cp + offset, process);
       
   379                 len -= process;
       
   380                 offset += process;
       
   381             }
       
   382         }
       
   383     }
       
   384 
       
   385     return (PyObject *)self;
       
   386 }
       
   387 
       
   388 
       
   389 /* The module-level function: new() */
       
   390 
       
   391 PyDoc_STRVAR(EVP_new__doc__,
       
   392 "Return a new hash object using the named algorithm.\n\
       
   393 An optional string argument may be provided and will be\n\
       
   394 automatically hashed.\n\
       
   395 \n\
       
   396 The MD5 and SHA1 algorithms are always supported.\n");
       
   397 
       
   398 static PyObject *
       
   399 EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
       
   400 {
       
   401     static char *kwlist[] = {"name", "string", NULL};
       
   402     PyObject *name_obj = NULL;
       
   403     char *name;
       
   404     const EVP_MD *digest;
       
   405     unsigned char *cp = NULL;
       
   406     Py_ssize_t len = 0;
       
   407 
       
   408     if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s#:new", kwlist,
       
   409                                      &name_obj, &cp, &len)) {
       
   410         return NULL;
       
   411     }
       
   412 
       
   413     if (!PyArg_Parse(name_obj, "s", &name)) {
       
   414         PyErr_SetString(PyExc_TypeError, "name must be a string");
       
   415         return NULL;
       
   416     }
       
   417 
       
   418     digest = EVP_get_digestbyname(name);
       
   419 
       
   420     return EVPnew(name_obj, digest, NULL, cp, len);
       
   421 }
       
   422 
       
   423 /*
       
   424  *  This macro generates constructor function definitions for specific
       
   425  *  hash algorithms.  These constructors are much faster than calling
       
   426  *  the generic one passing it a python string and are noticably
       
   427  *  faster than calling a python new() wrapper.  Thats important for
       
   428  *  code that wants to make hashes of a bunch of small strings.
       
   429  */
       
   430 #define GEN_CONSTRUCTOR(NAME)  \
       
   431     static PyObject * \
       
   432     EVP_new_ ## NAME (PyObject *self, PyObject *args) \
       
   433     { \
       
   434         unsigned char *cp = NULL; \
       
   435         Py_ssize_t len = 0; \
       
   436      \
       
   437         if (!PyArg_ParseTuple(args, "|s#:" #NAME , &cp, &len)) { \
       
   438             return NULL; \
       
   439         } \
       
   440      \
       
   441         return EVPnew( \
       
   442                 CONST_ ## NAME ## _name_obj, \
       
   443                 NULL, \
       
   444                 CONST_new_ ## NAME ## _ctx_p, \
       
   445                 cp, len); \
       
   446     }
       
   447 
       
   448 /* a PyMethodDef structure for the constructor */
       
   449 #define CONSTRUCTOR_METH_DEF(NAME)  \
       
   450     {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \
       
   451         PyDoc_STR("Returns a " #NAME \
       
   452                   " hash object; optionally initialized with a string") \
       
   453     }
       
   454 
       
   455 /* used in the init function to setup a constructor */
       
   456 #define INIT_CONSTRUCTOR_CONSTANTS(NAME)  do { \
       
   457     CONST_ ## NAME ## _name_obj = PyString_FromString(#NAME); \
       
   458     if (EVP_get_digestbyname(#NAME)) { \
       
   459         CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \
       
   460         EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
       
   461     } \
       
   462 } while (0);
       
   463 
       
   464 GEN_CONSTRUCTOR(md5)
       
   465 GEN_CONSTRUCTOR(sha1)
       
   466 GEN_CONSTRUCTOR(sha224)
       
   467 GEN_CONSTRUCTOR(sha256)
       
   468 GEN_CONSTRUCTOR(sha384)
       
   469 GEN_CONSTRUCTOR(sha512)
       
   470 
       
   471 /* List of functions exported by this module */
       
   472 
       
   473 static struct PyMethodDef EVP_functions[] = {
       
   474     {"new", (PyCFunction)EVP_new, METH_VARARGS|METH_KEYWORDS, EVP_new__doc__},
       
   475     CONSTRUCTOR_METH_DEF(md5),
       
   476     CONSTRUCTOR_METH_DEF(sha1),
       
   477     CONSTRUCTOR_METH_DEF(sha224),
       
   478     CONSTRUCTOR_METH_DEF(sha256),
       
   479     CONSTRUCTOR_METH_DEF(sha384),
       
   480     CONSTRUCTOR_METH_DEF(sha512),
       
   481     {NULL,	NULL}		 /* Sentinel */
       
   482 };
       
   483 
       
   484 
       
   485 /* Initialize this module. */
       
   486 
       
   487 PyMODINIT_FUNC
       
   488 init_hashlib(void)
       
   489 {
       
   490     PyObject *m;
       
   491 
       
   492     OpenSSL_add_all_digests();
       
   493 
       
   494     /* TODO build EVP_functions openssl_* entries dynamically based
       
   495      * on what hashes are supported rather than listing many
       
   496      * but having some be unsupported.  Only init appropriate
       
   497      * constants. */
       
   498 
       
   499     Py_TYPE(&EVPtype) = &PyType_Type;
       
   500     if (PyType_Ready(&EVPtype) < 0)
       
   501         return;
       
   502 
       
   503     m = Py_InitModule("_hashlib", EVP_functions);
       
   504     if (m == NULL)
       
   505         return;
       
   506 
       
   507 #if HASH_OBJ_CONSTRUCTOR
       
   508     Py_INCREF(&EVPtype);
       
   509     PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
       
   510 #endif
       
   511 
       
   512     /* these constants are used by the convenience constructors */
       
   513     INIT_CONSTRUCTOR_CONSTANTS(md5);
       
   514     INIT_CONSTRUCTOR_CONSTANTS(sha1);
       
   515     INIT_CONSTRUCTOR_CONSTANTS(sha224);
       
   516     INIT_CONSTRUCTOR_CONSTANTS(sha256);
       
   517     INIT_CONSTRUCTOR_CONSTANTS(sha384);
       
   518     INIT_CONSTRUCTOR_CONSTANTS(sha512);
       
   519 }