Alt-Digest-MD5-OpenSSL
view release on metacpan or search on metacpan
return MD5_Update(c, data, len);
}
static int md5_final(unsigned char *md, MD5_COMPAT_CTX *c) {
return MD5_Final(md, c);
}
static void md5_free(MD5_COMPAT_CTX *c) {
/* No cleanup needed for legacy API */
(void)c;
}
#endif
#if defined(USE_ITHREADS) && defined(MGf_DUP)
static int
md5_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *params)
{
MD5_COMPAT_CTX *new_context;
MD5_COMPAT_CTX *context = (MD5_COMPAT_CTX *)mg->mg_ptr;
PERL_UNUSED_ARG(params);
New(55, new_context, 1, MD5_COMPAT_CTX);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
new_context->ctx = EVP_MD_CTX_new();
if (new_context->ctx == NULL || !EVP_MD_CTX_copy_ex(new_context->ctx, context->ctx)) {
Safefree(new_context);
croak("Failed to duplicate MD5 context for thread");
}
new_context->Nl = context->Nl;
#else
memcpy(new_context, context, sizeof(MD5_COMPAT_CTX));
#endif
mg->mg_ptr = (char *)new_context;
return 0;
}
#endif
STATIC MGVTBL vtbl_md5 = {
NULL, /* get */
NULL, /* set */
NULL, /* len */
NULL, /* clear */
NULL, /* free */
#if defined(USE_ITHREADS) && defined(MGf_DUP)
NULL, /* copy */
md5_dup, /* dup */
#endif
};
static SV*
new_md5_ctx(pTHX_ MD5_COMPAT_CTX *context, const char *sclass)
{
SV *sv = newSV(0);
SV *obj = newRV_noinc(sv);
sv_bless(obj, gv_stashpv(sclass, 0));
sv_magicext(sv, NULL, PERL_MAGIC_ext, &vtbl_md5, (const char *)context, 0);
#if defined(USE_ITHREADS) && defined(MGf_DUP)
SvMAGIC(sv)->mg_flags |= MGf_DUP;
#endif
return obj;
}
static MD5_COMPAT_CTX*
get_md5_ctx(pTHX_ SV* sv)
{
MAGIC *mg;
if (!sv_derived_from(sv, "Digest::MD5"))
croak("Not a reference to a Digest::MD5 object");
for (mg = SvMAGIC(SvRV(sv)); mg; mg = mg->mg_moremagic) {
if (mg->mg_type == PERL_MAGIC_ext
&& mg->mg_virtual == &vtbl_md5) {
return (MD5_COMPAT_CTX *)mg->mg_ptr;
}
}
croak("Failed to get MD5_COMPAT_CTX pointer");
return (MD5_COMPAT_CTX*)0; /* some compilers insist on a return value */
}
static char*
hex_16(const unsigned char* from, char* to)
{
static const char hexdigits[] = "0123456789abcdef";
const unsigned char *end = from + 16;
char *d = to;
while (from < end) {
*d++ = hexdigits[(*from >> 4)];
*d++ = hexdigits[(*from & 0x0F)];
from++;
}
*d = '\0';
return to;
}
static char*
base64_16(const unsigned char* from, char* to)
{
static const char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const unsigned char *end = from + 16;
unsigned char c1, c2, c3;
char *d = to;
while (1) {
c1 = *from++;
*d++ = base64[c1>>2];
if (from == end) {
*d++ = base64[(c1 & 0x3) << 4];
break;
}
c2 = *from++;
( run in 2.486 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )