Crypt-GCrypt

 view release on metacpan or  search on metacpan

GCrypt.xs  view on Meta::CPAN

            /* we were asked for a secure MPI, but we were given an insecure one to copy */
            RETVAL=gcry_mpi_snew(gcry_mpi_get_nbits(src));
            if (RETVAL == NULL) XSRETURN_UNDEF;
            gcry_mpi_set(RETVAL, src);
          } else {
            /* this will give us a secure MPI if a secure MPI was passed in, even if we
               also got secure => 0 ; a bit weird, but on the safe side. */
            RETVAL=gcry_mpi_copy(src);
          }
        } else {
          if (secure) {
            RETVAL=gcry_mpi_snew(0);
          } else {
            RETVAL=gcry_mpi_new(0);
          }
          if (RETVAL == NULL) XSRETURN_UNDEF;

          /* do something with the info at valix */
          if (valix >= 0) {
            switch(SvTYPE(ST(valix))) {
              case SVt_PVIV:
                /* if negative value, we have to jump through some hoops: */
                if (SvIV(ST(valix)) < 0) {
                    RETVAL=gcry_mpi_set_ui(NULL, 0);
                    gcry_mpi_sub_ui(RETVAL, RETVAL, -1*(SvIV(ST(valix))));
                } else {
                /* this can be dealt with by regular unsigned ints */
                    gcry_mpi_set_ui(RETVAL, SvIV(ST(valix)));
                }
                break;
              case SVt_PV:
                /* handle bytestrings 
                   */
                s = SvPV(ST(valix), len);
                src = NULL;
                err = gcry_mpi_scan(&src, format, s, ((format == GCRYMPI_FMT_HEX) ? 0 : len), NULL);
                if (err != 0) croak("Crypt::GCrypt::MPI::new (from string, with format %d) libgcrypt internal failure %s", format, gcry_strerror(err));
                /* FIXME: can we "eat" the head of the the input string if format is FMT_PGP or FMT_SSH ? */
                /* avoid memory leak: */
                if (secure) {
                   gcry_mpi_set(RETVAL, src);
                   gcry_mpi_release(src);
                } else {
                   gcry_mpi_release(RETVAL);
                   RETVAL = src;
                }
                break;
              default:
                croak("value argument for Crypt::GCrypt::MPI->new() must currently be either an int or another Crypt::GCrypt::MPI (%d, %d, %d)", SvTYPE(ST(valix)), valix, format);
                break;
            }
          }
        }
    OUTPUT:
        RETVAL

