1package com.android.hotspot2.asn1;
2
3import java.nio.ByteBuffer;
4import java.util.ArrayList;
5import java.util.Arrays;
6import java.util.Collection;
7import java.util.HashMap;
8import java.util.List;
9import java.util.Map;
10
11public class Asn1Oid extends Asn1Object {
12    public static final int OidMaxOctet1 = 2;
13    public static final int OidOctet1Modulus = 40;
14
15    private final List<Long> mArcs;
16    private final int mHashcode;
17
18    private static final Map<Asn1Oid, String> sOidMap = new HashMap<>();
19
20    public Asn1Oid(int tag, Asn1Class asn1Class, int length, ByteBuffer data)
21            throws DecodeException {
22        super(tag, asn1Class, false, length);
23
24        if (length == 0)
25            throw new DecodeException("oid-encoding length is zero", data.position());
26
27        mArcs = new ArrayList<>();
28
29        ByteBuffer payload = data.duplicate();
30        payload.limit(payload.position() + length);
31        data.position(data.position() + length);
32
33        byte current = payload.get();
34        long seg01 = current & Asn1Decoder.ByteMask;
35        long segValue = seg01 / OidOctet1Modulus;
36        int hashcode = (int) segValue;
37        mArcs.add(segValue);
38        segValue = seg01 - segValue * OidOctet1Modulus;
39        hashcode = hashcode * 31 + (int) segValue;
40        mArcs.add(segValue);
41
42        current = 0;
43        segValue = 0L;
44
45        while (payload.hasRemaining()) {
46            current = payload.get();
47            segValue |= current & Asn1Decoder.MoreData;
48            if ((current & Asn1Decoder.MoreBit) == 0) {
49                hashcode = hashcode * 31 + (int) segValue;
50                mArcs.add(segValue);
51                segValue = 0L;
52            } else
53                segValue <<= Asn1Decoder.MoreWidth;
54        }
55        if ((current & Asn1Decoder.MoreBit) != 0)
56            throw new DecodeException("Illegal (end of) oid-encoding", payload.position());
57        mHashcode = hashcode;
58    }
59
60    public Asn1Oid(Long... arcs) {
61        super(Asn1Decoder.TAG_OID, Asn1Class.Universal, false, -1);
62        mArcs = Arrays.asList(arcs);
63        int hashcode = 0;
64        for (long arc : arcs) {
65            hashcode = hashcode * 31 + (int) arc;
66        }
67        mHashcode = hashcode;
68    }
69
70    @Override
71    public int hashCode() {
72        return mHashcode;
73    }
74
75    @Override
76    public boolean equals(Object thatObject) {
77        return !(thatObject == null || thatObject.getClass() != Asn1Oid.class) &&
78                mArcs.equals(((Asn1Oid) thatObject).mArcs);
79    }
80
81    public String toOIDString() {
82        StringBuilder sb = new StringBuilder();
83        boolean first = true;
84        for (long arc : mArcs) {
85            if (first) {
86                first = false;
87            } else {
88                sb.append('.');
89            }
90            sb.append(arc);
91        }
92        return sb.toString();
93    }
94
95    @Override
96    public String toString() {
97        StringBuilder sb = new StringBuilder();
98        sb.append(toOIDString());
99        String name = sOidMap.get(this);
100        if (name != null) {
101            sb.append(" (").append(name).append(')');
102        }
103        return super.toString() + '=' + sb.toString();
104    }
105
106    @Override
107    public Collection<Asn1Object> getChildren() {
108        throw new UnsupportedOperationException();
109    }
110
111    public static final Asn1Oid PKCS7Data = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 7L, 1L);
112    public static final Asn1Oid PKCS7SignedData = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 7L, 2L);
113    // encoded as an IA5STRING type
114    public static final Asn1Oid OidMacAddress = new Asn1Oid(1L, 3L, 6L, 1L, 1L, 1L, 1L, 22L);
115    // encoded as an IA5STRING type
116    public static final Asn1Oid OidImei = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 3L);
117    // encoded as a BITSTRING type
118    public static final Asn1Oid OidMeid = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 4L);
119    // encoded as a PRINTABLESTRING type
120    public static final Asn1Oid OidDevId = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 5L);
121
122    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 1L), "algo_id_dsa");
123    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 3L), "algo_id_dsawithsha1");
124    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 2L, 1L), "algo_id_ecPublicKey");
125    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 3L), "eccdaWithSHA384");
126    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 1L), "algo_id_rsaEncryption");
127    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 2L), "algo_id_md2WithRSAEncryption");
128    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 4L), "algo_id_md5WithRSAEncryption");
129    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 5L), "algo_id_sha1WithRSAEncryption");
130    //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 11L),
131    // "algo_id_sha256WithRSAEncryption");
132
133    static {
134        sOidMap.put(new Asn1Oid(0L, 0L), "NullOid");
135        sOidMap.put(new Asn1Oid(0L, 9L, 2342L, 19200300L, 100L, 1L, 25L), "domComp");
136
137        sOidMap.put(OidMacAddress, "mac-address");
138        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 1L), "algo_id_dsa");
139        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 3L), "algo_id_dsawithsha1");
140        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 2L, 1L), "algo_id_ecPublicKey");
141        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 3L), "eccdaWithSHA384");
142        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10046L, 2L, 1L), "algo_id_dhpublicnumber");
143        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 1L), "algo_id_rsaEncryption");
144        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 2L), "algo_id_md2WithRSAEncryption");
145        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 4L), "algo_id_md5WithRSAEncryption");
146        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 5L),
147                "algo_id_sha1WithRSAEncryption");
148        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 11L),
149                "algo_id_sha256WithRSAEncryption");
150        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 7L), "pkcs7");
151        sOidMap.put(PKCS7Data, "pkcs7-data");
152        sOidMap.put(PKCS7SignedData, "pkcs7-signedData");
153        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 1L), "emailAddress");
154        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 7L), "challengePassword");
155        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 14L), "extensionRequest");
156        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 2L), "algo_id_RC2_CBC");
157        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 4L), "algo_id_RC4_ENC");
158        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 7L), "algo_id_DES_EDE3_CBC");
159        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 9L), "algo_id_RC5_CBC_PAD");
160        sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 10L), "algo_id_desCDMF");
161        sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 2L), "id-kp-HS2.0Auth");
162        sOidMap.put(OidImei, "imei");
163        sOidMap.put(OidMeid, "meid");
164        sOidMap.put(OidDevId, "DevId");
165        sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 1L),
166                "certAuthorityInfoAccessSyntax");
167        sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 11L),
168                "certSubjectInfoAccessSyntax");
169        sOidMap.put(new Asn1Oid(1L, 3L, 14L, 3L, 2L, 26L), "algo_id_SHA1");
170        sOidMap.put(new Asn1Oid(1L, 3L, 132L, 0L, 34L), "secp384r1");
171
172        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 3L), "x500_CN");
173        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 4L), "x500_SN");
174        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 5L), "x500_serialNum");
175        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 6L), "x500_C");
176        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 7L), "x500_L");
177        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 8L), "x500_ST");
178        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 9L), "x500_STREET");
179        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 10L), "x500_O");
180        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 11L), "x500_OU");
181        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 12L), "x500_title");
182        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 13L), "x500_description");
183        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 17L), "x500_postalCode");
184        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 18L), "x500_poBox");
185        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 20L), "x500_phone");
186        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 41L), "x500_name");
187        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 42L), "x500_givenName");
188        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 44L), "x500_genQual");
189        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 43L), "x500_initials");
190        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 46L), "x500_dnQualifier");
191        sOidMap.put(new Asn1Oid(2L, 5L, 4L, 65L), "x500_pseudonym");
192        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 9L), "certSubjectDirectoryAttributes");
193        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 14L), "certSubjectKeyIdentifier ");
194        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 15L), "certKeyUsage");
195        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 16L), "certPrivateKeyUsagePeriod");
196        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 17L), "certSubjectAltName");
197        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 18L), "certIssuerAltName");
198        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 19L), "certBasicConstraints");
199        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 30L), "certNameConstraints");
200        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 31L), "certCRLDistributionPoints");
201        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 32L), "certificatePolicies");
202        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 33L), "certPolicyMappings");
203        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 35L), "certAuthorityKeyIdentifier ");
204        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 36L), "certPolicyConstraints");
205        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 37L), "certExtKeyUsageSyntax");
206        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 46L), "certFreshestCRL");
207        sOidMap.put(new Asn1Oid(2L, 5L, 29L, 54L), "certInhibitAnyPolicy");
208        sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 2L), "algo_id_aes128");
209        sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 22L), "algo_id_aes192");
210        sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 42L), "algo_id_aes256");
211    }
212}
213