Created
February 18, 2019 22:09
-
-
Save ateska/030f5fdadc5c0869982ae4eab38c8b96 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment