blob: 545df2bd71056cbe1b6358ba43992c741750f381 [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 *
34newmd5object()
35{
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[] = {
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000129 {"update", (PyCFunction)md5_update, 0, update_doc},
130 {"digest", (PyCFunction)md5_digest, 0, digest_doc},
131 {"copy", (PyCFunction)md5_copy, 0, copy_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000132 {NULL, NULL} /* sentinel */
133};
134
Barry Warsaw8b43b191996-12-09 22:32:36 +0000135static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000136md5_getattr(md5object *self, char *name)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000137{
Barry Warsaw8b43b191996-12-09 22:32:36 +0000138 return Py_FindMethod(md5_methods, (PyObject *)self, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000139}
140
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000141static char module_doc [] =
142
143"This module implements the interface to RSA's MD5 message digest\n\
144algorithm (see also Internet RFC 1321). Its use is quite\n\
145straightforward: use the new() to create an md5 object. You can now\n\
146feed this object with arbitrary strings using the update() method, and\n\
147at any point you can ask it for the digest (a strong kind of 128-bit\n\
148checksum, a.k.a. ``fingerprint'') of the contatenation of the strings\n\
149fed to it so far using the digest() method.\n\
150\n\
151Functions:\n\
152\n\
153new([arg]) -- return a new md5 object, initialized with arg if provided\n\
154md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
155\n\
156Special Objects:\n\
157\n\
158MD5Type -- type object for md5 objects\n\
159";
160
161static char md5type_doc [] =
162"An md5 represents the object used to calculate the MD5 checksum of a\n\
163string of information.\n\
164\n\
165Methods:\n\
166\n\
167update() -- updates the current digest with an additional string\n\
168digest() -- return the current digest value\n\
169copy() -- return a copy of the current md5 object\n\
170";
171
Barry Warsaw8b43b191996-12-09 22:32:36 +0000172statichere PyTypeObject MD5type = {
Fred Drake0d40ba42000-02-04 20:33:49 +0000173 PyObject_HEAD_INIT(NULL)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000174 0, /*ob_size*/
175 "md5", /*tp_name*/
176 sizeof(md5object), /*tp_size*/
177 0, /*tp_itemsize*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000178 /* methods */
Barry Warsaw8b43b191996-12-09 22:32:36 +0000179 (destructor)md5_dealloc, /*tp_dealloc*/
180 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000181 (getattrfunc)md5_getattr, /*tp_getattr*/
Barry Warsaw8b43b191996-12-09 22:32:36 +0000182 0, /*tp_setattr*/
183 0, /*tp_compare*/
184 0, /*tp_repr*/
185 0, /*tp_as_number*/
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000186 0, /*tp_as_sequence*/
187 0, /*tp_as_mapping*/
188 0, /*tp_hash*/
189 0, /*tp_call*/
190 0, /*tp_str*/
191 0, /*tp_getattro*/
192 0, /*tp_setattro*/
193 0, /*tp_as_buffer*/
194 0, /*tp_xxx4*/
195 md5type_doc, /*tp_doc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196};
197
198
199/* MD5 functions */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000200
Barry Warsaw8b43b191996-12-09 22:32:36 +0000201static PyObject *
Peter Schneider-Kamp286da3b2000-07-10 12:43:58 +0000202MD5_new(PyObject *self, PyObject *args)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000203{
204 md5object *md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205 unsigned char *cp = NULL;
Guido van Rossumef38b781995-07-26 17:33:10 +0000206 int len = 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000207
Guido van Rossum43713e52000-02-29 13:59:29 +0000208 if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
Guido van Rossumef38b781995-07-26 17:33:10 +0000209 return NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000210
211 if ((md5p = newmd5object()) == NULL)
212 return NULL;
213
214 if (cp)
215 MD5Update(&md5p->md5, cp, len);
216
Barry Warsaw8b43b191996-12-09 22:32:36 +0000217 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218}
Guido van Rossum5f59d601992-12-14 16:59:51 +0000219
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000220static char new_doc [] =
221"new([arg]) -> md5 object\n\
222\n\
223Return a new md5 object. If arg is present, the method call update(arg)\n\
224is made.";
225
Guido van Rossum5f59d601992-12-14 16:59:51 +0000226
Guido van Rossum5f59d601992-12-14 16:59:51 +0000227/* List of functions exported by this module */
228
Barry Warsaw8b43b191996-12-09 22:32:36 +0000229static PyMethodDef md5_functions[] = {
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000230 {"new", (PyCFunction)MD5_new, 1, new_doc},
231 {"md5", (PyCFunction)MD5_new, 1, new_doc}, /* Backward compatibility */
Guido van Rossumef38b781995-07-26 17:33:10 +0000232 {NULL, NULL} /* Sentinel */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000233};
234
235
236/* Initialize this module. */
237
Guido van Rossum3886bb61998-12-04 18:50:17 +0000238DL_EXPORT(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000239initmd5()
240{
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000241 PyObject *m, *d;
Fred Drake0d40ba42000-02-04 20:33:49 +0000242
243 MD5type.ob_type = &PyType_Type;
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000244 m = Py_InitModule3("md5", md5_functions, module_doc);
245 d = PyModule_GetDict(m);
246 PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
247 /* No need to check the error here, the caller will do that */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248}