int rsaverify(RSApub *key, DigestAlg *hash, uchar *digest, uint dlen, uchar *sig, uint siglen) { uchar asn1[512], *buf; int n, len, pad; mpint *m, *mm, *s; /* * Create ASN.1 */ n = mkasn1(asn1, hash, digest, dlen); /* * Create number to sign. */ len = (mpsignif(key->n)+7)/8 - 1; if(len < n+2) { werrstr("rsa key too short"); return -1; } pad = len - (n+2); if(siglen < len) { werrstr("signature buffer too short"); return -1; } buf = malloc(len); if(buf == nil) return -1; buf[0] = 0x01; memset(buf+1, 0xFF, pad); buf[1+pad] = 0x00; memmove(buf+1+pad+1, asn1, n); m = betomp(buf, len, nil); free(buf); if(m == nil) return -1; /* * Extract plaintext of signature. */ s = betomp(sig, siglen, nil); if(s == nil) return -1; mm = rsaencrypt(key, s, nil); mpfree(s); if(mm == nil) return -1; if(mpcmp(m, mm) != 0) { werrstr("signature did not verify"); mpfree(mm); mpfree(m); return -1; } mpfree(mm); mpfree(m); return 0; }
void ecdsasign(ECdomain *dom, ECpriv *priv, uchar *dig, int len, mpint *r, mpint *s) { ECpriv tmp; mpint *E, *t; tmp.x = mpnew(0); tmp.y = mpnew(0); tmp.d = mpnew(0); E = betomp(dig, len, nil); t = mpnew(0); if(mpsignif(dom->n) < 8*len) mpright(E, 8*len - mpsignif(dom->n), E); for(;;){ ecgen(dom, &tmp); mpmod(tmp.x, dom->n, r); if(mpcmp(r, mpzero) == 0) continue; mpmul(r, priv->d, s); mpadd(E, s, s); mpinvert(tmp.d, dom->n, t); mpmul(s, t, s); mpmod(s, dom->n, s); if(mpcmp(s, mpzero) != 0) break; } mpfree(t); mpfree(E); mpfree(tmp.x); mpfree(tmp.y); mpfree(tmp.d); }
int rsasign(RSApriv *key, DigestAlg *hash, uchar *digest, uint dlen, uchar *sig, uint siglen) { uchar asn1[64], *buf; int n, len, pad; mpint *m, *s; /* * Create ASN.1 */ n = mkasn1(asn1, hash, digest, dlen); /* * Create number to sign. */ len = (mpsignif(key->pub.n)+7)/8 - 1; if(len < n+2) { werrstr("rsa key too short"); return -1; } pad = len - (n+2); if(siglen < len) { werrstr("signature buffer too short"); return -1; } buf = malloc(len); if(buf == nil) return -1; buf[0] = 0x01; memset(buf+1, 0xFF, pad); buf[1+pad] = 0x00; memmove(buf+1+pad+1, asn1, n); m = betomp(buf, len, nil); free(buf); if(m == nil) return -1; /* * Sign it. */ s = rsadecrypt(key, m, nil); mpfree(m); if(s == nil) return -1; mptoberjust(s, sig, len+1); mpfree(s); return len+1; }
int ecdsaverify(ECdomain *dom, ECpub *pub, uchar *dig, int len, mpint *r, mpint *s) { mpint *E, *t, *u1, *u2; ECpoint R, S; int ret; if(mpcmp(r, mpone) < 0 || mpcmp(s, mpone) < 0 || mpcmp(r, dom->n) >= 0 || mpcmp(r, dom->n) >= 0) return 0; E = betomp(dig, len, nil); if(mpsignif(dom->n) < 8*len) mpright(E, 8*len - mpsignif(dom->n), E); t = mpnew(0); u1 = mpnew(0); u2 = mpnew(0); R.x = mpnew(0); R.y = mpnew(0); S.x = mpnew(0); S.y = mpnew(0); mpinvert(s, dom->n, t); mpmul(E, t, u1); mpmod(u1, dom->n, u1); mpmul(r, t, u2); mpmod(u2, dom->n, u2); ecmul(dom, dom->G, u1, &R); ecmul(dom, pub, u2, &S); ecadd(dom, &R, &S, &R); ret = 0; if(!R.inf){ mpmod(R.x, dom->n, t); ret = mpcmp(r, t) == 0; } mpfree(t); mpfree(u1); mpfree(u2); mpfree(R.x); mpfree(R.y); mpfree(S.x); mpfree(S.y); return ret; }
void base58enc(uchar *src, char *dst, int len) { mpint *n, *r, *b; char *sdst, t; sdst = dst; n = betomp(src, len, nil); b = uitomp(58, nil); r = mpnew(0); while(mpcmp(n, mpzero) != 0){ mpdiv(n, b, n, r); *dst++ = code[mptoui(r)]; } for(; *src == 0; src++) *dst++ = code[0]; dst--; while(dst > sdst){ t = *sdst; *sdst++ = *dst; *dst-- = t; } }
int verifysigner(uchar *sign, int len, uchar *data, ulong ndata) { Get sig; int alg; ulong issued, expires, now; int footprint, r, n; uchar buf[128], digest[SHA1dlen]; DigestState *ds; volatile struct {mpint* b;} b; volatile struct {mpint* s;} s; SigAlgVec *sa; Signerkey *key; Skeyset *sigs; /* alg[1] issued[4] expires[4] footprint[2] signer[n] sig[m] */ sigs = up->env->sigs; if(sigs == nil) return 1; /* not enforcing signed modules */ sig.p = sign; sig.ep = sign+len; alg = vc(&sig); if(alg != 2) return 0; /* we do only SHA1/RSA */ sa = findsigalg("rsa"); if(sa == nil) return 0; if(vs(buf, sizeof(buf), &sig, 4) < 0) return 0; now = osusectime()/1000000; issued = G32(buf); if(vs(buf, sizeof(buf), &sig, 4) < 0) return 0; if(issued != 0 && now < issued) return 0; expires = G32(buf); if(expires != 0 && now >= expires) return 0; footprint = vc(&sig) << 8; footprint |= vc(&sig); if(footprint < 0) return 0; r = 0; b.b = nil; s.s = nil; qlock(&sigs->l); if(waserror()) goto out; if((n = vs(buf, sizeof(buf)-NUMSIZE-1, &sig, -1)) < 0) /* owner */ goto out; buf[n] = 0; key = findsignerkey(sigs, sa->name, footprint, (char*)buf); if(key == nil) goto out; n += snprint((char*)buf+n, NUMSIZE, " %lud", expires); ds = sha1(buf, n, nil, nil); sha1(data, ndata, digest, ds); b.b = betomp(digest, SHA1dlen, nil); if(b.b == nil) goto out; s.s = betomp(sig.p, sig.ep-sig.p, nil); if(s.s == nil) goto out; r = (*sa->verify)(b.b, s.s, key->pk); out: qunlock(&sigs->l); if(b.b != nil) mpfree(b.b); if(s.s != nil) mpfree(s.s); return r; }