CryptX
view release on metacpan or search on metacpan
inc/CryptX_Digest.xs.inc view on Meta::CPAN
MODULE = CryptX PACKAGE = Crypt::Digest
PROTOTYPES: DISABLE
Crypt::Digest
new(char * cname, char * pname = NULL)
CODE:
{
int rv;
int id;
char *digest_name = strcmp(cname, "Crypt::Digest") == 0 ? pname : cname;
id = cryptx_internal_find_hash(digest_name);
if (id == -1) croak("FATAL: find_hash failed for '%s'", digest_name);
Newz(0, RETVAL, 1, struct digest_struct);
if (!RETVAL) croak("FATAL: Newz failed");
RETVAL->desc = &hash_descriptor[id];
rv = RETVAL->desc->init(&RETVAL->state);
if (rv != CRYPT_OK) {
Safefree(RETVAL);
croak("FATAL: digest setup failed: %s", error_to_string(rv));
}
}
OUTPUT:
RETVAL
void
DESTROY(Crypt::Digest self)
CODE:
{
zeromem(self, sizeof(*self));
Safefree(self);
}
void
reset(Crypt::Digest self)
PPCODE:
{
int rv;
rv = self->desc->init(&self->state);
if (rv != CRYPT_OK) croak("FATAL: digest init failed: %s", error_to_string(rv));
self->finalized = 0;
XPUSHs(ST(0)); /* return self */
}
Crypt::Digest
clone(Crypt::Digest self)
CODE:
if (self->desc != NULL && cryptx_internal_noclone_hash(self->desc->name)) {
croak("FATAL: clone is not supported for given hash state");
}
Newz(0, RETVAL, 1, struct digest_struct);
if (!RETVAL) croak("FATAL: Newz failed");
Copy(self, RETVAL, 1, struct digest_struct);
OUTPUT:
RETVAL
void
add(Crypt::Digest self, ...)
PPCODE:
{
STRLEN inlen;
int rv, i;
unsigned char *in;
if (self->finalized) croak("FATAL: digest object already finalized");
for(i = 1; i < items; i++) {
in = (unsigned char *)SvPVbyte(ST(i), inlen);
if (inlen > 0) {
rv = self->desc->process(&self->state, in, (unsigned long)inlen);
if (rv != CRYPT_OK) croak("FATAL: digest process failed: %s", error_to_string(rv));
}
}
XPUSHs(ST(0)); /* return self */
}
SV *
digest(Crypt::Digest self)
ALIAS:
hexdigest = 1
b64digest = 2
b64udigest = 3
CODE:
{
int rv;
unsigned long outlen;
unsigned char hash[MAXBLOCKSIZE];
char out[MAXBLOCKSIZE*2+1];
if (self->finalized) croak("FATAL: digest object already finalized");
rv = self->desc->done(&self->state, hash);
if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
self->finalized = 1;
outlen = sizeof(out);
if (ix == 3) {
rv = base64url_encode(hash, self->desc->hashsize, out, &outlen);
if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv));
RETVAL = newSVpvn(out, outlen);
}
else if (ix == 2) {
rv = base64_encode(hash, self->desc->hashsize, out, &outlen);
if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv));
RETVAL = newSVpvn(out, outlen);
}
else if (ix == 1) {
rv = base16_encode(hash, self->desc->hashsize, out, &outlen, 0);
if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
RETVAL = newSVpvn(out, outlen);
}
else {
RETVAL = newSVpvn((char *) hash, self->desc->hashsize);
}
}
OUTPUT:
RETVAL
SV *
digest_data(char * digest_name, ...)
ALIAS:
( run in 1.916 second using v1.01-cache-2.11-cpan-71847e10f99 )