void
cgm_swap(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_swap(gcma, gcmb);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_set(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_set(gcma, gcmb);
        ST(0) = sv_gcma;
        XSRETURN(1);

bool
cgm_is_secure(gcm)
    Crypt_GCrypt_MPI gcm;
    CODE:
        RETVAL=gcry_mpi_get_flag(gcm, GCRYMPI_FLAG_SECURE);
    OUTPUT:
        RETVAL

int
cgm_cmp(gcma, gcmb)
    Crypt_GCrypt_MPI gcma;
    Crypt_GCrypt_MPI gcmb;
    CODE:
        RETVAL=gcry_mpi_cmp(gcma, gcmb);
    OUTPUT:
        RETVAL

Crypt_GCrypt_MPI
cgm_copy(gcm)
    Crypt_GCrypt_MPI gcm;
    CODE:
        RETVAL=gcry_mpi_copy(gcm);
    OUTPUT:
        RETVAL

void
cgm_add(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_add(gcma, gcma, gcmb);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_addm(sv_gcma, gcmb, gcmm)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    Crypt_GCrypt_MPI gcmm;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_addm(gcma, gcma, gcmb, gcmm);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_sub(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_sub(gcma, gcma, gcmb);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_subm(sv_gcma, gcmb, gcmm)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    Crypt_GCrypt_MPI gcmm;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_subm(gcma, gcma, gcmb, gcmm);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_mul(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_mul(gcma, gcma, gcmb);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_mulm(sv_gcma, gcmb, gcmm)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    Crypt_GCrypt_MPI gcmm;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_mulm(gcma, gcma, gcmb, gcmm);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_mul_2exp(sv_gcm, e)
    SV* sv_gcm;
    int e;
    PPCODE:
        Crypt_GCrypt_MPI gcm = dereference_gcm(sv_gcm);
        if (e >= 0) {
          /* this can be dealt with by regular unsigned ints */
          gcry_mpi_mul_2exp(gcm, gcm, e);
        } else {
          croak("exponent argument for Crypt::GCrypt::MPI::mul_2exp() must be an unsigned integer");
        }
        ST(0) = sv_gcm;
        XSRETURN(1);
            
void
cgm_div(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_div(gcma, NULL, gcma, gcmb, 0);
        ST(0) = sv_gcma;
        /* FIXME: should we return the remainder as well, if called in a list context? */
        XSRETURN(1);

void
cgm_mod(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_mod(gcma, gcma, gcmb);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_powm(sv_gcma, gcme, gcmm)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcme;
    Crypt_GCrypt_MPI gcmm;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_powm(gcma, gcma, gcme, gcmm);
        ST(0) = sv_gcma;
        XSRETURN(1);

void
cgm_invm(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_invm(gcma, gcma, gcmb);
        ST(0) = sv_gcma;
        /* FIXME: should we do anything with the return value (1 if invm actually exists)? */
        XSRETURN(1);

void
cgm_gcd(sv_gcma, gcmb)
    SV* sv_gcma;
    Crypt_GCrypt_MPI gcmb;
    PPCODE:
        Crypt_GCrypt_MPI gcma = dereference_gcm(sv_gcma);
        gcry_mpi_gcd(gcma, gcma, gcmb);
        ST(0) = sv_gcma;
        XSRETURN(1);

bool
cgm_mutually_prime(gcma, gcmb)
    Crypt_GCrypt_MPI gcma;
    Crypt_GCrypt_MPI gcmb;
    PREINIT:
        Crypt_GCrypt_MPI gcd;
    CODE:
        gcd = gcry_mpi_new(0);
        RETVAL=gcry_mpi_gcd(gcd, gcma, gcmb);
        gcry_mpi_release(gcd);
    OUTPUT:
        RETVAL

void
cgm_dump(sv_gcm)
    SV* sv_gcm;
    PPCODE:
        Crypt_GCrypt_MPI gcm = dereference_gcm(sv_gcm);
        gcry_mpi_dump(gcm);
        ST(0) = sv_gcm;
        XSRETURN(1);

SV *
cgm_print(gcm, format)
    Crypt_GCrypt_MPI gcm;
    int format;
    PREINIT:
        size_t size;
        unsigned char* buf;
        gcry_error_t err;
    CODE:
        /* FIXME: make format default to FMT_STD somehow (how do we not require a parameter?) */
        err = gcry_mpi_print(format, NULL, 0, &size,  gcm);
        if (err != 0) croak("GCrypt::MPI::print start: %s", gcry_strerror(err));
        /* FMT_HEX asks for an extra byte for the null char, but perl allocates that
           already, so we treat that case special */
        RETVAL = newSVpv("", ((format == GCRYMPI_FMT_HEX) ? size-1 : size));
        buf = (unsigned char*) SvPV_nolen(RETVAL);
        err = gcry_mpi_print(format, buf, size, &size,  gcm);
        if (err != 0) croak("GCrypt::MPI::print finish: %s", gcry_strerror(err));
    OUTPUT:
        RETVAL

void
cgm_DESTROY(gmpi)
    Crypt_GCrypt_MPI gmpi;
    CODE:
        gcry_mpi_release(gmpi);
        gmpi = NULL;



( run in 2.571 seconds using v1.01-cache-2.11-cpan-71847e10f99 )