Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising.
You can look at this code here:
http://www.tux.org/pub/security/md5/md5.c http://www.tux.org/pub/security/md5/md5.h
We've identified packages which are possibly using this implementation, and all maintainers are on CC. Please take a moment to look at your packages and check to see if this md5 implementation is used.
GeoIP abiword cinepaint cook dietlibc dclib fedora-ds-base gammu gnome-pilot-conduits gnumeric htdig inn isdn4k-utils libosip libosip2 mail-notification mysql ser ssmtp wv xdelta
If your package is on this list, please email me back and let me know once you've checked the md5 implementation. If it is the RSA implementation, we're going to need to replace it (coreutils has a GPL compatible implementation that should be a drop in). If your package is not under GPL or LGPL, then there is no problem, and you can just email me and let me know that.
Thanks in advance,
~spot
"Tom "spot" Callaway" tcallawa@redhat.com writes:
Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising.
Hmm. mysql does appear to be using this implementation, but since they are specifically distributing under GPL v2 *only*, I'm not sure it's a problem. Or are you saying BSD+ad is incompatible with v2 as well?
If it is the RSA implementation, we're going to need to replace it (coreutils has a GPL compatible implementation that should be a drop in).
Not sure I see the point of the sort of patch you seem to envision. If we are shipping SRPMs containing upstream tarballs that contain BSD+ad code, haven't we got an issue anyway?
regards, tom lane
On Mon, 2007-09-17 at 18:02 -0400, Tom Lane wrote:
"Tom "spot" Callaway" tcallawa@redhat.com writes:
Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising.
Hmm. mysql does appear to be using this implementation, but since they are specifically distributing under GPL v2 *only*, I'm not sure it's a problem. Or are you saying BSD+ad is incompatible with v2 as well?
Yes. BSD+ad is incompatible with GPLv2 and GPLv3.
If it is the RSA implementation, we're going to need to replace it (coreutils has a GPL compatible implementation that should be a drop in).
Not sure I see the point of the sort of patch you seem to envision. If we are shipping SRPMs containing upstream tarballs that contain BSD+ad code, haven't we got an issue anyway?
BSD + advertising is Free, but GPL incompatible. It only becomes a problem when BSD+ad code is directly compiled into GPL/LGPL licensed code. So, its fine to have a standalone BSD+ad package, but it is definitely not fine for a GPL licensed software package to have BSD +advertising code inside it.
~spot
"Tom "spot" Callaway" tcallawa@redhat.com writes:
On Mon, 2007-09-17 at 18:02 -0400, Tom Lane wrote:
Not sure I see the point of the sort of patch you seem to envision. If we are shipping SRPMs containing upstream tarballs that contain BSD+ad code, haven't we got an issue anyway?
BSD + advertising is Free, but GPL incompatible. It only becomes a problem when BSD+ad code is directly compiled into GPL/LGPL licensed code. So, its fine to have a standalone BSD+ad package, but it is definitely not fine for a GPL licensed software package to have BSD +advertising code inside it.
I concur that they're not compatible. What I don't follow is why this argument doesn't prevent us from shipping the upstream tarball at all. A patch might make the binary "clean" in some ill-defined sense, but it doesn't fix the sources. And ultimately the point of the GPL is to have access to the source code and be able to do what you want with it.
ISTM the only answer is to pressure upstream to fix their issue.
regards, tom lane
On Tue, 2007-09-18 at 10:24 -0400, Tom Lane wrote:
"Tom "spot" Callaway" tcallawa@redhat.com writes:
On Mon, 2007-09-17 at 18:02 -0400, Tom Lane wrote:
Not sure I see the point of the sort of patch you seem to envision. If we are shipping SRPMs containing upstream tarballs that contain BSD+ad code, haven't we got an issue anyway?
BSD + advertising is Free, but GPL incompatible. It only becomes a problem when BSD+ad code is directly compiled into GPL/LGPL licensed code. So, its fine to have a standalone BSD+ad package, but it is definitely not fine for a GPL licensed software package to have BSD +advertising code inside it.
I concur that they're not compatible. What I don't follow is why this argument doesn't prevent us from shipping the upstream tarball at all. A patch might make the binary "clean" in some ill-defined sense, but it doesn't fix the sources. And ultimately the point of the GPL is to have access to the source code and be able to do what you want with it.
ISTM the only answer is to pressure upstream to fix their issue.
You're welcome to interpret it that way. Upstream has a problem. We (Fedora) have inherited that problem. If upstream chooses not (for whatever reason) to fix it in their sources, Fedora would need to fix it in our sources, or not ship the package at all.
Red Hat Legal has consistently advised us that we are meeting the burden of resolving the problem by patching out the code with problematic licensing. By writing the patch and submitting it upstream (which is what Fedora packagers should be doing with _ALL_ of their patches), we're doing more than simply passing the buck on the problem. :)
~spot
On 17.09.2007 22:30, Tom "spot" Callaway wrote:
Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising.
Uhhpps.
The requested URL /pub/security/md5/md5.c was not found on this server.
http://www.tux.org/pub/security/md5/md5.h
We've identified packages which are possibly using this implementation, and all maintainers are on CC. Please take a moment to look at your packages and check to see if this md5 implementation is used. [...] mail-notification [...]
If your package is on this list, please email me back and let me know once you've checked the md5 implementation. If it is the RSA implementation, we're going to need to replace it (coreutils has a GPL compatible implementation that should be a drop in).
My package mail-notification is GPL and uses it. :-/
But why are "*we* going to need to replace it"? Is the issue that urgent so there is not even 24 or 72 hours to talk to upstream to make them aware of the issue first? Then maybe upstream can fix it quickly once and for all and for all distributions? Or are we not allowed to talk about this in public bug trackers?
CU knurd
On Tue, 2007-09-18 at 09:02 +0200, Thorsten Leemhuis wrote:
The requested URL /pub/security/md5/md5.c was not found on this server.
The correct URL is
http://www.tux.org/pub/security/md5/md5c.c
Matthew Barnes
On Tue, 2007-09-18 at 09:02 +0200, Thorsten Leemhuis wrote:
My package mail-notification is GPL and uses it. :-/
But why are "*we* going to need to replace it"? Is the issue that urgent so there is not even 24 or 72 hours to talk to upstream to make them aware of the issue first? Then maybe upstream can fix it quickly once and for all and for all distributions? Or are we not allowed to talk about this in public bug trackers?
No, the issue is not that urgent. We (Fedora) need to take action to remedy this. This could be in the form of writing a patch and submitting it upstream for review, or simply pointing to upstream and having them resolve it, then taking in the same changes in Fedora.
Ultimately, upstream is responsible for this problem, but by helping make them aware of it (and possibly fixing it for them), we're being good community participants.
I would love to have all of these cases resolved by F8, but realistically, I'm not going to require it until F9.
~spot
"Tom "spot" Callaway" tcallawa@redhat.com writes:
Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising. ... If your package is on this list, please email me back and let me know once you've checked the md5 implementation. If it is the RSA implementation,
dietlibc is affected.
BUT... the md5 source code is part of RFC 1321. AFAIK, RFCs are under some public domain license which should allow use of this code under any license. E.g. top of this RFC says
| Distribution of this memo is unlimited.
Enrico
Enrico Scholz enrico.scholz@informatik.tu-chemnitz.de writes:
Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising. ...
http://www.ietf.org/ietf/IPR/RSA-MD-all states
| Implementations of these message-digest algorithms, including | implementations derived from the reference C code in RFC-1319, RFC-1320, | and RFC-1321, may be made, used, and sold without license from RSA for | any purpose.
This seems to allow relicensing with any license (inclusive GPL), doesn't it?
Enrico
On Tue, 2007-09-18 at 12:25 +0200, Enrico Scholz wrote:
Enrico Scholz enrico.scholz@informatik.tu-chemnitz.de writes:
Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising. ...
http://www.ietf.org/ietf/IPR/RSA-MD-all states
| Implementations of these message-digest algorithms, including | implementations derived from the reference C code in RFC-1319, RFC-1320, | and RFC-1321, may be made, used, and sold without license from RSA for | any purpose.
This seems to allow relicensing with any license (inclusive GPL), doesn't it?
Yes, but the way it is worded is specific. You may make MD5 implementations based on the RFC code, used them, and even sell them without license from RSA.
HOWEVER: RSA did make an MD5 implementation, which is under their license (a BSD with advertising style license). If your code is using that implementation, we need to replace it with an MD5 implementation that is under a GPL compatible license.
You could write the implementation yourself, or you can use an existing, GPL compatible implementation (coreutils has a well tested one), but you cannot use the RSA implementation (in GPL/LGPL licensed code).
Mutt recently did this conversion:
http://dev.mutt.org/hg/mutt/rev/4ade2517703a
It should be applicable to most (if not all) uses of the RSA implementation.
~spot
"Tom "spot" Callaway" tcallawa@redhat.com writes:
http://www.ietf.org/ietf/IPR/RSA-MD-all states
| ... | implementations derived from the reference C code in RFC-1319, RFC-1320, | and RFC-1321, may be made, used, and sold without license from RSA for | any purpose.
This seems to allow relicensing with any license (inclusive GPL), doesn't it?
Yes, but the way it is worded is specific. You may make MD5 implementations based on the RFC code, used them, and even sell them without license from RSA.
HOWEVER: RSA did make an MD5 implementation,
This implementation is equal to the reference C code in RFC-1321 (which seems to be GPL compatible accordingly the statement above).
which is under their license (a BSD with advertising style license). If your code is using that implementation,
So the question is, whether code was created by a copy & paste operation or by downloading a C file? Dunno, how I can check which method was used...
Enrico
On Tue, 2007-09-18 at 16:11 +0200, Enrico Scholz wrote:
So the question is, whether code was created by a copy & paste operation or by downloading a C file? Dunno, how I can check which method was used...
Fundamentally, you can't tell. And since the act is the same as "removing the license", which is explicitly forbidden by the license, we can't do it.
~spot
On Tue, 2007-09-18 at 09:36 -0400, Tom "spot" Callaway wrote:
HOWEVER: RSA did make an MD5 implementation, which is under their license (a BSD with advertising style license). If your code is using that implementation, we need to replace it with an MD5 implementation that is under a GPL compatible license.
To clarify:
Originally, the RSA MD5 implementation was released as public domain code. At some point, RSA slapped BSD with advertising on that code.
If the RSA md5 implementation has this license text in it:
"License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function."
Then, it is under the BSD with advertising style license, and we need to replace that code (since we cannot legally relicense it).
If for some reason, the RSA MD5 implementation does not have that license text, it can be interpreted as being in the public domain from the original release, and you do not need to replace it.
This is tricky, because reverting to the public domain code would be the same as simply removing the license, and we cannot do that.
~spot
"Tom "spot" Callaway" tcallawa@redhat.com writes:
On Tue, 2007-09-18 at 09:36 -0400, Tom "spot" Callaway wrote:
HOWEVER: RSA did make an MD5 implementation, which is under their license (a BSD with advertising style license). If your code is using that implementation, we need to replace it with an MD5 implementation that is under a GPL compatible license.
To clarify:
Originally, the RSA MD5 implementation was released as public domain code. At some point, RSA slapped BSD with advertising on that code.
Sure? I think it was:
* 1992, RSA added reference C code with BSD + advertising clause to RFC 1321
* 2000, RSA changed license to allow usage of "the reference C code ... without license from RSA for any purpose"
So, since 2000 the reference C code is dual-licensed (BSD w/ adv and public domain).
If the RSA md5 implementation has this license text in it:
"License to copy and use this software is granted provided that it ...
Then, it is under the BSD with advertising style license, and we need to replace that code (since we cannot legally relicense it).
It should be enough to remove this license text (which is allowed since 2000) to make it GPL compatible. Or, to make it legally perfect, remove the old code, take recent version of RFC 1321, copy reference code from it and remove the license text.
Enrico
On Tue, 2007-09-18 at 18:16 +0200, Enrico Scholz wrote:
It should be enough to remove this license text (which is allowed since 2000) to make it GPL compatible. Or, to make it legally perfect, remove the old code, take recent version of RFC 1321, copy reference code from it and remove the license text.
Only RSA can remove the license text, we can't do it, nor can the upstream using the RSA code (unless that upstream is RSA).
The license text in the code itself trumps all. It trumps readmes and "global email proclamations". Now, if RSA released a new file upstream that was under a GPL compatible license, different story, but they have not.
~spot
"Tom "spot" Callaway" tcallawa@redhat.com writes:
It should be enough to remove this license text (which is allowed since 2000) to make it GPL compatible. Or, to make it legally perfect, remove the old code, take recent version of RFC 1321, copy reference code from it and remove the license text.
Only RSA can remove the license text,
no; everybody can remove it because you can do everything what you want to do with the code since 2000.
The license text in the code itself trumps all.
Why? The text was written 1992 which was before the dual licensing to public domain in 2000.
It trumps readmes and "global email proclamations". Now, if RSA released a new file upstream that was under a GPL compatible license, different story, but they have not.
Relicensing can heppen in different ways. A new version with changed text can be released, or it can be given an explicit permission to use it with another license. Latter happened with the md5 source code in 2000.
Enrico
On 18.09.2007 19:44, Enrico Scholz wrote:
"Tom "spot" Callaway" tcallawa@redhat.com writes:
It should be enough to remove this license text (which is allowed since 2000) to make it GPL compatible. Or, to make it legally perfect, remove the old code, take recent version of RFC 1321, copy reference code from it and remove the license text.
Only RSA can remove the license text,
no; everybody can remove it because you can do everything what you want to do with the code since 2000.
The license text in the code itself trumps all.
Why? The text was written 1992 which was before the dual licensing to public domain in 2000. [...]
I like to let you two fight this out. But is there a real reasons to continue this in private? I'd say it's time to move it to fedora-devel, where everyone can participate. Maybe someone comes up with a explanation we all don't know about yet? Did the debian guys never discuss this earlier?
On 18.09.2007 15:31, Tom "spot" Callaway wrote:
On Tue, 2007-09-18 at 09:02 +0200, Thorsten Leemhuis wrote:
My package mail-notification is GPL and uses it. :-/ But why are "*we* going to need to replace it"? Is the issue that urgent so there is not even 24 or 72 hours to talk to upstream to make them aware of the issue first? Then maybe upstream can fix it quickly once and for all and for all distributions? Or are we not allowed to talk about this in public bug trackers?
No, the issue is not that urgent.
Thx for clarifying. It sounded a bit to me like this had to happen fast and silent.
We (Fedora) need to take action to remedy this.
Sure and np.
This could be in the form of writing a patch and submitting it upstream for review, or simply pointing to upstream and having them resolve it, then taking in the same changes in Fedora.
Sure -- but my upstream in this case is a bit problematic in general already, thus I'd like to safe your and my time and discuss it first with upstream to agree on a proper solution before working one out and throwing it away.
[...]
Cu knurd
On Tue, 2007-09-18 at 19:58 +0200, Thorsten Leemhuis wrote:
Sure -- but my upstream in this case is a bit problematic in general already, thus I'd like to safe your and my time and discuss it first with upstream to agree on a proper solution before working one out and throwing it away.
I am not going to tell you how to handle your packages (outside of the Packaging Guidelines, of course). ;)
~spot
On Tue, 2007-09-18 at 19:44 +0200, Enrico Scholz wrote:
"Tom "spot" Callaway" tcallawa@redhat.com writes:
It should be enough to remove this license text (which is allowed since 2000) to make it GPL compatible. Or, to make it legally perfect, remove the old code, take recent version of RFC 1321, copy reference code from it and remove the license text.
Only RSA can remove the license text,
no; everybody can remove it because you can do everything what you want to do with the code since 2000.
No, unfortunately, an email saying "you can do whatever you want with it" isn't legally binding. The lawyers have repeatedly advised us that licensing in the code trumps EVERYTHING. You're welcome to disagree, but this is the stance of Fedora.
RSA never bothered to update their source code, and since it is still online with the BSD+ad license, that's the license. Even more relevant, thats how it is in (most of) the included code in the Fedora packages.
~spot
On 09/18/2007 Enrico Scholz wrote:
- 2000, RSA changed license to allow usage of "the reference C code
... without license from RSA for any purpose"
A blast from the past on this one:
I've been giving some thought to this RSA license issue, and rereading all of the relevant documentation.
A couple of points:
The original RFC1321 reference code is here: http://www.faqs.org/rfcs/rfc1321.html
That code is under BSD with advertising (which is GPL incompatible). The contents of the RFC are explicitly stated to be freely redistributable (not public domain).
In 2000, RSA clarified some of the legal issues: http://www.ietf.org/ietf/IPR/RSA-MD-all
What they said was that:
Implementations of these message-digest algorithms, including implementations derived from the reference C code in RFC-1319, RFC-1320, and RFC-1321, may be made, used, and sold without license from RSA for any purpose.
This means that the RFC1321 reference implementation can be used without the license, and it effectively becomes Copyright only.
Accordingly, I'm going to have Fedora deal with this issue by implenting a policy that whenever we come across C code that implements RFC-1319, RFC-1320, and RFC-1321 (MD2, MD4, MD5) under the troublesome BSD with advertising clause, we will be using it without license from RSA.
In English, it means that we don't need to worry about resolving these conflicts, but we should advise upstream of the situation, and recommend that they "use" this code without RSA's license as well, and reflect that usage in the source code by removing RSA's license (but not RSA's copyright).
~spot
Enrico Scholz enrico.scholz@informatik.tu-chemnitz.de writes:
Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising. ... If your package is on this list, please email me back and let me know once you've checked the md5 implementation. If it is the RSA implementation,
dietlibc is affected.
I have to revert this. I do not have a reason to assume, that not the public domain version from RFC 1321 was used for this implementation.
Enrico
On Mon, Sep 17, 2007 at 04:30:10PM -0400, Tom spot Callaway wrote:
Some of Fedora's packages are using an MD5 implementation which is under a GPLv2/v3 incompatible license, specifically, the RSA implementation which is under BSD with advertising.
[...]
dclib
Patched.
luke
----- Forwarded message from Luke Macken lmacken@fedoraproject.org -----
From: Luke Macken lmacken@fedoraproject.org To: cvsextras@fedora.redhat.com, lmacken@redhat.com Subject: rpms/dclib/devel 01-dclib-0.3.10-remove-cmd4.patch, NONE, 1.1 02-dclib-0.3.10-use-gnulib-md5.patch, NONE, 1.1 03-dclib-0.3.10-use-new-md5-api.patch, NONE, 1.1 04-dclib-0.3.10-gnulib-md5-configure-test.patch, NONE, 1.1 dclib.spec, 1.12, 1.13 dclib-0.3.8-cconfig-use-cfile.patch, 1.1, NONE Date: Tue, 18 Sep 2007 15:31:52 -0400
Author: lmacken
Update of /cvs/pkgs/rpms/dclib/devel In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv25221
Modified Files: dclib.spec Added Files: 01-dclib-0.3.10-remove-cmd4.patch 02-dclib-0.3.10-use-gnulib-md5.patch 03-dclib-0.3.10-use-new-md5-api.patch 04-dclib-0.3.10-gnulib-md5-configure-test.patch Removed Files: dclib-0.3.8-cconfig-use-cfile.patch Log Message: * Tue Sep 18 2007 Luke Macken lmacken@redhat.com 0.3.10-2 - Remove RSA MD5 implementation in favor of the gnulib implementation. Patches taken from upstream ticket: https://sourceforge.net/tracker/?func=detail&atid=897767&aid=1796674... =181579
01-dclib-0.3.10-remove-cmd4.patch:
--- NEW FILE 01-dclib-0.3.10-remove-cmd4.patch --- diff -Naur dclib-0.3.10.orig/dclib/core/cmd4.cpp dclib-0.3.10/dclib/core/cmd4.cpp --- dclib-0.3.10.orig/dclib/core/cmd4.cpp 2007-09-18 10:24:40.000000000 +0100 +++ dclib-0.3.10/dclib/core/cmd4.cpp 1970-01-01 01:00:00.000000000 +0100 @@ -1,286 +0,0 @@ -/* - ********************************************************************** - ** md4.c ** - ** RSA Data Security, Inc. MD4 Message Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** - ********************************************************************** - */ - -/* - ********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD4 Message ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD4 Message Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - ********************************************************************** - */ - -#include <string.h> -#include "cmd4.h" - -static unsigned char PADDING[64] = { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* F, G and H are basic MD4 functions: selection, majority, parity */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) - -/* ROTATE_LEFT rotates x left n bits */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG and HH are MD4 transformations for rounds 1, 2 and 3 */ -/* Rotation is separate from addition to prevent recomputation */ -#define FF(a, b, c, d, x, s) {(a) += F ((b), (c), (d)) + (x); (a) = ROTATE_LEFT ((a), (s));} -#define GG(a, b, c, d, x, s) {(a) += G ((b), (c), (d)) + (x) + (UINT4)013240474631; (a) = ROTATE_LEFT ((a), (s));} -#define HH(a, b, c, d, x, s) {(a) += H ((b), (c), (d)) + (x) + (UINT4)015666365641; (a) = ROTATE_LEFT ((a), (s));} - -MD4::MD4() -{ - init(); -} - -void MD4::init() -{ - mdContext.i[0] = mdContext.i[1] = (UINT4)0; - - /* Load magic initialization constants. - */ - mdContext.buf[0] = (UINT4)0x67452301; - mdContext.buf[1] = (UINT4)0xefcdab89; - mdContext.buf[2] = (UINT4)0x98badcfe; - mdContext.buf[3] = (UINT4)0x10325476; -} - -void MD4::update(FILE *file){ - - unsigned char buffer[1024*1024]; - int len; - - while ( (len=fread(buffer, 1, 1024*1024, file)) > 0) - update(buffer, len); - - fclose (file); - -} - -void MD4::update(unsigned char *inBuf,unsigned int inLen) -{ - UINT4 in[16]; - int mdi; - unsigned int i, ii; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext.i[0] >> 3) & 0x3F); - - /* update number of bits */ - if ((mdContext.i[0] + ((UINT4)inLen << 3)) < mdContext.i[0]) - mdContext.i[1]++; - mdContext.i[0] += ((UINT4)inLen << 3); - mdContext.i[1] += ((UINT4)inLen >> 29); - - while (inLen--) { - /* add new character to buffer, increment mdi */ - mdContext.in[mdi++] = *inBuf++; - - /* transform if necessary */ - if (mdi == 0x40) { - for (i = 0, ii = 0; i < 16; i++, ii += 4) - in[i] = (((UINT4)mdContext.in[ii+3]) << 24) | - (((UINT4)mdContext.in[ii+2]) << 16) | - (((UINT4)mdContext.in[ii+1]) << 8) | - ((UINT4)mdContext.in[ii]); - transform (mdContext.buf, in); - mdi = 0; - } - } -} - -void MD4::finalize () -{ - UINT4 in[16]; - int mdi; - unsigned int i, ii; - unsigned int padLen; - - /* save number of bits */ - in[14] = mdContext.i[0]; - in[15] = mdContext.i[1]; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext.i[0] >> 3) & 0x3F); - - /* pad out to 56 mod 64 */ - padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); - update ( PADDING, padLen); - - /* append length in bits and transform */ - for (i = 0, ii = 0; i < 14; i++, ii += 4) - in[i] = (((UINT4)mdContext.in[ii+3]) << 24) | - (((UINT4)mdContext.in[ii+2]) << 16) | - (((UINT4)mdContext.in[ii+1]) << 8) | - ((UINT4)mdContext.in[ii]); - transform (mdContext.buf, in); - /* store buffer in digest */ - for (i = 0, ii = 0; i < 4; i++, ii += 4) { - mdContext.digest[ii] = (unsigned char)(mdContext.buf[i] & 0xFF); - - - mdContext.digest[ii+1] = - (unsigned char)((mdContext.buf[i] >> 8) & 0xFF); - mdContext.digest[ii+2] = - (unsigned char)((mdContext.buf[i] >> 16) & 0xFF); - mdContext.digest[ii+3] = - (unsigned char)((mdContext.buf[i] >> 24) & 0xFF); - } -} - -/* Basic MD4 step. Transform buf based on in. - */ -void MD4::transform (UINT4 *buf,UINT4 *in) -{ - UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - - /* Round 1 */ - FF (a, b, c, d, in[ 0], 3); - FF (d, a, b, c, in[ 1], 7); - FF (c, d, a, b, in[ 2], 11); - FF (b, c, d, a, in[ 3], 19); - FF (a, b, c, d, in[ 4], 3); - FF (d, a, b, c, in[ 5], 7); - FF (c, d, a, b, in[ 6], 11); - FF (b, c, d, a, in[ 7], 19); - FF (a, b, c, d, in[ 8], 3); - FF (d, a, b, c, in[ 9], 7); - FF (c, d, a, b, in[10], 11); - FF (b, c, d, a, in[11], 19); - FF (a, b, c, d, in[12], 3); - FF (d, a, b, c, in[13], 7); - FF (c, d, a, b, in[14], 11); - FF (b, c, d, a, in[15], 19); - - /* Round 2 */ - GG (a, b, c, d, in[ 0], 3); - GG (d, a, b, c, in[ 4], 5); - GG (c, d, a, b, in[ 8], 9); - GG (b, c, d, a, in[12], 13); - GG (a, b, c, d, in[ 1], 3); - GG (d, a, b, c, in[ 5], 5); - GG (c, d, a, b, in[ 9], 9); - GG (b, c, d, a, in[13], 13); - GG (a, b, c, d, in[ 2], 3); - GG (d, a, b, c, in[ 6], 5); - GG (c, d, a, b, in[10], 9); - GG (b, c, d, a, in[14], 13); - GG (a, b, c, d, in[ 3], 3); - GG (d, a, b, c, in[ 7], 5); - GG (c, d, a, b, in[11], 9); - GG (b, c, d, a, in[15], 13); - - /* Round 3 */ - HH (a, b, c, d, in[ 0], 3); - HH (d, a, b, c, in[ 8], 9); - HH (c, d, a, b, in[ 4], 11); - HH (b, c, d, a, in[12], 15); - HH (a, b, c, d, in[ 2], 3); - HH (d, a, b, c, in[10], 9); - HH (c, d, a, b, in[ 6], 11); - HH (b, c, d, a, in[14], 15); - HH (a, b, c, d, in[ 1], 3); - HH (d, a, b, c, in[ 9], 9); - HH (c, d, a, b, in[ 5], 11); - HH (b, c, d, a, in[13], 15); - HH (a, b, c, d, in[ 3], 3); - HH (d, a, b, c, in[11], 9); - HH (c, d, a, b, in[ 7], 11); - HH (b, c, d, a, in[15], 15); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -/** */ -unsigned char *MD4::raw_digest() -{ - - unsigned char *s = new unsigned char[16]; -/* - if (!finalized){ - cerr << "MD4::raw_digest: Can't get digest if you haven't "<< - "finalized the digest!" <<endl; - return ( (unsigned char*) ""); - } -*/ - memcpy(s, mdContext.digest, 16); - return s; -} - -/** */ -void MD4::raw_digest( unsigned char * s ) -{ -/* - if (!finalized){ - cerr << "MD4::raw_digest: Can't get digest if you haven't "<< - "finalized the digest!" <<endl; - return ( (unsigned char*) ""); - } -*/ - memcpy(s, mdContext.digest, 16); -} - -/** */ -CString MD4::hex_digest( unsigned char * p ) -{ - CString s; - int i; - char c[3]; - unsigned char *dig; - -/* - if (!finalized){ - cerr << "MD4::hex_digest: Can't get digest if you haven't "<< - "finalized the digest!" <<endl; - return ""; - } -*/ - - if ( p == 0 ) - dig = mdContext.digest; - else - dig = p; - - for (i=0; i<16; i++) - { - sprintf(c, "%02x", dig[i]); - c[2] = 0; - s += c; - } - - return s; -} diff -Naur dclib-0.3.10.orig/dclib/core/cmd4.h dclib-0.3.10/dclib/core/cmd4.h --- dclib-0.3.10.orig/dclib/core/cmd4.h 2007-09-18 10:24:40.000000000 +0100 +++ dclib-0.3.10/dclib/core/cmd4.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,80 +0,0 @@ -/* - ********************************************************************** - ** md4.h -- Header file for implementation of MD4 ** - ** RSA Data Security, Inc. MD4 Message Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** - ********************************************************************** - */ - -/* - ********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD4 Message ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD4 Message Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - ********************************************************************** - */ - -#ifndef CMD4_H -#define CMD4_H - -#include <stdio.h> -#include <dclib/dcos.h> -#include <dclib/core/cstring.h> - -#ifndef WIN32 -#include <fstream> -#include <iostream> -using namespace std; -#else -#include <fstream.h> -#include <iostream.h> -#endif - -/* typedef a 32 bit type */ -typedef unsigned long int UINT4; - -/* Data structure for MD4 (Message Digest) computation */ -typedef struct { - UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ - UINT4 buf[4]; /* scratch buffer */ - unsigned char in[64]; /* input buffer */ - unsigned char digest[16]; /* actual digest after MD4Final call */ -} MD4_CTX; - -class MD4 { - -public: - MD4(); - virtual ~MD4() {}; - void init (); - void update(unsigned char *inBuf,unsigned int inLen); - void update (FILE *file); - void finalize (); - - unsigned char *raw_digest (); // digest as a 16-byte binary array - void raw_digest( unsigned char * s ); // digest as a 16-byte binary array - - CString hex_digest( unsigned char * p = 0 ); // digest as a 33-byte ascii-hex string -private: - void transform (UINT4 *buf,UINT4 *in); - MD4_CTX mdContext; -}; - -#endif diff -Naur dclib-0.3.10.orig/dclib/core/Makefile.am dclib-0.3.10/dclib/core/Makefile.am --- dclib-0.3.10.orig/dclib/core/Makefile.am 2007-09-18 10:24:40.000000000 +0100 +++ dclib-0.3.10/dclib/core/Makefile.am 2007-09-18 10:25:39.000000000 +0100 @@ -8,7 +8,7 @@ cdir.cpp cdir.h cfile.cpp cfile.h che3.cpp che3.h \ clist.cpp clist.h clisten.cpp \ clisten.h clogfile.cpp clogfile.h cmanager.cpp cmanager.h \ -cmd4.cpp cmd4.h cmd5.cpp cmd5.h cobject.cpp cobject.h \ +cmd5.cpp cmd5.h cobject.cpp cobject.h \ cplugin.cpp cplugin.h csingleton.cpp csingleton.h \ csocket.cpp csocket.h cssl.cpp cssl.h cstring.cpp \ cstring.h cstringlist.cpp cstringlist.h cthread.cpp \ @@ -25,7 +25,7 @@ library_includedir=$(includedir)/dclib/core library_include_HEADERS = casyncdns.h cbase32.h cbase64.h cbytearray.h cbz.h ccallback.h \ cconnection.h cdir.h cfile.h che3.h clist.h \ -clisten.h clogfile.h cmanager.h cmd4.h cmd5.h cobject.h \ +clisten.h clogfile.h cmanager.h cmd5.h cobject.h \ cplugin.h csingleton.h csocket.h cssl.h cstring.h \ cstringlist.h cthread.h cxml.h filecopy.h types.h \ platform.h czlib.h
02-dclib-0.3.10-use-gnulib-md5.patch:
--- NEW FILE 02-dclib-0.3.10-use-gnulib-md5.patch --- --- dclib-0.3.10.orig/dclib/core/cmd5.h 2007-09-18 10:26:49.000000000 +0100 +++ dclib-0.3.10/dclib/core/cmd5.h 2007-09-18 13:20:32.000000000 +0100 @@ -1,124 +1,124 @@ -// MD5.CC - source code for the C++/object oriented translation and -// modification of MD5. +/* Declaration of functions and data types used for MD5 sum computing + library functions. + Copyright (C) 1995-1997,1999,2000,2001,2004,2005,2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-// Translation and modification (c) 1995 by Mordechai T. Abzug - -// This translation/ modification is provided "as is," without express or -// implied warranty of any kind. - -// The translator/ modifier does not claim (1) that MD5 will do what you think -// it does; (2) that this translation/ modification is accurate; or (3) that -// this software is "merchantible." (Language for this disclaimer partially -// copied from the disclaimer below). - -/* based on: - - MD5.H - header file for MD5C.C - MDDRIVER.C - test driver for MD2, MD4 and MD5 - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - -*/ - -#ifndef CMD5_H -#define CMD5_H +#ifndef _MD5_H +#define _MD5_H 1
#include <stdio.h> -#include <dclib/dcos.h> -#include <dclib/core/cstring.h> - -#ifndef WIN32 -#include <fstream> -#include <iostream> -using namespace std; -#else -#include <fstream.h> -#include <iostream.h> -#endif +#include <stdint.h>
-class CMD5 { - -public: -// methods for controlled operation: - CMD5 (); // simple initializer - virtual ~CMD5() {}; - void update (unsigned char *input, unsigned int input_length); - void update (istream& stream); - void update (FILE *file); - void update (ifstream& stream); - void finalize (); - -// constructors for special circumstances. All these constructors finalize -// the MD5 context. - CMD5 (unsigned char *string); // digest string, finalize - CMD5 (istream& stream); // digest stream, finalize - CMD5 (FILE *file); // digest file, close, finalize - CMD5 (ifstream& stream); // digest stream, close, finalize - -// methods to acquire finalized result - unsigned char *raw_digest (); // digest as a 16-byte binary array - CString hex_digest (); // digest as a 33-byte ascii-hex string - friend ostream& operator<< (ostream&, CMD5 context); +#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_SIZE 64
+#ifndef __GNUC_PREREQ +# if defined __GNUC__ && defined __GNUC_MINOR__ +# define __GNUC_PREREQ(maj, min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +# else +# define __GNUC_PREREQ(maj, min) 0 +# endif +#endif
+#ifndef __THROW +# if defined __cplusplus && __GNUC_PREREQ (2,8) +# define __THROW throw () +# else +# define __THROW +# endif +#endif
-private: - -// first, some types: - typedef unsigned int uint4; // assumes integer is 4 words long - typedef unsigned short int uint2; // assumes short integer is 2 words long - typedef unsigned char uint1; // assumes char is 1 word long - -// next, the private data: - uint4 state[4]; - uint4 count[2]; // number of *bits*, mod 2^64 - uint1 buffer[64]; // input buffer - uint1 digest[16]; - uint1 finalized; - -// last, the private methods, mostly static: - void init (); // called by all constructors - void transform (uint1 *buffer); // does the real update work. Note - // that length is implied to be 64. - - static void encode (uint1 *dest, uint4 *src, uint4 length); - static void decode (uint4 *dest, uint1 *src, uint4 length); - static void memcpy (uint1 *dest, uint1 *src, uint4 length); - static void memset (uint1 *start, uint1 val, uint4 length); - - static inline uint4 rotate_left (uint4 x, uint4 n); - static inline uint4 F (uint4 x, uint4 y, uint4 z); - static inline uint4 G (uint4 x, uint4 y, uint4 z); - static inline uint4 H (uint4 x, uint4 y, uint4 z); - static inline uint4 I (uint4 x, uint4 y, uint4 z); - static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, - uint4 s, uint4 ac); - static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, - uint4 s, uint4 ac); - static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, - uint4 s, uint4 ac); - static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, - uint4 s, uint4 ac); +#ifndef _LIBC +# define __md5_buffer md5_buffer +# define __md5_finish_ctx md5_finish_ctx +# define __md5_init_ctx md5_init_ctx +# define __md5_process_block md5_process_block +# define __md5_process_bytes md5_process_bytes +# define __md5_read_ctx md5_read_ctx +# define __md5_stream md5_stream +#endif
+/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + uint32_t A; + uint32_t B; + uint32_t C; + uint32_t D; + + uint32_t total[2]; + uint32_t buflen; + uint32_t buffer[32]; };
-#endif +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +extern void __md5_init_ctx (struct md5_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void __md5_process_block (const void *buffer, size_t len, + struct md5_ctx *ctx) __THROW; + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void __md5_process_bytes (const void *buffer, size_t len, + struct md5_ctx *ctx) __THROW; + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems, RESBUF must be aligned to a 32-bit + boundary. */ +extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __THROW; + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems, RESBUF must be aligned to a 32-bit + boundary. */ +extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW; + + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int __md5_stream (FILE *stream, void *resblock) __THROW; + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *__md5_buffer (const char *buffer, size_t len, + void *resblock) __THROW; + +#endif /* md5.h */ --- dclib-0.3.10.orig/dclib/core/cmd5.cpp 2007-09-18 10:26:49.000000000 +0100 +++ dclib-0.3.10/dclib/core/cmd5.cpp 2007-09-18 11:24:43.000000000 +0100 @@ -1,544 +1,451 @@ -// MD5.CC - source code for the C++/object oriented translation and -// modification of MD5. +/* Functions to compute MD5 message digest of files or memory blocks. + according to the definition of MD5 in RFC 1321 from April 1992. + Copyright (C) 1995,1996,1997,1999,2000,2001,2005,2006 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-// Translation and modification (c) 1995 by Mordechai T. Abzug +/* Written by Ulrich Drepper drepper@gnu.ai.mit.edu, 1995. */
-// This translation/ modification is provided "as is," without express or -// implied warranty of any kind. +#include <config.h>
-// The translator/ modifier does not claim (1) that MD5 will do what you think -// it does; (2) that this translation/ modification is accurate; or (3) that -// this software is "merchantible." (Language for this disclaimer partially -// copied from the disclaimer below). - -/* based on: - - MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - MDDRIVER.C - test driver for MD2, MD4 and MD5 - - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. +#include "cmd5.h"
-These notices must be retained in any copies of any part of this -documentation and/or software. +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h>
- */ +#if USE_UNLOCKED_IO +# include "unlocked-io.h" +#endif
-#include "cmd5.h" +#ifdef _LIBC +# include <endian.h> +# if __BYTE_ORDER == __BIG_ENDIAN +# define WORDS_BIGENDIAN 1 +# endif +/* We need to keep the namespace clean so define the MD5 function + protected using leading __ . */ +# define md5_init_ctx __md5_init_ctx +# define md5_process_block __md5_process_block +# define md5_process_bytes __md5_process_bytes +# define md5_finish_ctx __md5_finish_ctx +# define md5_read_ctx __md5_read_ctx +# define md5_stream __md5_stream +# define md5_buffer __md5_buffer +#endif
-#ifndef WIN32 -#include <strings.h> -#include <iostream> +#ifdef WORDS_BIGENDIAN +# define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #else -#include <iostream.h> +# define SWAP(n) (n) #endif
-#include <assert.h> - -// MD5 simple initialization method - -CMD5::CMD5(){ - - init(); - -} - - - - -// MD5 block update operation. Continues an MD5 message-digest -// operation, processing another message block, and updating the -// context. - -void CMD5::update (uint1 *input, uint4 input_length) { - - uint4 input_index, buffer_index; - uint4 buffer_space; // how much space is left in buffer - - if (finalized){ // so we can't update! - cerr << "MD5::update: Can't update a finalized digest!" << endl; - return; - } - - // Compute number of bytes mod 64 - buffer_index = (unsigned int)((count[0] >> 3) & 0x3F); - - // Update number of bits - if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) ) - count[1]++; - - count[1] += ((uint4)input_length >> 29); - - - buffer_space = 64 - buffer_index; // how much space is left in buffer - - // Transform as many times as possible. - if (input_length >= buffer_space) { // ie. we have enough to fill the buffer - // fill the rest of the buffer and transform - memcpy (buffer + buffer_index, input, buffer_space); - transform (buffer); - - // now, transform each 64-byte piece of the input, bypassing the buffer - for (input_index = buffer_space; input_index + 63 < input_length; - input_index += 64) - transform (input+input_index); - - buffer_index = 0; // so we can buffer remaining - } - else - input_index=0; // so we can buffer the whole input - - - // and here we do the buffering: - memcpy(buffer+buffer_index, input+input_index, input_length-input_index); -} - - - -// MD5 update for files. -// Like above, except that it works on files (and uses above as a primitive.) - -void CMD5::update(FILE *file){ - - unsigned char buffer[1024*1024]; - int len; - - while ( (len=fread(buffer, 1, 1024*1024, file)) > 0) - update(buffer, len); - - fclose (file); - -} - - - - - - -// MD5 update for istreams. -// Like update for files; see above. - -void CMD5::update(istream& stream){ - - unsigned char buffer[1024]; - int len; - - while (stream.good()){ - stream.read((char*)buffer, 1024); // note that return value of read is unusable. - len=stream.gcount(); - update(buffer, len); - } - -} - - - - - - -// MD5 update for ifstreams. -// Like update for files; see above. +#define BLOCKSIZE 4096 +#if BLOCKSIZE % 64 != 0 +# error "invalid BLOCKSIZE" +#endif
-void CMD5::update(ifstream& stream){ +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
- unsigned char buffer[1024]; - int len;
- while (stream.good()){ - stream.read((char*)buffer, 1024); // note that return value of read is unusable. - len=stream.gcount(); - update(buffer, len); - } +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +void +md5_init_ctx (struct md5_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32-bit value. */ +void * +md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) +{ + ((uint32_t *) resbuf)[0] = SWAP (ctx->A); + ((uint32_t *) resbuf)[1] = SWAP (ctx->B); + ((uint32_t *) resbuf)[2] = SWAP (ctx->C); + ((uint32_t *) resbuf)[3] = SWAP (ctx->D);
+ return resbuf; }
+/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF.
+ IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32-bit value. */ +void * +md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) +{ + /* Take yet unprocessed bytes into account. */ + uint32_t bytes = ctx->buflen; + size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
+ /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1];
+ /* Put the 64-bit file length in *bits* at the end of the buffer. */ + ctx->buffer[size - 2] = SWAP (ctx->total[0] << 3); + ctx->buffer[size - 1] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
+ memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
-// MD5 finalization. Ends an MD5 message-digest operation, writing the -// the message digest and zeroizing the context. - - -void CMD5::finalize (){ - - unsigned char bits[8]; - unsigned int index, padLen; - static uint1 PADDING[64]={ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - if (finalized){ - cerr << "MD5::finalize: Already finalized this digest!" << endl; - return; - } - - // Save number of bits - encode (bits, count, 8); - - // Pad out to 56 mod 64. - index = (uint4) ((count[0] >> 3) & 0x3f); - padLen = (index < 56) ? (56 - index) : (120 - index); - update (PADDING, padLen); - - // Append length (before padding) - update (bits, 8); - - // Store state in digest - encode (digest, state, 16); - - // Zeroize sensitive information - memset (buffer, 0, sizeof(*buffer)); - - finalized=1; - -} - - - - -CMD5::CMD5(FILE *file){ + /* Process last bytes. */ + md5_process_block (ctx->buffer, size * 4, ctx);
- init(); // must be called be all constructors - update(file); - finalize (); + return md5_read_ctx (ctx, resbuf); }
+/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md5_stream (FILE *stream, void *resblock) +{ + struct md5_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0;
+ /* Read block. Take care for partial reads. */ + while (1) + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
+ sum += n;
-CMD5::CMD5(istream& stream){ + if (sum == BLOCKSIZE) + break;
- init(); // must called by all constructors - update (stream); - finalize(); -} + if (n == 0) + { + /* Check for the error flag IFF N == 0, so that we don't + exit the loop after a partial read due to e.g., EAGAIN + or EWOULDBLOCK. */ + if (ferror (stream)) + return 1; + goto process_partial_block; + } + + /* We've read at least one byte, so ignore errors. But always + check for EOF, since feof may be true even though N > 0. + Otherwise, we could end up calling fread after EOF. */ + if (feof (stream)) + goto process_partial_block; + }
+ /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + md5_process_block (buffer, BLOCKSIZE, &ctx); + } + +process_partial_block: + + /* Process any remaining bytes. */ + if (sum > 0) + md5_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md5_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +md5_buffer (const char *buffer, size_t len, void *resblock) +{ + struct md5_ctx ctx;
+ /* Initialize the computation context. */ + md5_init_ctx (&ctx);
-CMD5::CMD5(ifstream& stream){ + /* Process whole buffer but last len % 64 bytes. */ + md5_process_bytes (buffer, len, &ctx);
- init(); // must called by all constructors - update (stream); - finalize(); + /* Put result in desired memory area. */ + return md5_finish_ctx (&ctx, resblock); }
+void +md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over;
-unsigned char *CMD5::raw_digest(){ - - uint1 *s = new uint1[16]; - - if (!finalized){ - cerr << "MD5::raw_digest: Can't get digest if you haven't "<< - "finalized the digest!" <<endl; - return ( (unsigned char*) ""); - } - - memcpy(s, digest, 16); - return s; -} - + memcpy (&((char *) ctx->buffer)[left_over], buffer, add); + ctx->buflen += add;
+ if (ctx->buflen > 64) + { + md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
-CString CMD5::hex_digest() -{ - int i; - CString s; - char c[3]; + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, + &((char *) ctx->buffer)[(left_over + add) & ~63], + ctx->buflen); + }
- if (!finalized) + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#if !_STRING_ARCH_unaligned +# define alignof(type) offsetof (struct { char c; type x; }, x) +# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0) + if (UNALIGNED_P (buffer)) + while (len > 64) + { + md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif { - cerr << "MD5::hex_digest: Can't get digest if you haven't "<< - "finalized the digest!" <<endl; - return ""; + md5_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; } + }
- for (i=0; i<16; i++) + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&((char *) ctx->buffer)[left_over], buffer, len); + left_over += len; + if (left_over >= 64) { - sprintf(c, "%02x", digest[i]); - c[2]=0; - s += c; + md5_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[16], left_over); } - - return s; -} - - - - - -ostream& operator<<(ostream &stream, CMD5 context){ - - stream << context.hex_digest().Data(); - return stream; -} - - - -// PRIVATE METHODS: - - - -void CMD5::init(){ - finalized=0; // we just started! - - // Nothing counted, so count=0 - count[0] = 0; - count[1] = 0; - - // Load magic initialization constants. - state[0] = 0x67452301; - state[1] = 0xefcdab89; - state[2] = 0x98badcfe; - state[3] = 0x10325476; + ctx->buflen = left_over; + } }
+/* These are the four functions used in the four steps of the MD5 algorithm + and defined in the RFC 1321. The first function is a little bit optimized + (as found in Colin Plumbs public domain implementation). */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d))
-// Constants for MD5Transform routine. -// Although we could use C++ style constants, defines are actually better, -// since they let us easily evade scope clashes. - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - - - - -// MD5 basic transformation. Transforms state based on block. -void CMD5::transform (uint1 block[64]){ - - uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - decode (x, block, 64); - - assert(!finalized); // not just a user error, since the method is private - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - // Zeroize sensitive information. - memset ( (uint1 *) x, 0, sizeof(x)); - -} - - - -// Encodes input (UINT4) into output (unsigned char). Assumes len is -// a multiple of 4. -void CMD5::encode (uint1 *output, uint4 *input, uint4 len) { - - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (uint1) (input[i] & 0xff); - output[j+1] = (uint1) ((input[i] >> 8) & 0xff); - output[j+2] = (uint1) ((input[i] >> 16) & 0xff); - output[j+3] = (uint1) ((input[i] >> 24) & 0xff); - } -} - - - - -// Decodes input (unsigned char) into output (UINT4). Assumes len is -// a multiple of 4. -void CMD5::decode (uint4 *output, uint1 *input, uint4 len){ - - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | - (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); -} - +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */
- - - -// Note: Replace "for loop" with standard memcpy if possible. -void CMD5::memcpy (uint1 *output, uint1 *input, uint4 len){ - - unsigned int i; - - for (i = 0; i < len; i++) - output[i] = input[i]; -} - - - -// Note: Replace "for loop" with standard memset if possible. -void CMD5::memset (uint1 *output, uint1 value, uint4 len){ - - unsigned int i; - - for (i = 0; i < len; i++) - output[i] = value; -} - - - -// ROTATE_LEFT rotates x left n bits. - -inline unsigned int CMD5::rotate_left (uint4 x, uint4 n){ - return (x << n) | (x >> (32-n)) ; -} - - - - -// F, G, H and I are basic MD5 functions. - -inline unsigned int CMD5::F (uint4 x, uint4 y, uint4 z){ - return (x & y) | (~x & z); -} - -inline unsigned int CMD5::G (uint4 x, uint4 y, uint4 z){ - return (x & z) | (y & ~z); -} - -inline unsigned int CMD5::H (uint4 x, uint4 y, uint4 z){ - return x ^ y ^ z; -} - -inline unsigned int CMD5::I (uint4 x, uint4 y, uint4 z){ - return y ^ (x | ~z); -} - - - -// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -// Rotation is separate from addition to prevent recomputation. - - -inline void CMD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, - uint4 s, uint4 ac){ - a += F(b, c, d) + x + ac; - a = rotate_left (a, s) +b; -} - -inline void CMD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, - uint4 s, uint4 ac){ - a += G(b, c, d) + x + ac; - a = rotate_left (a, s) +b; -} - -inline void CMD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, - uint4 s, uint4 ac){ - a += H(b, c, d) + x + ac; - a = rotate_left (a, s) +b; -} - -inline void CMD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, - uint4 s, uint4 ac){ - a += I(b, c, d) + x + ac; - a = rotate_left (a, s) +b; +void +md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) +{ + uint32_t correct_words[16]; + const uint32_t *words = (const uint32_t*) buffer; + size_t nwords = len / sizeof (uint32_t); + const uint32_t *endp = words + nwords; + uint32_t A = ctx->A; + uint32_t B = ctx->B; + uint32_t C = ctx->C; + uint32_t D = ctx->D; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + uint32_t *cwp = correct_words; + uint32_t A_save = A; + uint32_t B_save = B; + uint32_t C_save = C; + uint32_t D_save = D; + + /* First round: using the given function, the context and a constant + the next context is computed. Because the algorithms processing + unit is a 32-bit word and it is determined to work on words in + little endian byte order we perhaps have to change the byte order + before the computation. To reduce the work for the next steps + we store the swapped words in the array CORRECT_WORDS. */ + +#define OP(a, b, c, d, s, T) \ + do \ + { \ + a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ + ++words; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) + + /* Before we start, one word to the strange constants. + They are defined in RFC 1321 as + + T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + + Here is an equivalent invocation using Perl: + + perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' + */ + + /* Round 1. */ + OP (A, B, C, D, 7, 0xd76aa478); + OP (D, A, B, C, 12, 0xe8c7b756); + OP (C, D, A, B, 17, 0x242070db); + OP (B, C, D, A, 22, 0xc1bdceee); + OP (A, B, C, D, 7, 0xf57c0faf); + OP (D, A, B, C, 12, 0x4787c62a); + OP (C, D, A, B, 17, 0xa8304613); + OP (B, C, D, A, 22, 0xfd469501); + OP (A, B, C, D, 7, 0x698098d8); + OP (D, A, B, C, 12, 0x8b44f7af); + OP (C, D, A, B, 17, 0xffff5bb1); + OP (B, C, D, A, 22, 0x895cd7be); + OP (A, B, C, D, 7, 0x6b901122); + OP (D, A, B, C, 12, 0xfd987193); + OP (C, D, A, B, 17, 0xa679438e); + OP (B, C, D, A, 22, 0x49b40821); + + /* For the second to fourth round we have the possibly swapped words + in CORRECT_WORDS. Redefine the macro to take an additional first + argument specifying the function to use. */ +#undef OP +#define OP(f, a, b, c, d, k, s, T) \ + do \ + { \ + a += f (b, c, d) + correct_words[k] + T; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* Round 2. */ + OP (FG, A, B, C, D, 1, 5, 0xf61e2562); + OP (FG, D, A, B, C, 6, 9, 0xc040b340); + OP (FG, C, D, A, B, 11, 14, 0x265e5a51); + OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); + OP (FG, A, B, C, D, 5, 5, 0xd62f105d); + OP (FG, D, A, B, C, 10, 9, 0x02441453); + OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); + OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); + OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); + OP (FG, D, A, B, C, 14, 9, 0xc33707d6); + OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); + OP (FG, B, C, D, A, 8, 20, 0x455a14ed); + OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); + OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); + OP (FG, C, D, A, B, 7, 14, 0x676f02d9); + OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + + /* Round 3. */ + OP (FH, A, B, C, D, 5, 4, 0xfffa3942); + OP (FH, D, A, B, C, 8, 11, 0x8771f681); + OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); + OP (FH, B, C, D, A, 14, 23, 0xfde5380c); + OP (FH, A, B, C, D, 1, 4, 0xa4beea44); + OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); + OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); + OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); + OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); + OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); + OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); + OP (FH, B, C, D, A, 6, 23, 0x04881d05); + OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); + OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); + OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); + OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); + + /* Round 4. */ + OP (FI, A, B, C, D, 0, 6, 0xf4292244); + OP (FI, D, A, B, C, 7, 10, 0x432aff97); + OP (FI, C, D, A, B, 14, 15, 0xab9423a7); + OP (FI, B, C, D, A, 5, 21, 0xfc93a039); + OP (FI, A, B, C, D, 12, 6, 0x655b59c3); + OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); + OP (FI, C, D, A, B, 10, 15, 0xffeff47d); + OP (FI, B, C, D, A, 1, 21, 0x85845dd1); + OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); + OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); + OP (FI, C, D, A, B, 6, 15, 0xa3014314); + OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); + OP (FI, A, B, C, D, 4, 6, 0xf7537e82); + OP (FI, D, A, B, C, 11, 10, 0xbd3af235); + OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); + OP (FI, B, C, D, A, 9, 21, 0xeb86d391); + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + ctx->A = A; + ctx->B = B; + ctx->C = C; + ctx->D = D; }
03-dclib-0.3.10-use-new-md5-api.patch:
--- NEW FILE 03-dclib-0.3.10-use-new-md5-api.patch --- --- dclib-0.3.10.orig/dclib/cdownloadmanager.cpp 2007-09-18 10:26:49.000000000 +0100 +++ dclib-0.3.10/dclib/cdownloadmanager.cpp 2007-09-18 14:05:33.000000000 +0100 @@ -1513,7 +1513,11 @@ CByteArray ba; DCTransferFileObject * TransferFileObject; DCFileChunkObject * FileChunkObject; - CMD5 context; + md5_ctx * context = 0; + unsigned char resbuf[16]; + char c[3]; + int i = 0; + CString result = "";
if ( (TransferFileObject = m_pDownloadQueue->GetUserFileObject( Transfer->GetDstNick(), Transfer->GetHubName(), Transfer->GetHubHost(), Transfer->GetDstFilename() )) != 0 ) { @@ -1522,10 +1526,23 @@ if ( (TransferFileObject->m_stHash == "") && (TransferFileObject->m_bMulti == TRUE) ) { // calc hash - context.update( ba.Data(), ba.Size() ); - context.finalize(); + context = new md5_ctx(); + + md5_init_ctx( context ); + md5_process_bytes( ba.Data(), ba.Size(), context ); + md5_finish_ctx( context, &resbuf ); + + delete context; + + // convert digest to hexadecimal + for ( i = 0; i < 16; i++ ) + { + sprintf( c, "%02x", resbuf[i] ); + c[2] = 0; + result += c; + }
- TransferFileObject->m_stHash = context.hex_digest(); + TransferFileObject->m_stHash = result;
DPRINTF("hash is :'%s'\n",TransferFileObject->m_stHash.Data());
04-dclib-0.3.10-gnulib-md5-configure-test.patch:
--- NEW FILE 04-dclib-0.3.10-gnulib-md5-configure-test.patch --- --- dclib-0.3.10.orig/configure.in 2007-09-18 10:26:49.000000000 +0100 +++ dclib-0.3.10/configure.in 2007-09-18 11:57:21.000000000 +0100 @@ -90,6 +90,18 @@ jm_FILE_SYSTEM_USAGE( [], ) jm_FSTYPENAME
+dnl copied and pasted from md5.m4 +AC_DEFUN([gl_MD5], +[ + AC_LIBOBJ([md5]) + + dnl Prerequisites of lib/md5.c. + AC_REQUIRE([AC_C_BIGENDIAN]) + : +]) + +gl_MD5 + # Check for SunOS statfs brokenness wrt partitions 2GB and larger. # If <sys/vfs.h> exists and struct statfs has a member named f_spare, # enable the work-around code in fsusage.c.
Index: dclib.spec =================================================================== RCS file: /cvs/pkgs/rpms/dclib/devel/dclib.spec,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- dclib.spec 27 Aug 2007 12:46:36 -0000 1.12 +++ dclib.spec 18 Sep 2007 19:31:19 -0000 1.13 @@ -7,8 +7,13 @@ License: GPLv2 URL: http://sourceforge.net/projects/wxdcgui/ Source0: http://dl.sourceforge.net/wxdcgui/%%7Bname%7D-%%7Bversion%7D.tar.bz2 +Patch0: 01-%{name}-%{version}-remove-cmd4.patch +Patch1: 02-%{name}-%{version}-use-gnulib-md5.patch +Patch2: 03-%{name}-%{version}-use-new-md5-api.patch +Patch3: 04-%{name}-%{version}-gnulib-md5-configure-test.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: libxml2-devel, openssl-devel, bzip2-devel +BuildRequires: automake, autoconf
%description This library implements the Direct Connect file sharing protocol. The package @@ -30,9 +35,17 @@
%prep %setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1
%build +aclocal +automake +autoconf +make -f admin/Makefile.common %configure --disable-static make %{?_smp_mflags}
@@ -65,6 +78,11 @@
%changelog +* Tue Sep 18 2007 Luke Macken lmacken@redhat.com 0.3.10-2 +- Remove RSA MD5 implementation in favor of the gnulib implementation. Patches + taken from upstream ticket: + https://sourceforge.net/tracker/?func=detail&atid=897767&aid=1796674... + * Tue Aug 27 2007 Luke Macken lmacken@redhat.com 0.3.10-1 - 0.3.10 - Update License to GPLv2
--- dclib-0.3.8-cconfig-use-cfile.patch DELETED ---
----- End forwarded message -----