Alt-Digest-MD5-OpenSSL

 view release on metacpan or  search on metacpan

MD5.xs  view on Meta::CPAN

}

static int md5_update(MD5_COMPAT_CTX *c, const void *data, size_t len) {
    c->Nl += (unsigned int)len;
    return EVP_DigestUpdate(c->ctx, data, len);
}

static int md5_final(unsigned char *md, MD5_COMPAT_CTX *c) {
    unsigned int len;
    int ret = EVP_DigestFinal_ex(c->ctx, md, &len);
    EVP_MD_CTX_free(c->ctx);
    c->ctx = NULL;
    return ret;
}

static void md5_free(MD5_COMPAT_CTX *c) {
    if (c->ctx != NULL) {
        EVP_MD_CTX_free(c->ctx);
        c->ctx = NULL;
    }
}

#else
/* OpenSSL 1.x uses legacy MD5 API */
typedef MD5_CTX MD5_COMPAT_CTX;

static int md5_init(MD5_COMPAT_CTX *c) {
    return MD5_Init(c);
}

static int md5_update(MD5_COMPAT_CTX *c, const void *data, size_t len) {
    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)



( run in 1.157 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )