1 // swiftlint:disable all 2 // 3 // ASN1Encoder.swift 4 // ASN1Decoder 5 // 6 // Copyright © 2020 Filippo Maguolo. 7 // 8 // Permission is hereby granted, free of charge, to any person obtaining a copy 9 // of this software and associated documentation files (the "Software"), to deal 10 // in the Software without restriction, including without limitation the rights 11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 // copies of the Software, and to permit persons to whom the Software is 13 // furnished to do so, subject to the following conditions: 14 // 15 // The above copyright notice and this permission notice shall be included in all 16 // copies or substantial portions of the Software. 17 // 18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 // SOFTWARE. 25 26 import Foundation 27 28 public class ASN1DEREncoder { 29 encodeSequencenull30 public static func encodeSequence(content: Data) -> Data { 31 var encoded = Data() 32 encoded.append(ASN1Identifier.constructedTag | ASN1Identifier.TagNumber.sequence.rawValue) 33 encoded.append(contentLength(of: content.count)) 34 encoded.append(content) 35 return encoded 36 } 37 contentLengthnull38 private static func contentLength(of size: Int) -> Data { 39 if size >= 128 { 40 var lenBytes = byteArray(from: size) 41 while lenBytes.first == 0 { lenBytes.removeFirst() } 42 let len: UInt8 = 0x80 | UInt8(lenBytes.count) 43 return Data([len] + lenBytes) 44 } else { 45 return Data([UInt8(size)]) 46 } 47 } 48 byteArray<T>null49 private static func byteArray<T>(from value: T) -> [UInt8] where T: FixedWidthInteger { 50 return withUnsafeBytes(of: value.bigEndian, Array.init) 51 } 52 53 } 54 55 extension Data { 56 public var derEncodedSequence: Data { 57 return ASN1DEREncoder.encodeSequence(content: self) 58 } 59 } 60 // swiftlint:enable all 61