Index: src/OFASN1BitString.m ================================================================== --- src/OFASN1BitString.m +++ src/OFASN1BitString.m @@ -65,42 +65,42 @@ void *pool = objc_autoreleasePoolPush(); OFData *bitStringValue; size_t bitStringLength; @try { - unsigned char lastByteBits; + unsigned char unusedBits; size_t count = DEREncodedContents.count; if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || tagNumber != OF_ASN1_TAG_NUMBER_BIT_STRING || constructed) @throw [OFInvalidArgumentException exception]; if (DEREncodedContents.itemSize != 1 || count == 0) @throw [OFInvalidFormatException exception]; - lastByteBits = + unusedBits = *(unsigned char *)[DEREncodedContents itemAtIndex: 0]; - if (lastByteBits > 7) + if (unusedBits > 7) @throw [OFInvalidFormatException exception]; /* - * Can't have any bits of the last byte used if we have no byte. + * Can't have any bits of the last byte unused if we have no + * byte. */ - if (count == 1 && lastByteBits != 0) + if (count == 1 && unusedBits != 0) @throw [OFInvalidFormatException exception]; - if (SIZE_MAX / 8 < count - 1 || - SIZE_MAX - (count - 1) * 8 < lastByteBits) + if (SIZE_MAX / 8 < count - 1) @throw [OFOutOfRangeException exception]; bitStringLength = (count - 1) * 8; bitStringValue = [[DEREncodedContents subdataWithRange: of_range(1, count - 1)] copy]; - if (lastByteBits != 0) - bitStringLength -= (8 - lastByteBits); + if (unusedBits != 0) + bitStringLength -= unusedBits; } @catch (id e) { [self release]; @throw e; } @@ -125,23 +125,25 @@ } - (OFData *)ASN1DERRepresentation { size_t bitStringValueCount = [_bitStringValue count]; - unsigned char lastByteBits = _bitStringLength % 8; + size_t roundedUpLength = OF_ROUND_UP_POW2(8, _bitStringLength); + unsigned char unusedBits = roundedUpLength - _bitStringLength; unsigned char header[] = { OF_ASN1_TAG_NUMBER_BIT_STRING, bitStringValueCount + 1, - lastByteBits + unusedBits }; OFMutableData *data; if (bitStringValueCount + 1 > UINT8_MAX || - bitStringValueCount != OF_ROUND_UP_POW2(8, _bitStringLength) / 8) + bitStringValueCount != roundedUpLength / 8) @throw [OFInvalidFormatException exception]; - data = [OFMutableData dataWithCapacity: 3 + bitStringValueCount]; + data = [OFMutableData + dataWithCapacity: sizeof(header) + bitStringValueCount]; [data addItems: header count: sizeof(header)]; [data addItems: [_bitStringValue items] count: bitStringValueCount]; Index: tests/OFASN1DERRepresentationTests.m ================================================================== --- tests/OFASN1DERRepresentationTests.m +++ tests/OFASN1DERRepresentationTests.m @@ -30,13 +30,13 @@ module = @"OFASN1BitString"; TEST(@"-[ASN1DERRepresentation]", (data = [OFData dataWithItems: "\xFF\x00\xF8" count: 3]) && [[[OFASN1BitString bitStringWithBitStringValue: data - bitStringLength: 20] + bitStringLength: 21] ASN1DERRepresentation] isEqual: - [OFData dataWithItems: "\x03\x04\x04\xFF\x00\xF8" + [OFData dataWithItems: "\x03\x04\x03\xFF\x00\xF8" count: 6]] && (data = [OFData dataWithItems: "abcdefäöü" count: 12]) && [[[OFASN1BitString bitStringWithBitStringValue: data bitStringLength: 12 * 8] @@ -59,9 +59,15 @@ count: 3]] && [[[OFASN1Boolean booleanWithBooleanValue: true] ASN1DERRepresentation] isEqual: [OFData dataWithItems: "\x01\x01\xFF" count: 3]]) + + module = @"OFNull"; + TEST(@"-[OFASN1DERRepresentation]", + [[[OFNull null] ASN1DERRepresentation] isEqual: + [OFData dataWithItems: "\x05\x00" + count: 2]]) [pool drain]; } @end Index: tests/OFASN1DERValueTests.m ================================================================== --- tests/OFASN1DERValueTests.m +++ tests/OFASN1DERValueTests.m @@ -102,11 +102,11 @@ (bitString = [[OFData dataWithItems: "\x03\x0D\x01Hello World\x80" count: 15] ASN1DERValue]) && [bitString.bitStringValue isEqual: [OFData dataWithItems: "Hello World\x80" count: 12]] && - bitString.bitStringLength == 89 && + bitString.bitStringLength == 95 && (bitString = [[OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxx"