/[winpt]/trunk/Gnupg/md.c
ViewVC logotype

Diff of /trunk/Gnupg/md.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by twoaday, Mon Jan 31 11:02:21 2005 UTC revision 46 by werner, Fri Oct 28 12:57:05 2005 UTC
# Line 1  Line 1 
 /* md.c - message digest wrapper  
  *        Copyright (C) 2003, 2004 Timo Schulz  
  *  
  * This file is part of GPGLIB.  
  *  
  * GPGLIB 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 of the License, or  
  * (at your option) any later version.  
  *  
  * GPGLIB 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 GPGLIB; if not, write to the Free Software Foundation,  
  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
  */  
   
 #include <windows.h>  
 #include <stdio.h>  
 #include <malloc.h>  
 #include <sys/types.h>  
   
 #include "openpgp.h"  
 #include "md.h"  
   
 struct gpgm_md_s {  
     void * ctx;  
     int algo;  
     void (*write)( void *, unsigned char *inbuf, size_t inlen );  
 };  
   
   
 gpg_md_t  
 gpg_md_open( int algo )  
 {  
     gpg_md_t md;  
   
     if (algo != MD_SHA1 && algo != MD_MD5 && algo != MD_RMD160  
         && algo != MD_SHA256 && algo != MD_SHA384 && algo != MD_SHA512)  
         return NULL;  
     md = calloc (1, sizeof * md);  
     if( !md )  
         return NULL;  
     switch( algo ) {  
     case MD_MD5:  
         md->ctx = calloc( 1, sizeof (MD5_CONTEXT) );  
         if( !md->ctx ) {  
             free( md );  
             return NULL;  
         }  
         md5_init( (MD5_CONTEXT *)md->ctx );  
         md->write = md5_write;  
         break;  
   
     case MD_SHA1:  
         md->ctx = calloc( 1, sizeof (SHA1_CONTEXT) );  
         if( !md->ctx ) {  
             free( md );  
             return NULL;  
         }  
         sha1_init( (SHA1_CONTEXT *)md->ctx );  
         md->write = sha1_write;  
         break;  
   
     case MD_RMD160:  
         md->ctx = calloc( 1, sizeof (RMD160_CONTEXT) );  
         if( !md->ctx ) {  
             free( md );  
             return NULL;  
         }  
         rmd160_init( (RMD160_CONTEXT *)md->ctx );  
         md->write = rmd160_write;  
         break;  
   
     case MD_SHA256:  
         md->ctx = calloc (1, sizeof (sha256_context));  
         if (!md->ctx) {  
             free (md);  
             return NULL;  
         }  
         sha256_init ((sha256_context *)md->ctx);  
         md->write = sha256_write;  
         break;  
   
     case MD_SHA384:  
     case MD_SHA512:  
         md->ctx = calloc (1, sizeof (sha512_context));  
         if (!md->ctx) {  
             free (md);  
             return NULL;  
         }  
         sha512_init ((sha512_context *)md->ctx);  
         md->write = sha512_write;  
         break;  
   
     default:  
         free( md );  
         return NULL;  
     }  
     md->algo = algo;  
     return md;  
 }  
   
   
 void  
 gpg_md_close( gpg_md_t md )  
 {  
     if( md ) {  
         md->algo = 0;  
         md->write = NULL;  
         free( md->ctx ); md->ctx = NULL;  
         free( md );  
     }  
 }  
   
   
 void  
 gpg_md_final( gpg_md_t md )  
 {  
     switch( md->algo ) {  
     case MD_MD5   : md5_final( (MD5_CONTEXT *)md->ctx ); break;  
     case MD_SHA1  : sha1_final( (SHA1_CONTEXT *) md->ctx ); break;  
     case MD_RMD160: rmd160_final( (RMD160_CONTEXT *) md->ctx ); break;  
     case MD_SHA256: sha256_final ((sha256_context *)md->ctx); break;  
     case MD_SHA384:  
     case MD_SHA512: sha512_final ((sha512_context *)md->ctx); break;  
     }  
 }  
   
   
 const unsigned char *  
 gpg_md_read (gpg_md_t md)  
 {  
     switch( md->algo ) {  
     case MD_MD5   : return md5_read( (MD5_CONTEXT *)md->ctx ); break;  
     case MD_SHA1  : return sha1_read( (SHA1_CONTEXT *)md->ctx ); break;  
     case MD_RMD160: return rmd160_read( (RMD160_CONTEXT *)md->ctx ); break;  
     case MD_SHA256: return sha256_read ((sha256_context *)md->ctx); break;  
     case MD_SHA384:  
     case MD_SHA512: return sha512_read ((sha512_context *)md->ctx); break;  
     }  
     return NULL;  
 }  
   
   
 void  
 gpg_md_putc( gpg_md_t md, int c )  
 {  
     unsigned char buf[1];  
     buf[0] = c & 0xff;  
     md->write( md->ctx, buf, 1 );  
 }  
   
   
 size_t  
 _md_get_digest_len (gpg_md_t md)  
 {  
     switch (md->algo) {  
     case MD_MD5:  
         return 16;  
     case MD_SHA1:  
     case MD_RMD160:  
         return 20;  
     case MD_SHA256:  
         return 32;  
     case MD_SHA384:  
         return 48;  
     case MD_SHA512:  
         return 64;  
     }  
     return 0;  
 }  
   
   
 void  
 gpg_md_write( gpg_md_t md, unsigned char *inbuf, size_t len )  
 {  
     if( md )  
         md->write( md->ctx, inbuf, len );  
 }  
   
   
 int  
 gpg_md_hash_file( int mdalgo, const char *file, unsigned char *digest, size_t *nlen )  
 {  
     gpg_md_t md;  
     FILE * fp;  
     char buf[8192];  
     int n;  
   
     md = gpg_md_open( mdalgo );  
     if( !md )  
         return -1;  
     fp = fopen( file, "rb" );  
     if( !fp ) {  
         gpg_md_close( md );  
         return -2;  
     }  
     while( !feof( fp ) ) {  
         n = fread( buf, 1, sizeof buf-1, fp );  
         if( !n )  
             break;  
         md->write( md->ctx, buf, n );  
     }  
     *nlen = _md_get_digest_len( md );  
     gpg_md_final( md );  
     memcpy( digest, gpg_md_read( md ), *nlen );  
     fclose( fp );  
     gpg_md_close( md );  
     return 0;  
 }  
   
   
 static int  
 do_check_md (int algo, char * msg, const unsigned char * digest, size_t nlen)  
 {  
     const unsigned char * tmp;  
     int check=0;  
     gpg_md_t md;  
   
     md = gpg_md_open (algo);  
     if (!md)  
         return -1;  
     gpg_md_write (md, msg, strlen (msg));  
     gpg_md_final (md);  
     tmp = gpg_md_read (md);  
     check = memcmp (digest, tmp, nlen);  
     gpg_md_close (md);  
   
     return check;  
 }  
   
 struct {  
     int algo;  
     int dlen;  
     char * msg;  
     const unsigned char * md;  
 } md_test [] = {  
     {MD_RMD160, 20, "abc", "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc"},  
     {0, 0, NULL, NULL}  
 };  
   
   
 int  
 gpg_md_selftest (void)  
 {  
     int i, rc=0;  
   
     for (i=0; md_test[i].algo; i++) {  
         rc = do_check_md (md_test[i].algo, md_test[i].msg, md_test[i].md,  
                           md_test[i].dlen);  
         if (rc)  
             return rc;  
     }  
     return 0;  
 }  
