Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

rpmio/digest.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include "rpmio_internal.h"
00007 #include "debug.h"
00008 
00009 #ifdef  SHA_DEBUG
00010 #define DPRINTF(_a)     fprintf _a
00011 #else
00012 #define DPRINTF(_a)
00013 #endif
00014 
00015 /*@access DIGEST_CTX@*/
00016 
00020 struct DIGEST_CTX_s {
00021     rpmDigestFlags flags;       
00022     uint32_t datalen;           
00023     uint32_t paramlen;          
00024     uint32_t digestlen;         
00025     void * param;               
00026     int (*Reset) (void * param)
00027         /*@modifies param @*/;  
00028     int (*Update) (void * param, const byte * data, size_t size)
00029         /*@modifies param @*/;  
00030     int (*Digest) (void * param, /*@out@*/ byte * digest)
00031         /*@modifies param, digest @*/;  
00032 };
00033 
00034 /*@-boundsread@*/
00035 DIGEST_CTX
00036 rpmDigestDup(DIGEST_CTX octx)
00037 {
00038     DIGEST_CTX nctx;
00039     nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
00040     nctx->param = memcpy(xcalloc(1, nctx->paramlen), octx->param, nctx->paramlen);
00041     return nctx;
00042 }
00043 /*@=boundsread@*/
00044 
00045 DIGEST_CTX
00046 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
00047 {
00048     DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
00049     int xx;
00050 
00051     ctx->flags = flags;
00052 
00053     switch (hashalgo) {
00054     case PGPHASHALGO_MD5:
00055         ctx->digestlen = 16;
00056         ctx->datalen = 64;
00057 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00058         ctx->paramlen = sizeof(md5Param);
00059 /*@=sizeoftype@*/
00060         ctx->param = xcalloc(1, ctx->paramlen);
00061 /*@-type@*/ /* FIX: cast? */
00062         ctx->Reset = (void *) md5Reset;
00063         ctx->Update = (void *) md5Update;
00064         ctx->Digest = (void *) md5Digest;
00065 /*@=type@*/
00066         break;
00067     case PGPHASHALGO_SHA1:
00068         ctx->digestlen = 20;
00069         ctx->datalen = 64;
00070 /*@-sizeoftype@*/ /* FIX: union, not void pointer */
00071         ctx->paramlen = sizeof(sha1Param);
00072 /*@=sizeoftype@*/
00073         ctx->param = xcalloc(1, ctx->paramlen);
00074 /*@-type@*/ /* FIX: cast? */
00075         ctx->Reset = (void *) sha1Reset;
00076         ctx->Update = (void *) sha1Update;
00077         ctx->Digest = (void *) sha1Digest;
00078 /*@=type@*/
00079         break;
00080     case PGPHASHALGO_RIPEMD160:
00081     case PGPHASHALGO_MD2:
00082     case PGPHASHALGO_TIGER192:
00083     case PGPHASHALGO_HAVAL_5_160:
00084     default:
00085         free(ctx);
00086         return NULL;
00087         /*@notreached@*/ break;
00088     }
00089 
00090 /*@-boundsread@*/
00091     xx = (*ctx->Reset) (ctx->param);
00092 /*@=boundsread@*/
00093 
00094 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
00095     return ctx;
00096 }
00097 
00098 /*@-mustmod@*/ /* LCL: ctx->param may be modified, but ctx is abstract @*/
00099 int
00100 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00101 {
00102     if (ctx == NULL)
00103         return -1;
00104 
00105 DPRINTF((stderr, "*** Update(%p,%p,%d) param %p \"%s\"\n", ctx, data, len, ctx->param, ((char *)data)));
00106 /*@-boundsread@*/
00107     return (*ctx->Update) (ctx->param, data, len);
00108 /*@=boundsread@*/
00109 }
00110 /*@=mustmod@*/
00111 
00112 /*@-boundswrite@*/
00113 int
00114 rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
00115 {
00116     byte * digest;
00117     char * t;
00118     int i;
00119 
00120     if (ctx == NULL)
00121         return -1;
00122     digest = xmalloc(ctx->digestlen);
00123 
00124 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) param %p digest %p\n", ctx, datap, lenp, asAscii, ctx->param, digest));
00125 /*@-noeffectuncon@*/ /* FIX: check rc */
00126     (void) (*ctx->Digest) (ctx->param, digest);
00127 /*@=noeffectuncon@*/
00128 
00129     /* Return final digest. */
00130 /*@-branchstate@*/
00131     if (!asAscii) {
00132         if (lenp) *lenp = ctx->digestlen;
00133         if (datap) {
00134             *datap = digest;
00135             digest = NULL;
00136         }
00137     } else {
00138         if (lenp) *lenp = (2*ctx->digestlen) + 1;
00139         if (datap) {
00140             const byte * s = (const byte *) digest;
00141             static const char hex[] = "0123456789abcdef";
00142 
00143             *datap = t = xmalloc((2*ctx->digestlen) + 1);
00144             for (i = 0 ; i < ctx->digestlen; i++) {
00145                 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
00146                 *t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
00147             }
00148             *t = '\0';
00149         }
00150     }
00151 /*@=branchstate@*/
00152     if (digest) {
00153         memset(digest, 0, ctx->digestlen);      /* In case it's sensitive */
00154         free(digest);
00155     }
00156     memset(ctx->param, 0, ctx->paramlen);       /* In case it's sensitive */
00157     free(ctx->param);
00158     memset(ctx, 0, sizeof(*ctx));       /* In case it's sensitive */
00159     free(ctx);
00160     return 0;
00161 }
00162 /*@=boundswrite@*/

Generated on Sun Oct 26 13:02:03 2003 for rpm by doxygen1.2.18