blob: 5eac97b3fec19b4b4dd8b571e39fd95b2fb092ce [file] [log] [blame]
Guido van Rossum5f59d601992-12-14 16:59:51 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum5f59d601992-12-14 16:59:51 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum5f59d601992-12-14 16:59:51 +00009******************************************************************/
Guido van Rossumb6775db1994-08-01 11:34:53 +000010
Guido van Rossum5f59d601992-12-14 16:59:51 +000011/* MD5 module */
12
Guido van Rossumb6775db1994-08-01 11:34:53 +000013/* This module provides an interface to the RSA Data Security,
14 Inc. MD5 Message-Digest Algorithm, described in RFC 1321.
15 It requires the files md5c.c and md5.h (which are slightly changed
16 from the versions in the RFC to avoid the "global.h" file.) */
17
Guido van Rossum5f59d601992-12-14 16:59:51 +000018
19/* MD5 objects */
20
Barry Warsaw8b43b191996-12-09 22:32:36 +000021#include "Python.h"
Guido van Rossum5f59d601992-12-14 16:59:51 +000022#include "md5.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000023
Guido van Rossum5f59d601992-12-14 16:59:51 +000024typedef struct {
Barry Warsaw8b43b191996-12-09 22:32:36 +000025 PyObject_HEAD
Guido van Rossum5f59d601992-12-14 16:59:51 +000026 MD5_CTX md5; /* the context holder */
27} md5object;
28
Barry Warsaw8b43b191996-12-09 22:32:36 +000029staticforward PyTypeObject MD5type;
Guido van Rossum5f59d601992-12-14 16:59:51 +000030
31#define is_md5object(v) ((v)->ob_type == &MD5type)
32
Guido van Rossum5f59d601992-12-14 16:59:51 +000033static md5object *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000034newmd5object(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +000035{
36 md5object *md5p;
37
Guido van Rossumb18618d2000-05-03 23:44:39 +000038 md5p = PyObject_New(md5object, &MD5type);
Guido van Rossum5f59d601992-12-14 16:59:51 +000039 if (md5p == NULL)
40 return NULL;
41
42 MD5Init(&md5p->md5); /* actual initialisation */
43 return md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +000044}
Guido van Rossum5f59d601992-12-14 16:59:51 +000045
46
47/* MD5 methods */
48
49static void
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +000050md5_dealloc(md5object *md5p)
Guido van Rossum5f59d601992-12-14 16:59:51 +000051{
Guido van Rossumb18618d2000-05-03 23:44:39 +000052 PyObject_Del(md5p);
Guido van Rossumb6775db1994-08-01 11:34:53 +000053}
Guido van Rossum5f59d601992-12-14 16:59:51 +000054
55
Guido van Rossumb6775db1994-08-01 11:34:53 +000056/* MD5 methods-as-attributes */
57
Barry Warsaw8b43b191996-12-09 22:32:36 +000058static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +000059md5_update(md5object *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +000060{
61 unsigned char *cp;
62 int len;
63
Barry Warsaw8b43b191996-12-09 22:32:36 +000064 if (!PyArg_Parse(args, "s#", &cp, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +000065 return NULL;
66
67 MD5Update(&self->md5, cp, len);
68
Barry Warsaw8b43b191996-12-09 22:32:36 +000069 Py_INCREF(Py_None);
70 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +000071}
72
Guido van Rossumd3a6a141998-10-14 13:46:57 +000073static char update_doc [] =
74"update (arg)\n\
75\n\
76Update the md5 object with the string arg. Repeated calls are\n\
77equivalent to a single call with the concatenation of all the\n\
78arguments.";
79
80
Barry Warsaw8b43b191996-12-09 22:32:36 +000081static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +000082md5_digest(md5object *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +000083{
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +000084 MD5_CTX mdContext;
Guido van Rossumb6775db1994-08-01 11:34:53 +000085 unsigned char aDigest[16];
86
Barry Warsaw8b43b191996-12-09 22:32:36 +000087 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +000088 return NULL;
89
90 /* make a temporary copy, and perform the final */
91 mdContext = self->md5;
92 MD5Final(aDigest, &mdContext);
93
Barry Warsaw8b43b191996-12-09 22:32:36 +000094 return PyString_FromStringAndSize((char *)aDigest, 16);
Guido van Rossumb6775db1994-08-01 11:34:53 +000095}
96
Guido van Rossumd3a6a141998-10-14 13:46:57 +000097static char digest_doc [] =
98"digest() -> string\n\
99\n\
100Return the digest of the strings passed to the update() method so\n\
101far. This is an 16-byte string which may contain non-ASCII characters,\n\
102including null bytes.";
103
104
Barry Warsaw8b43b191996-12-09 22:32:36 +0000105static PyObject *
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000106md5_hexdigest(md5object *self, PyObject *args)
107{
108 MD5_CTX mdContext;
109 unsigned char digest[16];
110 unsigned char hexdigest[32];
111 int i, j;
112
113 if (!PyArg_NoArgs(args))
114 return NULL;
115
116 /* make a temporary copy, and perform the final */
117 mdContext = self->md5;
118 MD5Final(digest, &mdContext);
119
120 /* Make hex version of the digest */
121 for(i=j=0; i<16; i++) {
122 char c;
123 c = (digest[i] >> 4) & 0xf;
124 c = (c>9) ? c+'a'-10 : c + '0';
125 hexdigest[j++] = c;
126 c = (digest[i] & 0xf);
127 c = (c>9) ? c+'a'-10 : c + '0';
128 hexdigest[j++] = c;
129 }
130 return PyString_FromStringAndSize((char*)hexdigest, 32);
131}
132
133
134static char hexdigest_doc [] =
135"hexdigest() -> string\n\
136\n\
137Like digest(), but returns the digest as a string of hexadecimal digits.";
138
139
140static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000141md5_copy(md5object *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000142{
143 md5object *md5p;
144
Barry Warsaw8b43b191996-12-09 22:32:36 +0000145 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000146 return NULL;
147
148 if ((md5p = newmd5object()) == NULL)
149 return NULL;
150
151 md5p->md5 = self->md5;
152
Barry Warsaw8b43b191996-12-09 22:32:36 +0000153 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000154}
155
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000156static char copy_doc [] =
157"copy() -> md5 object\n\
158\n\
159Return a copy (``clone'') of the md5 object.";
160
161
Barry Warsaw8b43b191996-12-09 22:32:36 +0000162static PyMethodDef md5_methods[] = {
Barry Warsaw3ec0fbb2000-08-15 05:59:44 +0000163 {"update", (PyCFunction)md5_update, METH_OLDARGS, update_doc},
164 {"digest", (PyCFunction)md5_digest, METH_OLDARGS, digest_doc},
165 {"hexdigest", (PyCFunction)md5_hexdigest, METH_OLDARGS, hexdigest_doc},
166 {"copy", (PyCFunction)md5_copy, METH_OLDARGS, copy_doc},
167 {NULL, NULL} /* sentinel */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000168};
169
Barry Warsaw8b43b191996-12-09 22:32:36 +0000170static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000171md5_getattr(md5object *self, char *name)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000172{
Barry Warsaw8b43b191996-12-09 22:32:36 +0000173 return Py_FindMethod(md5_methods, (PyObject *)self, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000174}
175
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000176static char module_doc [] =
177
178"This module implements the interface to RSA's MD5 message digest\n\
179algorithm (see also Internet RFC 1321). Its use is quite\n\
180straightforward: use the new() to create an md5 object. You can now\n\
181feed this object with arbitrary strings using the update() method, and\n\
182at any point you can ask it for the digest (a strong kind of 128-bit\n\
Thomas Wouters7e474022000-07-16 12:04:32 +0000183checksum, a.k.a. ``fingerprint'') of the concatenation of the strings\n\
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000184fed to it so far using the digest() method.\n\
185\n\
186Functions:\n\
187\n\
188new([arg]) -- return a new md5 object, initialized with arg if provided\n\
189md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
190\n\
191Special Objects:\n\
192\n\
193MD5Type -- type object for md5 objects\n\
194";
195
196static char md5type_doc [] =
197"An md5 represents the object used to calculate the MD5 checksum of a\n\
198string of information.\n\
199\n\
200Methods:\n\
201\n\
202update() -- updates the current digest with an additional string\n\
203digest() -- return the current digest value\n\
204copy() -- return a copy of the current md5 object\n\
205";
206
Barry Warsaw8b43b191996-12-09 22:32:36 +0000207statichere PyTypeObject MD5type = {
Fred Drake0d40ba42000-02-04 20:33:49 +0000208 PyObject_HEAD_INIT(NULL)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000209 0, /*ob_size*/
210 "md5", /*tp_name*/
211 sizeof(md5object), /*tp_size*/
212 0, /*tp_itemsize*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000213 /* methods */
Barry Warsaw8b43b191996-12-09 22:32:36 +0000214 (destructor)md5_dealloc, /*tp_dealloc*/
215 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216 (getattrfunc)md5_getattr, /*tp_getattr*/
Barry Warsaw8b43b191996-12-09 22:32:36 +0000217 0, /*tp_setattr*/
218 0, /*tp_compare*/
219 0, /*tp_repr*/
220 0, /*tp_as_number*/
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000221 0, /*tp_as_sequence*/
222 0, /*tp_as_mapping*/
223 0, /*tp_hash*/
224 0, /*tp_call*/
225 0, /*tp_str*/
226 0, /*tp_getattro*/
227 0, /*tp_setattro*/
228 0, /*tp_as_buffer*/
229 0, /*tp_xxx4*/
230 md5type_doc, /*tp_doc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231};
232
233
234/* MD5 functions */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000235
Barry Warsaw8b43b191996-12-09 22:32:36 +0000236static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000237MD5_new(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000238{
239 md5object *md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000240 unsigned char *cp = NULL;
Guido van Rossumef38b781995-07-26 17:33:10 +0000241 int len = 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000242
Guido van Rossum43713e52000-02-29 13:59:29 +0000243 if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
Guido van Rossumef38b781995-07-26 17:33:10 +0000244 return NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000245
246 if ((md5p = newmd5object()) == NULL)
247 return NULL;
248
249 if (cp)
250 MD5Update(&md5p->md5, cp, len);
251
Barry Warsaw8b43b191996-12-09 22:32:36 +0000252 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000253}
Guido van Rossum5f59d601992-12-14 16:59:51 +0000254
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000255static char new_doc [] =
256"new([arg]) -> md5 object\n\
257\n\
258Return a new md5 object. If arg is present, the method call update(arg)\n\
259is made.";
260
Guido van Rossum5f59d601992-12-14 16:59:51 +0000261
Guido van Rossum5f59d601992-12-14 16:59:51 +0000262/* List of functions exported by this module */
263
Barry Warsaw8b43b191996-12-09 22:32:36 +0000264static PyMethodDef md5_functions[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000265 {"new", (PyCFunction)MD5_new, METH_VARARGS, new_doc},
266 {"md5", (PyCFunction)MD5_new, METH_VARARGS, new_doc}, /* Backward compatibility */
Guido van Rossumef38b781995-07-26 17:33:10 +0000267 {NULL, NULL} /* Sentinel */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000268};
269
270
271/* Initialize this module. */
272
Guido van Rossum3886bb61998-12-04 18:50:17 +0000273DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000274initmd5(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000275{
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000276 PyObject *m, *d;
Fred Drake0d40ba42000-02-04 20:33:49 +0000277
278 MD5type.ob_type = &PyType_Type;
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000279 m = Py_InitModule3("md5", md5_functions, module_doc);
280 d = PyModule_GetDict(m);
281 PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
282 /* No need to check the error here, the caller will do that */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000283}