Skip to content

Instantly share code, notes, and snippets.

@ateska
Created February 18, 2019 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ateska/030f5fdadc5c0869982ae4eab38c8b96 to your computer and use it in GitHub Desktop.
Save ateska/030f5fdadc5c0869982ae4eab38c8b96 to your computer and use it in GitHub Desktop.
//
// 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