added qse_encode_hmacstr() and qse_decode_hmacstr()

This commit is contained in:
hyung-hwan 2019-08-16 10:19:41 +00:00
parent 0ddcf3de1c
commit 2f07153431
2 changed files with 147 additions and 0 deletions

View File

@ -89,6 +89,41 @@ qse_size_t qse_hmac_digest (
qse_size_t size qse_size_t size
); );
qse_size_t qse_get_hmac_digest_size (
qse_hmac_sha_type_t sha_type
);
qse_size_t qse_get_hmac_block_size (
qse_hmac_sha_type_t sha_type
);
/* given an array of pointer and length pairs, it creates a string
* prefixed with hmac followed by the pair values encoded in hexdecimal
* digits seperated by a dash
*/
qse_mchar_t* qse_encode_hmacstr (
qse_hmac_sha_type_t sha_type,
const qse_uint8_t* keyptr,
qse_size_t keylen,
qse_xptl_t* data,
qse_size_t count,
qse_mmgr_t* mmgr
);
qse_xptl_t* qse_decode_hmacstr (
qse_hmac_sha_type_t sha_type,
const qse_uint8_t* keyptr,
qse_size_t keylen,
const qse_mchar_t* hmacstr,
qse_size_t* count,
qse_mmgr_t* mmgr
);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
#endif #endif

View File

@ -57,6 +57,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <qse/cry/hmac.h> #include <qse/cry/hmac.h>
#include <qse/cmn/chr.h>
#include <qse/cmn/str.h>
#include "../cmn/mem-prv.h"
static inline qse_size_t sha_block_size (qse_hmac_sha_type_t sha_type) static inline qse_size_t sha_block_size (qse_hmac_sha_type_t sha_type)
{ {
@ -240,3 +243,112 @@ qse_size_t qse_hmac_digest (qse_hmac_t* ctx, qse_uint8_t* digest, qse_size_t siz
sha_updatex (&ctx->sha, ctx->sha_type, tmp, tmpsz); sha_updatex (&ctx->sha, ctx->sha_type, tmp, tmpsz);
return sha_digest(&ctx->sha, ctx->sha_type, digest, size); return sha_digest(&ctx->sha, ctx->sha_type, digest, size);
} }
qse_mchar_t* qse_encode_hmacstr (qse_hmac_sha_type_t sha_type, const qse_uint8_t* keyptr, qse_size_t keylen, qse_xptl_t* data, qse_size_t count, qse_mmgr_t* mmgr)
{
qse_size_t reqsize = 0, i , j;
qse_mchar_t* buf, * ptr;
qse_xptl_t* dptr;
qse_hmac_t hmac;
qse_uint8_t digest[QSE_HMAC_MAX_DIGEST_LEN];
qse_size_t digest_len = sha_digest_size(sha_type);
for (i = 0, dptr = data; i < count; i++, dptr++) reqsize += 1 + (dptr->len * 2);
reqsize += digest_len * 2 + 1;
buf = (qse_mchar_t*)QSE_MMGR_ALLOC(mmgr, reqsize * QSE_SIZEOF(*buf));
if (!buf) return QSE_NULL;
ptr = &buf[digest_len * 2 + 1];
for (i = 0, dptr = data; i < count; i++, dptr++)
{
for (j = 0; j < dptr->len; j++)
{
ptr += qse_mbsfmt(ptr, QSE_MT("%02x"), *((qse_uint8_t*)dptr->ptr + j));
}
if (i < count - 1) *ptr++ = QSE_MT('-');
}
*ptr = '\0';
qse_hmac_initialize (&hmac, sha_type, keyptr, keylen);
qse_hmac_update (&hmac, (const qse_uint8_t*)&buf[digest_len * 2 + 1], ptr - &buf[digest_len * 2 + 1]);
qse_hmac_digest (&hmac, digest, digest_len);
ptr = buf;
for (i = 0; i < digest_len; i++) ptr += qse_mbsfmt(ptr, ("%02x"), digest[i]);
*ptr = '-';
return buf;
}
qse_xptl_t* qse_decode_hmacstr (qse_hmac_sha_type_t sha_type, const qse_uint8_t* keyptr, qse_size_t keylen, const qse_mchar_t* hmacstr, qse_size_t* count, qse_mmgr_t* mmgr)
{
qse_uint8_t digest[QSE_HMAC_MAX_DIGEST_LEN];
qse_uint8_t orgdig[QSE_HMAC_MAX_DIGEST_LEN];
qse_size_t digest_len = sha_digest_size(sha_type);
const qse_mchar_t* ptr, * segptr, * segstart;
qse_size_t seglen, reqlen = 0, segcount = 0, i;
qse_uint8_t* data, * uptr;
qse_xptl_t* xptl;
qse_hmac_t hmac;
for (ptr = hmacstr, i = 0; *ptr != QSE_MT('\0') && *ptr != QSE_MT('-'); ptr += 2, i++)
{
if (!QSE_ISMXDIGIT(ptr[0]) || !QSE_ISMXDIGIT(ptr[1])) return QSE_NULL;
if (i >= digest_len) return QSE_NULL; /* digest too long */
orgdig[i] = QSE_MXDIGITTONUM(ptr[0]) * 16 + QSE_MXDIGITTONUM(ptr[1]);
}
if (*ptr == QSE_MT('\0')) return QSE_NULL; /* no dash found after digest */
if (i != digest_len) return QSE_NULL; /* digest too short */
ptr++;
qse_hmac_initialize (&hmac, sha_type, keyptr, keylen);
qse_hmac_update (&hmac, (const qse_uint8_t*)ptr, qse_mbslen(ptr));
qse_hmac_digest (&hmac, digest, digest_len);
if (QSE_MEMCMP(digest, orgdig, digest_len) != 0) return QSE_NULL; /* wrong hmac */
segstart = ptr;
while (1)
{
segptr = ptr;
for (ptr = segptr; *ptr != QSE_MT('\0') && *ptr != QSE_MT('-'); ptr++) ;
seglen = ptr - segptr;
if (seglen & 1) return QSE_NULL; /* odd-length segment */
reqlen += (seglen >> 1) + QSE_SIZEOF(*xptl);
segcount++;
if (*ptr == QSE_MT('\0')) break;
ptr++;
}
data = (qse_uint8_t*)QSE_MMGR_ALLOC(mmgr, reqlen);
if (!data) return QSE_NULL;
ptr = segstart;
xptl = (qse_xptl_t*)data;
uptr = data + (segcount * QSE_SIZEOF(*xptl));
while (1)
{
segptr = ptr;
xptl->ptr = uptr;
for (ptr = segptr, i = 0; *ptr != QSE_MT('\0') && *ptr != QSE_MT('-'); ptr += 2, i++)
{
*uptr++ = QSE_MXDIGITTONUM(ptr[0]) * 16 + QSE_MXDIGITTONUM(ptr[1]);
}
xptl->len = i;
xptl++;
if (*ptr == QSE_MT('\0')) break;
ptr++;
}
*count = segcount;
return (qse_xptl_t*)data;
}