blob: 7081706ba3ce42e31c156bb3f5b5eee14455e0c1 [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"
Gregory P. Smithea388262009-02-13 03:00:00 +000015#include "hashlib.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000016
Guido van Rossum5f59d601992-12-14 16:59:51 +000017typedef struct {
Barry Warsaw8b43b191996-12-09 22:32:36 +000018 PyObject_HEAD
Matthias Klose8e39ec72006-04-03 16:27:50 +000019 md5_state_t md5; /* the context holder */
Guido van Rossum5f59d601992-12-14 16:59:51 +000020} md5object;
21
Jeremy Hylton938ace62002-07-17 16:30:39 +000022static PyTypeObject MD5type;
Guido van Rossum5f59d601992-12-14 16:59:51 +000023
24#define is_md5object(v) ((v)->ob_type == &MD5type)
25
Guido van Rossum5f59d601992-12-14 16:59:51 +000026static md5object *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000027newmd5object(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +000028{
29 md5object *md5p;
30
Guido van Rossumb18618d2000-05-03 23:44:39 +000031 md5p = PyObject_New(md5object, &MD5type);
Guido van Rossum5f59d601992-12-14 16:59:51 +000032 if (md5p == NULL)
33 return NULL;
34
Matthias Klose8e39ec72006-04-03 16:27:50 +000035 md5_init(&md5p->md5); /* actual initialisation */
Guido van Rossum5f59d601992-12-14 16:59:51 +000036 return md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +000037}
Guido van Rossum5f59d601992-12-14 16:59:51 +000038
39
40/* MD5 methods */
41
42static void
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +000043md5_dealloc(md5object *md5p)
Guido van Rossum5f59d601992-12-14 16:59:51 +000044{
Guido van Rossumb18618d2000-05-03 23:44:39 +000045 PyObject_Del(md5p);
Guido van Rossumb6775db1994-08-01 11:34:53 +000046}
Guido van Rossum5f59d601992-12-14 16:59:51 +000047
48
Guido van Rossumb6775db1994-08-01 11:34:53 +000049/* MD5 methods-as-attributes */
50
Barry Warsaw8b43b191996-12-09 22:32:36 +000051static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +000052md5_update(md5object *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +000053{
Gregory P. Smithea388262009-02-13 03:00:00 +000054 PyObject *data_obj;
55 Py_buffer view;
Guido van Rossumb6775db1994-08-01 11:34:53 +000056
Gregory P. Smithea388262009-02-13 03:00:00 +000057 if (!PyArg_ParseTuple(args, "O:update", &data_obj))
Guido van Rossumb6775db1994-08-01 11:34:53 +000058 return NULL;
59
Gregory P. Smithea388262009-02-13 03:00:00 +000060 GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Gregory P. Smithea388262009-02-13 03:00:00 +000062 md5_append(&self->md5, (unsigned char*)view.buf,
63 Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
64
65 PyBuffer_Release(&view);
Barry Warsaw8b43b191996-12-09 22:32:36 +000066 Py_INCREF(Py_None);
67 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +000068}
69
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000070PyDoc_STRVAR(update_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +000071"update (arg)\n\
72\n\
73Update the md5 object with the string arg. Repeated calls are\n\
74equivalent to a single call with the concatenation of all the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000075arguments.");
Guido van Rossumd3a6a141998-10-14 13:46:57 +000076
77
Barry Warsaw8b43b191996-12-09 22:32:36 +000078static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +000079md5_digest(md5object *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +000080{
Matthias Klose8e39ec72006-04-03 16:27:50 +000081 md5_state_t mdContext;
Guido van Rossumb6775db1994-08-01 11:34:53 +000082 unsigned char aDigest[16];
83
Guido van Rossumb6775db1994-08-01 11:34:53 +000084 /* make a temporary copy, and perform the final */
85 mdContext = self->md5;
Matthias Klose8e39ec72006-04-03 16:27:50 +000086 md5_finish(&mdContext, aDigest);
Guido van Rossumb6775db1994-08-01 11:34:53 +000087
Gregory P. Smithdd96db62008-06-09 04:58:54 +000088 return PyString_FromStringAndSize((char *)aDigest, 16);
Guido van Rossumb6775db1994-08-01 11:34:53 +000089}
90
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000091PyDoc_STRVAR(digest_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +000092"digest() -> string\n\
93\n\
94Return the digest of the strings passed to the update() method so\n\
Skip Montanarobd2de3a2003-07-08 21:17:25 +000095far. This is a 16-byte string which may contain non-ASCII characters,\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000096including null bytes.");
Guido van Rossumd3a6a141998-10-14 13:46:57 +000097
98
Barry Warsaw8b43b191996-12-09 22:32:36 +000099static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000100md5_hexdigest(md5object *self)
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000101{
Matthias Klose8e39ec72006-04-03 16:27:50 +0000102 md5_state_t mdContext;
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000103 unsigned char digest[16];
104 unsigned char hexdigest[32];
105 int i, j;
106
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000107 /* make a temporary copy, and perform the final */
108 mdContext = self->md5;
Matthias Klose8e39ec72006-04-03 16:27:50 +0000109 md5_finish(&mdContext, digest);
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000110
111 /* Make hex version of the digest */
112 for(i=j=0; i<16; i++) {
113 char c;
114 c = (digest[i] >> 4) & 0xf;
115 c = (c>9) ? c+'a'-10 : c + '0';
116 hexdigest[j++] = c;
117 c = (digest[i] & 0xf);
118 c = (c>9) ? c+'a'-10 : c + '0';
119 hexdigest[j++] = c;
120 }
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000121 return PyString_FromStringAndSize((char*)hexdigest, 32);
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000122}
123
124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000125PyDoc_STRVAR(hexdigest_doc,
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000126"hexdigest() -> string\n\
127\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000128Like digest(), but returns the digest as a string of hexadecimal digits.");
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000129
130
131static PyObject *
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000132md5_copy(md5object *self)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000133{
134 md5object *md5p;
135
Guido van Rossumb6775db1994-08-01 11:34:53 +0000136 if ((md5p = newmd5object()) == NULL)
137 return NULL;
138
139 md5p->md5 = self->md5;
140
Barry Warsaw8b43b191996-12-09 22:32:36 +0000141 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000142}
143
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000144PyDoc_STRVAR(copy_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000145"copy() -> md5 object\n\
146\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000147Return a copy (``clone'') of the md5 object.");
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000148
149
Barry Warsaw8b43b191996-12-09 22:32:36 +0000150static PyMethodDef md5_methods[] = {
Neal Norwitzba3a16c2002-03-31 15:27:00 +0000151 {"update", (PyCFunction)md5_update, METH_VARARGS, update_doc},
Neal Norwitz3a6f9782002-03-25 20:46:46 +0000152 {"digest", (PyCFunction)md5_digest, METH_NOARGS, digest_doc},
153 {"hexdigest", (PyCFunction)md5_hexdigest, METH_NOARGS, hexdigest_doc},
154 {"copy", (PyCFunction)md5_copy, METH_NOARGS, copy_doc},
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000155 {NULL, NULL} /* sentinel */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000156};
157
Barry Warsaw8b43b191996-12-09 22:32:36 +0000158static PyObject *
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000159md5_get_block_size(PyObject *self, void *closure)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000160{
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000161 return PyInt_FromLong(64);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000162}
163
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000164static PyObject *
165md5_get_digest_size(PyObject *self, void *closure)
166{
167 return PyInt_FromLong(16);
168}
169
170static PyObject *
171md5_get_name(PyObject *self, void *closure)
172{
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000173 return PyString_FromStringAndSize("MD5", 3);
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000174}
175
176static PyGetSetDef md5_getseters[] = {
177 {"digest_size",
178 (getter)md5_get_digest_size, NULL,
179 NULL,
180 NULL},
181 {"block_size",
182 (getter)md5_get_block_size, NULL,
183 NULL,
184 NULL},
185 {"name",
186 (getter)md5_get_name, NULL,
187 NULL,
188 NULL},
189 /* the old md5 and sha modules support 'digest_size' as in PEP 247.
190 * the old sha module also supported 'digestsize'. ugh. */
191 {"digestsize",
192 (getter)md5_get_digest_size, NULL,
193 NULL,
194 NULL},
195 {NULL} /* Sentinel */
196};
197
198
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000199PyDoc_STRVAR(module_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000200"This module implements the interface to RSA's MD5 message digest\n\
201algorithm (see also Internet RFC 1321). Its use is quite\n\
202straightforward: use the new() to create an md5 object. You can now\n\
203feed this object with arbitrary strings using the update() method, and\n\
204at any point you can ask it for the digest (a strong kind of 128-bit\n\
Thomas Wouters7e474022000-07-16 12:04:32 +0000205checksum, a.k.a. ``fingerprint'') of the concatenation of the strings\n\
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000206fed to it so far using the digest() method.\n\
207\n\
208Functions:\n\
209\n\
210new([arg]) -- return a new md5 object, initialized with arg if provided\n\
211md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
212\n\
213Special Objects:\n\
214\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000215MD5Type -- type object for md5 objects");
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000216
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000217PyDoc_STRVAR(md5type_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000218"An md5 represents the object used to calculate the MD5 checksum of a\n\
219string of information.\n\
220\n\
221Methods:\n\
222\n\
223update() -- updates the current digest with an additional string\n\
224digest() -- return the current digest value\n\
Neal Norwitz98a355d2002-10-11 21:53:01 +0000225hexdigest() -- return the current digest as a string of hexadecimal digits\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000226copy() -- return a copy of the current md5 object");
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000227
Tim Peters0c322792002-07-17 16:49:03 +0000228static PyTypeObject MD5type = {
Martin v. Löwis68192102007-07-21 06:55:02 +0000229 PyVarObject_HEAD_INIT(NULL, 0)
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000230 "_md5.md5", /*tp_name*/
Barry Warsaw8b43b191996-12-09 22:32:36 +0000231 sizeof(md5object), /*tp_size*/
232 0, /*tp_itemsize*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233 /* methods */
Barry Warsaw8b43b191996-12-09 22:32:36 +0000234 (destructor)md5_dealloc, /*tp_dealloc*/
235 0, /*tp_print*/
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000236 0, /*tp_getattr*/
Barry Warsaw8b43b191996-12-09 22:32:36 +0000237 0, /*tp_setattr*/
238 0, /*tp_compare*/
239 0, /*tp_repr*/
240 0, /*tp_as_number*/
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000241 0, /*tp_as_sequence*/
242 0, /*tp_as_mapping*/
243 0, /*tp_hash*/
244 0, /*tp_call*/
245 0, /*tp_str*/
246 0, /*tp_getattro*/
247 0, /*tp_setattro*/
248 0, /*tp_as_buffer*/
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000249 Py_TPFLAGS_DEFAULT, /*tp_flags*/
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000250 md5type_doc, /*tp_doc*/
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000251 0, /*tp_traverse*/
252 0, /*tp_clear*/
253 0, /*tp_richcompare*/
254 0, /*tp_weaklistoffset*/
255 0, /*tp_iter*/
256 0, /*tp_iternext*/
257 md5_methods, /*tp_methods*/
258 0, /*tp_members*/
259 md5_getseters, /*tp_getset*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260};
261
262
263/* MD5 functions */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000264
Barry Warsaw8b43b191996-12-09 22:32:36 +0000265static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000266MD5_new(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000267{
268 md5object *md5p;
Gregory P. Smithea388262009-02-13 03:00:00 +0000269 PyObject *data_obj = NULL;
270 Py_buffer view;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000271
Gregory P. Smithea388262009-02-13 03:00:00 +0000272 if (!PyArg_ParseTuple(args, "|O:new", &data_obj))
Guido van Rossumef38b781995-07-26 17:33:10 +0000273 return NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000274
Kristján Valur Jónsson7705d0a2009-03-03 03:20:42 +0000275 if (data_obj)
276 GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view, NULL);
Gregory P. Smithea388262009-02-13 03:00:00 +0000277
278 if ((md5p = newmd5object()) == NULL) {
Kristján Valur Jónsson7705d0a2009-03-03 03:20:42 +0000279 if (data_obj)
280 PyBuffer_Release(&view);
Guido van Rossum5f59d601992-12-14 16:59:51 +0000281 return NULL;
Gregory P. Smithea388262009-02-13 03:00:00 +0000282 }
Guido van Rossum5f59d601992-12-14 16:59:51 +0000283
Gregory P. Smithea388262009-02-13 03:00:00 +0000284 if (data_obj) {
285 md5_append(&md5p->md5, (unsigned char*)view.buf,
286 Py_SAFE_DOWNCAST(view.len, Py_ssize_t, unsigned int));
Kristján Valur Jónsson7705d0a2009-03-03 03:20:42 +0000287 PyBuffer_Release(&view);
Gregory P. Smithea388262009-02-13 03:00:00 +0000288 }
Kristján Valur Jónsson7705d0a2009-03-03 03:20:42 +0000289
Barry Warsaw8b43b191996-12-09 22:32:36 +0000290 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000291}
Guido van Rossum5f59d601992-12-14 16:59:51 +0000292
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000293PyDoc_STRVAR(new_doc,
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000294"new([arg]) -> md5 object\n\
295\n\
296Return a new md5 object. If arg is present, the method call update(arg)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000297is made.");
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000298
Guido van Rossum5f59d601992-12-14 16:59:51 +0000299
Guido van Rossum5f59d601992-12-14 16:59:51 +0000300/* List of functions exported by this module */
301
Barry Warsaw8b43b191996-12-09 22:32:36 +0000302static PyMethodDef md5_functions[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000303 {"new", (PyCFunction)MD5_new, METH_VARARGS, new_doc},
Guido van Rossumef38b781995-07-26 17:33:10 +0000304 {NULL, NULL} /* Sentinel */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000305};
306
307
308/* Initialize this module. */
309
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000310PyMODINIT_FUNC
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000311init_md5(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000312{
Fred Drake52a42e92001-11-02 22:05:06 +0000313 PyObject *m, *d;
Fred Drake0d40ba42000-02-04 20:33:49 +0000314
Christian Heimese93237d2007-12-19 02:37:44 +0000315 Py_TYPE(&MD5type) = &PyType_Type;
Gregory P. Smithf21a5f72005-08-21 18:45:59 +0000316 if (PyType_Ready(&MD5type) < 0)
317 return;
318 m = Py_InitModule3("_md5", md5_functions, module_doc);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000319 if (m == NULL)
320 return;
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000321 d = PyModule_GetDict(m);
322 PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
Fred Drake52a42e92001-11-02 22:05:06 +0000323 PyModule_AddIntConstant(m, "digest_size", 16);
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000324 /* No need to check the error here, the caller will do that */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000325}