blob: 591ba2816d4ae7fdda494ae83e853da0dafc66cc [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{
84
85 MD5_CTX mdContext;
86 unsigned char aDigest[16];
87
Barry Warsaw8b43b191996-12-09 22:32:36 +000088 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +000089 return NULL;
90
91 /* make a temporary copy, and perform the final */
92 mdContext = self->md5;
93 MD5Final(aDigest, &mdContext);
94
Barry Warsaw8b43b191996-12-09 22:32:36 +000095 return PyString_FromStringAndSize((char *)aDigest, 16);
Guido van Rossumb6775db1994-08-01 11:34:53 +000096}
97
Guido van Rossumd3a6a141998-10-14 13:46:57 +000098static char digest_doc [] =
99"digest() -> string\n\
100\n\
101Return the digest of the strings passed to the update() method so\n\
102far. This is an 16-byte string which may contain non-ASCII characters,\n\
103including null bytes.";
104
105
Barry Warsaw8b43b191996-12-09 22:32:36 +0000106static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000107md5_copy(md5object *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000108{
109 md5object *md5p;
110
Barry Warsaw8b43b191996-12-09 22:32:36 +0000111 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000112 return NULL;
113
114 if ((md5p = newmd5object()) == NULL)
115 return NULL;
116
117 md5p->md5 = self->md5;
118
Barry Warsaw8b43b191996-12-09 22:32:36 +0000119 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000120}
121
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000122static char copy_doc [] =
123"copy() -> md5 object\n\
124\n\
125Return a copy (``clone'') of the md5 object.";
126
127
Barry Warsaw8b43b191996-12-09 22:32:36 +0000128static PyMethodDef md5_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000129 {"update", (PyCFunction)md5_update,
130 METH_OLDARGS, update_doc},
131 {"digest", (PyCFunction)md5_digest,
132 METH_OLDARGS, digest_doc},
133 {"copy", (PyCFunction)md5_copy,
134 METH_OLDARGS, copy_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000135 {NULL, NULL} /* sentinel */
136};
137
Barry Warsaw8b43b191996-12-09 22:32:36 +0000138static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000139md5_getattr(md5object *self, char *name)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000140{
Barry Warsaw8b43b191996-12-09 22:32:36 +0000141 return Py_FindMethod(md5_methods, (PyObject *)self, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000142}
143
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000144static char module_doc [] =
145
146"This module implements the interface to RSA's MD5 message digest\n\
147algorithm (see also Internet RFC 1321). Its use is quite\n\
148straightforward: use the new() to create an md5 object. You can now\n\
149feed this object with arbitrary strings using the update() method, and\n\
150at any point you can ask it for the digest (a strong kind of 128-bit\n\
Thomas Wouters7e474022000-07-16 12:04:32 +0000151checksum, a.k.a. ``fingerprint'') of the concatenation of the strings\n\
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000152fed to it so far using the digest() method.\n\
153\n\
154Functions:\n\
155\n\
156new([arg]) -- return a new md5 object, initialized with arg if provided\n\
157md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
158\n\
159Special Objects:\n\
160\n\
161MD5Type -- type object for md5 objects\n\
162";
163
164static char md5type_doc [] =
165"An md5 represents the object used to calculate the MD5 checksum of a\n\
166string of information.\n\
167\n\
168Methods:\n\
169\n\
170update() -- updates the current digest with an additional string\n\
171digest() -- return the current digest value\n\
172copy() -- return a copy of the current md5 object\n\
173";
174
Barry Warsaw8b43b191996-12-09 22:32:36 +0000175statichere PyTypeObject MD5type = {
Fred Drake0d40ba42000-02-04 20:33:49 +0000176 PyObject_HEAD_INIT(NULL)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000177 0, /*ob_size*/
178 "md5", /*tp_name*/
179 sizeof(md5object), /*tp_size*/
180 0, /*tp_itemsize*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181 /* methods */
Barry Warsaw8b43b191996-12-09 22:32:36 +0000182 (destructor)md5_dealloc, /*tp_dealloc*/
183 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000184 (getattrfunc)md5_getattr, /*tp_getattr*/
Barry Warsaw8b43b191996-12-09 22:32:36 +0000185 0, /*tp_setattr*/
186 0, /*tp_compare*/
187 0, /*tp_repr*/
188 0, /*tp_as_number*/
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000189 0, /*tp_as_sequence*/
190 0, /*tp_as_mapping*/
191 0, /*tp_hash*/
192 0, /*tp_call*/
193 0, /*tp_str*/
194 0, /*tp_getattro*/
195 0, /*tp_setattro*/
196 0, /*tp_as_buffer*/
197 0, /*tp_xxx4*/
198 md5type_doc, /*tp_doc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199};
200
201
202/* MD5 functions */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000203
Barry Warsaw8b43b191996-12-09 22:32:36 +0000204static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000205MD5_new(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000206{
207 md5object *md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208 unsigned char *cp = NULL;
Guido van Rossumef38b781995-07-26 17:33:10 +0000209 int len = 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000210
Guido van Rossum43713e52000-02-29 13:59:29 +0000211 if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
Guido van Rossumef38b781995-07-26 17:33:10 +0000212 return NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000213
214 if ((md5p = newmd5object()) == NULL)
215 return NULL;
216
217 if (cp)
218 MD5Update(&md5p->md5, cp, len);
219
Barry Warsaw8b43b191996-12-09 22:32:36 +0000220 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221}
Guido van Rossum5f59d601992-12-14 16:59:51 +0000222
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000223static char new_doc [] =
224"new([arg]) -> md5 object\n\
225\n\
226Return a new md5 object. If arg is present, the method call update(arg)\n\
227is made.";
228
Guido van Rossum5f59d601992-12-14 16:59:51 +0000229
Guido van Rossum5f59d601992-12-14 16:59:51 +0000230/* List of functions exported by this module */
231
Barry Warsaw8b43b191996-12-09 22:32:36 +0000232static PyMethodDef md5_functions[] = {
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000233 {"new", (PyCFunction)MD5_new, METH_VARARGS, new_doc},
234 {"md5", (PyCFunction)MD5_new, METH_VARARGS, new_doc}, /* Backward compatibility */
Guido van Rossumef38b781995-07-26 17:33:10 +0000235 {NULL, NULL} /* Sentinel */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000236};
237
238
239/* Initialize this module. */
240
Guido van Rossum3886bb61998-12-04 18:50:17 +0000241DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000242initmd5(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000243{
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000244 PyObject *m, *d;
Fred Drake0d40ba42000-02-04 20:33:49 +0000245
246 MD5type.ob_type = &PyType_Type;
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000247 m = Py_InitModule3("md5", md5_functions, module_doc);
248 d = PyModule_GetDict(m);
249 PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
250 /* No need to check the error here, the caller will do that */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251}