packaging: Initial packaging
[platform/upstream/cmake.git] / Source / cmCryptoHash.cxx
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #include "cmCryptoHash.h"
13
14 #include <cmsys/MD5.h>
15 #include "cm_sha2.h"
16
17 //----------------------------------------------------------------------------
18 cmsys::auto_ptr<cmCryptoHash> cmCryptoHash::New(const char* algo)
19 {
20   if(strcmp(algo,"MD5") == 0)
21     { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashMD5); }
22   else if(strcmp(algo,"SHA1") == 0)
23     { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA1); }
24   else if(strcmp(algo,"SHA224") == 0)
25     { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA224); }
26   else if(strcmp(algo,"SHA256") == 0)
27     { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA256); }
28   else if(strcmp(algo,"SHA384") == 0)
29     { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA384); }
30   else if(strcmp(algo,"SHA512") == 0)
31     { return cmsys::auto_ptr<cmCryptoHash>(new cmCryptoHashSHA512); }
32   else
33     { return cmsys::auto_ptr<cmCryptoHash>(0); }
34 }
35
36 //----------------------------------------------------------------------------
37 std::string cmCryptoHash::HashString(const char* input)
38 {
39   this->Initialize();
40   this->Append(reinterpret_cast<unsigned char const*>(input),
41                static_cast<int>(strlen(input)));
42   return this->Finalize();
43 }
44
45 //----------------------------------------------------------------------------
46 std::string cmCryptoHash::HashFile(const char* file)
47 {
48   std::ifstream fin(file, std::ios::in | cmsys_ios_binary);
49   if(!fin)
50     {
51     return "";
52     }
53
54   this->Initialize();
55
56   // Should be efficient enough on most system:
57   cm_sha2_uint64_t buffer[512];
58   char* buffer_c = reinterpret_cast<char*>(buffer);
59   unsigned char const* buffer_uc =
60     reinterpret_cast<unsigned char const*>(buffer);
61   // This copy loop is very sensitive on certain platforms with
62   // slightly broken stream libraries (like HPUX).  Normally, it is
63   // incorrect to not check the error condition on the fin.read()
64   // before using the data, but the fin.gcount() will be zero if an
65   // error occurred.  Therefore, the loop should be safe everywhere.
66   while(fin)
67     {
68     fin.read(buffer_c, sizeof(buffer));
69     if(int gcount = static_cast<int>(fin.gcount()))
70       {
71       this->Append(buffer_uc, gcount);
72       }
73     }
74   if(fin.eof())
75     {
76     return this->Finalize();
77     }
78   return "";
79 }
80
81 //----------------------------------------------------------------------------
82 cmCryptoHashMD5::cmCryptoHashMD5(): MD5(cmsysMD5_New())
83 {
84 }
85
86 //----------------------------------------------------------------------------
87 cmCryptoHashMD5::~cmCryptoHashMD5()
88 {
89   cmsysMD5_Delete(this->MD5);
90 }
91
92 //----------------------------------------------------------------------------
93 void cmCryptoHashMD5::Initialize()
94 {
95   cmsysMD5_Initialize(this->MD5);
96 }
97
98 //----------------------------------------------------------------------------
99 void cmCryptoHashMD5::Append(unsigned char const* buf, int sz)
100 {
101   cmsysMD5_Append(this->MD5, buf, sz);
102 }
103
104 //----------------------------------------------------------------------------
105 std::string cmCryptoHashMD5::Finalize()
106 {
107   char md5out[32];
108   cmsysMD5_FinalizeHex(this->MD5, md5out);
109   return std::string(md5out, 32);
110 }
111
112
113 #define cmCryptoHash_SHA_CLASS_IMPL(SHA) \
114 cmCryptoHash##SHA::cmCryptoHash##SHA(): SHA(new SHA_CTX) {} \
115 cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; } \
116 void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); } \
117 void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz) \
118 { SHA##_Update(this->SHA, buf, sz); } \
119 std::string cmCryptoHash##SHA::Finalize() \
120 { \
121   char out[SHA##_DIGEST_STRING_LENGTH]; \
122   SHA##_End(this->SHA, out); \
123   return std::string(out, SHA##_DIGEST_STRING_LENGTH-1); \
124 }
125
126 cmCryptoHash_SHA_CLASS_IMPL(SHA1)
127 cmCryptoHash_SHA_CLASS_IMPL(SHA224)
128 cmCryptoHash_SHA_CLASS_IMPL(SHA256)
129 cmCryptoHash_SHA_CLASS_IMPL(SHA384)
130 cmCryptoHash_SHA_CLASS_IMPL(SHA512)