blob: 0683ef50ba5986cc54f0bc46476369298c56b898 [file] [log] [blame]
Guido van Rossumb6775db1994-08-01 11:34:53 +00001
Guido van Rossum5f59d601992-12-14 16:59:51 +00002/* MD5 module */
3
Guido van Rossumb6775db1994-08-01 11:34:53 +00004/* This module provides an interface to the RSA Data Security,
5 Inc. MD5 Message-Digest Algorithm, described in RFC 1321.
6 It requires the files md5c.c and md5.h (which are slightly changed
7 from the versions in the RFC to avoid the "global.h" file.) */
8
Guido van Rossum5f59d601992-12-14 16:59:51 +00009
10/* MD5 objects */
11
Barry Warsaw8b43b191996-12-09 22:32:36 +000012#include "Python.h"
Gregory P. Smithf21a5f72005-08-21 18:45:59 +000013#include "structmember.h"
Guido van Rossum5f59d601992-12-14 16:59:51 +000014#include "md5.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000015
Guido van Rossum5f59d601992-12-14 16:59:51 +000016typedef struct {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000017 PyObject_HEAD
18 md5_state_t md5; /* the context holder */
Guido van Rossum5f59d601992-12-14 16:59:51 +000019} md5object;
20
Jeremy Hylton938ace62002-07-17 16:30:39 +000021static PyTypeObject MD5type;
Guido van Rossum5f59d601992-12-14 16:59:51 +000022
Antoine Pitrouc83ea132010-05-09 14:46:46 +000023#define is_md5object(v) ((v)->ob_type == &MD5type)
Guido van Rossum5f59d601992-12-14 16:59:51 +000024
Guido van Rossum5f59d601992-12-14 16:59:51 +000025static md5object *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000026newmd5object(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +000027{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000028 md5object *md5p;
Guido van Rossum5f59d601992-12-14 16:59:51 +000029
Antoine Pitrouc83ea132010-05-09 14:46:46 +000030 md5p = PyObject_New(md5object, &MD5type);
31 if (md5p == NULL)
32 return NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +000033
Antoine Pitrouc83ea132010-05-09 14:46:46 +000034 md5_init(&md5p->md5); /* actual initialisation */
35 return md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +000036}
Guido van Rossum5f59d601992-12-14 16:59:51 +000037
38
39/* MD5 methods */
40
41static void
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +000042md5_dealloc(md5object *md5p)
Guido van Rossum5f59d601992-12-14 16:59:51 +000043{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000044 PyObject_Del(md5p);
Guido van Rossumb6775db1994-08-01 11:34:53 +000045}
Guido van Rossum5f59d601992-12-14 16:59:51 +000046
47
Guido van Rossumb6775db1994-08-01 11:34:53 +000048/* MD5 methods-as-attributes */
49
Barry Warsaw8b43b191996-12-09 22:32:36 +000050static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +000051md5_update(md5object *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +000052{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000053 Py_buffer view;
Guido van Rossumb6775db1994-08-01 11:34:53 +000054
Antoine Pitrouc83ea132010-05-09 14:46:46 +000055 if (!PyArg_ParseTuple(args, "s*:update", &view))
56 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +000057
Antoine Pitrouc83ea132010-05-09 14:46:46 +000058 md5_append(&self->md5, (unsigned char*)view.buf,
59 Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
Gregory P. Smithea388262009-02-13 03:00:00 +000060
Antoine Pitrouc83ea132010-05-09 14:46:46 +000061 PyBuffer_Release(&view);
62 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +000063}
64
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000065PyDoc_STRVAR(update_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +000066"update (arg)\n\
67\n\
68Update the md5 object with the string arg. Repeated calls are\n\
69equivalent to a single call with the concatenation of all the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000070arguments.");
Guido van Rossumd3a6a141998-10-14 13:46:57 +000071
72
Barry Warsaw8b43b191996-12-09 22:32:36 +000073static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000074md5_digest(md5object *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +000075{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000076 md5_state_t mdContext;
77 unsigned char aDigest[16];
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Antoine Pitrouc83ea132010-05-09 14:46:46 +000079 /* make a temporary copy, and perform the final */
80 mdContext = self->md5;
81 md5_finish(&mdContext, aDigest);
Guido van Rossumb6775db1994-08-01 11:34:53 +000082
Antoine Pitrouc83ea132010-05-09 14:46:46 +000083 return PyString_FromStringAndSize((char *)aDigest, 16);
Guido van Rossumb6775db1994-08-01 11:34:53 +000084}
85
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000086PyDoc_STRVAR(digest_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +000087"digest() -> string\n\
88\n\
89Return the digest of the strings passed to the update() method so\n\
Skip Montanarobd2de3a2003-07-08 21:17:25 +000090far. This is a 16-byte string which may contain non-ASCII characters,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000091including null bytes.");
Guido van Rossumd3a6a141998-10-14 13:46:57 +000092
93
Barry Warsaw8b43b191996-12-09 22:32:36 +000094static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000095md5_hexdigest(md5object *self)
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +000096{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000097 md5_state_t mdContext;
98 unsigned char digest[16];
99 unsigned char hexdigest[32];
100 int i, j;
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000101
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000102 /* make a temporary copy, and perform the final */
103 mdContext = self->md5;
104 md5_finish(&mdContext, digest);
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000105
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000106 /* Make hex version of the digest */
107 for(i=j=0; i<16; i++) {
108 char c;
109 c = (digest[i] >> 4) & 0xf;
110 c = (c>9) ? c+'a'-10 : c + '0';
111 hexdigest[j++] = c;
112 c = (digest[i] & 0xf);
113 c = (c>9) ? c+'a'-10 : c + '0';
114 hexdigest[j++] = c;
115 }
116 return PyString_FromStringAndSize((char*)hexdigest, 32);
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000117}
118
119
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000120PyDoc_STRVAR(hexdigest_doc,
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000121"hexdigest() -> string\n\
122\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000123Like digest(), but returns the digest as a string of hexadecimal digits.");
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000124
125
126static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000127md5_copy(md5object *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000128{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000129 md5object *md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000130
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000131 if ((md5p = newmd5object()) == NULL)
132 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000133
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000134 md5p->md5 = self->md5;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000135
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000136 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000137}
138
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000139PyDoc_STRVAR(copy_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000140"copy() -> md5 object\n\
141\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000142Return a copy (``clone'') of the md5 object.");
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000143
144
Barry Warsaw8b43b191996-12-09 22:32:36 +0000145static PyMethodDef md5_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000146 {"update", (PyCFunction)md5_update, METH_VARARGS, update_doc},
147 {"digest", (PyCFunction)md5_digest, METH_NOARGS, digest_doc},
148 {"hexdigest", (PyCFunction)md5_hexdigest, METH_NOARGS, hexdigest_doc},
149 {"copy", (PyCFunction)md5_copy, METH_NOARGS, copy_doc},
150 {NULL, NULL} /* sentinel */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000151};
152
Barry Warsaw8b43b191996-12-09 22:32:36 +0000153static PyObject *
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000154md5_get_block_size(PyObject *self, void *closure)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000155{
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000156 return PyInt_FromLong(64);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000157}
158
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000159static PyObject *
160md5_get_digest_size(PyObject *self, void *closure)
161{
162 return PyInt_FromLong(16);
163}
164
165static PyObject *
166md5_get_name(PyObject *self, void *closure)
167{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000168 return PyString_FromStringAndSize("MD5", 3);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000169}
170
171static PyGetSetDef md5_getseters[] = {
172 {"digest_size",
173 (getter)md5_get_digest_size, NULL,
174 NULL,
175 NULL},
176 {"block_size",
177 (getter)md5_get_block_size, NULL,
178 NULL,
179 NULL},
180 {"name",
181 (getter)md5_get_name, NULL,
182 NULL,
183 NULL},
184 /* the old md5 and sha modules support 'digest_size' as in PEP 247.
185 * the old sha module also supported 'digestsize'. ugh. */
186 {"digestsize",
187 (getter)md5_get_digest_size, NULL,
188 NULL,
189 NULL},
190 {NULL} /* Sentinel */
191};
192
193
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000194PyDoc_STRVAR(module_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000195"This module implements the interface to RSA's MD5 message digest\n\
196algorithm (see also Internet RFC 1321). Its use is quite\n\
197straightforward: use the new() to create an md5 object. You can now\n\
198feed this object with arbitrary strings using the update() method, and\n\
199at any point you can ask it for the digest (a strong kind of 128-bit\n\
Thomas Wouters7e474022000-07-16 12:04:32 +0000200checksum, a.k.a. ``fingerprint'') of the concatenation of the strings\n\
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000201fed to it so far using the digest() method.\n\
202\n\
203Functions:\n\
204\n\
205new([arg]) -- return a new md5 object, initialized with arg if provided\n\
206md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
207\n\
208Special Objects:\n\
209\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000210MD5Type -- type object for md5 objects");
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000211
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000212PyDoc_STRVAR(md5type_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000213"An md5 represents the object used to calculate the MD5 checksum of a\n\
214string of information.\n\
215\n\
216Methods:\n\
217\n\
218update() -- updates the current digest with an additional string\n\
219digest() -- return the current digest value\n\
Neal Norwitz98a355d2002-10-11 21:53:01 +0000220hexdigest() -- return the current digest as a string of hexadecimal digits\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000221copy() -- return a copy of the current md5 object");
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000222
Tim Peters0c322792002-07-17 16:49:03 +0000223static PyTypeObject MD5type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000224 PyVarObject_HEAD_INIT(NULL, 0)
225 "_md5.md5", /*tp_name*/
226 sizeof(md5object), /*tp_size*/
227 0, /*tp_itemsize*/
228 /* methods */
229 (destructor)md5_dealloc, /*tp_dealloc*/
230 0, /*tp_print*/
231 0, /*tp_getattr*/
232 0, /*tp_setattr*/
233 0, /*tp_compare*/
234 0, /*tp_repr*/
235 0, /*tp_as_number*/
236 0, /*tp_as_sequence*/
237 0, /*tp_as_mapping*/
238 0, /*tp_hash*/
239 0, /*tp_call*/
240 0, /*tp_str*/
241 0, /*tp_getattro*/
242 0, /*tp_setattro*/
243 0, /*tp_as_buffer*/
244 Py_TPFLAGS_DEFAULT, /*tp_flags*/
245 md5type_doc, /*tp_doc*/
246 0, /*tp_traverse*/
247 0, /*tp_clear*/
248 0, /*tp_richcompare*/
249 0, /*tp_weaklistoffset*/
250 0, /*tp_iter*/
251 0, /*tp_iternext*/
252 md5_methods, /*tp_methods*/
253 0, /*tp_members*/
254 md5_getseters, /*tp_getset*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000255};
256
257
258/* MD5 functions */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000259
Barry Warsaw8b43b191996-12-09 22:32:36 +0000260static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000261MD5_new(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000262{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000263 md5object *md5p;
264 Py_buffer view = { 0 };
Guido van Rossum5f59d601992-12-14 16:59:51 +0000265
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000266 if (!PyArg_ParseTuple(args, "|s*:new", &view))
267 return NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000268
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000269 if ((md5p = newmd5object()) == NULL) {
270 PyBuffer_Release(&view);
271 return NULL;
272 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000273
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000274 if (view.len > 0) {
275 md5_append(&md5p->md5, (unsigned char*)view.buf,
276 Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
277 }
278 PyBuffer_Release(&view);
279
280 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281}
Guido van Rossum5f59d601992-12-14 16:59:51 +0000282
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000283PyDoc_STRVAR(new_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000284"new([arg]) -> md5 object\n\
285\n\
286Return a new md5 object. If arg is present, the method call update(arg)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000287is made.");
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000288
Guido van Rossum5f59d601992-12-14 16:59:51 +0000289
Guido van Rossum5f59d601992-12-14 16:59:51 +0000290/* List of functions exported by this module */
291
Barry Warsaw8b43b191996-12-09 22:32:36 +0000292static PyMethodDef md5_functions[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000293 {"new", (PyCFunction)MD5_new, METH_VARARGS, new_doc},
294 {NULL, NULL} /* Sentinel */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000295};
296
297
298/* Initialize this module. */
299
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000300PyMODINIT_FUNC
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000301init_md5(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000302{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000303 PyObject *m, *d;
Fred Drake0d40ba42000-02-04 20:33:49 +0000304
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000305 Py_TYPE(&MD5type) = &PyType_Type;
306 if (PyType_Ready(&MD5type) < 0)
307 return;
308 m = Py_InitModule3("_md5", md5_functions, module_doc);
309 if (m == NULL)
310 return;
311 d = PyModule_GetDict(m);
312 PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
313 PyModule_AddIntConstant(m, "digest_size", 16);
314 /* No need to check the error here, the caller will do that */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000315}