Changeset f38cfcc


Ignore:
Timestamp:
Jan 24, 2016 7:02:13 PM (5 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
ed9d403
Parents:
649d712
Message:

SigUtil?: Enhance ASN.1 parser/generator to support
signatures up to 64K, needed for ElG
Log and javadoc tweaks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • core/java/src/net/i2p/crypto/SigUtil.java

    r649d712 rf38cfcc  
    142142            return fromJavaKey(k, type);
    143143        }
    144         throw new IllegalArgumentException("Unknown type");
     144        throw new IllegalArgumentException("Unknown type: " + pk.getClass());
    145145    }
    146146
     
    162162                return fromJavaKey((RSAPublicKey) pk, type);
    163163            default:
    164                 throw new IllegalArgumentException();
     164                throw new IllegalArgumentException("Unknown type: " + type);
    165165        }
    166166    }
     
    210210            return fromJavaKey(k, type);
    211211        }
    212         throw new IllegalArgumentException("Unknown type");
     212        throw new IllegalArgumentException("Unknown type: " + pk.getClass());
    213213    }
    214214
     
    230230                return fromJavaKey((RSAPrivateKey) pk, type);
    231231            default:
    232                 throw new IllegalArgumentException();
     232                throw new IllegalArgumentException("Unknown type: " + type);
    233233        }
    234234    }
     
    662662     *  r and s are always non-negative.
    663663     *
    664      *  Only supports sigs up to about 252 bytes. See code to fix BER encoding for this before you
     664     *  Only supports sigs up to about 65530 bytes. See code to fix BER encoding for this before you
    665665     *  add a SigType with bigger signatures.
    666666     *
     
    670670     */
    671671    public static byte[] sigBytesToASN1(BigInteger r, BigInteger s) {
     672        int extra = 4;
    672673        byte[] rb = r.toByteArray();
    673         if (rb.length > 127)
    674             throw new IllegalArgumentException("FIXME R length > 127");
     674        if (rb.length > 127) {
     675            extra++;
     676            if (rb.length > 255)
     677                extra++;
     678        }
    675679        byte[] sb = s.toByteArray();
    676         if (sb.length > 127)
    677             throw new IllegalArgumentException("FIXME S length > 127");
    678         int seqlen = rb.length + sb.length + 4;
    679         if (seqlen > 255)
    680             throw new IllegalArgumentException("FIXME seq length > 255");
     680        if (sb.length > 127) {
     681            extra++;
     682            if (sb.length > 255)
     683                extra++;
     684        }
     685        int seqlen = rb.length + sb.length + extra;
    681686        int totlen = seqlen + 2;
    682         if (seqlen > 127)
     687        if (seqlen > 127) {
    683688            totlen++;
     689            if (seqlen > 255)
     690                totlen++;
     691        }
    684692        byte[] rv = new byte[totlen];
    685693        int idx = 0;
    686694
    687695        rv[idx++] = 0x30;
    688         if (seqlen > 127)
    689             rv[idx++] =(byte) 0x81;
    690         rv[idx++] = (byte) seqlen;
     696        idx = intToASN1(rv, idx, seqlen);
    691697
    692698        rv[idx++] = 0x02;
    693         rv[idx++] = (byte) rb.length;
     699        idx = intToASN1(rv, idx, rb.length);
    694700        System.arraycopy(rb, 0, rv, idx, rb.length);
    695701        idx += rb.length;
    696702
    697703        rv[idx++] = 0x02;
    698         rv[idx++] = (byte) sb.length;
     704        idx = intToASN1(rv, idx, sb.length);
    699705        System.arraycopy(sb, 0, rv, idx, sb.length);
    700706
     
    704710
    705711    /**
     712     *  Output an length or integer value in ASN.1
     713     *  Does NOT output the tag e.g. 0x02 / 0x30
     714     *
     715     *  @param val 0-65535
     716     *  @return the new index
     717     *  @since 0.9.25
     718     */
     719    private static int intToASN1(byte[] d, int idx, int val) {
     720        if (val < 0 || val > 65535)
     721            throw new IllegalArgumentException("fixme length " + val);
     722        if (val > 127) {
     723            if (val > 255) {
     724                d[idx++] = (byte) 0x82;
     725                d[idx++] = (byte) (val >> 8);
     726            } else {
     727                d[idx++] = (byte) 0x81;
     728            }
     729        }
     730        d[idx++] = (byte) val;
     731        return idx;
     732    }
     733
     734    /**
    706735     *  See above.
    707      *  Only supports sigs up to about 252 bytes. See code to fix BER encoding for bigger than that.
     736     *  Only supports sigs up to about 65530 bytes. See code to fix BER encoding for bigger than that.
    708737     *
    709738     *  @param len must be even, twice the nominal length of each BigInteger
     
    725754        int sublen = len / 2;
    726755        int rlen = asn[++idx];
    727         if ((rlen & 0x80) != 0)
    728             throw new SignatureException("FIXME R length > 127");
     756        if ((rlen & 0x80) != 0) {
     757            if ((rlen & 0xff) == 0x81) {
     758                rlen = asn[++idx] & 0xff;
     759            } else if ((rlen & 0xff) == 0x82) {
     760                rlen = asn[++idx] & 0xff;
     761                rlen <<= 8;
     762                rlen |= asn[++idx] & 0xff;
     763            } else {
     764                throw new SignatureException("FIXME R length > 65535");
     765            }
     766        }
    729767        if ((asn[++idx] & 0x80) != 0)
    730768            throw new SignatureException("R is negative");
     
    736774            System.arraycopy(asn, idx, rv, sublen - rlen, rlen);
    737775        idx += rlen;
    738         int slenloc = idx + 1;
     776
    739777        if (asn[idx] != 0x02)
    740778            throw new SignatureException("asn[s] = " + (asn[idx] & 0xff));
    741         int slen = asn[slenloc];
    742         if ((slen & 0x80) != 0)
    743             throw new SignatureException("FIXME S length > 127");
    744         if ((asn[slenloc + 1] & 0x80) != 0)
     779        int slen = asn[++idx];
     780        if ((slen & 0x80) != 0) {
     781            if ((slen & 0xff) == 0x81) {
     782                slen = asn[++idx] & 0xff;
     783            } else if ((slen & 0xff) == 0x82) {
     784                slen = asn[++idx] & 0xff;
     785                slen <<= 8;
     786                slen |= asn[++idx] & 0xff;
     787            } else {
     788                throw new SignatureException("FIXME S length > 65535");
     789            }
     790        }
     791        if ((asn[++idx] & 0x80) != 0)
    745792            throw new SignatureException("S is negative");
    746793        if (slen > sublen + 1)
    747794            throw new SignatureException("S too big " + slen);
    748795        if (slen == sublen + 1)
    749             System.arraycopy(asn, slenloc + 2, rv, sublen, sublen);
     796            System.arraycopy(asn, idx + 1, rv, sublen, sublen);
    750797        else
    751             System.arraycopy(asn, slenloc + 1, rv, len - slen, slen);
     798            System.arraycopy(asn, idx, rv, len - slen, slen);
    752799        //System.out.println("post from asn1\n" + net.i2p.util.HexDump.dump(rv));
    753800        return rv;
     
    756803    /**
    757804     *  See above.
    758      *  Only supports sigs up to about 252 bytes. See code to fix BER encoding for bigger than that.
     805     *  Only supports sigs up to about 65530 bytes. See code to fix BER encoding for bigger than that.
    759806     *
    760807     *  @param len nominal length of each BigInteger
Note: See TracChangeset for help on using the changeset viewer.