libcryptx-perl/inc/CryptX_Digest.xs.inc

170 lines
4.2 KiB
C++

MODULE = CryptX PACKAGE = Crypt::Digest
Crypt::Digest
_new(digest_name)
char * digest_name
CODE:
{
int rv;
int id;
id = 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->id = id;
RETVAL->desc = &hash_descriptor[id];
rv = RETVAL->desc->init(&RETVAL->state);
if(rv!=CRYPT_OK) croak("FATAL: digest setup failed: %s", error_to_string(rv));
}
OUTPUT:
RETVAL
void
DESTROY(self)
Crypt::Digest self
CODE:
Safefree(self);
void
reset(self)
Crypt::Digest self
CODE:
{
int rv;
rv = self->desc->init(&self->state);
if (rv != CRYPT_OK) croak("FATAL: digest init failed: %s", error_to_string(rv));
}
Crypt::Digest
clone(self)
Crypt::Digest self
CODE:
Newz(0, RETVAL, 1, struct digest_struct);
Copy(&self->state, &RETVAL->state, 1, struct digest_struct);
OUTPUT:
RETVAL
void
add(Crypt::Digest self, ...)
PPCODE:
{
STRLEN inlen;
int rv, i;
unsigned char *in;
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(self)
Crypt::Digest self
CODE:
{
unsigned char hash[MAXBLOCKSIZE];
int rv;
rv = self->desc->done(&self->state, hash);
if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
RETVAL = newSVpvn((char *) hash, self->desc->hashsize);
}
OUTPUT:
RETVAL
SV *
hexdigest(self)
Crypt::Digest self
CODE:
{
int rv;
unsigned long i;
unsigned char hash[MAXBLOCKSIZE];
char hash_hex[MAXBLOCKSIZE*2 + 1];
rv = self->desc->done(&self->state, hash);
if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
hash_hex[0] = '\0';
for(i=0; i<self->desc->hashsize; i++)
sprintf(&hash_hex[2*i], "%02x", hash[i]);
RETVAL = newSVpvn(hash_hex, strlen(hash_hex));
}
OUTPUT:
RETVAL
SV *
b64digest(self)
Crypt::Digest self
CODE:
{
int rv;
unsigned long outlen;
unsigned char hash[MAXBLOCKSIZE];
char hash_base64[MAXBLOCKSIZE*2 + 1];
rv = self->desc->done(&self->state, hash);
if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
outlen = sizeof(hash_base64);
rv = base64_encode(hash, self->desc->hashsize, (unsigned char *)hash_base64, &outlen);
if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv));
RETVAL = newSVpvn(hash_base64, outlen);
}
OUTPUT:
RETVAL
SV *
b64udigest(self)
Crypt::Digest self
CODE:
{
int rv;
unsigned long outlen;
unsigned char hash[MAXBLOCKSIZE];
char hash_base64[MAXBLOCKSIZE*2 + 1];
rv = self->desc->done(&self->state, hash);
if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
outlen = sizeof(hash_base64);
rv = base64url_encode(hash, self->desc->hashsize, (unsigned char *)hash_base64, &outlen);
if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv));
RETVAL = newSVpvn(hash_base64, outlen);
}
OUTPUT:
RETVAL
int
_hashsize(self)
Crypt::Digest self
CODE:
RETVAL = self->desc->hashsize;
OUTPUT:
RETVAL
int
_hashsize_by_name(digest_name)
char * digest_name
CODE:
{
int rv, id;
id = find_hash(digest_name);
if(id==-1) croak("FATAL: find_digest failed for '%s'", digest_name);
rv = hash_descriptor[id].hashsize;
if (!rv) croak("FATAL: invalid hashsize for '%s'", digest_name);;
RETVAL = rv;
}
OUTPUT:
RETVAL