Search in sources :

Example 1 with BerDataValueReader

use of com.android.apksig.internal.asn1.ber.BerDataValueReader in project apksig by venshine.

the class Asn1BerParser method parseSequence.

private static <T> T parseSequence(BerDataValue container, Class<T> containerClass, boolean isUnencodedContainer) throws Asn1DecodingException {
    List<AnnotatedField> fields = getAnnotatedFields(containerClass);
    Collections.sort(fields, (f1, f2) -> f1.getAnnotation().index() - f2.getAnnotation().index());
    // Check that there are no fields with the same index
    if (fields.size() > 1) {
        AnnotatedField lastField = null;
        for (AnnotatedField field : fields) {
            if ((lastField != null) && (lastField.getAnnotation().index() == field.getAnnotation().index())) {
                throw new Asn1DecodingException("Fields have the same index: " + containerClass.getName() + "." + lastField.getField().getName() + " and ." + field.getField().getName());
            }
            lastField = field;
        }
    }
    // Instantiate the container object / result
    T t;
    try {
        t = containerClass.getConstructor().newInstance();
    } catch (IllegalArgumentException | ReflectiveOperationException e) {
        throw new Asn1DecodingException("Failed to instantiate " + containerClass.getName(), e);
    }
    // Parse fields one by one. A complication is that there may be optional fields.
    int nextUnreadFieldIndex = 0;
    BerDataValueReader elementsReader = container.contentsReader();
    while (nextUnreadFieldIndex < fields.size()) {
        BerDataValue dataValue;
        try {
            // the container should be used when assigning to this field.
            if (isUnencodedContainer && nextUnreadFieldIndex == 0) {
                dataValue = container;
            } else {
                dataValue = elementsReader.readDataValue();
            }
        } catch (BerDataValueFormatException e) {
            throw new Asn1DecodingException("Malformed data value", e);
        }
        if (dataValue == null) {
            break;
        }
        for (int i = nextUnreadFieldIndex; i < fields.size(); i++) {
            AnnotatedField field = fields.get(i);
            try {
                if (field.isOptional()) {
                    // it from the wrong tag.
                    try {
                        field.setValueFrom(dataValue, t);
                        nextUnreadFieldIndex = i + 1;
                        break;
                    } catch (Asn1UnexpectedTagException e) {
                        // next / iteration of the loop
                        continue;
                    }
                } else {
                    // Mandatory field -- if we can't set its value from this data value, then
                    // it's an error
                    field.setValueFrom(dataValue, t);
                    nextUnreadFieldIndex = i + 1;
                    break;
                }
            } catch (Asn1DecodingException e) {
                throw new Asn1DecodingException("Failed to parse " + containerClass.getName() + "." + field.getField().getName(), e);
            }
        }
    }
    return t;
}
Also used : BerDataValue(com.android.apksig.internal.asn1.ber.BerDataValue) BerDataValueFormatException(com.android.apksig.internal.asn1.ber.BerDataValueFormatException) ByteBufferBerDataValueReader(com.android.apksig.internal.asn1.ber.ByteBufferBerDataValueReader) BerDataValueReader(com.android.apksig.internal.asn1.ber.BerDataValueReader)

Example 2 with BerDataValueReader

use of com.android.apksig.internal.asn1.ber.BerDataValueReader in project apksig by venshine.

the class Asn1BerParser method parseSetOf.

// NOTE: This method returns List rather than Set because ASN.1 SET_OF does require uniqueness
// of elements -- it's an unordered collection.
@SuppressWarnings("unchecked")
private static <T> List<T> parseSetOf(BerDataValue container, Class<T> elementClass) throws Asn1DecodingException {
    List<T> result = new ArrayList<>();
    BerDataValueReader elementsReader = container.contentsReader();
    while (true) {
        BerDataValue dataValue;
        try {
            dataValue = elementsReader.readDataValue();
        } catch (BerDataValueFormatException e) {
            throw new Asn1DecodingException("Malformed data value", e);
        }
        if (dataValue == null) {
            break;
        }
        T element;
        if (ByteBuffer.class.equals(elementClass)) {
            element = (T) dataValue.getEncodedContents();
        } else if (Asn1OpaqueObject.class.equals(elementClass)) {
            element = (T) new Asn1OpaqueObject(dataValue.getEncoded());
        } else {
            element = parse(dataValue, elementClass);
        }
        result.add(element);
    }
    return result;
}
Also used : BerDataValue(com.android.apksig.internal.asn1.ber.BerDataValue) BerDataValueFormatException(com.android.apksig.internal.asn1.ber.BerDataValueFormatException) ArrayList(java.util.ArrayList) ByteBufferBerDataValueReader(com.android.apksig.internal.asn1.ber.ByteBufferBerDataValueReader) BerDataValueReader(com.android.apksig.internal.asn1.ber.BerDataValueReader)

Aggregations

BerDataValue (com.android.apksig.internal.asn1.ber.BerDataValue)2 BerDataValueFormatException (com.android.apksig.internal.asn1.ber.BerDataValueFormatException)2 BerDataValueReader (com.android.apksig.internal.asn1.ber.BerDataValueReader)2 ByteBufferBerDataValueReader (com.android.apksig.internal.asn1.ber.ByteBufferBerDataValueReader)2 ArrayList (java.util.ArrayList)1