blob: 37094a365ad1e29b1743fa7a7a3eb82bb24a101c [file] [log] [blame]
Guido van Rossum5f59d601992-12-14 16:59:51 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum5f59d601992-12-14 16:59:51 +00004
5 All Rights Reserved
6
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007Copyright (c) 2000, BeOpen.com.
8Copyright (c) 1995-2000, Corporation for National Research Initiatives.
9Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
10All rights reserved.
Guido van Rossum5f59d601992-12-14 16:59:51 +000011
Guido van Rossumfd71b9e2000-06-30 23:50:40 +000012See the file "Misc/COPYRIGHT" for information on usage and
13redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum5f59d601992-12-14 16:59:51 +000014
15******************************************************************/
Guido van Rossumb6775db1994-08-01 11:34:53 +000016
Guido van Rossum5f59d601992-12-14 16:59:51 +000017/* MD5 module */
18
Guido van Rossumb6775db1994-08-01 11:34:53 +000019/* This module provides an interface to the RSA Data Security,
20 Inc. MD5 Message-Digest Algorithm, described in RFC 1321.
21 It requires the files md5c.c and md5.h (which are slightly changed
22 from the versions in the RFC to avoid the "global.h" file.) */
23
Guido van Rossum5f59d601992-12-14 16:59:51 +000024
25/* MD5 objects */
26
Barry Warsaw8b43b191996-12-09 22:32:36 +000027#include "Python.h"
Guido van Rossum5f59d601992-12-14 16:59:51 +000028#include "md5.h"
Guido van Rossumb6775db1994-08-01 11:34:53 +000029
Guido van Rossum5f59d601992-12-14 16:59:51 +000030typedef struct {
Barry Warsaw8b43b191996-12-09 22:32:36 +000031 PyObject_HEAD
Guido van Rossum5f59d601992-12-14 16:59:51 +000032 MD5_CTX md5; /* the context holder */
33} md5object;
34
Barry Warsaw8b43b191996-12-09 22:32:36 +000035staticforward PyTypeObject MD5type;
Guido van Rossum5f59d601992-12-14 16:59:51 +000036
37#define is_md5object(v) ((v)->ob_type == &MD5type)
38
Guido van Rossum5f59d601992-12-14 16:59:51 +000039static md5object *
40newmd5object()
41{
42 md5object *md5p;
43
Guido van Rossumb18618d2000-05-03 23:44:39 +000044 md5p = PyObject_New(md5object, &MD5type);
Guido van Rossum5f59d601992-12-14 16:59:51 +000045 if (md5p == NULL)
46 return NULL;
47
48 MD5Init(&md5p->md5); /* actual initialisation */
49 return md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +000050}
Guido van Rossum5f59d601992-12-14 16:59:51 +000051
52
53/* MD5 methods */
54
55static void
56md5_dealloc(md5p)
57 md5object *md5p;
58{
Guido van Rossumb18618d2000-05-03 23:44:39 +000059 PyObject_Del(md5p);
Guido van Rossumb6775db1994-08-01 11:34:53 +000060}
Guido van Rossum5f59d601992-12-14 16:59:51 +000061
62
Guido van Rossumb6775db1994-08-01 11:34:53 +000063/* MD5 methods-as-attributes */
64
Barry Warsaw8b43b191996-12-09 22:32:36 +000065static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +000066md5_update(self, args)
67 md5object *self;
Barry Warsaw8b43b191996-12-09 22:32:36 +000068 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +000069{
70 unsigned char *cp;
71 int len;
72
Barry Warsaw8b43b191996-12-09 22:32:36 +000073 if (!PyArg_Parse(args, "s#", &cp, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +000074 return NULL;
75
76 MD5Update(&self->md5, cp, len);
77
Barry Warsaw8b43b191996-12-09 22:32:36 +000078 Py_INCREF(Py_None);
79 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +000080}
81
Guido van Rossumd3a6a141998-10-14 13:46:57 +000082static char update_doc [] =
83"update (arg)\n\
84\n\
85Update the md5 object with the string arg. Repeated calls are\n\
86equivalent to a single call with the concatenation of all the\n\
87arguments.";
88
89
Barry Warsaw8b43b191996-12-09 22:32:36 +000090static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +000091md5_digest(self, args)
92 md5object *self;
Barry Warsaw8b43b191996-12-09 22:32:36 +000093 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +000094{
95
96 MD5_CTX mdContext;
97 unsigned char aDigest[16];
98
Barry Warsaw8b43b191996-12-09 22:32:36 +000099 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000100 return NULL;
101
102 /* make a temporary copy, and perform the final */
103 mdContext = self->md5;
104 MD5Final(aDigest, &mdContext);
105
Barry Warsaw8b43b191996-12-09 22:32:36 +0000106 return PyString_FromStringAndSize((char *)aDigest, 16);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000107}
108
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000109static char digest_doc [] =
110"digest() -> string\n\
111\n\
112Return the digest of the strings passed to the update() method so\n\
113far. This is an 16-byte string which may contain non-ASCII characters,\n\
114including null bytes.";
115
116
Barry Warsaw8b43b191996-12-09 22:32:36 +0000117static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000118md5_copy(self, args)
119 md5object *self;
Barry Warsaw8b43b191996-12-09 22:32:36 +0000120 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000121{
122 md5object *md5p;
123
Barry Warsaw8b43b191996-12-09 22:32:36 +0000124 if (!PyArg_NoArgs(args))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000125 return NULL;
126
127 if ((md5p = newmd5object()) == NULL)
128 return NULL;
129
130 md5p->md5 = self->md5;
131
Barry Warsaw8b43b191996-12-09 22:32:36 +0000132 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000133}
134
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000135static char copy_doc [] =
136"copy() -> md5 object\n\
137\n\
138Return a copy (``clone'') of the md5 object.";
139
140
Barry Warsaw8b43b191996-12-09 22:32:36 +0000141static PyMethodDef md5_methods[] = {
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000142 {"update", (PyCFunction)md5_update, 0, update_doc},
143 {"digest", (PyCFunction)md5_digest, 0, digest_doc},
144 {"copy", (PyCFunction)md5_copy, 0, copy_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000145 {NULL, NULL} /* sentinel */
146};
147
Barry Warsaw8b43b191996-12-09 22:32:36 +0000148static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000149md5_getattr(self, name)
150 md5object *self;
151 char *name;
152{
Barry Warsaw8b43b191996-12-09 22:32:36 +0000153 return Py_FindMethod(md5_methods, (PyObject *)self, name);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000154}
155
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000156static char module_doc [] =
157
158"This module implements the interface to RSA's MD5 message digest\n\
159algorithm (see also Internet RFC 1321). Its use is quite\n\
160straightforward: use the new() to create an md5 object. You can now\n\
161feed this object with arbitrary strings using the update() method, and\n\
162at any point you can ask it for the digest (a strong kind of 128-bit\n\
163checksum, a.k.a. ``fingerprint'') of the contatenation of the strings\n\
164fed to it so far using the digest() method.\n\
165\n\
166Functions:\n\
167\n\
168new([arg]) -- return a new md5 object, initialized with arg if provided\n\
169md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
170\n\
171Special Objects:\n\
172\n\
173MD5Type -- type object for md5 objects\n\
174";
175
176static char md5type_doc [] =
177"An md5 represents the object used to calculate the MD5 checksum of a\n\
178string of information.\n\
179\n\
180Methods:\n\
181\n\
182update() -- updates the current digest with an additional string\n\
183digest() -- return the current digest value\n\
184copy() -- return a copy of the current md5 object\n\
185";
186
Barry Warsaw8b43b191996-12-09 22:32:36 +0000187statichere PyTypeObject MD5type = {
Fred Drake0d40ba42000-02-04 20:33:49 +0000188 PyObject_HEAD_INIT(NULL)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000189 0, /*ob_size*/
190 "md5", /*tp_name*/
191 sizeof(md5object), /*tp_size*/
192 0, /*tp_itemsize*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000193 /* methods */
Barry Warsaw8b43b191996-12-09 22:32:36 +0000194 (destructor)md5_dealloc, /*tp_dealloc*/
195 0, /*tp_print*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196 (getattrfunc)md5_getattr, /*tp_getattr*/
Barry Warsaw8b43b191996-12-09 22:32:36 +0000197 0, /*tp_setattr*/
198 0, /*tp_compare*/
199 0, /*tp_repr*/
200 0, /*tp_as_number*/
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000201 0, /*tp_as_sequence*/
202 0, /*tp_as_mapping*/
203 0, /*tp_hash*/
204 0, /*tp_call*/
205 0, /*tp_str*/
206 0, /*tp_getattro*/
207 0, /*tp_setattro*/
208 0, /*tp_as_buffer*/
209 0, /*tp_xxx4*/
210 md5type_doc, /*tp_doc*/
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211};
212
213
214/* MD5 functions */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000215
Barry Warsaw8b43b191996-12-09 22:32:36 +0000216static PyObject *
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000217MD5_new(self, args)
Barry Warsaw8b43b191996-12-09 22:32:36 +0000218 PyObject *self;
219 PyObject *args;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000220{
221 md5object *md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222 unsigned char *cp = NULL;
Guido van Rossumef38b781995-07-26 17:33:10 +0000223 int len = 0;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000224
Guido van Rossum43713e52000-02-29 13:59:29 +0000225 if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
Guido van Rossumef38b781995-07-26 17:33:10 +0000226 return NULL;
Guido van Rossum5f59d601992-12-14 16:59:51 +0000227
228 if ((md5p = newmd5object()) == NULL)
229 return NULL;
230
231 if (cp)
232 MD5Update(&md5p->md5, cp, len);
233
Barry Warsaw8b43b191996-12-09 22:32:36 +0000234 return (PyObject *)md5p;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235}
Guido van Rossum5f59d601992-12-14 16:59:51 +0000236
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000237static char new_doc [] =
238"new([arg]) -> md5 object\n\
239\n\
240Return a new md5 object. If arg is present, the method call update(arg)\n\
241is made.";
242
Guido van Rossum5f59d601992-12-14 16:59:51 +0000243
Guido van Rossum5f59d601992-12-14 16:59:51 +0000244/* List of functions exported by this module */
245
Barry Warsaw8b43b191996-12-09 22:32:36 +0000246static PyMethodDef md5_functions[] = {
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000247 {"new", (PyCFunction)MD5_new, 1, new_doc},
248 {"md5", (PyCFunction)MD5_new, 1, new_doc}, /* Backward compatibility */
Guido van Rossumef38b781995-07-26 17:33:10 +0000249 {NULL, NULL} /* Sentinel */
Guido van Rossum5f59d601992-12-14 16:59:51 +0000250};
251
252
253/* Initialize this module. */
254
Guido van Rossum3886bb61998-12-04 18:50:17 +0000255DL_EXPORT(void)
Guido van Rossum5f59d601992-12-14 16:59:51 +0000256initmd5()
257{
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000258 PyObject *m, *d;
Fred Drake0d40ba42000-02-04 20:33:49 +0000259
260 MD5type.ob_type = &PyType_Type;
Guido van Rossumd3a6a141998-10-14 13:46:57 +0000261 m = Py_InitModule3("md5", md5_functions, module_doc);
262 d = PyModule_GetDict(m);
263 PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
264 /* No need to check the error here, the caller will do that */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265}