ref: 7975eec3e602fd5bc3e93c78f4166259190f2fe9
dir: /libkeyring/rsaalg.c/
#include <lib9.h>
#include <kernel.h>
#include <isa.h>
#include "interp.h"
#include "../libinterp/keyringif.h"
#include "mp.h"
#include "libsec.h"
#include "keys.h"
static char* pkattr[] = { "n", "ek", nil };
static char* skattr[] = { "n", "ek", "!dk", "!p", "!q", "!kp", "!kq", "!c2", nil };
static char* sigattr[] = { "val", nil };
static void*
rsa_str2sk(char *str, char **strp)
{
RSApriv *rsa;
char *p;
rsa = rsaprivalloc();
rsa->pub.n = base64tobig(str, &p);
rsa->pub.ek = base64tobig(p, &p);
rsa->dk = base64tobig(p, &p);
rsa->p = base64tobig(p, &p);
rsa->q = base64tobig(p, &p);
rsa->kp = base64tobig(p, &p);
rsa->kq = base64tobig(p, &p);
rsa->c2 = base64tobig(p, &p);
if(strp)
*strp = p;
if(rsa->pub.n == nil || rsa->pub.ek == nil ||
rsa->dk == nil || rsa->p == nil || rsa->q == nil ||
rsa->kp == nil || rsa->kq == nil || rsa->c2 == nil){
rsaprivfree(rsa);
return nil;
}
return rsa;
}
static void*
rsa_str2pk(char *str, char **strp)
{
RSApub *rsa;
char *p;
rsa = rsapuballoc();
rsa->n = base64tobig(str, &p);
rsa->ek = base64tobig(p, &p);
if(strp)
*strp = p;
if(rsa->n == nil || rsa->ek == nil){
rsapubfree(rsa);
return nil;
}
return rsa;
}
static void*
rsa_str2sig(char *str, char **strp)
{
mpint *rsa;
char *p;
rsa = base64tobig(str, &p);
if(rsa == nil)
return nil;
if(strp)
*strp = p;
return rsa;
}
static int
rsa_sk2str(void *vrsa, char *buf, int len)
{
RSApriv *rsa;
char *cp, *ep;
rsa = vrsa;
ep = buf + len - 1;
cp = buf;
cp += snprint(cp, ep - cp, "%U\n", rsa->pub.n);
cp += snprint(cp, ep - cp, "%U\n", rsa->pub.ek);
cp += snprint(cp, ep - cp, "%U\n", rsa->dk);
cp += snprint(cp, ep - cp, "%U\n", rsa->p);
cp += snprint(cp, ep - cp, "%U\n", rsa->q);
cp += snprint(cp, ep - cp, "%U\n", rsa->kp);
cp += snprint(cp, ep - cp, "%U\n", rsa->kq);
cp += snprint(cp, ep - cp, "%U\n", rsa->c2);
*cp = 0;
return cp - buf;
}
static int
rsa_pk2str(void *vrsa, char *buf, int len)
{
RSApub *rsa;
char *cp, *ep;
rsa = vrsa;
ep = buf + len - 1;
cp = buf;
cp += snprint(cp, ep - cp, "%U\n", rsa->n);
cp += snprint(cp, ep - cp, "%U\n", rsa->ek);
*cp = 0;
return cp - buf;
}
static int
rsa_sig2str(void *vrsa, char *buf, int len)
{
mpint *rsa;
char *cp, *ep;
rsa = vrsa;
ep = buf + len - 1;
cp = buf;
cp += snprint(cp, ep - cp, "%U\n", rsa);
*cp = 0;
return cp - buf;
}
static void*
rsa_sk2pk(void *vs)
{
return rsaprivtopub((RSApriv*)vs);
}
/* generate an rsa secret key */
static void*
rsa_gen(int len)
{
RSApriv *key;
for(;;){
key = rsagen(len, 6, 0);
if(mpsignif(key->pub.n) == len)
return key;
rsaprivfree(key);
}
}
/* generate an rsa secret key with same params as a public key */
static void*
rsa_genfrompk(void *vpub)
{
RSApub *pub;
pub = vpub;
return rsagen(mpsignif(pub->n), mpsignif(pub->ek), 0);
}
static void*
rsa_sign(mpint* m, void *key)
{
return rsadecrypt((RSApriv*)key, m, nil);
}
static int
rsa_verify(mpint* m, void *sig, void *key)
{
mpint *t;
int r;
t = rsaencrypt((RSApub*)key, (mpint*)sig, nil);
r = mpcmp(t, m) == 0;
mpfree(t);
return r;
}
static void
rsa_freepriv(void *a)
{
rsaprivfree((RSApriv*)a);
}
static void
rsa_freepub(void *a)
{
rsapubfree((RSApub*)a);
}
static void
rsa_freesig(void *a)
{
mpfree(a);
}
SigAlgVec*
rsainit(void)
{
SigAlgVec *vec;
vec = malloc(sizeof(SigAlgVec));
if(vec == nil)
return nil;
vec->name = "rsa";
vec->pkattr = pkattr;
vec->skattr = skattr;
vec->sigattr = sigattr;
vec->str2sk = rsa_str2sk;
vec->str2pk = rsa_str2pk;
vec->str2sig = rsa_str2sig;
vec->sk2str = rsa_sk2str;
vec->pk2str = rsa_pk2str;
vec->sig2str = rsa_sig2str;
vec->sk2pk = rsa_sk2pk;
vec->gensk = rsa_gen;
vec->genskfrompk = rsa_genfrompk;
vec->sign = rsa_sign;
vec->verify = rsa_verify;
vec->skfree = rsa_freepriv;
vec->pkfree = rsa_freepub;
vec->sigfree = rsa_freesig;
return vec;
}