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 HASHContext *hashctx;
00023 };
00024
00025
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);
00035 }
00036 return nctx;
00037 }
00038
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 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
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
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
00124 }
00125
00126
00127
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
00143 HASH_End(ctx->hashctx, digest, &digestlen, digestlen);
00144
00145
00146
00147
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
00169 if (digest) {
00170 memset(digest, 0, digestlen);
00171 free(digest);
00172 }
00173 HASH_Destroy(ctx->hashctx);
00174 memset(ctx, 0, sizeof(*ctx));
00175 free(ctx);
00176 return 0;
00177 }
00178