Advertisement
Guest User

Untitled

a guest
Feb 21st, 2019
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.45 KB | None | 0 0
  1. //
  2. // mini_asn1_der.swift
  3. // miniasn1
  4. //
  5. // Created by Ales Teska on 18.2.19.
  6. // Copyright © 2019 TeskaLabs. All rights reserved.
  7. //
  8.  
  9. import Foundation
  10.  
  11. func asn1_int_to_bytes(x: UInt) -> [UInt8] {
  12. var l = x
  13. var d:[UInt8] = []
  14. while (l > 0) {
  15. d.append(UInt8(l & 0xFF))
  16. l = l >> 8
  17. }
  18. return d
  19. }
  20.  
  21. func asn1_il(tag: UInt8, length: UInt) -> [UInt8] {
  22. if (length < 128) {
  23. return [tag, UInt8(length)]
  24. }
  25. let d = asn1_int_to_bytes(x:length)
  26. return [tag, 0x80 | UInt8(d.count)] + d
  27. }
  28.  
  29. func asn1_SEQUENCE(elements: [[UInt8]?], implicit_tagging: Bool = true) -> [UInt8] {
  30. var d:[UInt8] = []
  31.  
  32. var n: UInt8 = 0
  33. for e:[UInt8]? in elements {
  34. guard (e != nil) else {
  35. n += 1
  36. continue
  37. }
  38. var identifier: UInt8 = e![0]
  39. if implicit_tagging {
  40. let e0 = e![0]
  41. if (((e0 & 0x1F) == 0x10) || ((e0 & 0x1F) == 0x11) || (e0 == 0xA0)) {
  42. // the element is constructed
  43. identifier = 0xA0
  44. } else {
  45. // the element is primitive
  46. identifier = 0x80
  47. }
  48. }
  49. else {
  50. identifier = e![0]
  51. }
  52. d.append(identifier + n)
  53. d += e![1..<e!.count]
  54.  
  55. n += 1
  56. }
  57.  
  58. return asn1_il(tag:0x30, length:UInt(d.count)) + d
  59. }
  60.  
  61. func asn1_SEQUENCE_OF(elements: [[UInt8]?], implicit_tagging: Bool = true) -> [UInt8] {
  62. return asn1_SEQUENCE(elements: elements, implicit_tagging: false)
  63. }
  64.  
  65. func asn1_INTEGER(value: UInt) -> [UInt8] {
  66. // TODO: Support for negative numbers
  67. if (value == 0) {
  68. return asn1_il(tag: 0x02, length: 1) + [0]
  69. }
  70. var b = asn1_int_to_bytes(x: value)
  71. if (b[0] & 0x80 == 0x80){
  72. b.insert(0, at: 0)
  73. }
  74. return asn1_il(tag: 0x02, length: UInt(b.count)) + b
  75. }
  76.  
  77. func asn1_OCTEC_STRING(value: Data) -> [UInt8] {
  78. return asn1_il(tag:0x04, length:UInt(value.count)) + value
  79. }
  80.  
  81. func asn1_IA5STRING(value: String) -> [UInt8] {
  82. let b = value.data(using: .ascii)!
  83. return asn1_il(tag:0x16, length:UInt(b.count)) + b
  84. }
  85.  
  86. func asn1_BITSTRING(value: Data) -> [UInt8] {
  87. return asn1_il(tag:0x03, length:UInt(value.count)+1) + [0] + value
  88. }
  89.  
  90. func asn1_UTF8String(value: String) -> [UInt8] {
  91. let b = value.data(using: .utf8)!
  92. return asn1_il(tag:12, length:UInt(b.count)) + b
  93. }
  94.  
  95. func asn1_UTCTime(value: Date) -> [UInt8] {
  96.  
  97. let formatter = DateFormatter()
  98. formatter.dateFormat = "yyMMddHHmmSS"
  99. let s = formatter.string(from: value) + "Z"
  100. let b = s.data(using: .ascii)!
  101. return asn1_il(tag: 23, length: UInt(b.count)) + b
  102. }
  103.  
  104. func asn1_variable_length_quantity(value: Int) -> [UInt8] {
  105. // Break it up in groups of 7 bits starting from the lowest significant bit
  106. // For all the other groups of 7 bits than lowest one, set the MSB to 1
  107.  
  108. var v = value
  109. var m: UInt8 = 0x00
  110. var output: [UInt8] = []
  111. while (v >= 0x80) {
  112. output.insert(UInt8(v & 0x7f) | m | m, at:0)
  113. v = v >> 7
  114. m = 0x80
  115. }
  116. output.insert(UInt8(v) | m, at:0)
  117. return output
  118. }
  119.  
  120. func asn1_OBJECT_IDENTIFIER(value:String) -> [UInt8] {
  121. let a: [Int] = value.split(separator: ".").map { Int($0)! }
  122. var oid: [UInt8] = [UInt8(a[0]*40 + a[1])] // First two items are coded by a1*40+a2
  123. // A rest is Variable-length_quantity
  124. for n in a[2..<a.count] {
  125. oid += asn1_variable_length_quantity(value:n)
  126. }
  127. return asn1_il(tag: 0x06, length: UInt(oid.count)) + oid
  128. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement