Files
Matthieu Sieben f560cf2266 Allow "use" claims only in public jwk (#4103)
Disallow use of `use` claim in private JWK (replaced with `key_ops`)
2025-10-02 13:33:56 +02:00

84 lines
2.1 KiB
Swift
Executable File

import Foundation
import CryptoKit
import JOSESwift
class CryptoUtil: NSObject {
static func digest(data: Data) -> Data {
let hash = SHA256.hash(data: data)
return Data(hash)
}
public static func getRandomValues(byteLength: Int) -> Data {
let bytes = (0..<byteLength).map { _ in UInt8.random(in: UInt8.min...UInt8.max) }
return Data(bytes)
}
static func generateJwk() -> EncodedJWK {
let kid = UUID().uuidString
let privKey = P256.Signing.PrivateKey()
let pubKey = privKey.publicKey
let x = pubKey.x963Representation[1..<33].base64URLEncodedString()
let y = pubKey.x963Representation[33...].base64URLEncodedString()
let d = privKey.rawRepresentation.base64URLEncodedString()
let jwk = EncodedJWK()
jwk.kty = "EC"
jwk.crv = "P-256"
jwk.kid = kid
jwk.x = x
jwk.y = y
jwk.d = d
jwk.alg = "ES256"
return jwk
}
static func decodeJwk(x: String, y: String, d: String) throws -> SecKey {
func base64UrlDecode(_ string: String) -> Data? {
var base64 = string
.replacingOccurrences(of: "-", with: "+")
.replacingOccurrences(of: "_", with: "/")
let remainder = base64.count % 4
if remainder > 0 {
base64 += String(repeating: "=", count: 4 - remainder)
}
return Data(base64Encoded: base64)
}
guard let xData = base64UrlDecode(x),
let yData = base64UrlDecode(y),
let dData = base64UrlDecode(d) else {
throw ExpoAtprotoOAuthClientError.invalidJwk
}
var keyData = Data()
keyData.append(0x04)
keyData.append(xData)
keyData.append(yData)
keyData.append(dData)
let attributes: [String: Any] = [
kSecAttrKeyType as String: kSecAttrKeyTypeEC,
kSecAttrKeyClass as String: kSecAttrKeyClassPrivate,
kSecAttrKeySizeInBits as String: 256
]
var error: Unmanaged<CFError>?
let key = SecKeyCreateWithData(keyData as CFData, attributes as CFDictionary, &error)
if error != nil {
throw error!.takeUnretainedValue()
}
guard let key = key else {
throw ExpoAtprotoOAuthClientError.invalidJwk
}
return key
}
}