DERObjectIdentifier.java revision 5db505e1f6a68c8d5dfdb0fed0b8607dea7bed96
1274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenekpackage org.bouncycastle.asn1; 2274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek 3274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenekimport java.io.ByteArrayOutputStream; 4274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenekimport java.io.IOException; 5274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenekimport java.math.BigInteger; 6274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek 7274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenekimport org.bouncycastle.util.Arrays; 8274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek 9274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek/** 10274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek * Use ASN1ObjectIdentifier instead of this, 11274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek */ 12274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenekpublic class DERObjectIdentifier 13274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek extends ASN1Primitive 140c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek{ 150c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek String identifier; 160c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek 179378ba44b3f46d697653003c784be87746e138d2Douglas Gregor private byte[] body; 183574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar 19274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek /** 20274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek * return an OID from the passed in object 210c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek * 220c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek * @throws IllegalArgumentException if the object cannot be converted. 230c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek */ 240c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek public static ASN1ObjectIdentifier getInstance( 252596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar Object obj) 262596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar { 276f78c3b8b9343e7e9fbf2d457cccf00df6da5d47Chris Lattner if (obj == null || obj instanceof ASN1ObjectIdentifier) 28337edcdbec05316b407d0d64865c88ff8597d910Ted Kremenek { 29274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek return (ASN1ObjectIdentifier)obj; 309378ba44b3f46d697653003c784be87746e138d2Douglas Gregor } 31274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek 327b78b7c6d96deb1e63f8d0655ee6fa53de0b65efTed Kremenek if (obj instanceof DERObjectIdentifier) 33268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 34e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek return new ASN1ObjectIdentifier(((DERObjectIdentifier)obj).getId()); 35e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek } 36e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek 37e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier) 38da9d61c96c412f6babc7f824152609562f302388Chris Lattner { 39277faca30c9f8f72b79f55695cbe3395ec246e7cTed Kremenek return (ASN1ObjectIdentifier)((ASN1Encodable)obj).toASN1Primitive(); 402b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner } 41277faca30c9f8f72b79f55695cbe3395ec246e7cTed Kremenek 421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (obj instanceof byte[]) 432b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner { 445f074266cc59563036c40516c814d63825723e20Ted Kremenek byte[] enc = (byte[])obj; 45274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek if (enc[0] == BERTags.OBJECT_IDENTIFIER) 46e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek { 47e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek try 48866bdf74547efe32c320554837ffce00fcc084feTed Kremenek { 49866bdf74547efe32c320554837ffce00fcc084feTed Kremenek return (ASN1ObjectIdentifier)fromByteArray(enc); 50866bdf74547efe32c320554837ffce00fcc084feTed Kremenek } 51866bdf74547efe32c320554837ffce00fcc084feTed Kremenek catch (IOException e) 521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 53866bdf74547efe32c320554837ffce00fcc084feTed Kremenek throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage()); 541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 55866bdf74547efe32c320554837ffce00fcc084feTed Kremenek } 561b5285e1ba31975864da356b2ed927e87670e654Chris Lattner else 575ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner { // TODO: this really shouldn't be supported here... 585ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner return ASN1ObjectIdentifier.fromOctetString((byte[])obj); 595ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner } 601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 617b78b7c6d96deb1e63f8d0655ee6fa53de0b65efTed Kremenek 627b78b7c6d96deb1e63f8d0655ee6fa53de0b65efTed Kremenek throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 63aff6ef8e7bc3c3739f984c390e0af693e60be064Chris Lattner } 647b78b7c6d96deb1e63f8d0655ee6fa53de0b65efTed Kremenek 65aff6ef8e7bc3c3739f984c390e0af693e60be064Chris Lattner /** 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump * return an Object Identifier from a tagged object. 67866bdf74547efe32c320554837ffce00fcc084feTed Kremenek * 68866bdf74547efe32c320554837ffce00fcc084feTed Kremenek * @param obj the tagged object holding the object we want 69866bdf74547efe32c320554837ffce00fcc084feTed Kremenek * @param explicit true if the object is meant to be explicitly 701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump * tagged false otherwise. 71866bdf74547efe32c320554837ffce00fcc084feTed Kremenek * @throws IllegalArgumentException if the tagged object cannot 72898a0bb1972efb6e03cb1151412ec7392cef07deChris Lattner * be converted. 73898a0bb1972efb6e03cb1151412ec7392cef07deChris Lattner */ 7459d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek public static ASN1ObjectIdentifier getInstance( 752b2453a7d8fe732561795431f39ceb2b2a832d84Chris Lattner ASN1TaggedObject obj, 76866bdf74547efe32c320554837ffce00fcc084feTed Kremenek boolean explicit) 7789d7ee9619d2dbdfa8d956a695c612a104a92cadTed Kremenek { 78d0a69696acca62798dfc8b98f97c92bfa7fa0490Chris Lattner ASN1Primitive o = obj.getObject(); 79277faca30c9f8f72b79f55695cbe3395ec246e7cTed Kremenek 80277faca30c9f8f72b79f55695cbe3395ec246e7cTed Kremenek if (explicit || o instanceof DERObjectIdentifier) 81277faca30c9f8f72b79f55695cbe3395ec246e7cTed Kremenek { 82277faca30c9f8f72b79f55695cbe3395ec246e7cTed Kremenek return getInstance(o); 83d0a69696acca62798dfc8b98f97c92bfa7fa0490Chris Lattner } 84d0a69696acca62798dfc8b98f97c92bfa7fa0490Chris Lattner else 851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 86d0a69696acca62798dfc8b98f97c92bfa7fa0490Chris Lattner return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(obj.getObject()).getOctets()); 871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 88863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner } 89863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner 90863c486fcb6162495a94fddf7ac8409de2638995Chris Lattner private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f; 911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 92d0a69696acca62798dfc8b98f97c92bfa7fa0490Chris Lattner DERObjectIdentifier( 93d0a69696acca62798dfc8b98f97c92bfa7fa0490Chris Lattner byte[] bytes) 94d0a69696acca62798dfc8b98f97c92bfa7fa0490Chris Lattner { 95d0a69696acca62798dfc8b98f97c92bfa7fa0490Chris Lattner StringBuffer objId = new StringBuffer(); 961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump long value = 0; 97866bdf74547efe32c320554837ffce00fcc084feTed Kremenek BigInteger bigValue = null; 98866bdf74547efe32c320554837ffce00fcc084feTed Kremenek boolean first = true; 99866bdf74547efe32c320554837ffce00fcc084feTed Kremenek 100898a0bb1972efb6e03cb1151412ec7392cef07deChris Lattner for (int i = 0; i != bytes.length; i++) 101e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek { 102e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek int b = bytes[i] & 0xff; 1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 104cd4e2aecde5bb7810715d5d5a88ac63ce7946f34Ted Kremenek if (value <= LONG_LIMIT) 1051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 10659d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek value += (b & 0x7f); 10759d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek if ((b & 0x80) == 0) // end of number reached 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 10959d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek if (first) 11059d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek { 111d6f53dc4951aace69014619761760addac9e59ecTed Kremenek if (value < 40) 1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 113cd4e2aecde5bb7810715d5d5a88ac63ce7946f34Ted Kremenek objId.append('0'); 114cd4e2aecde5bb7810715d5d5a88ac63ce7946f34Ted Kremenek } 115cd4e2aecde5bb7810715d5d5a88ac63ce7946f34Ted Kremenek else if (value < 80) 1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 117898a0bb1972efb6e03cb1151412ec7392cef07deChris Lattner objId.append('1'); 11859d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek value -= 40; 11959d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek } 12059d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek else 1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 12259d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek objId.append('2'); 12359d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek value -= 80; 1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 12559d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek first = false; 126e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek } 1271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 128898a0bb1972efb6e03cb1151412ec7392cef07deChris Lattner objId.append('.'); 12959d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek objId.append(value); 13059d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek value = 0; 13159d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek } 13259d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek else 133274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek { 13459d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek value <<= 7; 135cd4e2aecde5bb7810715d5d5a88ac63ce7946f34Ted Kremenek } 136cd4e2aecde5bb7810715d5d5a88ac63ce7946f34Ted Kremenek } 137e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek else 138e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek { 13959d08cb672136322375e5400578ee1fbd0947de2Ted Kremenek if (bigValue == null) 140defb7094c835998bb821e894253287625ce8c74dTed Kremenek { 1410c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek bigValue = BigInteger.valueOf(value); 142274b20863a728cc6a31ee75c670e3733600c1531Ted Kremenek } 14317ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f)); 14417ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek if ((b & 0x80) == 0) 14517ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek { 14617ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek if (first) 1474d35da2e41941965bbee8ed7e8c30e7c21000d71Ted Kremenek { 148e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek objId.append('2'); 149e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek bigValue = bigValue.subtract(BigInteger.valueOf(80)); 150e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek first = false; 1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 15274c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek 15374c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek objId.append('.'); 15474c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek objId.append(bigValue); 155da9d61c96c412f6babc7f824152609562f302388Chris Lattner bigValue = null; 15674c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek value = 0; 15774c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek } 15874c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek else 15974c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek { 1601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump bigValue = bigValue.shiftLeft(7); 16174c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek } 16274c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek } 16380d2f3059326f99ebf7c867db1c7f106ec9485f5Ted Kremenek } 16474c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek 16574c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek // BEGIN android-changed 16674c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek /* 16774c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek * Intern the identifier so there aren't hundreds of duplicates 1681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump * (in practice). 16974c3e6e5e95af08096aab415d1ce15f15ffff02aTed Kremenek */ 17017ff58a63197b398ae52697b088dc0fb8b255519Ted Kremenek this.identifier = objId.toString().intern(); 1710c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek // END android-changed 172268ee7016a2811803989487c0ad3799486092c63Ted Kremenek this.body = Arrays.clone(bytes); 173268ee7016a2811803989487c0ad3799486092c63Ted Kremenek } 174268ee7016a2811803989487c0ad3799486092c63Ted Kremenek 175268ee7016a2811803989487c0ad3799486092c63Ted Kremenek /** 1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump * @deprecated use ASN1ObjectIdentifier constructor. 177da9d61c96c412f6babc7f824152609562f302388Chris Lattner */ 1781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump public DERObjectIdentifier( 179268ee7016a2811803989487c0ad3799486092c63Ted Kremenek String identifier) 1801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 181268ee7016a2811803989487c0ad3799486092c63Ted Kremenek if (identifier == null) 18241a2660377d215d004fe413c03874bd066b5384cTed Kremenek { 1835ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner throw new IllegalArgumentException("'identifier' cannot be null"); 1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!isValidIdentifier(identifier)) 1865ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner { 1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump throw new IllegalArgumentException("string " + identifier + " not an OID"); 18841a2660377d215d004fe413c03874bd066b5384cTed Kremenek } 18941a2660377d215d004fe413c03874bd066b5384cTed Kremenek 19041a2660377d215d004fe413c03874bd066b5384cTed Kremenek // BEGIN android-changed 19141a2660377d215d004fe413c03874bd066b5384cTed Kremenek /* 19241a2660377d215d004fe413c03874bd066b5384cTed Kremenek * Intern the identifier so there aren't hundreds of duplicates 19341a2660377d215d004fe413c03874bd066b5384cTed Kremenek * (in practice). 19441a2660377d215d004fe413c03874bd066b5384cTed Kremenek */ 19541a2660377d215d004fe413c03874bd066b5384cTed Kremenek this.identifier = identifier.intern(); 19641a2660377d215d004fe413c03874bd066b5384cTed Kremenek // END android-changed 19741a2660377d215d004fe413c03874bd066b5384cTed Kremenek } 19841a2660377d215d004fe413c03874bd066b5384cTed Kremenek 199da9d61c96c412f6babc7f824152609562f302388Chris Lattner DERObjectIdentifier(DERObjectIdentifier oid, String branchID) 200da9d61c96c412f6babc7f824152609562f302388Chris Lattner { 20141a2660377d215d004fe413c03874bd066b5384cTed Kremenek if (!isValidBranchID(branchID, 0)) 20241a2660377d215d004fe413c03874bd066b5384cTed Kremenek { 2035ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner throw new IllegalArgumentException("string " + branchID + " not a valid OID branch"); 204da9d61c96c412f6babc7f824152609562f302388Chris Lattner } 2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20641a2660377d215d004fe413c03874bd066b5384cTed Kremenek this.identifier = oid.getId() + "." + branchID; 20741a2660377d215d004fe413c03874bd066b5384cTed Kremenek } 20841a2660377d215d004fe413c03874bd066b5384cTed Kremenek 20941a2660377d215d004fe413c03874bd066b5384cTed Kremenek public String getId() 2105ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner { 21141a2660377d215d004fe413c03874bd066b5384cTed Kremenek return identifier; 21241a2660377d215d004fe413c03874bd066b5384cTed Kremenek } 21341a2660377d215d004fe413c03874bd066b5384cTed Kremenek 214268ee7016a2811803989487c0ad3799486092c63Ted Kremenek private void writeField( 2151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ByteArrayOutputStream out, 21641a2660377d215d004fe413c03874bd066b5384cTed Kremenek long fieldValue) 217268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump byte[] result = new byte[9]; 219268ee7016a2811803989487c0ad3799486092c63Ted Kremenek int pos = 8; 220da9d61c96c412f6babc7f824152609562f302388Chris Lattner result[pos] = (byte)((int)fieldValue & 0x7f); 221268ee7016a2811803989487c0ad3799486092c63Ted Kremenek while (fieldValue >= (1L << 7)) 222268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump fieldValue >>= 7; 224268ee7016a2811803989487c0ad3799486092c63Ted Kremenek result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80); 2255ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner } 2265ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner out.write(result, pos, 9 - pos); 2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 228268ee7016a2811803989487c0ad3799486092c63Ted Kremenek 229268ee7016a2811803989487c0ad3799486092c63Ted Kremenek private void writeField( 230268ee7016a2811803989487c0ad3799486092c63Ted Kremenek ByteArrayOutputStream out, 2311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BigInteger fieldValue) 232268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 233268ee7016a2811803989487c0ad3799486092c63Ted Kremenek int byteCount = (fieldValue.bitLength() + 6) / 7; 234268ee7016a2811803989487c0ad3799486092c63Ted Kremenek if (byteCount == 0) 235268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 236268ee7016a2811803989487c0ad3799486092c63Ted Kremenek out.write(0); 237268ee7016a2811803989487c0ad3799486092c63Ted Kremenek } 238268ee7016a2811803989487c0ad3799486092c63Ted Kremenek else 239268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 2401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump BigInteger tmpValue = fieldValue; 24141a2660377d215d004fe413c03874bd066b5384cTed Kremenek byte[] tmp = new byte[byteCount]; 24241a2660377d215d004fe413c03874bd066b5384cTed Kremenek for (int i = byteCount - 1; i >= 0; i--) 243268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 244268ee7016a2811803989487c0ad3799486092c63Ted Kremenek tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80); 245e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek tmpValue = tmpValue.shiftRight(7); 246268ee7016a2811803989487c0ad3799486092c63Ted Kremenek } 24741a2660377d215d004fe413c03874bd066b5384cTed Kremenek tmp[byteCount - 1] &= 0x7f; 2481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump out.write(tmp, 0, tmp.length); 249268ee7016a2811803989487c0ad3799486092c63Ted Kremenek } 250268ee7016a2811803989487c0ad3799486092c63Ted Kremenek } 251268ee7016a2811803989487c0ad3799486092c63Ted Kremenek 252268ee7016a2811803989487c0ad3799486092c63Ted Kremenek private void doOutput(ByteArrayOutputStream aOut) 25341a2660377d215d004fe413c03874bd066b5384cTed Kremenek { 2541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump OIDTokenizer tok = new OIDTokenizer(identifier); 255268ee7016a2811803989487c0ad3799486092c63Ted Kremenek int first = Integer.parseInt(tok.nextToken()) * 40; 256268ee7016a2811803989487c0ad3799486092c63Ted Kremenek 257268ee7016a2811803989487c0ad3799486092c63Ted Kremenek String secondToken = tok.nextToken(); 258268ee7016a2811803989487c0ad3799486092c63Ted Kremenek if (secondToken.length() <= 18) 259e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek { 260da9d61c96c412f6babc7f824152609562f302388Chris Lattner writeField(aOut, first + Long.parseLong(secondToken)); 261e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek } 2621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump else 263268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 264e5680f3cd678014cf0872d34726dc804b0cbbdd4Ted Kremenek writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first))); 265268ee7016a2811803989487c0ad3799486092c63Ted Kremenek } 266268ee7016a2811803989487c0ad3799486092c63Ted Kremenek 267268ee7016a2811803989487c0ad3799486092c63Ted Kremenek while (tok.hasMoreTokens()) 268268ee7016a2811803989487c0ad3799486092c63Ted Kremenek { 26930a12ec2a7f331d9e08acabe7cda853aaa7ba54bTed Kremenek String token = tok.nextToken(); 2701b5285e1ba31975864da356b2ed927e87670e654Chris Lattner if (token.length() <= 18) 2711b5285e1ba31975864da356b2ed927e87670e654Chris Lattner { 27230a12ec2a7f331d9e08acabe7cda853aaa7ba54bTed Kremenek writeField(aOut, Long.parseLong(token)); 27330a12ec2a7f331d9e08acabe7cda853aaa7ba54bTed Kremenek } 27430a12ec2a7f331d9e08acabe7cda853aaa7ba54bTed Kremenek else 275b248d53f2599d8e7b53b144b713e163ca521ffcaTed Kremenek { 2765ff4317536dbd7f03332bb250c8b35ec04a6f5dbChris Lattner writeField(aOut, new BigInteger(token)); 2771b5285e1ba31975864da356b2ed927e87670e654Chris Lattner } 27830a12ec2a7f331d9e08acabe7cda853aaa7ba54bTed Kremenek } 27930a12ec2a7f331d9e08acabe7cda853aaa7ba54bTed Kremenek } 2805f074266cc59563036c40516c814d63825723e20Ted Kremenek 281d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek protected synchronized byte[] getBody() 282d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek { 2830c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek if (body == null) 2840c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek { 2850c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 2860c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek 2870c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek doOutput(bOut); 28885b4521e34dcd4a0a4a1f0819e1123128e5a3125Benjamin Kramer 289d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek body = bOut.toByteArray(); 290d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek } 2910c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek 292d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek return body; 293d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek } 2941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump boolean isConstructed() 2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 297d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek return false; 2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 30085b4521e34dcd4a0a4a1f0819e1123128e5a3125Benjamin Kramer int encodedLength() 3010c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek throws IOException 302a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek { 303a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek int length = getBody().length; 304a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek 3052596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar return 1 + StreamUtil.calculateBodyLength(length) + length; 306d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek } 3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 308d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek void encode( 309d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek ASN1OutputStream out) 310a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek throws IOException 311a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek { 312a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek byte[] enc = getBody(); 3130c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek 3141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump out.write(BERTags.OBJECT_IDENTIFIER); 315a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek out.writeLength(enc.length); 316a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek out.write(enc); 317a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek } 318d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek 319337edcdbec05316b407d0d64865c88ff8597d910Ted Kremenek public int hashCode() 3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 32185b4521e34dcd4a0a4a1f0819e1123128e5a3125Benjamin Kramer return identifier.hashCode(); 322337edcdbec05316b407d0d64865c88ff8597d910Ted Kremenek } 323337edcdbec05316b407d0d64865c88ff8597d910Ted Kremenek 324337edcdbec05316b407d0d64865c88ff8597d910Ted Kremenek boolean asn1Equals( 3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ASN1Primitive o) 326a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek { 327a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek if (!(o instanceof DERObjectIdentifier)) 328337edcdbec05316b407d0d64865c88ff8597d910Ted Kremenek { 329a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek return false; 330a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek } 331a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek 3321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return identifier.equals(((DERObjectIdentifier)o).identifier); 3331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump public String toString() 336a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek { 337d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek return getId(); 338d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek } 3391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3400c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek private static boolean isValidBranchID( 3410c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek String branchID, int start) 3427e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek { 34385b4521e34dcd4a0a4a1f0819e1123128e5a3125Benjamin Kramer boolean periodAllowed = false; 3447e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump int pos = branchID.length(); 3467e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek while (--pos >= start) 3477e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek { 3487e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek char ch = branchID.charAt(pos); 3497e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3507e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek // TODO Leading zeroes? 3517e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek if ('0' <= ch && ch <= '9') 3521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 3537e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek periodAllowed = true; 3547e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek continue; 3557e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek } 3567e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3577e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek if (ch == '.') 3581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 3597e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek if (!periodAllowed) 3602596e429a61602312bdd149786045b8a90cd2d10Daniel Dunbar { 3617e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek return false; 3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3637e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3647e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek periodAllowed = false; 3657e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek continue; 3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3677e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3687e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek return false; 3697e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek } 3707e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return periodAllowed; 3727e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek } 3737e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3747e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek private static boolean isValidIdentifier( 3757e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek String identifier) 3767e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek { 3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (identifier.length() < 3 || identifier.charAt(1) != '.') 378a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek { 379a4b44dd9d30929a35c44d85102e5241ee847b2f2Ted Kremenek return false; 3807e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek } 3817e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3827e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek char first = identifier.charAt(0); 3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (first < '0' || first > '2') 3841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 385d8c02929fe70f03111be73e7b8c402c724238ee9Ted Kremenek return false; 3867e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek } 3877e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek 3880c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek return isValidBranchID(identifier, 2); 3890c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek } 3900c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek 3910c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][]; 3920c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek 3930c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek static ASN1ObjectIdentifier fromOctetString(byte[] enc) 394da9d61c96c412f6babc7f824152609562f302388Chris Lattner { 3951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (enc.length < 3) 3967e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek { 39768228634016f644a1164fa1f024a9ce2093656bfTed Kremenek return new ASN1ObjectIdentifier(enc); 39868228634016f644a1164fa1f024a9ce2093656bfTed Kremenek } 3996183e4815a4019e97ad01bd880f12355599b75fdTed Kremenek 4007e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek int idx1 = enc[enc.length - 2] & 0xff; 40168228634016f644a1164fa1f024a9ce2093656bfTed Kremenek // in this case top bit is always zero 40268228634016f644a1164fa1f024a9ce2093656bfTed Kremenek int idx2 = enc[enc.length - 1] & 0x7f; 4030c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek 4040c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek ASN1ObjectIdentifier possibleMatch; 4050c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek 4060c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek synchronized (cache) 4077e3a004c6ed1fe87912203b9c5a113f8da89d261Ted Kremenek { 4080e50b6e7c104d00614baa3d80df62f1630a94d9cTed Kremenek ASN1ObjectIdentifier[] first = cache[idx1]; 4090c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek if (first == null) 4100c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek { 4113574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar first = cache[idx1] = new ASN1ObjectIdentifier[128]; 4123574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar } 41326555b18aa2c3b78744e77927acd3faa53ae7369Ted Kremenek 41426555b18aa2c3b78744e77927acd3faa53ae7369Ted Kremenek possibleMatch = first[idx2]; 4153574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar if (possibleMatch == null) 4160c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek { 4170c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek return first[idx2] = new ASN1ObjectIdentifier(enc); 4180c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek } 4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4208a6aec620dbec1f292fe4116c0373ac81ab90234Ted Kremenek if (Arrays.areEqual(enc, possibleMatch.getBody())) 4213574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar { 4220c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek return possibleMatch; 4238a6aec620dbec1f292fe4116c0373ac81ab90234Ted Kremenek } 4241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4250c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek idx1 = (idx1 + 1) & 0xff; 4260c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek first = cache[idx1]; 427da9d61c96c412f6babc7f824152609562f302388Chris Lattner if (first == null) 428da9d61c96c412f6babc7f824152609562f302388Chris Lattner { 429e1b6498c41b94c3bc5cede17b0702282543385efTed Kremenek first = cache[idx1] = new ASN1ObjectIdentifier[128]; 430e1b6498c41b94c3bc5cede17b0702282543385efTed Kremenek } 4314adc71ae2cfc190f8d2cf58876e2a7893aa74ee0Ted Kremenek 43226555b18aa2c3b78744e77927acd3faa53ae7369Ted Kremenek possibleMatch = first[idx2]; 4333574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar if (possibleMatch == null) 434e1b6498c41b94c3bc5cede17b0702282543385efTed Kremenek { 43526555b18aa2c3b78744e77927acd3faa53ae7369Ted Kremenek return first[idx2] = new ASN1ObjectIdentifier(enc); 4361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 43767d15050bbea16ae256e204ecd464f2e454c3c99Ted Kremenek 438e1b6498c41b94c3bc5cede17b0702282543385efTed Kremenek if (Arrays.areEqual(enc, possibleMatch.getBody())) 43967d15050bbea16ae256e204ecd464f2e454c3c99Ted Kremenek { 4401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return possibleMatch; 4413574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar } 4423574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar 4431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump idx2 = (idx2 + 1) & 0x7f; 44426555b18aa2c3b78744e77927acd3faa53ae7369Ted Kremenek possibleMatch = first[idx2]; 44526555b18aa2c3b78744e77927acd3faa53ae7369Ted Kremenek if (possibleMatch == null) 44667d15050bbea16ae256e204ecd464f2e454c3c99Ted Kremenek { 44726555b18aa2c3b78744e77927acd3faa53ae7369Ted Kremenek return first[idx2] = new ASN1ObjectIdentifier(enc); 44867d15050bbea16ae256e204ecd464f2e454c3c99Ted Kremenek } 4491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 450a4bd8eb4d6d4b625f6bbb62fc180b02eab6433edTed Kremenek 4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (Arrays.areEqual(enc, possibleMatch.getBody())) 452a4bd8eb4d6d4b625f6bbb62fc180b02eab6433edTed Kremenek { 4533574f46cf495ec61618fd6864b045c5b1d0d5068Daniel Dunbar return possibleMatch; 454e1b6498c41b94c3bc5cede17b0702282543385efTed Kremenek } 45526555b18aa2c3b78744e77927acd3faa53ae7369Ted Kremenek 4561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return new ASN1ObjectIdentifier(enc); 4570c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek } 4580c6a77bc1f52f282a969538f139ebde429076ed3Ted Kremenek} 459a4bd8eb4d6d4b625f6bbb62fc180b02eab6433edTed Kremenek