1 // swiftlint:disable all 2 // 3 // ASN1Object.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 ASN1Object: CustomStringConvertible { 28 29 /// This property contains the DER encoded object 30 public var rawValue: Data? 31 32 /// This property contains the decoded Swift object whenever is possible 33 public var value: Any? 34 35 public var identifier: ASN1Identifier? 36 37 var sub: [ASN1Object]? 38 39 public internal(set) weak var parent: ASN1Object? 40 41 public func sub(_ index: Int) -> ASN1Object? { 42 if let sub = self.sub, index >= 0, index < sub.count { 43 return sub[index] 44 } 45 return nil 46 } 47 48 public func subCount() -> Int { 49 return sub?.count ?? 0 50 } 51 52 public func findOid(_ oid: OID) -> ASN1Object? { 53 return findOid(oid.rawValue) 54 } 55 56 public func findOid(_ oid: String) -> ASN1Object? { 57 for child in sub ?? [] { 58 if child.identifier?.tagNumber() == .objectIdentifier { 59 if child.value as? String == oid { 60 return child 61 } 62 } else { 63 if let result = child.findOid(oid) { 64 return result 65 } 66 } 67 } 68 return nil 69 } 70 71 public var description: String { 72 return printAsn1() 73 } 74 75 public var asString: String? { 76 if let string = value as? String { 77 return string 78 } 79 80 for item in sub ?? [] { 81 if let string = item.asString { 82 return string 83 } 84 } 85 86 return nil 87 } 88 89 fileprivate func printAsn1(insets: String = "") -> String { 90 var output = insets 91 output.append(identifier?.description.uppercased() ?? "") 92 output.append(value != nil ? ": \(value!)": "") 93 if identifier?.typeClass() == .universal, identifier?.tagNumber() == .objectIdentifier { 94 if let oidName = OID.description(of: value as? String ?? "") { 95 output.append(" (\(oidName))") 96 } 97 } 98 output.append(sub != nil && sub!.count > 0 ? " {": "") 99 output.append("\n") 100 for item in sub ?? [] { 101 output.append(item.printAsn1(insets: insets + " ")) 102 } 103 output.append(sub != nil && sub!.count > 0 ? insets + "}\n": "") 104 return output 105 } 106 } 107 // swiftlint:enable all 108