Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // mini_asn1_der.swift
- // miniasn1
- //
- // Created by Ales Teska on 18.2.19.
- // Copyright © 2019 TeskaLabs. All rights reserved.
- //
- import Foundation
- func asn1_int_to_bytes(x: UInt) -> [UInt8] {
- var l = x
- var d:[UInt8] = []
- while (l > 0) {
- d.append(UInt8(l & 0xFF))
- l = l >> 8
- }
- return d
- }
- func asn1_il(tag: UInt8, length: UInt) -> [UInt8] {
- if (length < 128) {
- return [tag, UInt8(length)]
- }
- let d = asn1_int_to_bytes(x:length)
- return [tag, 0x80 | UInt8(d.count)] + d
- }
- func asn1_SEQUENCE(elements: [[UInt8]?], implicit_tagging: Bool = true) -> [UInt8] {
- var d:[UInt8] = []
- var n: UInt8 = 0
- for e:[UInt8]? in elements {
- guard (e != nil) else {
- n += 1
- continue
- }
- var identifier: UInt8 = e![0]
- if implicit_tagging {
- let e0 = e![0]
- if (((e0 & 0x1F) == 0x10) || ((e0 & 0x1F) == 0x11) || (e0 == 0xA0)) {
- // the element is constructed
- identifier = 0xA0
- } else {
- // the element is primitive
- identifier = 0x80
- }
- }
- else {
- identifier = e![0]
- }
- d.append(identifier + n)
- d += e![1..<e!.count]
- n += 1
- }
- return asn1_il(tag:0x30, length:UInt(d.count)) + d
- }
- func asn1_SEQUENCE_OF(elements: [[UInt8]?], implicit_tagging: Bool = true) -> [UInt8] {
- return asn1_SEQUENCE(elements: elements, implicit_tagging: false)
- }
- func asn1_INTEGER(value: UInt) -> [UInt8] {
- // TODO: Support for negative numbers
- if (value == 0) {
- return asn1_il(tag: 0x02, length: 1) + [0]
- }
- var b = asn1_int_to_bytes(x: value)
- if (b[0] & 0x80 == 0x80){
- b.insert(0, at: 0)
- }
- return asn1_il(tag: 0x02, length: UInt(b.count)) + b
- }
- func asn1_OCTEC_STRING(value: Data) -> [UInt8] {
- return asn1_il(tag:0x04, length:UInt(value.count)) + value
- }
- func asn1_IA5STRING(value: String) -> [UInt8] {
- let b = value.data(using: .ascii)!
- return asn1_il(tag:0x16, length:UInt(b.count)) + b
- }
- func asn1_BITSTRING(value: Data) -> [UInt8] {
- return asn1_il(tag:0x03, length:UInt(value.count)+1) + [0] + value
- }
- func asn1_UTF8String(value: String) -> [UInt8] {
- let b = value.data(using: .utf8)!
- return asn1_il(tag:12, length:UInt(b.count)) + b
- }
- func asn1_UTCTime(value: Date) -> [UInt8] {
- let formatter = DateFormatter()
- formatter.dateFormat = "yyMMddHHmmSS"
- let s = formatter.string(from: value) + "Z"
- let b = s.data(using: .ascii)!
- return asn1_il(tag: 23, length: UInt(b.count)) + b
- }
- func asn1_variable_length_quantity(value: Int) -> [UInt8] {
- // Break it up in groups of 7 bits starting from the lowest significant bit
- // For all the other groups of 7 bits than lowest one, set the MSB to 1
- var v = value
- var m: UInt8 = 0x00
- var output: [UInt8] = []
- while (v >= 0x80) {
- output.insert(UInt8(v & 0x7f) | m | m, at:0)
- v = v >> 7
- m = 0x80
- }
- output.insert(UInt8(v) | m, at:0)
- return output
- }
- func asn1_OBJECT_IDENTIFIER(value:String) -> [UInt8] {
- let a: [Int] = value.split(separator: ".").map { Int($0)! }
- var oid: [UInt8] = [UInt8(a[0]*40 + a[1])] // First two items are coded by a1*40+a2
- // A rest is Variable-length_quantity
- for n in a[2..<a.count] {
- oid += asn1_variable_length_quantity(value:n)
- }
- return asn1_il(tag: 0x06, length: UInt(oid.count)) + oid
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement