added qse_encode_hmacstr() and qse_decode_hmacstr()
This commit is contained in:
parent
0ddcf3de1c
commit
2f07153431
@ -89,6 +89,41 @@ qse_size_t qse_hmac_digest (
|
||||
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)
|
||||
}
|
||||
#endif
|
||||
|
@ -57,6 +57,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#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)
|
||||
{
|
||||
@ -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);
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user