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     HASHContext *hashctx;       
00023 };
00024 
00025 /*@-boundsread@*/
00026 DIGEST_CTX
00027 rpmDigestDup(DIGEST_CTX octx)
00028 {
00029     DIGEST_CTX nctx;
00030     nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
00031     nctx->hashctx = HASH_Clone(octx->hashctx);
00032     if (nctx->hashctx == NULL) {
00033         fprintf(stderr, "HASH_Clone failed\n");
00034         exit(EXIT_FAILURE);  /* FIX: callers do not bother checking error return */
00035     }
00036     return nctx;
00037 }
00038 /*@=boundsread@*/
00039 
00040 static HASH_HashType
00041 getHashType(pgpHashAlgo hashalgo)
00042 {
00043     switch (hashalgo) {
00044     case PGPHASHALGO_MD5:
00045         return HASH_AlgMD5;
00046         break;
00047     case PGPHASHALGO_SHA1:
00048         return HASH_AlgSHA1;
00049         break;
00050     case PGPHASHALGO_SHA256:
00051         return HASH_AlgSHA256;
00052         break;
00053     case PGPHASHALGO_SHA384:
00054         return HASH_AlgSHA384;
00055         break;
00056     case PGPHASHALGO_SHA512:
00057         return HASH_AlgSHA512;
00058         break;
00059     case PGPHASHALGO_RIPEMD160:
00060     case PGPHASHALGO_MD2:
00061     case PGPHASHALGO_TIGER192:
00062     case PGPHASHALGO_HAVAL_5_160:
00063     default:
00064         return HASH_AlgNULL;
00065         /*@notreached@*/ break;
00066     }
00067 }
00068 
00069 size_t
00070 rpmDigestLength(pgpHashAlgo hashalgo)
00071 {
00072     return HASH_ResultLen(getHashType(hashalgo));
00073 }
00074 
00075 DIGEST_CTX
00076 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
00077 {
00078     HASH_HashType type;
00079     DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
00080 
00081     ctx->flags = flags;
00082 
00083     type = getHashType(hashalgo);
00084     if (type == HASH_AlgNULL) {
00085         free(ctx);
00086         return NULL;
00087     }
00088 
00089     ctx->hashctx = HASH_Create(type);
00090     if (ctx->hashctx == NULL) {
00091         free(ctx);
00092         return NULL;
00093     }
00094 
00095     HASH_Begin(ctx->hashctx);
00096     
00097 DPRINTF((stderr, "*** Init(%x) ctx %p hashctx %p\n", flags, ctx, ctx->hashctx));
00098     return ctx;
00099 }
00100 
00101 /*@-mustmod@*/ /* LCL: ctx->hashctx may be modified, but ctx is abstract @*/
00102 int
00103 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
00104 {
00105     unsigned int partlen;
00106     const unsigned char *ptr = data;
00107 
00108     if (ctx == NULL)
00109         return -1;
00110 
00111 DPRINTF((stderr, "*** Update(%p,%p,%d) hashctx %p \"%s\"\n", ctx, data, len, ctx->hashctx, ((char *)data)));
00112 /*@-boundsread@*/
00113    partlen = ~(unsigned int)0xFF;
00114    while (len > 0) {
00115         if (len < partlen) {
00116                 partlen = (unsigned int)len;
00117         }
00118         HASH_Update(ctx->hashctx, ptr, partlen);
00119         ptr += partlen;
00120         len -= partlen;
00121    }
00122    return 0;
00123 /*@=boundsread@*/
00124 }
00125 /*@=mustmod@*/
00126 
00127 /*@-boundswrite@*/
00128 int
00129 rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
00130 {
00131     unsigned char * digest;
00132     char * t;
00133     int i;
00134     unsigned int digestlen;
00135 
00136     if (ctx == NULL)
00137         return -1;
00138     digestlen = HASH_ResultLenContext(ctx->hashctx);
00139     digest = xmalloc(digestlen);
00140 
00141 DPRINTF((stderr, "*** Final(%p,%p,%p,%d) hashctx %p digest %p\n", ctx, datap, lenp, asAscii, ctx->hashctx, digest));
00142 /*@-noeffectuncon@*/
00143     HASH_End(ctx->hashctx, digest, &digestlen, digestlen);
00144 /*@=noeffectuncon@*/
00145 
00146     /* Return final digest. */
00147 /*@-branchstate@*/
00148     if (!asAscii) {
00149         if (lenp) *lenp = digestlen;
00150         if (datap) {
00151             *datap = digest;
00152             digest = NULL;
00153         }
00154     } else {
00155         if (lenp) *lenp = (2*digestlen) + 1;
00156         if (datap) {
00157             const byte * s = (const byte *) digest;
00158             static const char hex[] = "0123456789abcdef";
00159 
00160             *datap = t = xmalloc((2*digestlen) + 1);
00161             for (i = 0 ; i < digestlen; i++) {
00162                 *t++ = hex[ (unsigned)((*s >> 4) & 0x0f) ];
00163                 *t++ = hex[ (unsigned)((*s++   ) & 0x0f) ];
00164             }
00165             *t = '\0';
00166         }
00167     }
00168 /*@=branchstate@*/
00169     if (digest) {
00170         memset(digest, 0, digestlen);   /* In case it's sensitive */
00171         free(digest);
00172     }
00173     HASH_Destroy(ctx->hashctx);
00174     memset(ctx, 0, sizeof(*ctx));       /* In case it's sensitive */
00175     free(ctx);
00176     return 0;
00177 }
00178 /*@=boundswrite@*/

Generated on Tue Jan 5 15:36:38 2010 for rpm by  doxygen 1.4.7