1 package com.android.hotspot2.asn1;
2 
3 import java.nio.ByteBuffer;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Collection;
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10 
11 public 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 
Asn1Oid(int tag, Asn1Class asn1Class, int length, ByteBuffer data)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 
Asn1Oid(Long... arcs)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
hashCode()71     public int hashCode() {
72         return mHashcode;
73     }
74 
75     @Override
equals(Object thatObject)76     public boolean equals(Object thatObject) {
77         return !(thatObject == null || thatObject.getClass() != Asn1Oid.class) &&
78                 mArcs.equals(((Asn1Oid) thatObject).mArcs);
79     }
80 
toOIDString()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
toString()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
getChildren()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 {
sOidMap.put(new Asn1Oid(0L, 0L), "NullOid")134         sOidMap.put(new Asn1Oid(0L, 0L), "NullOid");
sOidMap.put(new Asn1Oid(0L, 9L, 2342L, 19200300L, 100L, 1L, 25L), "domComp")135         sOidMap.put(new Asn1Oid(0L, 9L, 2342L, 19200300L, 100L, 1L, 25L), "domComp");
136 
sOidMap.put(OidMacAddress, "mac-address")137         sOidMap.put(OidMacAddress, "mac-address");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 1L), "algo_id_dsa")138         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 1L), "algo_id_dsa");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 3L), "algo_id_dsawithsha1")139         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 3L), "algo_id_dsawithsha1");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 2L, 1L), "algo_id_ecPublicKey")140         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 2L, 1L), "algo_id_ecPublicKey");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 3L), "eccdaWithSHA384")141         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 3L), "eccdaWithSHA384");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10046L, 2L, 1L), "algo_id_dhpublicnumber")142         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10046L, 2L, 1L), "algo_id_dhpublicnumber");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 1L), "algo_id_rsaEncryption")143         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 1L), "algo_id_rsaEncryption");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 2L), "algo_id_md2WithRSAEncryption")144         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 2L), "algo_id_md2WithRSAEncryption");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 4L), "algo_id_md5WithRSAEncryption")145         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 4L), "algo_id_md5WithRSAEncryption");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 5L), "algo_id_sha1WithRSAEncryption")146         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 5L),
147                 "algo_id_sha1WithRSAEncryption");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 11L), "algo_id_sha256WithRSAEncryption")148         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 11L),
149                 "algo_id_sha256WithRSAEncryption");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 7L), "pkcs7")150         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 7L), "pkcs7");
sOidMap.put(PKCS7Data, "pkcs7-data")151         sOidMap.put(PKCS7Data, "pkcs7-data");
sOidMap.put(PKCS7SignedData, "pkcs7-signedData")152         sOidMap.put(PKCS7SignedData, "pkcs7-signedData");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 1L), "emailAddress")153         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 1L), "emailAddress");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 7L), "challengePassword")154         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 7L), "challengePassword");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 14L), "extensionRequest")155         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 14L), "extensionRequest");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 2L), "algo_id_RC2_CBC")156         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 2L), "algo_id_RC2_CBC");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 4L), "algo_id_RC4_ENC")157         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 4L), "algo_id_RC4_ENC");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 7L), "algo_id_DES_EDE3_CBC")158         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 7L), "algo_id_DES_EDE3_CBC");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 9L), "algo_id_RC5_CBC_PAD")159         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 9L), "algo_id_RC5_CBC_PAD");
sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 10L), "algo_id_desCDMF")160         sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 10L), "algo_id_desCDMF");
sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 2L), "id-kp-HS2.0Auth")161         sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 2L), "id-kp-HS2.0Auth");
sOidMap.put(OidImei, "imei")162         sOidMap.put(OidImei, "imei");
sOidMap.put(OidMeid, "meid")163         sOidMap.put(OidMeid, "meid");
sOidMap.put(OidDevId, "DevId")164         sOidMap.put(OidDevId, "DevId");
sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 1L), "certAuthorityInfoAccessSyntax")165         sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 1L),
166                 "certAuthorityInfoAccessSyntax");
sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 11L), "certSubjectInfoAccessSyntax")167         sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 11L),
168                 "certSubjectInfoAccessSyntax");
sOidMap.put(new Asn1Oid(1L, 3L, 14L, 3L, 2L, 26L), "algo_id_SHA1")169         sOidMap.put(new Asn1Oid(1L, 3L, 14L, 3L, 2L, 26L), "algo_id_SHA1");
sOidMap.put(new Asn1Oid(1L, 3L, 132L, 0L, 34L), "secp384r1")170         sOidMap.put(new Asn1Oid(1L, 3L, 132L, 0L, 34L), "secp384r1");
171 
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 3L), "x500_CN")172         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 3L), "x500_CN");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 4L), "x500_SN")173         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 4L), "x500_SN");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 5L), "x500_serialNum")174         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 5L), "x500_serialNum");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 6L), "x500_C")175         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 6L), "x500_C");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 7L), "x500_L")176         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 7L), "x500_L");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 8L), "x500_ST")177         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 8L), "x500_ST");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 9L), "x500_STREET")178         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 9L), "x500_STREET");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 10L), "x500_O")179         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 10L), "x500_O");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 11L), "x500_OU")180         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 11L), "x500_OU");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 12L), "x500_title")181         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 12L), "x500_title");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 13L), "x500_description")182         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 13L), "x500_description");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 17L), "x500_postalCode")183         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 17L), "x500_postalCode");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 18L), "x500_poBox")184         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 18L), "x500_poBox");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 20L), "x500_phone")185         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 20L), "x500_phone");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 41L), "x500_name")186         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 41L), "x500_name");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 42L), "x500_givenName")187         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 42L), "x500_givenName");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 44L), "x500_genQual")188         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 44L), "x500_genQual");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 43L), "x500_initials")189         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 43L), "x500_initials");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 46L), "x500_dnQualifier")190         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 46L), "x500_dnQualifier");
sOidMap.put(new Asn1Oid(2L, 5L, 4L, 65L), "x500_pseudonym")191         sOidMap.put(new Asn1Oid(2L, 5L, 4L, 65L), "x500_pseudonym");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 9L), "certSubjectDirectoryAttributes")192         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 9L), "certSubjectDirectoryAttributes");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 14L), "certSubjectKeyIdentifier ")193         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 14L), "certSubjectKeyIdentifier ");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 15L), "certKeyUsage")194         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 15L), "certKeyUsage");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 16L), "certPrivateKeyUsagePeriod")195         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 16L), "certPrivateKeyUsagePeriod");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 17L), "certSubjectAltName")196         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 17L), "certSubjectAltName");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 18L), "certIssuerAltName")197         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 18L), "certIssuerAltName");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 19L), "certBasicConstraints")198         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 19L), "certBasicConstraints");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 30L), "certNameConstraints")199         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 30L), "certNameConstraints");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 31L), "certCRLDistributionPoints")200         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 31L), "certCRLDistributionPoints");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 32L), "certificatePolicies")201         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 32L), "certificatePolicies");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 33L), "certPolicyMappings")202         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 33L), "certPolicyMappings");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 35L), "certAuthorityKeyIdentifier ")203         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 35L), "certAuthorityKeyIdentifier ");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 36L), "certPolicyConstraints")204         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 36L), "certPolicyConstraints");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 37L), "certExtKeyUsageSyntax")205         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 37L), "certExtKeyUsageSyntax");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 46L), "certFreshestCRL")206         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 46L), "certFreshestCRL");
sOidMap.put(new Asn1Oid(2L, 5L, 29L, 54L), "certInhibitAnyPolicy")207         sOidMap.put(new Asn1Oid(2L, 5L, 29L, 54L), "certInhibitAnyPolicy");
sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 2L), "algo_id_aes128")208         sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 2L), "algo_id_aes128");
sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 22L), "algo_id_aes192")209         sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 22L), "algo_id_aes192");
sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 42L), "algo_id_aes256")210         sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 42L), "algo_id_aes256");
211     }
212 }
213