Skip to content

Commit 726a63b

Browse files
committed
Add function WebAuthnCodecs.parseDerExplicitlyTaggedContextSpecificConstructed
1 parent c5a23e4 commit 726a63b

File tree

1 file changed

+34
-9
lines changed

1 file changed

+34
-9
lines changed

webauthn-server-core/src/main/java/com/yubico/webauthn/WebAuthnCodecs.java

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -299,20 +299,45 @@ static ParseDerResult<Integer> parseDerLength(@NonNull byte[] der, int offset) {
299299
}
300300
}
301301

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) {
304304
final int len = der.length - offset;
305305
if (len == 0) {
306306
throw new IllegalArgumentException(
307307
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);
313308
} 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));
316341
}
317342
}
318343

0 commit comments

Comments
 (0)