/* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019, 2020 * Jonathan Schleifer <js@nil.im> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include "config.h" #import "TestsAppDelegate.h" static OFString *module = @"OFData+ASN1DERParsing"; @implementation TestsAppDelegate (OFASN1DERParsingTests) - (void)ASN1DERParsingTests { void *pool = objc_autoreleasePoolPush(); OFASN1BitString *bitString; OFArray *array; OFSet *set; OFEnumerator *enumerator; /* Boolean */ TEST(@"Parsing of boolean", ![[OFData dataWithItems: "\x01\x01\x00" count: 3].objectByParsingASN1DER booleanValue] && [[OFData dataWithItems: "\x01\x01\xFF" count: 3].objectByParsingASN1DER booleanValue]) EXPECT_EXCEPTION(@"Detection of invalid boolean #1", OFInvalidFormatException, [[OFData dataWithItems: "\x01\x01\x01" count: 3] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid boolean #2", OFInvalidFormatException, [[OFData dataWithItems: "\x01\x02\x00\x00" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid boolean #3", OFInvalidFormatException, [[OFData dataWithItems: "\x01\x00" count: 2] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated boolean", OFTruncatedDataException, [[OFData dataWithItems: "\x01\x01" count: 2] objectByParsingASN1DER]) /* Integer */ TEST(@"Parsing of integer", [[OFData dataWithItems: "\x02\x00" count: 2].objectByParsingASN1DER longLongValue] == 0 && [[OFData dataWithItems: "\x02\x01\x01" count: 3].objectByParsingASN1DER longLongValue] == 1 && [[OFData dataWithItems: "\x02\x02\x01\x04" count: 4].objectByParsingASN1DER longLongValue] == 260 && [[OFData dataWithItems: "\x02\x01\xFF" count: 3].objectByParsingASN1DER longLongValue] == -1 && [[OFData dataWithItems: "\x02\x03\xFF\x00\x00" count: 5].objectByParsingASN1DER longLongValue] == -65536 && (unsigned long long)[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF" "\xFF" count: 11] .objectByParsingASN1DER longLongValue] == ULLONG_MAX) EXPECT_EXCEPTION(@"Detection of invalid integer #1", OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x00" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid integer #2", OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x7F" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid integer #3", OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\xFF\x80" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of out of range integer", OFOutOfRangeException, [[OFData dataWithItems: "\x02\x09\x01" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" count: 11] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated integer", OFTruncatedDataException, [[OFData dataWithItems: "\x02\x02\x00" count: 3] objectByParsingASN1DER]) /* Bit string */ TEST(@"Parsing of bit string", (bitString = [OFData dataWithItems: "\x03\x01\x00" count: 3].objectByParsingASN1DER) && [bitString.bitStringValue isEqual: [OFData dataWithItems: "" count: 0]] && bitString.bitStringLength == 0 && (bitString = [OFData dataWithItems: "\x03\x0D\x01Hello World\x80" count: 15].objectByParsingASN1DER) && [bitString.bitStringValue isEqual: [OFData dataWithItems: "Hello World\x80" count: 12]] && bitString.bitStringLength == 95 && (bitString = [OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxx" count: 131].objectByParsingASN1DER) && [bitString.bitStringValue isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxx" count: 127]] && bitString.bitStringLength == 127 * 8) EXPECT_EXCEPTION(@"Detection of invalid bit string #1", OFInvalidFormatException, [[OFData dataWithItems: "\x03\x00" count: 2] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid bit string #2", OFInvalidFormatException, [[OFData dataWithItems: "\x03\x01\x01" count: 3] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of out of range bit string", OFOutOfRangeException, [[OFData dataWithItems: "\x03\x89" "\x01\x01\x01\x01\x01\x01\x01\x01\x01" count: 11] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated bit string", OFTruncatedDataException, [[OFData dataWithItems: "\x03\x01" count: 2] objectByParsingASN1DER]) /* Octet string */ TEST(@"Parsing of octet string", [[[OFData dataWithItems: "\x04\x0CHello World!" count: 14].objectByParsingASN1DER octetStringValue] isEqual: [OFData dataWithItems: "Hello World!" count: 12]] && [[[OFData dataWithItems: "\x04\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxx" count: 131].objectByParsingASN1DER octetStringValue] isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" count: 128]]) EXPECT_EXCEPTION(@"Detection of out of range octet string", OFOutOfRangeException, [[OFData dataWithItems: "\x04\x89" "\x01\x01\x01\x01\x01\x01\x01\x01\x01" count: 11] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated octet string", OFTruncatedDataException, [[OFData dataWithItems: "\x04\x01" count: 2] objectByParsingASN1DER]) /* Null */ TEST(@"Parsing of null", [[OFData dataWithItems: "\x05\x00" count: 2].objectByParsingASN1DER isEqual: [OFNull null]]) EXPECT_EXCEPTION(@"Detection of invalid null", OFInvalidFormatException, [[OFData dataWithItems: "\x05\x01\x00" count: 3] objectByParsingASN1DER]) /* Object Identifier */ TEST(@"Parsing of Object Identifier", (array = [[OFData dataWithItems: "\x06\x01\x27" count: 3].objectByParsingASN1DER subidentifiers]) && array.count == 2 && [[array objectAtIndex: 0] unsignedLongLongValue] == 0 && [[array objectAtIndex: 1] unsignedLongLongValue] == 39 && (array = [[OFData dataWithItems: "\x06\x01\x4F" count: 3].objectByParsingASN1DER subidentifiers]) && array.count == 2 && [[array objectAtIndex: 0] unsignedLongLongValue] == 1 && [[array objectAtIndex: 1] unsignedLongLongValue] == 39 && (array = [[OFData dataWithItems: "\x06\x02\x88\x37" count: 4].objectByParsingASN1DER subidentifiers]) && array.count == 2 && [[array objectAtIndex: 0] unsignedLongLongValue] == 2 && [[array objectAtIndex: 1] unsignedLongLongValue] == 999 && (array = [[OFData dataWithItems: "\x06\x09\x2A\x86\x48\x86\xF7\x0D" "\x01\x01\x0B" count: 11].objectByParsingASN1DER subidentifiers]) && array.count == 7 && [[array objectAtIndex: 0] unsignedLongLongValue] == 1 && [[array objectAtIndex: 1] unsignedLongLongValue] == 2 && [[array objectAtIndex: 2] unsignedLongLongValue] == 840 && [[array objectAtIndex: 3] unsignedLongLongValue] == 113549 && [[array objectAtIndex: 4] unsignedLongLongValue] == 1 && [[array objectAtIndex: 5] unsignedLongLongValue] == 1 && [[array objectAtIndex: 6] unsignedLongLongValue] == 11) EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #1", OFInvalidFormatException, [[OFData dataWithItems: "\x06\x01\x81" count: 3] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #2", OFInvalidFormatException, [[OFData dataWithItems: "\x06\x02\x80\x01" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of out of range Object Identifier", OFOutOfRangeException, [[OFData dataWithItems: "\x06\x0A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\x7F" count: 12] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated Object Identifier", OFTruncatedDataException, [[OFData dataWithItems: "\x06\x02\x00" count: 3] objectByParsingASN1DER]) /* Enumerated */ TEST(@"Parsing of enumerated", [[OFData dataWithItems: "\x0A\x00" count: 2].objectByParsingASN1DER longLongValue] == 0 && [[OFData dataWithItems: "\x0A\x01\x01" count: 3].objectByParsingASN1DER longLongValue] == 1 && [[OFData dataWithItems: "\x0A\x02\x01\x04" count: 4].objectByParsingASN1DER longLongValue] == 260 && [[OFData dataWithItems: "\x0A\x01\xFF" count: 3].objectByParsingASN1DER longLongValue] == -1 && [[OFData dataWithItems: "\x0A\x03\xFF\x00\x00" count: 5].objectByParsingASN1DER longLongValue] == -65536 && (unsigned long long)[[OFData dataWithItems: "\x0A\x09\x00\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF" "\xFF" count: 11] .objectByParsingASN1DER longLongValue] == ULLONG_MAX) EXPECT_EXCEPTION(@"Detection of invalid enumerated #1", OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\x00\x00" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid enumerated #2", OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\x00\x7F" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid enumerated #3", OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\xFF\x80" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of out of range enumerated", OFOutOfRangeException, [[OFData dataWithItems: "\x0A\x09\x01" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" count: 11] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated enumerated", OFTruncatedDataException, [[OFData dataWithItems: "\x0A\x02\x00" count: 3] objectByParsingASN1DER]) /* UTF-8 string */ TEST(@"Parsing of UTF-8 string", [[[OFData dataWithItems: "\x0C\x0EHällo Wörld!" count: 16].objectByParsingASN1DER UTF8StringValue] isEqual: @"Hällo Wörld!"] && [[[OFData dataWithItems: "\x0C\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxx" count: 131].objectByParsingASN1DER UTF8StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @"xxxxxxxxxxx"]) EXPECT_EXCEPTION(@"Detection of out of range UTF-8 string", OFOutOfRangeException, [[OFData dataWithItems: "\x0C\x89" "\x01\x01\x01\x01\x01\x01\x01\x01\x01" count: 11] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated UTF-8 string", OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x01" count: 2] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated length", OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x83\x01\x01" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #1", OFInvalidFormatException, [[OFData dataWithItems: "\x0C\x81\x7F" count: 3] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #2", OFInvalidFormatException, [[OFData dataWithItems: "\x0C\x82\x00\x80xxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxx" count: 132] objectByParsingASN1DER]) /* Sequence */ TEST(@"Parsing of sequence", (array = [OFData dataWithItems: "\x30\x00" count: 2].objectByParsingASN1DER) && [array isKindOfClass: [OFArray class]] && array.count == 0 && (array = [OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test" count: 11].objectByParsingASN1DER) && [array isKindOfClass: [OFArray class]] && array.count == 2 && [[array objectAtIndex: 0] longLongValue] == 123 && [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"]) EXPECT_EXCEPTION(@"Detection of truncated sequence #1", OFTruncatedDataException, [[OFData dataWithItems: "\x30\x01" count: 2] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated sequence #2", OFTruncatedDataException, [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00" count: 7] objectByParsingASN1DER]) /* Set */ TEST(@"Parsing of set", (set = [OFData dataWithItems: "\x31\x00" count: 2].objectByParsingASN1DER) && [set isKindOfClass: [OFSet class]] && set.count == 0 && (set = [OFData dataWithItems: "\x31\x09\x02\x01\x7B\x0C\x04Test" count: 11].objectByParsingASN1DER) && [set isKindOfClass: [OFSet class]] && set.count == 2 && (enumerator = [set objectEnumerator]) && [[enumerator nextObject] longLongValue] == 123 && [[[enumerator nextObject] stringValue] isEqual: @"Test"]) EXPECT_EXCEPTION(@"Detection of invalid set", OFInvalidFormatException, [[OFData dataWithItems: "\x31\x06\x02\x01\x02\x02\x01\x01" count: 8] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated set #1", OFTruncatedDataException, [[OFData dataWithItems: "\x31\x01" count: 2] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated set #2", OFTruncatedDataException, [[OFData dataWithItems: "\x31\x04\x02\x01\x01\x00\x00" count: 7] objectByParsingASN1DER]) /* NumericString */ TEST(@"Parsing of NumericString", [[[OFData dataWithItems: "\x12\x0B" "12345 67890" count: 13].objectByParsingASN1DER numericStringValue] isEqual: @"12345 67890"] && [[[OFData dataWithItems: "\x12\x81\x80" "00000000000000000000000000" "00000000000000000000000000000000000000000" "00000000000000000000000000000000000000000" "00000000000000000000" count: 131].objectByParsingASN1DER numericStringValue] isEqual: @"000000000000000000000000000000000000" @"000000000000000000000000000000000000" @"000000000000000000000000000000000000" @"00000000000000000000"]) EXPECT_EXCEPTION(@"Detection of invalid NumericString", OFInvalidEncodingException, [[OFData dataWithItems: "\x12\x02." count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of out of range NumericString", OFOutOfRangeException, [[OFData dataWithItems: "\x12\x89" "\x01\x01\x01\x01\x01\x01\x01\x01\x01" count: 11] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated NumericString", OFTruncatedDataException, [[OFData dataWithItems: "\x12\x01" count: 2] objectByParsingASN1DER]) /* PrintableString */ TEST(@"Parsing of PrintableString", [[[OFData dataWithItems: "\x13\x0CHello World." count: 14].objectByParsingASN1DER printableStringValue] isEqual: @"Hello World."] && [[[OFData dataWithItems: "\x13\x81\x80 '()+,-./:=?abcdefghijklmnopq" "rstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()+," "-./:=?abcdefghijklmnopqrstuvwxyzABCDEFGHI" "JKLMNOPQRSTUVWXYZ" count: 131].objectByParsingASN1DER printableStringValue] isEqual: @" '()+,-./:=?abcdefghijklmnopqrstuv" @"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()" @"+,-./:=?abcdefghijklmnopqrstuvwxyz" @"ABCDEFGHIJKLMNOPQRSTUVWXYZ"]) EXPECT_EXCEPTION(@"Detection of invalid PrintableString", OFInvalidEncodingException, [[OFData dataWithItems: "\x13\x02;" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of out of range PrintableString", OFOutOfRangeException, [[OFData dataWithItems: "\x13\x89" "\x01\x01\x01\x01\x01\x01\x01\x01\x01" count: 11] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated PrintableString", OFTruncatedDataException, [[OFData dataWithItems: "\x13\x01" count: 2] objectByParsingASN1DER]) /* IA5String */ TEST(@"Parsing of IA5String", [[[OFData dataWithItems: "\x16\x0CHello World!" count: 14].objectByParsingASN1DER IA5StringValue] isEqual: @"Hello World!"] && [[[OFData dataWithItems: "\x16\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxx" count: 131].objectByParsingASN1DER IA5StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @"xxxxxxxxxxxxxxxx"]) EXPECT_EXCEPTION(@"Detection of invalid IA5String", OFInvalidEncodingException, [[OFData dataWithItems: "\x16\x02ä" count: 4] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of out of range IA5String", OFOutOfRangeException, [[OFData dataWithItems: "\x16\x89" "\x01\x01\x01\x01\x01\x01\x01\x01\x01" count: 11] objectByParsingASN1DER]) EXPECT_EXCEPTION(@"Detection of truncated IA5String", OFTruncatedDataException, [[OFData dataWithItems: "\x16\x01" count: 2] objectByParsingASN1DER]) objc_autoreleasePoolPop(pool); } @end