更新了登录
This commit is contained in:
163
Pods/SwiftyRSA/Source/X509Certificate.swift
generated
Normal file
163
Pods/SwiftyRSA/Source/X509Certificate.swift
generated
Normal file
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// X509Certificate.swift
|
||||
// SwiftyRSA
|
||||
//
|
||||
// Created by Stchepinsky Nathan on 24/06/2021.
|
||||
// Copyright © 2021 Scoop. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Encoding/Decoding lengths as octets
|
||||
private extension NSInteger {
|
||||
func encodedOctets() -> [CUnsignedChar] {
|
||||
// Short form
|
||||
if self < 128 {
|
||||
return [CUnsignedChar(self)]
|
||||
}
|
||||
|
||||
// Long form
|
||||
let long = Int(log2(Double(self)) / 8 + 1)
|
||||
var len = self
|
||||
var result: [CUnsignedChar] = [CUnsignedChar(long + 0x80)]
|
||||
|
||||
for _ in 0..<long {
|
||||
result.insert(CUnsignedChar(len & 0xFF), at: 1)
|
||||
len = len >> 8
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
init?(octetBytes: [CUnsignedChar], startIdx: inout NSInteger) {
|
||||
if octetBytes[startIdx] < 128 {
|
||||
// Short form
|
||||
self.init(octetBytes[startIdx])
|
||||
startIdx += 1
|
||||
} else {
|
||||
// Long form
|
||||
let octets = NSInteger(octetBytes[startIdx] as UInt8 - 128)
|
||||
|
||||
if octets > octetBytes.count - startIdx {
|
||||
self.init(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
var result = UInt64(0)
|
||||
|
||||
for octet in 1...octets {
|
||||
result = (result << 8)
|
||||
result = result + UInt64(octetBytes[startIdx + octet])
|
||||
}
|
||||
|
||||
startIdx += 1 + octets
|
||||
self.init(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public extension Data {
|
||||
// This code source come from Heimdall project https://github.com/henrinormak/Heimdall published under MIT Licence
|
||||
|
||||
/// This method prepend the X509 header to a given public key
|
||||
func prependx509Header() -> Data {
|
||||
let result = NSMutableData()
|
||||
|
||||
let encodingLength: Int = (self.count + 1).encodedOctets().count
|
||||
let OID: [CUnsignedChar] = [0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
|
||||
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00]
|
||||
|
||||
var builder: [CUnsignedChar] = []
|
||||
|
||||
// ASN.1 SEQUENCE
|
||||
builder.append(0x30)
|
||||
|
||||
// Overall size, made of OID + bitstring encoding + actual key
|
||||
let size = OID.count + 2 + encodingLength + self.count
|
||||
let encodedSize = size.encodedOctets()
|
||||
builder.append(contentsOf: encodedSize)
|
||||
result.append(builder, length: builder.count)
|
||||
result.append(OID, length: OID.count)
|
||||
builder.removeAll(keepingCapacity: false)
|
||||
|
||||
builder.append(0x03)
|
||||
builder.append(contentsOf: (self.count + 1).encodedOctets())
|
||||
builder.append(0x00)
|
||||
result.append(builder, length: builder.count)
|
||||
|
||||
// Actual key bytes
|
||||
result.append(self)
|
||||
|
||||
return result as Data
|
||||
}
|
||||
|
||||
func hasX509Header() throws -> Bool {
|
||||
let node: Asn1Parser.Node
|
||||
do {
|
||||
node = try Asn1Parser.parse(data: self)
|
||||
} catch {
|
||||
throw SwiftyRSAError.asn1ParsingFailed
|
||||
}
|
||||
|
||||
// Ensure the raw data is an ASN1 sequence
|
||||
guard case .sequence(let nodes) = node else {
|
||||
return false
|
||||
}
|
||||
|
||||
// Must contain 2 elements, a sequence and a bit string
|
||||
if nodes.count != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
// Ensure the first node is an ASN1 sequence
|
||||
guard case .sequence(let firstNode) = nodes[0] else {
|
||||
return false
|
||||
}
|
||||
|
||||
// Must contain 2 elements, an object id and NULL
|
||||
if firstNode.count != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
guard case .objectIdentifier(_) = firstNode[0] else {
|
||||
return false
|
||||
}
|
||||
|
||||
guard case .null = firstNode[1] else {
|
||||
return false
|
||||
}
|
||||
|
||||
// The 2sd child has to be a bit string containing a sequence of 2 int
|
||||
let last = nodes[1]
|
||||
if case .bitString(let secondChildSequence) = last {
|
||||
return try secondChildSequence.isAnHeaderlessKey()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isAnHeaderlessKey() throws -> Bool {
|
||||
let node: Asn1Parser.Node
|
||||
do {
|
||||
node = try Asn1Parser.parse(data: self)
|
||||
} catch {
|
||||
throw SwiftyRSAError.asn1ParsingFailed
|
||||
}
|
||||
|
||||
// Ensure the raw data is an ASN1 sequence
|
||||
guard case .sequence(let nodes) = node else {
|
||||
return false
|
||||
}
|
||||
|
||||
// Detect whether the sequence only has integers, in which case it's a headerless key
|
||||
let onlyHasIntegers = nodes.filter { node -> Bool in
|
||||
if case .integer = node {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}.isEmpty
|
||||
|
||||
// Headerless key
|
||||
return onlyHasIntegers
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user