libsec: refactor asn1 encoding of digest for rsa signatures, fix memory leak in ecverify

This commit is contained in:
cinap_lenrek 2016-02-03 04:18:54 +01:00
parent cc8e8c978c
commit 78808ca314
3 changed files with 58 additions and 36 deletions

View file

@ -476,6 +476,7 @@ ecdsaverify(ECdomain *dom, ECpub *pub, uchar *dig, int len, mpint *r, mpint *s)
mpmod(R.x, dom->n, t); mpmod(R.x, dom->n, t);
ret = mpcmp(r, t) == 0; ret = mpcmp(r, t) == 0;
} }
mpfree(E);
mpfree(t); mpfree(t);
mpfree(u1); mpfree(u1);
mpfree(u2); mpfree(u2);

View file

@ -432,7 +432,7 @@ static void freeints(Ints* b);
/* x509.c */ /* x509.c */
extern mpint* pkcs1padbuf(uchar *buf, int len, mpint *modulus); extern mpint* pkcs1padbuf(uchar *buf, int len, mpint *modulus);
extern int X509encodesignature_sha256(uchar digest[SHA2_256dlen], uchar *buf, int len); extern int asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest, uchar *buf, int len);
//================= client/server ======================== //================= client/server ========================
@ -1298,13 +1298,18 @@ tlsClient2(int ctl, int hand,
m.u.certificateVerify.sigalg = 0x0401; /* RSA SHA256 */ m.u.certificateVerify.sigalg = 0x0401; /* RSA SHA256 */
sha2_256(nil, 0, digest, &c->handhash.sha2_256); sha2_256(nil, 0, digest, &c->handhash.sha2_256);
buflen = X509encodesignature_sha256(digest, buf, sizeof(buf)); buflen = asn1encodedigest(sha2_256, digest, buf, sizeof(buf));
} else { } else {
md5(nil, 0, buf, &c->handhash.md5); md5(nil, 0, buf, &c->handhash.md5);
sha1(nil, 0, buf+MD5dlen, &c->handhash.sha1); sha1(nil, 0, buf+MD5dlen, &c->handhash.sha1);
buflen = MD5dlen+SHA1dlen; buflen = MD5dlen+SHA1dlen;
} }
c->handhash = hsave; c->handhash = hsave;
if(buflen <= 0){
tlsError(c, EInternalError, "can't encode handshake hashes");
goto Err;
}
paddedHashes = pkcs1padbuf(buf, buflen, c->sec->rsapub->n); paddedHashes = pkcs1padbuf(buf, buflen, c->sec->rsapub->n);
signedMP = factotum_rsa_decrypt(c->sec->rpc, paddedHashes); signedMP = factotum_rsa_decrypt(c->sec->rpc, paddedHashes);

View file

@ -1896,7 +1896,7 @@ errret:
} }
/* /*
* RSAPublickKey :: SEQUENCE { * RSAPublickKey ::= SEQUENCE {
* modulus INTEGER, * modulus INTEGER,
* publicExponent INTEGER * publicExponent INTEGER
* } * }
@ -2552,30 +2552,52 @@ mkDN(char *dn)
return mkseq(el); return mkseq(el);
} }
int /*
X509encodesignature_sha256(uchar digest[SHA2_256dlen], uchar *buf, int len) * DigestInfo ::= SEQUENCE {
* digestAlgorithm AlgorithmIdentifier,
* digest OCTET STRING }
*/
static Bytes*
encode_digest(DigestAlg *da, uchar *digest)
{ {
Bytes *sigbytes; Bytes *ans;
Elem sig;
int err; int err;
Elem e;
sig = mkseq( e = mkseq(
mkel(mkalg(ALG_sha256), mkel(mkalg(da->alg),
mkel(mkoctet(digest, SHA2_256dlen), mkel(mkoctet(digest, da->len),
nil))); nil)));
err = encode(sig, &sigbytes); err = encode(e, &ans);
freevalfields(&sig.val); freevalfields(&e.val);
if(err != ASN_OK) if(err != ASN_OK)
return -1; return nil;
if(len < sigbytes->len){
freebytes(sigbytes);
return -1;
}
len = sigbytes->len;
memmove(buf, sigbytes->data, len);
freebytes(sigbytes);
return len; return ans;
}
int
asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest, uchar *buf, int len)
{
Bytes *bytes;
DigestAlg **dp;
for(dp = digestalg; *dp != nil; dp++){
if((*dp)->fun != fun)
continue;
bytes = encode_digest(*dp, digest);
if(bytes == nil)
break;
if(bytes->len > len){
freebytes(bytes);
break;
}
len = bytes->len;
memmove(buf, bytes->data, len);
freebytes(bytes);
return len;
}
return -1;
} }
uchar* uchar*
@ -2612,21 +2634,18 @@ X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen)
freebytes(pkbytes); freebytes(pkbytes);
if(encode(e, &certinfobytes) != ASN_OK) if(encode(e, &certinfobytes) != ASN_OK)
goto errret; goto errret;
da = digestalg[sigalg]; da = digestalg[sigalg];
(*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0); (*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
freebytes(certinfobytes); freebytes(certinfobytes);
certinfo = e; certinfo = e;
e = mkseq(
mkel(mkalg(da->alg), sigbytes = encode_digest(da, digest);
mkel(mkoctet(digest, da->len), if(sigbytes == nil)
nil)));
if(encode(e, &sigbytes) != ASN_OK){
freevalfields(&certinfo.val);
goto errret; goto errret;
}
freevalfields(&e.val);
pkcs1 = pkcs1pad(sigbytes, pk->n); pkcs1 = pkcs1pad(sigbytes, pk->n);
freebytes(sigbytes); freebytes(sigbytes);
rsadecrypt(priv, pkcs1, pkcs1); rsadecrypt(priv, pkcs1, pkcs1);
buflen = mptobe(pkcs1, nil, 0, &buf); buflen = mptobe(pkcs1, nil, 0, &buf);
mpfree(pkcs1); mpfree(pkcs1);
@ -2682,16 +2701,13 @@ X509rsareq(RSApriv *priv, char *subj, int *certlen)
(*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0); (*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
freebytes(certinfobytes); freebytes(certinfobytes);
certinfo = e; certinfo = e;
e = mkseq(
mkel(mkalg(da->alg), sigbytes = encode_digest(da, digest);
mkel(mkoctet(digest, da->len), if(sigbytes == nil)
nil)));
if(encode(e, &sigbytes) != ASN_OK){
freevalfields(&certinfo.val);
goto errret; goto errret;
}
pkcs1 = pkcs1pad(sigbytes, pk->n); pkcs1 = pkcs1pad(sigbytes, pk->n);
freebytes(sigbytes); freebytes(sigbytes);
rsadecrypt(priv, pkcs1, pkcs1); rsadecrypt(priv, pkcs1, pkcs1);
buflen = mptobe(pkcs1, nil, 0, &buf); buflen = mptobe(pkcs1, nil, 0, &buf);
mpfree(pkcs1); mpfree(pkcs1);