openssl/perl/openssl_bn.xs
Richard Levitte 95ffe86dbc Perl code patch contributed by "Kurt J. Pires" <kjpires@iat.com>
His own words are:

The patch adds no new functionality (other than a simple test package)
to the libraries, but it allows them to be compiled with Perl5.6.0.
It has only been tested under "Red Hat Linux release 7.0 (Guinness)"
with the unpatched verion of OpenSSL 0.9.6 released last September.
2001-02-19 09:29:53 +00:00

593 lines
10 KiB
Text

#include "openssl.h"
int sv_to_BIGNUM(var,arg,name)
BIGNUM **var;
SV *arg;
char *name;
{
int ret=1;
if (sv_derived_from(arg,"OpenSSL::BN"))
{
IV tmp = SvIV((SV*)SvRV(arg));
*var = (BIGNUM *) tmp;
}
else if (SvIOK(arg)) {
SV *tmp=sv_newmortal();
*var=BN_new();
BN_set_word(*var,SvIV(arg));
sv_setref_pv(tmp,"OpenSSL::BN",(void*)*var);
}
else if (SvPOK(arg)) {
char *ptr;
STRLEN len;
SV *tmp=sv_newmortal();
*var=BN_new();
sv_setref_pv(tmp,"OpenSSL::BN", (void*)*var);
ptr=SvPV(arg,len);
SvGROW(arg,len+1);
ptr[len]='\0';
BN_dec2bn(var,ptr);
}
else
{
croak(name);
ret=0;
}
return(ret);
}
typedef struct gpc_args_st {
SV *cb;
SV *arg;
} GPC_ARGS;
static void generate_prime_callback(pos,num,arg)
int pos;
int num;
char *arg;
{
dSP ;
int i;
GPC_ARGS *a=(GPC_ARGS *)arg;
ENTER ;
SAVETMPS ;
PUSHMARK(sp);
XPUSHs(sv_2mortal(newSViv(pos)));
XPUSHs(sv_2mortal(newSViv(num)));
XPUSHs(sv_2mortal(newSVsv(a->arg)));
PUTBACK;
i=perl_call_sv(a->cb,G_DISCARD);
SPAGAIN;
PUTBACK;
FREETMPS;
LEAVE;
}
MODULE = OpenSSL::BN PACKAGE = OpenSSL::BN PREFIX = p5_BN_
PROTOTYPES: ENABLE
VERSIONCHECK: DISABLE
void
p5_BN_new(...)
PREINIT:
BIGNUM *bn;
SV *arg;
PPCODE:
pr_name("p5_BN_new");
EXTEND(sp,1);
PUSHs(sv_newmortal());
bn=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)bn);
void
p5_BN_dup(a)
BIGNUM *a;
PREINIT:
BIGNUM *bn;
PPCODE:
pr_name("p5_BN_dup");
EXTEND(sp,1);
PUSHs(sv_newmortal());
bn=BN_dup(a);
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)bn);
void
p5_BN_rand(bits,...)
int bits;
PREINIT:
int top=1;
int bottom=0;
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_rand");
if ((items < 1) || (items > 3))
croak("Usage: OpenSSL::BN::rand(bits[,top_bit][,bottombit]");
if (items >= 2) top=(int)SvIV(ST(0));
if (items >= 3) bottom=(int)SvIV(ST(1));
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
BN_rand(ret,bits,top,bottom);
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
void
p5_BN_bin2bn(a)
datum a;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_bin2bn");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_bin2bn(a.dptr,a.dsize,NULL);
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
void
p5_BN_bn2bin(a)
BIGNUM *a;
PREINIT:
int i;
PPCODE:
pr_name("p5_BN_bn2bin");
EXTEND(sp,1);
PUSHs(sv_newmortal());
i=BN_num_bytes(a)+2;
sv_setpvn(ST(0),"",1);
SvGROW(ST(0),i+1);
SvCUR_set(ST(0),BN_bn2bin(a,SvPV_nolen(ST(0))));
void
p5_BN_mpi2bn(a)
datum a;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_mpi2bn");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_mpi2bn(a.dptr,a.dsize,NULL);
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
void
p5_BN_bn2mpi(a)
BIGNUM *a;
PREINIT:
int i;
PPCODE:
pr_name("p5_BN_bn2mpi");
EXTEND(sp,1);
PUSHs(sv_newmortal());
i=BN_bn2mpi(a,NULL);
sv_setpvn(ST(0),"",1);
SvGROW(ST(0),i+1);
SvCUR_set(ST(0),BN_bn2mpi(a,SvPV_nolen(ST(0))));
void
p5_BN_hex2bn(a)
datum a;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_hex2bn");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_hex2bn(&ret,a.dptr);
void
p5_BN_dec2bn(a)
datum a;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_dec2bn");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_dec2bn(&ret,a.dptr);
SV *
p5_BN_bn2hex(a)
BIGNUM *a;
PREINIT:
char *ptr;
int i;
CODE:
pr_name("p5_BN_bn2hex");
ptr=BN_bn2hex(a);
RETVAL=newSVpv("",0);
i=strlen(ptr);
SvGROW(RETVAL,i+1);
memcpy(SvPV_nolen(RETVAL),ptr,i+1);
SvCUR_set(RETVAL,i);
OPENSSL_free(ptr);
OUTPUT:
RETVAL
SV *
p5_BN_bn2dec(a)
BIGNUM *a;
PREINIT:
char *ptr;
int i;
CODE:
pr_name("p5_BN_bn2dec");
ptr=BN_bn2dec(a);
RETVAL=newSVpv("",0);
i=strlen(ptr);
SvGROW(RETVAL,i+1);
memcpy(SvPV_nolen(RETVAL),ptr,i+1);
SvCUR_set(RETVAL,i);
OPENSSL_free(ptr);
OUTPUT:
RETVAL
void
p5_BN_add(a,b)
BIGNUM *a;
BIGNUM *b;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_add");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_add(ret,a,b);
void
p5_BN_sub(a,b)
BIGNUM *a;
BIGNUM *b;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_sub");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_sub(ret,a,b);
void
p5_BN_mul(a,b)
BIGNUM *a;
BIGNUM *b;
PREINIT:
static BN_CTX *ctx=NULL;
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_mul");
if (ctx == NULL) ctx=BN_CTX_new();
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_mul(ret,a,b,ctx);
void
p5_BN_div(a,b)
BIGNUM *a;
BIGNUM *b;
PREINIT:
static BN_CTX *ctx=NULL;
BIGNUM *div,*mod;
PPCODE:
pr_name("p5_BN_div");
if (ctx == NULL) ctx=BN_CTX_new();
EXTEND(sp,2);
PUSHs(sv_newmortal());
PUSHs(sv_newmortal());
div=BN_new();
mod=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)div);
sv_setref_pv(ST(1), "OpenSSL::BN", (void*)mod);
BN_div(div,mod,a,b,ctx);
void
p5_BN_mod(a,b)
BIGNUM *a;
BIGNUM *b;
PREINIT:
static BN_CTX *ctx=NULL;
BIGNUM *rem;
PPCODE:
pr_name("p5_BN_mod");
if (ctx == NULL) ctx=BN_CTX_new();
EXTEND(sp,1);
PUSHs(sv_newmortal());
rem=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)rem);
BN_mod(rem,a,b,ctx);
void
p5_BN_exp(a,p)
BIGNUM *a;
BIGNUM *p;
PREINIT:
BIGNUM *ret;
static BN_CTX *ctx=NULL;
PPCODE:
pr_name("p5_BN_exp");
if (ctx == NULL) ctx=BN_CTX_new();
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_exp(ret,a,p,ctx);
void
p5_BN_mod_mul(a,b,c)
BIGNUM *a;
BIGNUM *b;
BIGNUM *c;
PREINIT:
static BN_CTX *ctx=NULL;
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_mod_mul");
if (ctx == NULL) ctx=BN_CTX_new();
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_mod_mul(ret,a,b,c,ctx);
void
p5_BN_mod_exp(a,b,c)
BIGNUM *a;
BIGNUM *b;
BIGNUM *c;
PREINIT:
static BN_CTX *ctx=NULL;
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_mod_exp");
if (ctx == NULL) ctx=BN_CTX_new();
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_mod_exp(ret,a,b,c,ctx);
void
p5_BN_generate_prime(...)
PREINIT:
int bits=512;
int strong=0;
BIGNUM *ret=NULL;
SV *callback=NULL;
SV *cb_arg=NULL;
GPC_ARGS arg;
dSP;
PPCODE:
pr_name("p5_BN_generate_prime");
if ((items < 0) || (items > 4))
croak("Usage: OpenSSL::BN::generate_prime(a[,strong][,callback][,cb_arg]");
if (items >= 1) bits=(int)SvIV(ST(0));
if (items >= 2) strong=(int)SvIV(ST(1));
if (items >= 3) callback=ST(2);
if (items == 4) cb_arg=ST(3);
if (callback == NULL)
ret=BN_generate_prime(ret,bits,strong,NULL,NULL,NULL,NULL);
else
{
arg.cb=callback;
arg.arg=cb_arg;
ret=BN_generate_prime(ret,bits,strong,NULL,NULL,
generate_prime_callback,(char *)&arg);
}
SPAGAIN;
sp-=items; /* a bit evil that I do this */
EXTEND(sp,1);
PUSHs(sv_newmortal());
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
void
p5_BN_is_prime(p,...)
BIGNUM *p;
PREINIT:
int nchecks=5,ret;
SV *callback=NULL;
SV *cb_arg=NULL;
GPC_ARGS arg;
dSP;
static BN_CTX *ctx=NULL;
PPCODE:
pr_name("p5_BN_is_prime");
if ((items < 1) || (items > 4))
croak("Usage: OpenSSL::BN::is_prime(a[,ncheck][,callback][,callback_arg]");
if (ctx == NULL) ctx=BN_CTX_new();
if (items >= 2) nchecks=(int)SvIV(ST(1));
if (items >= 3) callback=ST(2);
if (items >= 4) cb_arg=ST(3);
arg.arg=cb_arg;
if (callback == NULL)
ret=BN_is_prime(p,nchecks,NULL,ctx,NULL);
else
{
arg.cb=callback;
arg.arg=cb_arg;
ret=BN_is_prime(p,nchecks,generate_prime_callback,
ctx,(char *)&arg);
}
SPAGAIN;
sp-=items; /* a bit evil */
PUSHs(sv_2mortal(newSViv(ret)));
int
p5_BN_num_bits(a)
BIGNUM *a;
CODE:
pr_name("p5_BN_num_bits");
RETVAL=BN_num_bits(a);
OUTPUT:
RETVAL
int
p5_BN_cmp(a,b)
BIGNUM *a;
BIGNUM *b;
CODE:
pr_name("p5_BN_cmp");
RETVAL=BN_cmp(a,b);
OUTPUT:
RETVAL
int
p5_BN_ucmp(a,b)
BIGNUM *a;
BIGNUM *b;
CODE:
pr_name("p5_BN_ucmp");
RETVAL=BN_ucmp(a,b);
OUTPUT:
RETVAL
int
p5_BN_is_bit_set(a,b)
BIGNUM *a;
int b;
CODE:
pr_name("p5_BN_is_bit_set");
RETVAL=BN_is_bit_set(a,b);
OUTPUT:
RETVAL
void
p5_BN_set_bit(a,b)
BIGNUM *a;
int b;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_set_bit");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_dup(a);
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_set_bit(ret,b);
void
p5_BN_clear_bit(a,b)
BIGNUM *a;
int b;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_clear_bit");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_dup(a);
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_clear_bit(ret,b);
void
p5_BN_lshift(a,b)
BIGNUM *a;
int b;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_lshift");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
if (b == 1)
BN_lshift1(ret,a);
else
BN_lshift(ret,a,b);
void
p5_BN_rshift(a,b)
BIGNUM *a;
int b;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_rshift");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
if (b == 1)
BN_rshift1(ret,a);
else
BN_rshift(ret,a,b);
void
p5_BN_mask_bits(a,b)
BIGNUM *a;
int b;
PREINIT:
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_mask_bits");
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_dup(a);
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_mask_bits(ret,b);
void
p5_BN_clear(a)
BIGNUM *a;
PPCODE:
pr_name("p5_BN_clear");
BN_clear(a);
void
p5_BN_gcd(a,b)
BIGNUM *a;
BIGNUM *b;
PREINIT:
static BN_CTX *ctx=NULL;
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_gcd");
if (ctx == NULL) ctx=BN_CTX_new();
EXTEND(sp,1);
PUSHs(sv_newmortal());
ret=BN_new();
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
BN_gcd(ret,a,b,ctx);
void
p5_BN_mod_inverse(a,mod)
BIGNUM *a;
BIGNUM *mod;
PREINIT:
static BN_CTX *ctx=NULL;
BIGNUM *ret;
PPCODE:
pr_name("p5_BN_mod_inverse");
if (ctx == NULL) ctx=BN_CTX_new();
ret=BN_mod_inverse(ret,a,mod,ctx);
EXTEND(sp,1);
PUSHs(sv_newmortal());
sv_setref_pv(ST(0), "OpenSSL::BN", (void*)ret);
void
p5_BN_DESTROY(bn)
BIGNUM *bn
CODE:
pr_name("p5_BN_DESTROY");
BN_free(bn);