Codebase list libcryptx-perl / v0.020 lib / CryptX_Digest.xs.inc
v0.020

Tree @v0.020 (Download .tar.gz)

CryptX_Digest.xs.inc @v0.020

dd9a707
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4adeeb6
bf45748
4adeeb6
dd9a707
 
bf45748
dd9a707
ce15e24
bf45748
 
4adeeb6
b016410
4adeeb6
 
bf45748
4adeeb6
dd9a707
 
 
 
 
 
 
 
 
ce15e24
dd9a707
 
0debb3d
dd9a707
 
 
 
 
 
 
 
 
347b6ad
 
dd9a707
 
ce15e24
dd9a707
 
ce15e24
dd9a707
 
 
0debb3d
dd9a707
 
 
 
 
 
 
 
 
 
 
 
 
ce15e24
dd9a707
 
ce15e24
dd9a707
 
 
0debb3d
dd9a707
 
 
 
5784586
 
 
 
 
 
 
 
 
ce15e24
5784586
 
ce15e24
5784586
 
 
 
 
 
 
 
dd9a707
 
 
 
 
 
 
 
 
 
 
 
 
 
ce15e24
dd9a707
 
ce15e24
dd9a707
 
 
 
 
 
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(sv_2mortal(newSVsv(ST(0)))); /* XXX-HACK returning '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