@@ -299,20 +299,45 @@ static ParseDerResult<Integer> parseDerLength(@NonNull byte[] der, int offset) {
299
299
}
300
300
}
301
301
302
- /** Parse a SEQUENCE and return a copy of the content octets. */
303
- static ParseDerResult < ByteArray > parseDerSequence ( @ NonNull byte [] der , int offset ) {
302
+ private static ParseDerResult < ByteArray > parseDerTagged (
303
+ @ NonNull byte [] der , int offset , byte expectTag ) {
304
304
final int len = der .length - offset ;
305
305
if (len == 0 ) {
306
306
throw new IllegalArgumentException (
307
307
String .format ("Empty input at offset %d: %s" , offset , new ByteArray (der )));
308
- } else if ((der [offset ] & 0xff ) == 0x30 ) {
309
- final ParseDerResult <Integer > contentLen = parseDerLength (der , offset + 1 );
310
- final int contentEnd = contentLen .nextOffset + contentLen .result ;
311
- return new ParseDerResult <>(
312
- new ByteArray (Arrays .copyOfRange (der , contentLen .nextOffset , contentEnd )), contentEnd );
313
308
} else {
314
- throw new IllegalArgumentException (
315
- String .format ("Not a SEQUENCE tag (0x30) at offset %d: %s" , offset , new ByteArray (der )));
309
+ final byte tag = der [offset ];
310
+ if (tag == expectTag ) {
311
+ final ParseDerResult <Integer > contentLen = parseDerLength (der , offset + 1 );
312
+ final int contentEnd = contentLen .nextOffset + contentLen .result ;
313
+ return new ParseDerResult <>(
314
+ new ByteArray (Arrays .copyOfRange (der , contentLen .nextOffset , contentEnd )), contentEnd );
315
+ } else {
316
+ throw new IllegalArgumentException (
317
+ String .format (
318
+ "Incorrect tag: 0x%02x (expected 0x%02x) at offset %d: %s" ,
319
+ tag , expectTag , offset , new ByteArray (der )));
320
+ }
321
+ }
322
+ }
323
+
324
+ /** Parse a SEQUENCE and return a copy of the content octets. */
325
+ static ParseDerResult <ByteArray > parseDerSequence (@ NonNull byte [] der , int offset ) {
326
+ return parseDerTagged (der , offset , (byte ) 0x30 );
327
+ }
328
+
329
+ /**
330
+ * Parse an explicitly tagged value of class "context-specific" (bits 8-7 are 0b10), in
331
+ * "constructed" encoding (bit 6 is 1), with a prescribed tag value, and return a copy of the
332
+ * content octets.
333
+ */
334
+ static ParseDerResult <ByteArray > parseDerExplicitlyTaggedContextSpecificConstructed (
335
+ @ NonNull byte [] der , int offset , byte tagNumber ) {
336
+ if (tagNumber <= 30 && tagNumber >= 0 ) {
337
+ return parseDerTagged (der , offset , (byte ) ((tagNumber & 0x1f ) | 0xa0 ));
338
+ } else {
339
+ throw new UnsupportedOperationException (
340
+ String .format ("Tag number out of range: %d (expected 0 to 30, inclusive)" , tagNumber ));
316
341
}
317
342
}
318
343
0 commit comments