package model.pki.cert; import model.asn1.ASN1Object; import model.asn1.Bool; import model.asn1.ObjectIdentifier; import model.asn1.OctetString; import model.asn1.exceptions.ParseException; import model.asn1.parsing.BytesReader; import org.junit.jupiter.api.Test; import java.util.Arrays; import java.util.Collection; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.*; public class ExtensionsTest { @Test void testConstructor() { final Extension ext1 = new Extension(ASN1Object.TAG_SEQUENCE, null, new ObjectIdentifier(ObjectIdentifier.TAG, null, ObjectIdentifier.OID_BASIC_CONSTRAINTS), new Bool(Bool.TAG, null, true), new OctetString(OctetString.TAG, null, new Byte[]{0x30, 0x03, 0x01, 0x01, -1})); final Extension ext2 = new Extension(ASN1Object.TAG_SEQUENCE, null, new ObjectIdentifier(ObjectIdentifier.TAG, null, ObjectIdentifier.OID_SUBJECT_KEY_IDENTIFIER), null, new OctetString(OctetString.TAG, null, new Byte[]{ 0x04, 0x14, -79, -62, -89, -127, 0x63, 0x66, 0x4B, 0x72, 0x0A, -35, -3, 0x7D, 0x20, 0x29, -67, 0x6B, 0x49, 0x09, 0x61, -64 })); final Extensions extensions = new Extensions(ASN1Object.TAG_SEQUENCE, null, new Extension[]{ ext1, ext2 }); assertEquals(2, extensions.getExtensions().length); assertArrayEquals(ObjectIdentifier.OID_BASIC_CONSTRAINTS, extensions.getExtensions()[0].getExtnId().getInts()); assertArrayEquals(ObjectIdentifier.OID_SUBJECT_KEY_IDENTIFIER, extensions.getExtensions()[1].getExtnId().getInts()); } @Test void testParse() throws ParseException { final Extensions parsed = new Extensions(new BytesReader( Stream.of(Arrays.asList((byte) 0x30, (byte) (ExtensionTest.EXT_KEY_USAGE.length + ExtensionTest.EXT_SUBJECT_KEY_ID.length)), Arrays.asList(ExtensionTest.EXT_KEY_USAGE), Arrays.asList(ExtensionTest.EXT_SUBJECT_KEY_ID)) .flatMap(Collection::stream) .toArray(Byte[]::new)), false); assertArrayEquals(ObjectIdentifier.OID_KEY_USAGE, parsed.getExtensions()[0].getExtnId().getInts()); assertArrayEquals(ObjectIdentifier.OID_SUBJECT_KEY_IDENTIFIER, parsed.getExtensions()[1].getExtnId().getInts()); } @Test void testParseFail() { assertThrows(ParseException.class, () -> { new Extensions(new BytesReader(new Byte[]{0x30, 0x1}), false); }); assertThrows(ParseException.class, () -> { Byte[] bytes = Stream.of(Arrays.asList((byte) 0x30, (byte) (ExtensionTest.EXT_KEY_USAGE.length + ExtensionTest.EXT_SUBJECT_KEY_ID.length)), Arrays.asList(ExtensionTest.EXT_KEY_USAGE), Arrays.asList(ExtensionTest.EXT_SUBJECT_KEY_ID)) .flatMap(Collection::stream) .toArray(Byte[]::new); assertEquals((byte) 0x30, bytes[2]); bytes[2] = 0x31; new Extensions(new BytesReader(bytes), false); }); assertThrows(ParseException.class, () -> { Byte[] bytes = Stream.of(Arrays.asList((byte) 0x30, (byte) (ExtensionTest.EXT_KEY_USAGE.length + ExtensionTest.EXT_SUBJECT_KEY_ID.length)), Arrays.asList(ExtensionTest.EXT_KEY_USAGE), Arrays.asList(ExtensionTest.EXT_SUBJECT_KEY_ID)) .flatMap(Collection::stream) .toArray(Byte[]::new); assertEquals((byte) 0x30, bytes[2 + ExtensionTest.EXT_KEY_USAGE.length]); bytes[2 + ExtensionTest.EXT_KEY_USAGE.length] = 0x31; new Extensions(new BytesReader(bytes), false); }); } @Test void testEncode() { assertArrayEquals( Stream.of(Arrays.asList((byte) 0x30, (byte) (ExtensionTest.EXT_KEY_USAGE.length + ExtensionTest.EXT_SUBJECT_KEY_ID.length)), Arrays.asList(ExtensionTest.EXT_SUBJECT_KEY_ID), Arrays.asList(ExtensionTest.EXT_KEY_USAGE)) .flatMap(Collection::stream) .toArray(Byte[]::new), new Extensions(ASN1Object.TAG_SEQUENCE, null, new Extension[]{ new Extension(ASN1Object.TAG_SEQUENCE, null, new ObjectIdentifier(ObjectIdentifier.TAG, null, ObjectIdentifier.OID_SUBJECT_KEY_IDENTIFIER), null, new OctetString(OctetString.TAG, null, new Byte[]{ 0x04, 0x14, -79, -62, -89, -127, 0x63, 0x66, 0x4B, 0x72, 0x0A, -35, -3, 0x7D, 0x20, 0x29, -67, 0x6B, 0x49, 0x09, 0x61, -64 })), new Extension(ASN1Object.TAG_SEQUENCE, null, new ObjectIdentifier(ObjectIdentifier.TAG, null, ObjectIdentifier.OID_KEY_USAGE), new Bool(Bool.TAG, null, true), new OctetString(OctetString.TAG, null, new Byte[]{ 0x03, 0x02, 0x01, -122 })) }).encodeDER()); } }