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
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 ;
00028 int (*Update) (void * param, const byte * data, size_t size)
00029 ;
00030 int (*Digest) (void * param, byte * digest)
00031 ;
00032 };
00033
00034
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
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
00058 ctx->paramlen = sizeof(md5Param);
00059
00060 ctx->param = xcalloc(1, ctx->paramlen);
00061
00062 ctx->Reset = (void *) md5Reset;
00063 ctx->Update = (void *) md5Update;
00064 ctx->Digest = (void *) md5Digest;
00065
00066 break;
00067 case PGPHASHALGO_SHA1:
00068 ctx->digestlen = 20;
00069 ctx->datalen = 64;
00070
00071 ctx->paramlen = sizeof(sha1Param);
00072
00073 ctx->param = xcalloc(1, ctx->paramlen);
00074
00075 ctx->Reset = (void *) sha1Reset;
00076 ctx->Update = (void *) sha1Update;
00077 ctx->Digest = (void *) sha1Digest;
00078
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 break;
00088 }
00089
00090
00091 xx = (*ctx->Reset) (ctx->param);
00092
00093
00094 DPRINTF((stderr, "*** Init(%x) ctx %p param %p\n", flags, ctx, ctx->param));
00095 return ctx;
00096 }
00097
00098
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
00107 return (*ctx->Update) (ctx->param, data, len);
00108
00109 }
00110
00111
00112
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
00126 (void) (*ctx->Digest) (ctx->param, digest);
00127
00128
00129
00130
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
00152 if (digest) {
00153 memset(digest, 0, ctx->digestlen);
00154 free(digest);
00155 }
00156 memset(ctx->param, 0, ctx->paramlen);
00157 free(ctx->param);
00158 memset(ctx, 0, sizeof(*ctx));
00159 free(ctx);
00160 return 0;
00161 }
00162