daily pastebin goal
83%
SHARE
TWEET

Untitled

a guest Feb 21st, 2019 83 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top