From 9e48c6f7d602364eb1c18de7e1e4c00e4852839c Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 4 Aug 2009 05:24:13 +0000 Subject: ***IMPORTANT*** The function Bu::Md5::getResult no longer returns a hex string, it returns the raw binary string that makes up the md5 sum, this matches the original goal of the API and makes the whole system more general and transportable. I have added a handy helper function named getHexResult that will return the same classic hex md5 string we're used to, change anything in your code that uses getResult to getHexResult now. I've also added a handy function to the CryptoHash to write the result to a stream, writeResult. I've fixed some more things in the formatter, and added a cryptPass function that works very much like the system crypt function, md5 and base64. If I knew more about the glibc implementation I could probably make them compatible. For now there are some subtle differences in the formatting and the salting algorithm, also the output mantains it's base64 trailer (==) wheras the system function chops those off. There's also another helper that will only work on linux for now, that only takes the password, and generates a salt for you using urandom. --- src/crypt.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ src/crypt.h | 12 ++++++++++++ src/cryptohash.h | 3 +++ src/formatter.h | 6 ++++-- src/md5.cpp | 47 ++++++++++++++++++++++++++++++++++------------- src/md5.h | 3 +++ src/tests/cryptpass.cpp | 18 ++++++++++++++++++ src/tests/md5.cpp | 2 +- src/util.cpp | 1 + 9 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 src/crypt.cpp create mode 100644 src/crypt.h create mode 100644 src/tests/cryptpass.cpp create mode 100644 src/util.cpp diff --git a/src/crypt.cpp b/src/crypt.cpp new file mode 100644 index 0000000..9111cda --- /dev/null +++ b/src/crypt.cpp @@ -0,0 +1,40 @@ +#include "bu/crypt.h" +#include "bu/md5.h" +#include "bu/base64.h" +#include "bu/membuf.h" +#include "bu/file.h" + +Bu::FString Bu::cryptPass( const Bu::FString &sPass, const Bu::FString &sSalt ) +{ + Bu::Md5 md5; + Bu::MemBuf mbOut; + Bu::Base64 b64Out( mbOut ); + + Bu::FString::const_iterator i = sSalt.find('$'); + Bu::FString sSaltSml = sSalt.getSubStr( sSalt.begin(), i ); + + md5.addData( sPass ); + md5.addData( sSaltSml ); + md5.writeResult( b64Out ); + + b64Out.stop(); + + return sSaltSml + "$" + mbOut.getString(); +} + +Bu::FString Bu::cryptPass( const Bu::FString &sPass ) +{ + Bu::MemBuf mbSalt; + Bu::Base64 b64Salt( mbSalt ); + Bu::File fRand("/dev/urandom", Bu::File::Read ); + +#define STR 6 + char buf[STR]; + fRand.read( buf, STR ); + b64Salt.write( buf, STR ); + + b64Salt.stop(); + + return cryptPass( sPass, mbSalt.getString() ); +} + diff --git a/src/crypt.h b/src/crypt.h new file mode 100644 index 0000000..1ea1b85 --- /dev/null +++ b/src/crypt.h @@ -0,0 +1,12 @@ +#ifndef BU_CRYPT_H +#define BU_CRYPT_H + +#include "bu/fstring.h" + +namespace Bu +{ + FString cryptPass( const FString &sPass, const FString &sSalt ); + FString cryptPass( const FString &sPass ); +}; + +#endif diff --git a/src/cryptohash.h b/src/cryptohash.h index 87aaf09..91c9511 100644 --- a/src/cryptohash.h +++ b/src/cryptohash.h @@ -12,6 +12,8 @@ namespace Bu { + class Stream; + class CryptoHash { public: @@ -23,6 +25,7 @@ namespace Bu virtual void addData( const void *sData, int iSize ) = 0; virtual void addData( const Bu::FString &sData ); virtual FString getResult() = 0; + virtual void writeResult( Stream &sOut ) = 0; }; }; diff --git a/src/formatter.h b/src/formatter.h index 8bb8e08..9f407a4 100644 --- a/src/formatter.h +++ b/src/formatter.h @@ -134,6 +134,7 @@ namespace Bu { // This code is taken from Nango, hopefully we can make it better. bool bNeg = i<0; + char cBase = fLast.bCaps?'A':'a'; char buf[sizeof(type)*8+1]; if( bNeg ) i = -i; if( fLast.uRadix < 2 || fLast.uRadix > 36 ) @@ -146,7 +147,7 @@ namespace Bu { int c = i%fLast.uRadix; i /= fLast.uRadix; - buf[j] = (char)((c<10)?('0'+c):('A'+c-10)); + buf[j] = (char)((c<10)?('0'+c):(cBase+c-10)); if( i == 0 ) { if( bNeg ) buf[--j] = '-'; @@ -164,6 +165,7 @@ namespace Bu { // This code is taken from Nango, hopefully we can make it better. char buf[sizeof(type)*8+1]; + char cBase = fLast.bCaps?'A':'a'; if( fLast.uRadix < 2 || fLast.uRadix > 36 ) { usedFormat(); @@ -174,7 +176,7 @@ namespace Bu { int c = i%fLast.uRadix; i /= fLast.uRadix; - buf[j] = (char)((c<10)?('0'+c):('A'+c-10)); + buf[j] = (char)((c<10)?('0'+c):(cBase+c-10)); if( i == 0 ) { if( fLast.bPlus ) buf[--j] = '+'; diff --git a/src/md5.cpp b/src/md5.cpp index 14b244a..8d7b7c9 100644 --- a/src/md5.cpp +++ b/src/md5.cpp @@ -9,6 +9,8 @@ #include #include #include "md5.h" +#include "bu/stream.h" + // This performs a wrapping bitwise shift, kinda' fun! @@ -83,12 +85,40 @@ void Bu::Md5::addData( const void *sVData, int iSize ) } Bu::FString Bu::Md5::getResult() +{ + long lsum[4]; + compCap( lsum ); + return Bu::FString( (const char *)lsum, 4*4 ); +} + +void Bu::Md5::writeResult( Bu::Stream &sOut ) +{ + long lsum[4]; + compCap( lsum ); + sOut.write( lsum, 4*4 ); +} + +Bu::FString Bu::Md5::getHexResult() { static const char hex_tab[] = {"0123456789abcdef"}; char str[33]; long lsum[4]; - memcpy( lsum, sum, 4*4 ); + compCap( lsum ); + + int k = 0; + for( int i = 0; i < 16; i++ ) + { + str[k++] = hex_tab[(lsum[i>>2] >> ((i%4)*8+4)) & 0xF]; + str[k++] = hex_tab[(lsum[i>>2] >> ((i%4)*8 )) & 0xF]; + } + + return Bu::FString( str, 32 ); +} + +void Bu::Md5::compCap( long *sumout ) +{ + memcpy( sumout, sum, 4*4 ); long lbuf[16]; memcpy( lbuf, inbuf, 4*16 ); @@ -96,25 +126,16 @@ Bu::FString Bu::Md5::getResult() uint64_t iBits = iBytes*8; if( iBytes > 0 && iFill>>2 >= 14 ) { - compBlock( lbuf, lsum ); + compBlock( lbuf, sumout ); memset( lbuf, 0, 4*16 ); memcpy( lbuf+14, &iBits, 8 ); - compBlock( lbuf, lsum ); + compBlock( lbuf, sumout ); } else { memcpy( lbuf+14, &iBits, 8 ); - compBlock( lbuf, lsum ); + compBlock( lbuf, sumout ); } - - int k = 0; - for( int i = 0; i < 16; i++ ) - { - str[k++] = hex_tab[(lsum[i>>2] >> ((i%4)*8+4)) & 0xF]; - str[k++] = hex_tab[(lsum[i>>2] >> ((i%4)*8 )) & 0xF]; - } - - return Bu::FString( str, 32 ); } void Bu::Md5::compBlock( long *x, long *lsum ) diff --git a/src/md5.h b/src/md5.h index 96ba2ce..76bdd88 100644 --- a/src/md5.h +++ b/src/md5.h @@ -30,12 +30,15 @@ namespace Bu virtual void addData( const void *sData, int iSize ); using Bu::CryptoHash::addData; virtual FString getResult(); + virtual void writeResult( Bu::Stream &sOut ); + virtual FString getHexResult(); private: /** * Compute one block of input data. */ void compBlock( long *x, long *lsum ); + void compCap( long *sumout ); long inbuf[16]; long iFill; diff --git a/src/tests/cryptpass.cpp b/src/tests/cryptpass.cpp new file mode 100644 index 0000000..4b090fe --- /dev/null +++ b/src/tests/cryptpass.cpp @@ -0,0 +1,18 @@ +#include "bu/crypt.h" +#include "bu/sio.h" + +using namespace Bu; + +int main( int argc, char *argv[] ) +{ + if( argc == 1 ) + sio << "Syntax: " << argv[0] << " [salt]" << sio.nl + << sio.nl; + else if( argc == 2 ) + sio << "Crypt1: >> " << cryptPass( argv[1] ) << " <<" << sio.nl; + else + sio << "Crypt2: >> " << cryptPass( argv[1], argv[2] ) << " <<" << sio.nl; + + return 0; +} + diff --git a/src/tests/md5.cpp b/src/tests/md5.cpp index 3b3d5e7..69ddd1d 100644 --- a/src/tests/md5.cpp +++ b/src/tests/md5.cpp @@ -28,7 +28,7 @@ int main( int argc, char *argv[] ) break; } - sio << m.getResult() << " *" << *argv << sio.nl; + sio << m.getHexResult() << " *" << *argv << sio.nl; } } diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..111574c --- /dev/null +++ b/src/util.cpp @@ -0,0 +1 @@ +#include "bu/util.h" -- cgit v1.2.3