1 // swiftlint:disable all 2 // 3 // ASN1Identifier.swift 4 // 5 // Copyright © 2017 Filippo Maguolo. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in all 15 // copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 // SOFTWARE. 24 25 import Foundation 26 27 public class ASN1Identifier: CustomStringConvertible { 28 29 public enum Class: UInt8 { 30 case universal = 0x00 31 case application = 0x40 32 case contextSpecific = 0x80 33 case `private` = 0xC0 34 } 35 36 public enum TagNumber: UInt8 { 37 case endOfContent = 0x00 38 case boolean = 0x01 39 case integer = 0x02 40 case bitString = 0x03 41 case octetString = 0x04 42 case null = 0x05 43 case objectIdentifier = 0x06 44 case objectDescriptor = 0x07 45 case external = 0x08 46 case read = 0x09 47 case enumerated = 0x0A 48 case embeddedPdv = 0x0B 49 case utf8String = 0x0C 50 case relativeOid = 0x0D 51 case sequence = 0x10 52 case set = 0x11 53 case numericString = 0x12 54 case printableString = 0x13 55 case t61String = 0x14 56 case videotexString = 0x15 57 case ia5String = 0x16 58 case utcTime = 0x17 59 case generalizedTime = 0x18 60 case graphicString = 0x19 61 case visibleString = 0x1A 62 case generalString = 0x1B 63 case universalString = 0x1C 64 case characterString = 0x1D 65 case bmpString = 0x1E 66 } 67 68 public static let constructedTag: UInt8 = 0x20 69 70 var rawValue: UInt8 71 72 init(rawValue: UInt8) { 73 self.rawValue = rawValue 74 } 75 typeClassnull76 public func typeClass() -> Class { 77 for tc in [Class.application, Class.contextSpecific, Class.private] where (rawValue & tc.rawValue) == tc.rawValue { 78 return tc 79 } 80 return .universal 81 } 82 isPrimitivenull83 public func isPrimitive() -> Bool { 84 return (rawValue & ASN1Identifier.constructedTag) == 0 85 } isConstructednull86 public func isConstructed() -> Bool { 87 return (rawValue & ASN1Identifier.constructedTag) != 0 88 } 89 tagNumbernull90 public func tagNumber() -> TagNumber { 91 return TagNumber(rawValue: rawValue & 0x1F) ?? .endOfContent 92 } 93 94 public var description: String { 95 if typeClass() == .universal { 96 return String(describing: tagNumber()) 97 } else { 98 return "\(typeClass())(\(tagNumber().rawValue))" 99 } 100 } 101 } 102 // swiftlint:enable all 103