From d342a45d98c4795b3a3fe1aaef5236ad4a782b55 Mon Sep 17 00:00:00 2001 From: Yuuta Liang Date: Thu, 12 Oct 2023 12:10:33 +0800 Subject: Implement data structures from X.680, X.501, X.509, and PKCS#10, with X.690 encoding / decoding support The implementation took four days, and it is still a little bit rough. Updated version should arrive soon. Signed-off-by: Yuuta Liang --- src/test/model/pki/cert/ExtensionsTest.java | 112 ++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/test/model/pki/cert/ExtensionsTest.java (limited to 'src/test/model/pki/cert/ExtensionsTest.java') diff --git a/src/test/model/pki/cert/ExtensionsTest.java b/src/test/model/pki/cert/ExtensionsTest.java new file mode 100644 index 0000000..e50b3e6 --- /dev/null +++ b/src/test/model/pki/cert/ExtensionsTest.java @@ -0,0 +1,112 @@ +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(new 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(new 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(new 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(new 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()); + } +} -- cgit v1.2.3