7 #include "rpmio/digest.h"
12 #define DPRINTF(_a) fprintf _a
19 * MD5/SHA1 digest private data.
22 rpmDigestFlags flags; /*!< Bit(s) to control digest operation. */
23 HASHContext *hashctx; /*!< Internal NSS hash context. */
27 rpmDigestDup(DIGEST_CTX octx)
30 nctx = memcpy(xcalloc(1, sizeof(*nctx)), octx, sizeof(*nctx));
31 nctx->hashctx = HASH_Clone(octx->hashctx);
32 if (nctx->hashctx == NULL) {
33 fprintf(stderr, "HASH_Clone failed\n");
34 exit(EXIT_FAILURE); /* FIX: callers do not bother checking error return */
40 getHashType(pgpHashAlgo hashalgo)
46 case PGPHASHALGO_SHA1:
49 case PGPHASHALGO_SHA256:
50 return HASH_AlgSHA256;
52 case PGPHASHALGO_SHA384:
53 return HASH_AlgSHA384;
55 case PGPHASHALGO_SHA512:
56 return HASH_AlgSHA512;
58 case PGPHASHALGO_RIPEMD160:
60 case PGPHASHALGO_TIGER192:
61 case PGPHASHALGO_HAVAL_5_160:
69 rpmDigestLength(pgpHashAlgo hashalgo)
71 return HASH_ResultLen(getHashType(hashalgo));
75 rpmDigestInit(pgpHashAlgo hashalgo, rpmDigestFlags flags)
78 DIGEST_CTX ctx = xcalloc(1, sizeof(*ctx));
82 type = getHashType(hashalgo);
83 if (type == HASH_AlgNULL) {
88 ctx->hashctx = HASH_Create(type);
89 if (ctx->hashctx == NULL) {
94 HASH_Begin(ctx->hashctx);
96 DPRINTF((stderr, "*** Init(%x) ctx %p hashctx %p\n", flags, ctx, ctx->hashctx));
101 rpmDigestUpdate(DIGEST_CTX ctx, const void * data, size_t len)
104 const unsigned char *ptr = data;
109 DPRINTF((stderr, "*** Update(%p,%p,%zd) hashctx %p \"%s\"\n", ctx, data, len, ctx->hashctx, ((char *)data)));
110 partlen = ~(unsigned int)0xFF;
115 HASH_Update(ctx->hashctx, ptr, partlen);
123 rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t *lenp, int asAscii)
125 unsigned char * digest;
130 digestlen = HASH_ResultLenContext(ctx->hashctx);
131 digest = xmalloc(digestlen);
133 DPRINTF((stderr, "*** Final(%p,%p,%p,%zd) hashctx %p digest %p\n", ctx, datap, lenp, asAscii, ctx->hashctx, digest));
135 HASH_End(ctx->hashctx, digest, (unsigned int *) &digestlen, digestlen);
137 /* Return final digest. */
139 if (lenp) *lenp = digestlen;
145 if (lenp) *lenp = (2*digestlen) + 1;
147 const uint8_t * s = (const uint8_t *) digest;
148 *datap = pgpHexStr(s, digestlen);
152 memset(digest, 0, digestlen); /* In case it's sensitive */
155 HASH_Destroy(ctx->hashctx);
156 memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
161 void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int flags)
163 FDDIGEST_t fddig = fd->digests + fd->ndigests;
164 if (fddig != (fd->digests + FDDIGEST_MAX)) {
166 fddig->hashalgo = hashalgo;
167 fdstat_enter(fd, FDSTAT_DIGEST);
168 fddig->hashctx = rpmDigestInit(hashalgo, flags);
169 fdstat_exit(fd, FDSTAT_DIGEST, (ssize_t) 0);
173 void fdUpdateDigests(FD_t fd, const unsigned char * buf, size_t buflen)
177 if (buf != NULL && buflen > 0)
178 for (i = fd->ndigests - 1; i >= 0; i--) {
179 FDDIGEST_t fddig = fd->digests + i;
180 if (fddig->hashctx == NULL)
182 fdstat_enter(fd, FDSTAT_DIGEST);
183 (void) rpmDigestUpdate(fddig->hashctx, buf, buflen);
184 fdstat_exit(fd, FDSTAT_DIGEST, (ssize_t) buflen);
188 void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
196 for (i = fd->ndigests - 1; i >= 0; i--) {
197 FDDIGEST_t fddig = fd->digests + i;
198 if (fddig->hashctx == NULL)
200 if (i > imax) imax = i;
201 if (fddig->hashalgo != hashalgo)
203 fdstat_enter(fd, FDSTAT_DIGEST);
204 (void) rpmDigestFinal(fddig->hashctx, datap, lenp, asAscii);
205 fdstat_exit(fd, FDSTAT_DIGEST, (ssize_t) 0);
206 fddig->hashctx = NULL;
210 if (datap) *datap = NULL;
216 fd->ndigests++; /* convert index to count */
220 void fdStealDigest(FD_t fd, pgpDig dig)
223 for (i = fd->ndigests - 1; i >= 0; i--) {
224 FDDIGEST_t fddig = fd->digests + i;
225 if (fddig->hashctx != NULL)
226 switch (fddig->hashalgo) {
227 case PGPHASHALGO_MD5:
228 assert(dig->md5ctx == NULL);
229 dig->md5ctx = fddig->hashctx;
230 fddig->hashctx = NULL;
232 case PGPHASHALGO_SHA1:
233 case PGPHASHALGO_SHA256:
234 case PGPHASHALGO_SHA384:
235 case PGPHASHALGO_SHA512:
236 assert(dig->sha1ctx == NULL);
237 dig->sha1ctx = fddig->hashctx;
238 fddig->hashctx = NULL;