blob: 53f987a36daa2002cd8ff61b93981dddacc71335 [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
50md5_dealloc(md5p)
51 md5object *md5p;
52{
Guido van Rossumb18618d2000-05-03 23:44:39 +000053 PyObject_Del(md5p);
Guido van Rossumb6775db1994-08-01 11:34:53 +000054}
Guido van Rossum5f59d601992-12-14 16:59:51 +000055
56
Guido van Rossumb6775db1994-08-01 11:34:53 +000057/* MD5 methods-as-attributes */
58
Barry Warsaw8b43b191996-12-09 22:32:36 +000059static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +000060md5_update(self, args)
61 md5object *self;
Barry Warsaw8b43b191996-12-09 22:32:36 +000062 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +000063{
64 unsigned char *cp;
65 int len;
66
Barry Warsaw8b43b191996-12-09 22:32:36 +000067 if (!PyArg_Parse(args, "s#", &cp, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +000068 return NULL;
69
70 MD5Update(&self->md5, cp, len);
71
Barry Warsaw8b43b191996-12-09 22:32:36 +000072 Py_INCREF(Py_None);
73 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +000074}
75
Guido van Rossumd3a6a141998-10-14 13:46:57 +000076static char update_doc [] =
77"update (arg)\n\
78\n\
79Update the md5 object with the string arg. Repeated calls are\n\
80equivalent to a single call with the concatenation of all the\n\
81arguments.";
82
83
Barry Warsaw8b43b191996-12-09 22:32:36 +000084static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +000085md5_digest(self, args)
86 md5object *self;
Barry Warsaw8b43b191996-12-09 22:32:36 +000087 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +000088{
89
90 MD5_CTX mdContext;
91 unsigned char aDigest[16];
92
Barry Warsaw8b43b191996-12-09 22:32:36 +000093 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +000094 return NULL;
95
96 /* make a temporary copy, and perform the final */
97 mdContext = self->md5;
98 MD5Final(aDigest, &mdContext);
99
Barry Warsaw8b43b191996-12-09 22:32:36 +0000100 return PyString_FromStringAndSize((char *)aDigest, 16);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000101}
102
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000103static char digest_doc [] =
104"digest() -> string\n\
105\n\
106Return the digest of the strings passed to the update() method so\n\
107far. This is an 16-byte string which may contain non-ASCII characters,\n\
108including null bytes.";
109
110
Barry Warsaw8b43b191996-12-09 22:32:36 +0000111static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000112md5_copy(self, args)
113 md5object *self;
Barry Warsaw8b43b191996-12-09 22:32:36 +0000114 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000115{
116 md5object *md5p;
117
Barry Warsaw8b43b191996-12-09 22:32:36 +0000118 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000119 return NULL;
120
121 if ((md5p = newmd5object()) == NULL)
122 return NULL;
123
124 md5p->md5 = self->md5;
125
Barry Warsaw8b43b191996-12-09 22:32:36 +0000126 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000127}
128
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000129static char copy_doc [] =
130"copy() -> md5 object\n\
131\n\
132Return a copy (``clone'') of the md5 object.";
133
134
Barry Warsaw8b43b191996-12-09 22:32:36 +0000135static PyMethodDef md5_methods[] = {
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000136 {"update", (PyCFunction)md5_update, 0, update_doc},
137 {"digest", (PyCFunction)md5_digest, 0, digest_doc},
138 {"copy", (PyCFunction)md5_copy, 0, copy_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000139 {NULL, NULL} /* sentinel */
140};
141
Barry Warsaw8b43b191996-12-09 22:32:36 +0000142static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000143md5_getattr(self, name)
144 md5object *self;
145 char *name;
146{
Barry Warsaw8b43b191996-12-09 22:32:36 +0000147 return Py_FindMethod(md5_methods, (PyObject *)self, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000148}
149
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000150static char module_doc [] =
151
152"This module implements the interface to RSA's MD5 message digest\n\
153algorithm (see also Internet RFC 1321). Its use is quite\n\
154straightforward: use the new() to create an md5 object. You can now\n\
155feed this object with arbitrary strings using the update() method, and\n\
156at any point you can ask it for the digest (a strong kind of 128-bit\n\
157checksum, a.k.a. ``fingerprint'') of the contatenation of the strings\n\
158fed to it so far using the digest() method.\n\
159\n\
160Functions:\n\
161\n\
162new([arg]) -- return a new md5 object, initialized with arg if provided\n\
163md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
164\n\
165Special Objects:\n\
166\n\
167MD5Type -- type object for md5 objects\n\
168";
169
170static char md5type_doc [] =
171"An md5 represents the object used to calculate the MD5 checksum of a\n\
172string of information.\n\
173\n\
174Methods:\n\
175\n\
176update() -- updates the current digest with an additional string\n\
177digest() -- return the current digest value\n\
178copy() -- return a copy of the current md5 object\n\
179";
180
Barry Warsaw8b43b191996-12-09 22:32:36 +0000181statichere PyTypeObject MD5type = {
Fred Drake0d40ba42000-02-04 20:33:49 +0000182 PyObject_HEAD_INIT(NULL)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000183 0, /*ob_size*/
184 "md5", /*tp_name*/
185 sizeof(md5object), /*tp_size*/
186 0, /*tp_itemsize*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187 /* methods */
Barry Warsaw8b43b191996-12-09 22:32:36 +0000188 (destructor)md5_dealloc, /*tp_dealloc*/
189 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190 (getattrfunc)md5_getattr, /*tp_getattr*/
Barry Warsaw8b43b191996-12-09 22:32:36 +0000191 0, /*tp_setattr*/
192 0, /*tp_compare*/
193 0, /*tp_repr*/
194 0, /*tp_as_number*/
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000195 0, /*tp_as_sequence*/
196 0, /*tp_as_mapping*/
197 0, /*tp_hash*/
198 0, /*tp_call*/
199 0, /*tp_str*/
200 0, /*tp_getattro*/
201 0, /*tp_setattro*/
202 0, /*tp_as_buffer*/
203 0, /*tp_xxx4*/
204 md5type_doc, /*tp_doc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205};
206
207
208/* MD5 functions */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000209
Barry Warsaw8b43b191996-12-09 22:32:36 +0000210static PyObject *
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000211MD5_new(self, args)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000212 PyObject *self;
213 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000214{
215 md5object *md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216 unsigned char *cp = NULL;
Guido van Rossumef38b781995-07-26 17:33:10 +0000217 int len = 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000218
Guido van Rossum43713e52000-02-29 13:59:29 +0000219 if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
Guido van Rossumef38b781995-07-26 17:33:10 +0000220 return NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000221
222 if ((md5p = newmd5object()) == NULL)
223 return NULL;
224
225 if (cp)
226 MD5Update(&md5p->md5, cp, len);
227
Barry Warsaw8b43b191996-12-09 22:32:36 +0000228 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229}
Guido van Rossum5f59d601992-12-14 16:59:51 +0000230
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000231static char new_doc [] =
232"new([arg]) -> md5 object\n\
233\n\
234Return a new md5 object. If arg is present, the method call update(arg)\n\
235is made.";
236
Guido van Rossum5f59d601992-12-14 16:59:51 +0000237
Guido van Rossum5f59d601992-12-14 16:59:51 +0000238/* List of functions exported by this module */
239
Barry Warsaw8b43b191996-12-09 22:32:36 +0000240static PyMethodDef md5_functions[] = {
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000241 {"new", (PyCFunction)MD5_new, 1, new_doc},
242 {"md5", (PyCFunction)MD5_new, 1, new_doc}, /* Backward compatibility */
Guido van Rossumef38b781995-07-26 17:33:10 +0000243 {NULL, NULL} /* Sentinel */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000244};
245
246
247/* Initialize this module. */
248
Guido van Rossum3886bb61998-12-04 18:50:17 +0000249DL_EXPORT(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000250initmd5()
251{
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000252 PyObject *m, *d;
Fred Drake0d40ba42000-02-04 20:33:49 +0000253
254 MD5type.ob_type = &PyType_Type;
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000255 m = Py_InitModule3("md5", md5_functions, module_doc);
256 d = PyModule_GetDict(m);
257 PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
258 /* No need to check the error here, the caller will do that */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259}