#include "xs/openssl.h" MODULE = Crypt::Keyczar PACKAGE = Crypt::Keyczar::DsaPublicKeyEngine Crypt::Keyczar::DsaPublicKeyEngine new(class, y, p, q, g) SV *class SV *y SV *p SV *q SV *g CODE: { DSA *dsa; STRLEN l; unsigned char *in; BIGNUM *bp, *bq, *bg, *pub_key; PERL_UNUSED_VAR(class); if ((dsa = DSA_new()) == NULL) { crypt__keyczar__util__croak_openssl(); /* NOTREACHED */ } in = (unsigned char *)SvPV(p, l); bp = BN_bin2bn((const unsigned char *)in, l, NULL); if (bp == NULL) { DSA_free(dsa); crypt__keyczar__util__croak_openssl(); /* NOTREACHED */ } in = (unsigned char *)SvPV(q, l); bq = BN_bin2bn((const unsigned char *)in, l, NULL); if (bq == NULL) { DSA_free(dsa); crypt__keyczar__util__croak_openssl(); /* NOTREACHED */ } in = (unsigned char *)SvPV(g, l); bg = BN_bin2bn((const unsigned char *)in, l, NULL); if (bg == NULL) { DSA_free(dsa); crypt__keyczar__util__croak_openssl(); /* NOTREACHED */ } DSA_set0_pqg(dsa, bp, bq, bg); in = (unsigned char *)SvPV(y, l); pub_key = BN_bin2bn((const unsigned char *)in, l, NULL); if (pub_key == NULL) { DSA_free(dsa); crypt__keyczar__util__croak_openssl(); /* NOTREACHED */ } DSA_set0_key(dsa, pub_key, NULL); Newz(0, RETVAL, 1, struct Crypt__Keyczar__DsaPublicKeyEngine_class); RETVAL->dsa = dsa; } OUTPUT: RETVAL void DESTROY(self) Crypt::Keyczar::DsaPublicKeyEngine self CODE: { if (self->dsa != NULL) { DSA_free(self->dsa); self->dsa = NULL; } Safefree(self); } SV * init(self, ...) Crypt::Keyczar::DsaPublicKeyEngine self CODE: { RETVAL = newSVpv("", 0); } OUTPUT: RETVAL void update(self, ...) Crypt::Keyczar::DsaPublicKeyEngine self CODE: { int i; SV *data; STRLEN l; unsigned char *in; if (self->message == NULL) { self->message = EVP_MD_CTX_create(); if (!EVP_DigestInit_ex(self->message, EVP_sha1(), NULL)) { croak("cannot initialize SHA1 context"); } } for (i = 1; i < items; i++) { data = ST(i); in = (unsigned char *)SvPV(data, l); if (!EVP_DigestUpdate(self->message, in, l)) { croak("cannot update SHA1 context"); } } } int verify(self, mac) Crypt::Keyczar::DsaPublicKeyEngine self SV *mac CODE: { unsigned char md[EVP_MAX_MD_SIZE]; unsigned int l = 0; int rc; STRLEN in_l; unsigned char *in; if (self->message == NULL) { RETVAL = 0; return; } EVP_DigestFinal_ex(self->message, md, &l); in = (unsigned char *)SvPV(mac, in_l); rc = DSA_verify(0, md, l, in, in_l, self->dsa); if (rc == -1) { crypt__keyczar__util__croak_openssl(); /* NOTREACHED */ } RETVAL = rc == 1; } OUTPUT: RETVAL