libcryptx-perl/inc/CryptX_Digest.xs.inc

187 lines
5.8 KiB
PHP
Raw Permalink Normal View History

2018-03-22 15:51:09 +01:00
MODULE = CryptX PACKAGE = Crypt::Digest
2018-03-22 15:54:03 +01:00
PROTOTYPES: DISABLE
2018-03-22 15:51:09 +01:00
Crypt::Digest
2018-03-22 15:54:03 +01:00
new(char * cname, char * pname = NULL)
2018-03-22 15:51:09 +01:00
CODE:
{
int rv;
int id;
2018-03-22 15:54:03 +01:00
char *digest_name = strcmp(cname, "Crypt::Digest") == 0 ? pname : cname;
2018-03-22 15:51:09 +01:00
2018-03-22 15:54:03 +01:00
id = _find_hash(digest_name);
if (id == -1) croak("FATAL: find_hash failed for '%s'", digest_name);
2018-03-22 15:51:09 +01:00
Newz(0, RETVAL, 1, struct digest_struct);
if (!RETVAL) croak("FATAL: Newz failed");
RETVAL->desc = &hash_descriptor[id];
rv = RETVAL->desc->init(&RETVAL->state);
2018-03-22 15:54:03 +01:00
if (rv != CRYPT_OK) {
Safefree(RETVAL);
croak("FATAL: digest setup failed: %s", error_to_string(rv));
}
2018-03-22 15:51:09 +01:00
}
OUTPUT:
RETVAL
void
2018-03-22 15:54:03 +01:00
DESTROY(Crypt::Digest self)
2018-03-22 15:51:09 +01:00
CODE:
Safefree(self);
void
2018-03-22 15:54:03 +01:00
reset(Crypt::Digest self)
PPCODE:
2018-03-22 15:51:09 +01:00
{
int rv;
rv = self->desc->init(&self->state);
if (rv != CRYPT_OK) croak("FATAL: digest init failed: %s", error_to_string(rv));
2018-03-22 15:54:03 +01:00
XPUSHs(ST(0)); /* return self */
2018-03-22 15:51:09 +01:00
}
Crypt::Digest
2018-03-22 15:54:03 +01:00
clone(Crypt::Digest self)
2018-03-22 15:51:09 +01:00
CODE:
Newz(0, RETVAL, 1, struct digest_struct);
2018-03-22 15:54:03 +01:00
if (!RETVAL) croak("FATAL: Newz failed");
2018-03-22 15:51:09 +01:00
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;
2018-03-22 15:54:03 +01:00
for(i = 1; i < items; i++) {
2018-03-22 15:51:09 +01:00
in = (unsigned char *)SvPVbyte(ST(i), inlen);
2018-03-22 15:54:03 +01:00
if (inlen > 0) {
2018-03-22 15:51:09 +01:00
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 *
2018-03-22 15:54:03 +01:00
digest(Crypt::Digest self)
ALIAS:
hexdigest = 1
b64digest = 2
b64udigest = 3
2018-03-22 15:51:09 +01:00
CODE:
{
int rv;
unsigned long outlen;
unsigned char hash[MAXBLOCKSIZE];
2018-03-22 15:54:03 +01:00
char out[MAXBLOCKSIZE*2];
2018-03-22 15:51:09 +01:00
rv = self->desc->done(&self->state, hash);
if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
2018-03-22 15:54:03 +01:00
outlen = sizeof(out);
if (ix == 3) {
rv = base64url_encode(hash, self->desc->hashsize, (unsigned char *)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, (unsigned char *)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, (unsigned char *)out, &outlen);
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);
}
2018-03-22 15:51:09 +01:00
}
OUTPUT:
RETVAL
SV *
2018-03-22 15:54:03 +01:00
digest_data(char * digest_name, ...)
ALIAS:
digest_data_hex = 1
digest_data_b64 = 2
digest_data_b64u = 3
2018-03-22 15:51:09 +01:00
CODE:
{
2018-03-22 15:54:03 +01:00
STRLEN inlen;
int rv, id, i;
unsigned char *in, hash[MAXBLOCKSIZE];
unsigned long len = sizeof(hash), outlen;
char out[MAXBLOCKSIZE*2];
hash_state md;
id = _find_hash(digest_name);
if (id == -1) croak("FATAL: find_digest failed for '%s'", digest_name);
/* digest_data("SHA1", $data1, $data2, $data3); */
len = hash_descriptor[id].hashsize;
rv = hash_descriptor[id].init(&md);
if (rv != CRYPT_OK) croak("FATAL: digest init failed: %s", error_to_string(rv));
for (i = 1; i < items; i++) {
in = (unsigned char *)SvPVbyte(ST(i), inlen);
if (inlen > 0) {
rv = hash_descriptor[id].process(&md, in, (unsigned long)inlen);
if (rv != CRYPT_OK) croak("FATAL: digest process failed: %s", error_to_string(rv));
}
}
rv = hash_descriptor[id].done(&md, hash);
2018-03-22 15:51:09 +01:00
if (rv != CRYPT_OK) croak("FATAL: digest done failed: %s", error_to_string(rv));
2018-03-22 15:54:03 +01:00
outlen = sizeof(out);
if (ix == 3) {
rv = base64url_encode(hash, len, (unsigned char *)out, &outlen);
if (rv != CRYPT_OK) croak("FATAL: base64url_encode failed: %s", error_to_string(rv));
RETVAL = newSVpvn((char *) out, outlen);
}
else if (ix == 2) {
rv = base64_encode(hash, len, (unsigned char *)out, &outlen);
if (rv != CRYPT_OK) croak("FATAL: base64_encode failed: %s", error_to_string(rv));
RETVAL = newSVpvn((char *) out, outlen);
}
else if (ix == 1) {
rv = _base16_encode(hash, len, (unsigned char *)out, &outlen);
if (rv != CRYPT_OK) croak("FATAL: base16_encode failed: %s", error_to_string(rv));
RETVAL = newSVpvn((char *) out, outlen);
}
else {
RETVAL = newSVpvn((char *) hash, len);
}
2018-03-22 15:51:09 +01:00
}
OUTPUT:
RETVAL
int
2018-03-22 15:54:03 +01:00
hashsize(SV * param, char * extra = NULL)
2018-03-22 15:51:09 +01:00
CODE:
{
2018-03-22 15:54:03 +01:00
if (sv_isobject(param) && sv_derived_from(param, "Crypt::Digest")) {
IV tmp = SvIV((SV*)SvRV(param));
Crypt__Digest obj = INT2PTR(Crypt__Digest, tmp);
RETVAL = obj->desc->hashsize;
}
else {
char *digest_name;
int rv, id;
digest_name = SvPOK(param) && strcmp(SvPVX(param), "Crypt::Digest") ? SvPVX(param) : extra;
id = _find_hash(digest_name);
if (id == -1) croak("FATAL: find_hash failed for '%s'", digest_name);
rv = hash_descriptor[id].hashsize;
if (!rv) croak("FATAL: invalid hashsize for '%s'", digest_name);;
RETVAL = rv;
}
2018-03-22 15:51:09 +01:00
}
OUTPUT:
RETVAL