1
0

DER.swift 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //
  2. // DER.swift
  3. // Swifter
  4. //
  5. // Copyright © 2016 Damian Kołakowski. All rights reserved.
  6. //
  7. import Foundation
  8. public struct DER {
  9. //
  10. // Distinguished Encoding Rules (DER)
  11. //
  12. // https://en.wikipedia.org/wiki/X.690
  13. //
  14. public enum DecodeError: Error { case invalidData }
  15. public enum DERClass: UInt8 { case universal = 0, application = 1, context = 2, priv = 3 }
  16. public static func decode(_ input: [UInt8]) throws -> DEROObject {
  17. var iterator = input[0..<input.count].makeIterator()
  18. return try parseObject(&iterator)
  19. }
  20. public struct DEROObject {
  21. public let clazz: DERClass
  22. public let primitive: Bool
  23. public let tag: UInt32
  24. public let data: [UInt8]
  25. }
  26. private static func parseObject(_ generator: inout IndexingIterator<ArraySlice<UInt8>>) throws -> DEROObject {
  27. guard let first = generator.next() else { throw DecodeError.invalidData }
  28. let clazz = try parseClass(first)
  29. let primitive = try parsePrimitive(first)
  30. let tag = try parseTag(first, &generator)
  31. let data = try parseContent(&generator)
  32. return DEROObject(clazz: clazz, primitive: primitive, tag: tag, data: data)
  33. }
  34. private static func parsePrimitive(_ first: UInt8) throws -> Bool {
  35. return (first & 0x20) == 0
  36. }
  37. private static func parseClass(_ first: UInt8) throws -> DERClass {
  38. if let cls = DERClass(rawValue: (first & 0xC0) >> 6) {
  39. return cls
  40. }
  41. throw DecodeError.invalidData
  42. }
  43. private static func parseTag(_ first: UInt8, _ generator: inout IndexingIterator<ArraySlice<UInt8>>) throws -> UInt32 {
  44. switch first & 0x1F {
  45. case let short where short < 0x1F:
  46. return UInt32(short)
  47. case let long where long == 0x1F:
  48. // Arbitrary allow only for UInt32 as max TAG value.
  49. var buffer = [UInt8](repeating: 0, count: 4)
  50. for i in 0..<buffer.count {
  51. guard let b = generator.next() else { throw DecodeError.invalidData }
  52. buffer[i] = (b & 0x7F)
  53. if b & 0x80 != 0 { break }
  54. }
  55. // Validate if the last byte has leading 0 bit. We read 4 tag bytes but there could be more.
  56. guard buffer[3] & 0x80 != 0 else {
  57. throw DecodeError.invalidData
  58. }
  59. return buffer.withUnsafeBufferPointer { UnsafePointer<UInt32>(OpaquePointer($0.baseAddress!)).pointee.littleEndian }
  60. default:
  61. throw DecodeError.invalidData
  62. }
  63. }
  64. private static func parseContent(_ generator: inout IndexingIterator<ArraySlice<UInt8>>) throws -> [UInt8] {
  65. guard let length = generator.next() else { throw DecodeError.invalidData }
  66. switch length {
  67. case 0..<0x80:
  68. var content = [UInt8]()
  69. for _ in 0..<length {
  70. guard let b = generator.next() else { throw DecodeError.invalidData }
  71. content.append(b)
  72. }
  73. return content
  74. case 0x80:
  75. throw DecodeError.invalidData // DER - Length encoding must use the definite form
  76. default:
  77. let numberOfDigits = Int(length & 0x7F)
  78. if numberOfDigits > 4 { /* Arbitrary allow only for UInt32 max content size. */ throw DecodeError.invalidData }
  79. var buffer = [UInt8]()
  80. for _ in 0..<numberOfDigits {
  81. guard let b = generator.next() else { throw DecodeError.invalidData }
  82. buffer.append(b)
  83. }
  84. buffer = buffer.reversed() + /* padding */ [UInt8](repeating: 0, count: 4 - numberOfDigits)
  85. let length = buffer.withUnsafeBufferPointer { UnsafePointer<UInt32>(OpaquePointer($0.baseAddress!)).pointee.littleEndian }
  86. var content = [UInt8]()
  87. for _ in 0..<length {
  88. guard let b = generator.next() else { throw DecodeError.invalidData }
  89. content.append(b)
  90. }
  91. return content
  92. }
  93. }
  94. }