1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftASN1 open source project
//
// Copyright (c) 2021 Apple Inc. and the SwiftASN1 project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftASN1 project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import XCTest
@testable import SwiftASN1
final class ASN1StringTests: XCTestCase {
private func assertRoundTrips<ASN1Object: DERParseable & DERSerializable & Equatable>(_ value: ASN1Object) throws {
var serializer = DER.Serializer()
try serializer.serialize(value)
let parsed = try ASN1Object(derEncoded: serializer.serializedBytes)
XCTAssertEqual(parsed, value)
}
func testUTF8StringEncoding() throws {
var serializer = DER.Serializer()
let originalString = ASN1UTF8String(contentBytes: [1, 2, 3, 4])
try serializer.serialize(originalString)
XCTAssertEqual(serializer.serializedBytes, [12, 4, 1, 2, 3, 4])
}
func testUTF8StringRoundTrips() throws {
try self.assertRoundTrips(ASN1UTF8String(contentBytes: [1, 2, 3, 4]))
}
func testUTF8StringContiguousBytes() throws {
let string = ASN1UTF8String(contentBytes: [1, 2, 3, 4])
string.withUnsafeBytes { XCTAssertTrue($0.elementsEqual([1, 2, 3, 4])) }
}
func testTeletexStringEncoding() throws {
var serializer = DER.Serializer()
let originalString = ASN1TeletexString(contentBytes: [1, 2, 3, 4])
try serializer.serialize(originalString)
XCTAssertEqual(serializer.serializedBytes, [20, 4, 1, 2, 3, 4])
}
func testTeletexStringRoundTrips() throws {
try self.assertRoundTrips(ASN1TeletexString(contentBytes: [1, 2, 3, 4]))
}
func testTeletexStringContiguousBytes() throws {
let string = ASN1TeletexString(contentBytes: [1, 2, 3, 4])
string.withUnsafeBytes { XCTAssertTrue($0.elementsEqual([1, 2, 3, 4])) }
}
func testPrintableStringEncoding() throws {
var serializer = DER.Serializer()
let originalString = try ASN1PrintableString(contentBytes: [0x54, 0x65, 0x73, 0x74])
try serializer.serialize(originalString)
XCTAssertEqual(serializer.serializedBytes, [19, 4, 0x54, 0x65, 0x73, 0x74])
}
func testPrintableStringRoundTrips() throws {
try self.assertRoundTrips(ASN1PrintableString(contentBytes: [0x54, 0x65, 0x73, 0x74]))
}
func testPrintableStringContiguousBytes() throws {
let string = try ASN1PrintableString(contentBytes: [0x54, 0x65, 0x73, 0x74])
string.withUnsafeBytes { XCTAssertTrue($0.elementsEqual([0x54, 0x65, 0x73, 0x74])) }
}
func testUniversalStringEncoding() throws {
var serializer = DER.Serializer()
let originalString = ASN1UniversalString(contentBytes: [1, 2, 3, 4])
try serializer.serialize(originalString)
XCTAssertEqual(serializer.serializedBytes, [28, 4, 1, 2, 3, 4])
}
func testUniversalStringRoundTrips() throws {
try self.assertRoundTrips(ASN1UniversalString(contentBytes: [1, 2, 3, 4]))
}
func testUniversalStringContiguousBytes() throws {
let string = ASN1UniversalString(contentBytes: [1, 2, 3, 4])
string.withUnsafeBytes { XCTAssertTrue($0.elementsEqual([1, 2, 3, 4])) }
}
func testBMPStringEncoding() throws {
var serializer = DER.Serializer()
let originalString = ASN1BMPString(contentBytes: [1, 2, 3, 4])
try serializer.serialize(originalString)
XCTAssertEqual(serializer.serializedBytes, [30, 4, 1, 2, 3, 4])
}
func testBMPStringRoundTrips() throws {
try self.assertRoundTrips(ASN1BMPString(contentBytes: [1, 2, 3, 4]))
}
func testBMPStringContiguousBytes() throws {
let string = ASN1BMPString(contentBytes: [1, 2, 3, 4])
string.withUnsafeBytes { XCTAssertTrue($0.elementsEqual([1, 2, 3, 4])) }
}
func testUTF8StringCanCreateAString() throws {
let string = "hello, world!"
let utf8String = ASN1UTF8String(string)
let newString = String(utf8String)
XCTAssertEqual(newString, string)
}
func testPrintableStringCanCreateAString() throws {
let string = "hello, world"
let utf8String = try ASN1PrintableString(string)
let newString = String(utf8String)
XCTAssertEqual(newString, string)
}
func testIA5StringCanCreateAString() throws {
let string = "hello, world"
let ia5String = try ASN1IA5String(string)
let newString = String(ia5String)
XCTAssertEqual(newString, string)
}
func testPrintableStringRejectsCharacters() throws {
let allBytes = (UInt8(0)...UInt8.max)
let invalidBytes = (UInt8(0)...UInt8(255)).filter {
switch $0 {
case UInt8(ascii: "a")...UInt8(ascii: "z"),
UInt8(ascii: "A")...UInt8(ascii: "Z"),
UInt8(ascii: "0")...UInt8(ascii: "9"),
UInt8(ascii: "'"), UInt8(ascii: "("),
UInt8(ascii: ")"), UInt8(ascii: "+"),
UInt8(ascii: "-"), UInt8(ascii: "?"),
UInt8(ascii: ":"), UInt8(ascii: "/"),
UInt8(ascii: "="), UInt8(ascii: " "),
UInt8(ascii: ","), UInt8(ascii: "."):
return false
default:
return true
}
}
let validBytes = allBytes.filter { !invalidBytes.contains($0) }
for byte in invalidBytes {
XCTAssertThrowsError(try ASN1PrintableString(contentBytes: [byte]))
XCTAssertThrowsError(try ASN1PrintableString(String(UnicodeScalar(byte))))
XCTAssertThrowsError(try ASN1PrintableString(derEncoded: [0x13, 1, byte]))
}
for byte in validBytes {
XCTAssertNoThrow(try ASN1PrintableString(contentBytes: [byte]))
XCTAssertNoThrow(try ASN1PrintableString(String(UnicodeScalar(byte))))
XCTAssertNoThrow(try ASN1PrintableString(derEncoded: [0x13, 1, byte]))
}
}
func testIA5StringRejectsCharacters() throws {
let invalidBytes = (UInt8(128)...(UInt8.max))
let validBytes = (UInt8(0)..<UInt8(128))
for byte in invalidBytes {
XCTAssertThrowsError(try ASN1IA5String(contentBytes: [byte]))
XCTAssertThrowsError(try ASN1IA5String(String(UnicodeScalar(byte))))
XCTAssertThrowsError(try ASN1IA5String(derEncoded: [0x16, 1, byte]))
}
for byte in validBytes {
XCTAssertNoThrow(try ASN1IA5String(contentBytes: [byte]))
XCTAssertNoThrow(try ASN1IA5String(String(UnicodeScalar(byte))))
XCTAssertNoThrow(try ASN1IA5String(derEncoded: [0x16, 1, byte]))
}
}
}
|