Skip to content

Commit

Permalink
Merge pull request #13 from dimitribouniol/dimitri/data-cleanup
Browse files Browse the repository at this point in the history
Data Type Cleanup
  • Loading branch information
m-barthelemy authored Nov 17, 2024
2 parents d065e51 + dd6d7a6 commit b93d4df
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 45 deletions.
26 changes: 11 additions & 15 deletions Sources/AcmeSwift/APIs/AcmeSwift+Orders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,13 @@ extension AcmeSwift {
var descs: [ChallengeDescription] = []
for auth in authorizations where auth.status == .pending {
for challenge in auth.challenges where (challenge.type == preferring || auth.wildcard == true) && (challenge.status == .pending || challenge.status == .invalid) {
let digest = "\(challenge.token).\(accountThumbprint.base64EncodedString().base64ToBase64Url())"
let digest = "\(challenge.token).\(accountThumbprint.base64URLString)"

if challenge.type == .dns {
let challengeDesc = ChallengeDescription(
type: challenge.type,
endpoint: "_acme-challenge.\(auth.identifier.value)",
value: sha256Digest(data: digest.data(using: .utf8)!).base64EncodedString().base64ToBase64Url(),
value: Crypto.SHA256.hash(data: Array(digest.utf8)).base64URLString,
url: challenge.url
)
descs.append(challengeDesc)
Expand Down Expand Up @@ -323,7 +324,7 @@ extension AcmeSwift {
/// Return the SHA256 digest of the ACMEv2 account public key's JWK JSON.
///
/// This value has to be present in an HTTP challenge value.
private func getAccountThumbprint() throws -> Data {
private func getAccountThumbprint() throws -> SHA256Digest {
guard let login = self.client.login else {
throw AcmeError.mustBeAuthenticated("\(AcmeSwift.self).init() must be called with an \(AccountCredentials.self)")
}
Expand All @@ -339,18 +340,13 @@ extension AcmeSwift {
)
let encoder = JSONEncoder()
encoder.outputFormatting = .sortedKeys
let jwkData = try! encoder.encode(jwk)
return sha256Digest(data: jwkData)
return Crypto.SHA256.hash(data: try encoder.encode(jwk))
}

private func sha256Digest(data: Data) -> Data {
let digest: SHA256Digest = Crypto.SHA256.hash(data: data)
let array = digest.compactMap{UInt8($0)}
let hashData = Data(array)
return hashData
/*return String(data: data, encoding: .utf8)!
return digest.map { String(format: "%02x", $0) }.joined()*/
}

}
}

extension SHA256Digest {
var base64URLString: String {
Data(self).base64EncodedString().base64ToBase64Url()
}
}
2 changes: 1 addition & 1 deletion Sources/AcmeSwift/APIs/AcmeSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public class AcmeSwift {
let wrappedBody = try AcmeRequestBody(accountURL: accountURL, privateKey: privateKey, nonce: nonce, payload: endpoint)
let body = try JSONEncoder().encode(wrappedBody)

let bodyDebug = String(data: body, encoding: .utf8)!
let bodyDebug = String(decoding: body, as: UTF8.self)
logger.debug("\(Self.self) Endpoint: \(endpoint.method) \(endpoint.url) request body: \(bodyDebug)")

request.body = .bytes(ByteBuffer(data: body))
Expand Down
26 changes: 6 additions & 20 deletions Sources/AcmeSwift/Helpers/AcmeRequestBody.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,33 +88,19 @@ struct AcmeRequestBody<T: EndpointProtocol>: Encodable {
var container = encoder.container(keyedBy: CodingKeys.self)

let protectedData = try jsonEncoder.encode(self.protected)
guard let protectedJson = String(data: protectedData, encoding: .utf8) else {
throw AcmeError.jwsEncodeError("Unable to encode AcmeRequestBody.protected as JSON string")
}
let protectedBase64 = protectedJson.toBase64Url()
let protectedJSON = String(decoding: protectedData, as: UTF8.self)
let protectedBase64 = protectedJSON.toBase64Url()
try container.encode(protectedBase64, forKey: .protected)

let payloadData = try jsonEncoder.encode(self.payload)
guard let payloadJson = String(data: payloadData, encoding: .utf8) else {
throw AcmeError.jwsEncodeError("Unable to encode AcmeRequestBody.payload as JSON string")
}
let payloadJSON = String(decoding: payloadData, as: UTF8.self)

let payloadBase64: String!
// Empty payload is required most of the time for so-called POST-AS-GET ACMEv2 requests.
if payloadJson == "\"\"" {
payloadBase64 = ""
}
else {
payloadBase64 = payloadJson.toBase64Url()
}
let payloadBase64 = payloadJSON == "\"\"" ? "" : payloadJSON.toBase64Url()
try container.encode(payloadBase64, forKey: .payload)

let signedString = "\(protectedBase64).\(payloadBase64!)"
guard let signedData = signedString.data(using: .utf8) else {
throw AcmeError.jwsEncodeError("Unable to encode data to sign String as Data")
}

let signature = try self.privateKey.signature(for: signedData)
let signedString = "\(protectedBase64).\(payloadBase64)"
let signature = try self.privateKey.signature(for: Data(signedString.utf8))
let signatureData = signature.rawRepresentation

let signatureBase64 = signatureData.toBase64UrlString()
Expand Down
4 changes: 2 additions & 2 deletions Sources/AcmeSwift/Helpers/HttpClient+Decode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extension HTTPClientResponse {
throw AcmeError.dataCorrupted("Unable to read Data from response body buffer")
}
if T.self == String.self {
return String(data: data, encoding: .utf8) as! T
return String(decoding: data, as: UTF8.self) as! T
}

return try decoder.decode(type, from: Data(data))
Expand All @@ -42,7 +42,7 @@ extension HTTPClientResponse {
if let error = try? JSONDecoder().decode(AcmeResponseError.self, from: data) {
throw error
}
throw AcmeError.errorCode(self.status.code, String(data: data, encoding: .utf8))
throw AcmeError.errorCode(self.status.code, String(decoding: data, as: UTF8.self))
}
throw AcmeError.errorCode(self.status.code, self.status.reasonPhrase)
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/AcmeSwift/Helpers/String+base64Url.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ extension String {
while base64.count % 4 != 0 {
base64 = base64.appending("=")
}
guard let data = Data(base64Encoded: base64) else {
return nil
}
return String(data: data, encoding: .utf8)
guard let data = Data(base64Encoded: base64)
else { return nil }

return String(decoding: data, as: UTF8.self)
}

/// Encodes the string as a Base64 string suitable for use as URL parameters.
Expand Down
2 changes: 1 addition & 1 deletion Sources/AcmeSwift/Models/AcmeError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public enum AcmeError: Error, Sendable {
case jwsEncodeError(String)

case dataCorrupted(String)
case errorCode(UInt, String?)
case errorCode(UInt, String)

/// A resource should have a URL, returned in a response "Location" header, but couldn't find or parse the header.
case noResourceUrl
Expand Down
3 changes: 1 addition & 2 deletions Tests/AcmeSwiftTests/OrderTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ final class OrderTests: XCTestCase {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(value)
return String(data: data, encoding: .utf8)!

return String(decoding: data, as: UTF8.self)
}

}

0 comments on commit b93d4df

Please sign in to comment.