2

I'm new to ASN1 notation and I'm struck where I'm not able to proceed further. I'm able to dump the output using ASN1Dump.dumpAsString() [Referred from link]

I'm able to get a dump(see example below). But I want to extract individual values and use them. How can I convert it to a class or access individual oids?

Sequence
    DER Set
        Sequence
            ObjectIdentifier(1.3.6.1.4.1.4843.1.1)
            PrintableString(testValue1) 
    DER Set
        Sequence
            ObjectIdentifier(1.3.6.1.4.1.4843.1.2)
            PrintableString(testValue2) 
    DER Set
        Sequence
            ObjectIdentifier(1.3.6.1.4.1.4843.1.3)
            PrintableString(testValue3) 

I want something like this..

t.getValue("1.3.6.1.4.1.4843.1.1") should return testValue1 where t is of type some TestClass which contains members of testValue1,testValue2,testValue3.

Thanks in advance..

Community
  • 1
  • 1
thirstylad
  • 357
  • 5
  • 12

1 Answers1

1

I'm assuming that, if you could use ASN1Dump, then you already have the object with the structure above.

For this answer, I've created the same structure (as I don't have your original data), but with minor differences (DERSequence instead of just Sequence), but the logic is basically the same.

You'll need to parse the asn1 structure and store the fields you want. For this code, I used bouncycastle 1.46 jdk1.6.

First, you create TestClass with a constructor that parses the object (the same object you passed to ASN1Dump.dumpAsString(). I'm assuming it's a DERSequence - probably is, but it can also be a ASN1Sequence (do a obj.getClass() to make sure). The code wouldn't change because ASN1Sequence is a super class of DERSequence and the methods used belongs to the super class.

public class TestClass {
    // this map will contain the values (key is 1.3.6.etc and value is testValue1, testValue2...)
    private Map<String, String> fields = new HashMap<String, String>();

    public TestClass(DERSequence sequence) {
        // parse objects from sequence
        Enumeration<?> objects = sequence.getObjects();
        while (objects.hasMoreElements()) {
            DERSet set = (DERSet) objects.nextElement(); // casting because I know from dump it's a DERSet

            // I'm assuming it's a DERSequence, but do a System.out.println(set.getObjectAt(0).getClass()) to make sure and cast accordinly
            DERSequence seq = (DERSequence) set.getObjectAt(0);

            // I'm assuming it's a DERObjectIdentifier, but do a System.out.println(set.getObjectAt(0).getClass()) to make sure and cast accordinly
            DERObjectIdentifier oid = (DERObjectIdentifier) seq.getObjectAt(0); // this object contains 1.3.6.etc...

            // I'm assuming it's a DERPrintableString, but do a System.out.println(set.getObjectAt(1).getClass()) to make sure and cast accordinly
            DERPrintableString str = (DERPrintableString) seq.getObjectAt(1);

            // store the values in the map
            fields.put(oid.getId(), str.getString());
        }
    }

    public String getValue(String oid) {
        // optional: you can check for null, or if oid exists (fields.contains(oid)), and return "" or null when it doesn't
        return fields.get(oid);
    }
}

After that, you can use TestClass this way:

// assuming seq is the object you passed to ASN1Dump.dumpAsString
// check if its type is DERSequence (do a seq.getClass() to check)
// if it's another type of sequence, change the TestClass code accordingly, as already explained above
TestClass t = new TestClass(seq);
System.out.println(t.getValue("1.3.6.1.4.1.4843.1.1")); // prints testValue1

PS: note that I've just parsed following the structure printed by ASN1Dump:

  • the object is a sequence that contains 3 sets
    • each set contains just one element, which is a sequence
      • each sequence contains 2 elements: an object identifier and a printable string

I've just went through the elements until I've got the ones I want.

  • thank you very much for the answer. I also wanted whether writing custom parsing logic is the only way to parse custom subject name values in x.509 certificate? Above dump is a custom subject name in x.509 certificate. `ASN1InputStream asnInputStream = new ASN1InputStream(new ByteArrayInputStream(clientCertificate.getSubjectX500Principal().getEncoded())); ASN1Primitive obj = asnInputStream.readObject(); System.out.println(ASN1Dump.dumpAsString(obj));` – thirstylad Mar 23 '17 at 03:05
  • For Subject Name, I prefer to call `getSubjectX500Principal().toString()` and parse the string using `StringTokenizer` –  Mar 23 '17 at 12:05