Alt-Digest-MD5-OpenSSL

 view release on metacpan or  search on metacpan

MD5.xs  view on Meta::CPAN

    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 )