Skip to content

Commit

Permalink
Fix Sonar feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
kdubb committed Feb 6, 2023
1 parent 16eebb4 commit 08200c3
Show file tree
Hide file tree
Showing 31 changed files with 996 additions and 602 deletions.
4 changes: 4 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ line_length:
- 150
- 175

function_parameter_count:
- 8
- 11

function_body_length:
- 300
- 350
Expand Down
43 changes: 27 additions & 16 deletions Sources/PotentASN1/ASN1.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public indirect enum ASN1 {
case characterString = 29
case bmpString = 30

/// Creates an ASN.1 tag from the tag code (``ASN1/AnyTag-swift.typealias``), ``Class``, and if the tag is constructed.
/// Creates an ASN.1 tag from the tag code (``ASN1/AnyTag-swift.typealias``), ``Class``,
/// and if the tag is constructed.
public static func tag(from value: UInt8, in tagClass: Class, constructed: Bool) -> AnyTag {
return (value & ~0xE0) | tagClass.rawValue | (constructed ? 0x20 : 0x00)
}
Expand Down Expand Up @@ -335,10 +336,13 @@ public indirect enum ASN1 {
/// Tag code for this ASN.1 value.
///
public var anyTag: AnyTag {
guard case .tagged(let tag, _) = self else {
return knownTag!.universal
if let universal = knownTag?.universal {
return universal
}
return tag
if case .tagged(let tag, _) = self {
return tag
}
fatalError()
}

/// Name of the tag for this value in ASN.1 notation.
Expand Down Expand Up @@ -533,14 +537,12 @@ extension ASN1: Decodable {
self = .ia5String(try container.decode(String.self))
case .utcTime:
guard let time = ZonedDate(iso8601Encoded: try container.decode(String.self)) else {
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Invalid ISO8601 formatted date")
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid ISO8601 formatted date")
}
self = .utcTime(time)
case .generalizedTime:
guard let time = ZonedDate(iso8601Encoded: try container.decode(String.self)) else {
throw DecodingError.dataCorruptedError(in: container,
debugDescription: "Invalid ISO8601 formatted date")
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid ISO8601 formatted date")
}
self = .generalizedTime(time)
case .graphicString:
Expand Down Expand Up @@ -640,19 +642,28 @@ extension ASN1: Encodable {
try container.encode(anyTag)
try container.encode(value)
case .tagged(let tagValue, let data):
if let tag = Tag(rawValue: tagValue) {
let value = try ASN1DERReader.parseItem(data, as: tag.rawValue)
try value.encode(to: encoder)
}
else {
try container.encode(tagValue)
try container.encode(data)
}
try encodeTagged(tagValue: tagValue, data: data, encoder: encoder, container: &container)
case .default:
break
}
}

private func encodeTagged(
tagValue: AnyTag,
data: Data,
encoder: Swift.Encoder,
container: inout UnkeyedEncodingContainer
) throws {
if let tag = Tag(rawValue: tagValue) {
let value = try ASN1DERReader.parseItem(data, as: tag.rawValue)
try value.encode(to: encoder)
}
else {
try container.encode(tagValue)
try container.encode(data)
}
}

}


Expand Down
71 changes: 43 additions & 28 deletions Sources/PotentASN1/ASN1DERReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public enum ASN1DERReader {
return .set(try parseItems(&itemBuffer))
default:
// Default to saving tagged version
return .tagged(tagValue, Data(itemBuffer.popAll()))
return .tagged(tagValue, Data(try itemBuffer.popAll()))
}
}

Expand All @@ -132,19 +132,15 @@ public enum ASN1DERReader {
return .boolean(try itemBuffer.pop() != 0)

case .integer:
if itemBuffer.isEmpty {
return .integer(BigInt.zero)
}
let data = Data(itemBuffer.popAll())
return .integer(BigInt(derEncoded: data))
return .integer(try parseInt(&itemBuffer))

case .bitString:
let unusedBits = try itemBuffer.pop()
let data = Data(itemBuffer.popAll())
let data = Data(try itemBuffer.popAll())
return .bitString((data.count * 8) - Int(unusedBits), data)

case .octetString:
return .octetString(Data(itemBuffer.popAll()))
return .octetString(Data(try itemBuffer.popAll()))

case .null:
return .null
Expand Down Expand Up @@ -174,18 +170,10 @@ public enum ASN1DERReader {
return .ia5String(try parseString(&itemBuffer, tag: tag, encoding: .ascii))

case .utcTime:
let string = try parseString(&itemBuffer, tag: tag, encoding: .ascii)
guard let zonedDate = utcFormatter.date(from: string) else {
throw Error.invalidUTCTime
}
return .utcTime(zonedDate)
return .utcTime(try parseTime(&itemBuffer, formatter: utcFormatter))

case .generalizedTime:
let string = try parseString(&itemBuffer, tag: tag, encoding: .ascii)
guard let zonedDate = generalizedFormatter.date(from: string) else {
throw Error.invalidGeneralizedTime
}
return .generalizedTime(zonedDate)
return .generalizedTime(try parseTime(&itemBuffer, formatter: generalizedFormatter))

case .graphicString:
return .graphicString(try parseString(&itemBuffer, tag: tag, encoding: .ascii))
Expand All @@ -210,18 +198,42 @@ public enum ASN1DERReader {

case .objectDescriptor, .external, .enumerated, .embedded, .relativeOID:
// Default to saving tagged version
return .tagged(tag.rawValue, Data(itemBuffer.popAll()))
return .tagged(tag.rawValue, Data(try itemBuffer.popAll()))
}

}

private static func parseTime(
_ buffer: inout UnsafeBufferPointer<UInt8>,
formatter: SuffixedDateFormatter
) throws -> ZonedDate {

guard let string = String(data: Data(try buffer.popAll()), encoding: .ascii) else {
throw Error.invalidStringEncoding
}

guard let zonedDate = formatter.date(from: string) else {
throw Error.invalidUTCTime
}

return zonedDate
}

private static func parseInt(_ buffer: inout UnsafeBufferPointer<UInt8>) throws -> BigInt {
if buffer.isEmpty {
return BigInt.zero
}
let data = Data(try buffer.popAll())
return BigInt(derEncoded: data)
}

private static func parseReal(_ buffer: inout UnsafeBufferPointer<UInt8>) throws -> Decimal {
let lead = try buffer.pop()
if lead & 0x40 == 0x40 {
return lead & 0x1 == 0 ? Decimal(Double.infinity) : Decimal(-Double.infinity)
}
else if lead & 0xC0 == 0 {
let bytes = buffer.popAll()
let bytes = try buffer.popAll()
return Decimal(string: String(bytes: bytes, encoding: .ascii) ?? "") ?? .zero
}
else {
Expand All @@ -236,7 +248,7 @@ public enum ASN1DERReader {
characterSet: CharacterSet? = nil
) throws -> String {

guard let string = String(data: Data(buffer.popAll()), encoding: encoding) else {
guard let string = String(data: Data(try buffer.popAll()), encoding: encoding) else {
throw Error.invalidStringEncoding
}

Expand Down Expand Up @@ -322,29 +334,32 @@ public enum ASN1DERReader {

private extension UnsafeBufferPointer {

mutating func popAll() -> UnsafeRawBufferPointer {
mutating func popAll() throws -> UnsafeRawBufferPointer {
guard let baseAddress = baseAddress else {
throw ASN1DERReader.Error.unexpectedEOF
}
let buffer = UnsafeRawBufferPointer(start: baseAddress, count: count)
self = UnsafeBufferPointer(start: baseAddress?.advanced(by: count), count: 0)
self = UnsafeBufferPointer(start: baseAddress.advanced(by: count), count: 0)
return buffer
}

mutating func pop(count: Int = 0) throws -> UnsafeBufferPointer {
guard self.count >= count else {
guard let baseAddress = baseAddress, self.count >= count else {
throw ASN1DERReader.Error.unexpectedEOF
}
let buffer = UnsafeBufferPointer(start: baseAddress, count: count)
self = UnsafeBufferPointer(start: baseAddress?.advanced(by: count), count: self.count - count)
self = UnsafeBufferPointer(start: baseAddress.advanced(by: count), count: self.count - count)
return buffer
}

mutating func pop() throws -> Element {
guard self.count >= 1 else {
guard let baseAddress = baseAddress, self.count >= 1 else {
throw ASN1DERReader.Error.unexpectedEOF
}
defer {
self = UnsafeBufferPointer(start: baseAddress?.advanced(by: 1), count: self.count - 1)
self = UnsafeBufferPointer(start: baseAddress.advanced(by: 1), count: self.count - 1)
}
return baseAddress!.pointee
return baseAddress.pointee
}

}
Expand Down
Loading

0 comments on commit 08200c3

Please sign in to comment.