1    /* md.c - message digest wrapper
2     *        Copyright (C) 2003, 2004 Timo Schulz
3     *
4     * This file is part of GPGLIB.
5     *
6     * GPGLIB is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * GPGLIB is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with GPGLIB; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21    #ifdef HAVE_CONFIG_H
22    #include <config.h>
23    #endif
24    
25    #include <windows.h>
26    #include <windows.h>
27    #include <stdio.h>
28    #include <malloc.h>
29    #include <sys/types.h>
30    
31    #include "openpgp.h"
32    #include "md.h"
33    
34    struct gpgm_md_s {
35        void * ctx;
36        int algo;
37        void (*write)( void *ctx, unsigned char *inbuf, size_t inlen );
38    };
39    
40    
41    gpg_md_t
42    gpg_md_open( int algo )
43    {
44        gpg_md_t md;
45    
46        if (algo != MD_SHA1 && algo != MD_MD5 && algo != MD_RMD160
47            && algo != MD_SHA256 && algo != MD_SHA384 && algo != MD_SHA512)
48            return NULL;
49        md = calloc (1, sizeof * md);
50        if( !md )
51            return NULL;
52        switch( algo ) {
53        case MD_MD5:
54            md->ctx = calloc( 1, sizeof (MD5_CONTEXT) );
55            if( !md->ctx ) {
56                free( md );
57                return NULL;
58            }
59            md5_init( (MD5_CONTEXT *)md->ctx );
60            md->write = md5_write;
61            break;
62    
63        case MD_SHA1:
64            md->ctx = calloc( 1, sizeof (SHA1_CONTEXT) );
65            if( !md->ctx ) {
66                free( md );
67                return NULL;
68            }
69            sha1_init( (SHA1_CONTEXT *)md->ctx );
70            md->write = sha1_write;
71            break;
72    
73        case MD_RMD160:
74            md->ctx = calloc( 1, sizeof (RMD160_CONTEXT) );
75            if( !md->ctx ) {
76                free( md );
77                return NULL;
78            }
79            rmd160_init( (RMD160_CONTEXT *)md->ctx );
80            md->write = rmd160_write;
81            break;
82    
83        case MD_SHA256:
84            md->ctx = calloc (1, sizeof (sha256_context));
85            if (!md->ctx) {
86                free (md);
87                return NULL;
88            }
89            sha256_init ((sha256_context *)md->ctx);
90            md->write = sha256_write;
91            break;
92    
93        case MD_SHA384:
94        case MD_SHA512:
95            md->ctx = calloc (1, sizeof (sha512_context));
96            if (!md->ctx) {
97                free (md);
98                return NULL;
99            }
100            sha512_init ((sha512_context *)md->ctx);
101            md->write = sha512_write;
102            break;
103    
104        default:
105            free( md );
106            return NULL;
107        }
108        md->algo = algo;
109        return md;
110    }
111    
112    
113    void
114    gpg_md_close( gpg_md_t md )
115    {
116        if( md ) {
117            md->algo = 0;
118            md->write = NULL;
119            free( md->ctx ); md->ctx = NULL;
120            free( md );
121        }
122    }
123    
124    
125    void
126    gpg_md_final( gpg_md_t md )
127    {
128        switch( md->algo ) {
129        case MD_MD5   : md5_final( (MD5_CONTEXT *)md->ctx ); break;
130        case MD_SHA1  : sha1_final( (SHA1_CONTEXT *) md->ctx ); break;
131        case MD_RMD160: rmd160_final( (RMD160_CONTEXT *) md->ctx ); break;
132        case MD_SHA256: sha256_final ((sha256_context *)md->ctx); break;
133        case MD_SHA384:
134        case MD_SHA512: sha512_final ((sha512_context *)md->ctx); break;
135        }
136    }
137    
138    
139    const unsigned char *
140    gpg_md_read (gpg_md_t md)
141    {
142        switch( md->algo ) {
143        case MD_MD5   : return md5_read( (MD5_CONTEXT *)md->ctx ); break;
144        case MD_SHA1  : return sha1_read( (SHA1_CONTEXT *)md->ctx ); break;
145        case MD_RMD160: return rmd160_read( (RMD160_CONTEXT *)md->ctx ); break;
146        case MD_SHA256: return sha256_read ((sha256_context *)md->ctx); break;
147        case MD_SHA384:
148        case MD_SHA512: return sha512_read ((sha512_context *)md->ctx); break;
149        }
150        return NULL;
151    }
152    
153    
154    void
155    gpg_md_putc( gpg_md_t md, int c )
156    {
157        unsigned char buf[1];
158        buf[0] = c & 0xff;
159        md->write( md->ctx, buf, 1 );
160    }
161    
162    
163    size_t
164    _md_get_digest_len (gpg_md_t md)
165    {
166        switch (md->algo) {
167        case MD_MD5:
168            return 16;
169        case MD_SHA1:
170        case MD_RMD160:
171            return 20;
172        case MD_SHA256:
173            return 32;
174        case MD_SHA384:
175            return 48;
176        case MD_SHA512:
177            return 64;
178        }
179        return 0;
180    }
181    
182    
183    void
184    gpg_md_write( gpg_md_t md, unsigned char *inbuf, size_t len )
185    {
186        if( md )
187            md->write( md->ctx, inbuf, len );
188    }
189    
190    
191    int
192    gpg_md_hash_file( int mdalgo, const char *file, unsigned char *digest, size_t *nlen )
193    {
194        gpg_md_t md;
195        FILE * fp;
196        char buf[8192];
197        int n;
198    
199        md = gpg_md_open( mdalgo );
200        if( !md )
201            return -1;
202        fp = fopen( file, "rb" );
203        if( !fp ) {
204            gpg_md_close( md );
205            return -2;
206        }
207        while( !feof( fp ) ) {
208            n = fread( buf, 1, sizeof buf-1, fp );
209            if( !n )
210                break;
211            md->write( md->ctx, buf, n );
212        }
213        *nlen = _md_get_digest_len( md );
214        gpg_md_final( md );
215        memcpy( digest, gpg_md_read( md ), *nlen );
216        fclose( fp );
217        gpg_md_close( md );
218        return 0;
219    }
220    
221    
222    static int
223    do_check_md (int algo, char * msg, const unsigned char * digest, size_t nlen)
224    {
225        const unsigned char * tmp;
226        int check=0;
227        gpg_md_t md;
228    
229        md = gpg_md_open (algo);
230        if (!md)
231            return -1;
232        gpg_md_write (md, msg, strlen (msg));
233        gpg_md_final (md);
234        tmp = gpg_md_read (md);
235        check = memcmp (digest, tmp, nlen);
236        gpg_md_close (md);
237    
238        return check;
239    }
240    
241    struct {
242        int algo;
243        int dlen;
244        char * msg;
245        const unsigned char * md;
246    } md_test [] = {
247        {MD_RMD160, 20, "abc", "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc"},
248        {0, 0, NULL, NULL}
249    };
250    
251    
252    int
253    gpg_md_selftest (void)
254    {
255        int i, rc=0;
256    
257        for (i=0; md_test[i].algo; i++) {
258            rc = do_check_md (md_test[i].algo, md_test[i].msg, md_test[i].md,
259                              md_test[i].dlen);
260            if (rc)
261                return rc;
262        }
263        return 0;
264    }

Legend:
Removed from v.2  
changed lines
  Added in v.46

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26