Hi
I am very new to swift.
What I have tried till now is
import UIKit
import Foundation
import Security
// Custom URLSessionDelegate
class SSLPinningDelegate: NSObject, URLSessionDelegate {
let certificate: SecCertificate
let privateKey: SecKey
init(certificate: SecCertificate, privateKey: SecKey) {
self.certificate = certificate
self.privateKey = privateKey
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate {
let credential = URLCredential(identity: privateKey as! SecIdentity, certificates: [certificate], persistence: .forSession)
completionHandler(.useCredential, credential)
} else {
completionHandler(.performDefaultHandling, nil)
}
}
}
@objc(AzureProvisionWithCertificate)
class AzureProvisionWithCertificate: NSObject {
@objc(provisionAndUploadFile:withRegistrationId:withKey:withCertificate:withProvisionHost:withFileNameWithFolder:withModelId:withResolver:withRejecter:)
func provisionAndUploadFile(scopeId:String, registrationId:String, key:String, certificate:String, provisionHost:String, fileNameWithFolder:String, modelId:String, resolve:@escaping RCTPromiseResolveBlock, reject:@escaping RCTPromiseRejectBlock) -> Void {
print("started: provisionAndUploadFile api")
// Create a session with the SSLPinningDelegate
let sslPinningDelegate = SSLPinningDelegate(certificate: certificate as! SecCertificate, privateKey: key as! SecKey)
print("sslPinningDelegate: \(sslPinningDelegate)")
// Create the URL
let url = URL(string: "https://global.azure-devices-provisioning.net/\(scopeId)/registrations/\(registrationId)/register?api-version=2021-06-01")!
// Create the request
var request = URLRequest(url: url)
request.httpMethod = "PUT"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("utf-8", forHTTPHeaderField: "Content-Encoding")
// Create the request body
let bodyData = ["registrationId": registrationId]
let jsonData = try? JSONSerialization.data(withJSONObject: bodyData)
// Set the request body
request.httpBody = jsonData
// Create the session configuration
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
// Create the data task
let task = session.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Error: \(error.localizedDescription)")
reject("Error", error.localizedDescription, error)
} else if let data = data {
// Process the response data
let responseString = String(data: data, encoding: .utf8)
print("Response data: \(responseString)")
resolve("Response data: \(responseString)")
} else {
print("No data received")
reject("Error", "No data received", nil)
}
}
// Start the data task
task.resume()
}
}
Please help me to correct it.
Post
Replies
Boosts
Views
Activity
Hi I have updated the code but I am getting error : Cannot find 'SecIdentityCreateWithCertificate' in scope
import Foundation
import Security
import UIKit
class URLSessionPinningDelegate: NSObject, URLSessionDelegate {
var identity: SecIdentity
init(identity: SecIdentity) {
self.identity = identity
}
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let credential = URLCredential(identity: self.identity, certificates: nil, persistence: .forSession)
completionHandler(.useCredential, credential)
}
}
func loadIdentity(certPath: String, keyPath: String) -> SecIdentity? {
guard let certData = try? Data(contentsOf: URL(fileURLWithPath: certPath)) else {
print("Unable to load certificate")
return nil
}
guard let cert = SecCertificateCreateWithData(nil, certData as CFData) else {
print("Unable to create certificate")
return nil
}
guard let keyData = try? Data(contentsOf: URL(fileURLWithPath: keyPath)) else {
print("Unable to load private key")
return nil
}
let keyDict: [NSString: Any] = [
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
kSecAttrKeySizeInBits: 2048,
kSecReturnPersistentRef: true
]
var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateWithData(keyData as CFData, keyDict as CFDictionary, &error) else {
// print("Unable to create private key: \(error?.takeRetainedValue() ?? "Unknown error" as CFError)")
print("Unable to create private key")
return nil
}
var identity: SecIdentity?
let status = SecIdentityCreateWithCertificate(cert, privateKey, &identity) // GETTING ERROR HERE : Cannot find 'SecIdentityCreateWithCertificate' in scope
guard status == errSecSuccess else {
print("Unable to create identity")
return nil
}
return identity
}
@objc(AzureProvisionWithCertificate)
class AzureProvisionWithCertificate: NSObject {
@objc(provisionAndUploadFile:withRegistrationId:withKey:withCertificate:withProvisionHost:withFileNameWithFolder:withModelId:withResolver:withRejecter:)
func provisionAndUploadFile(scopeId:String, registrationId:String, key:String, certificate:String, provisionHost:String, fileNameWithFolder:String, modelId:String, resolve:@escaping RCTPromiseResolveBlock, reject:@escaping RCTPromiseRejectBlock) -> Void {
let certPath = "/path/to/your/device-cert.pem"
let keyPath = "/path/to/your/device-key.pem"
guard let identity = loadIdentity(certPath: certificate, keyPath: key) else {
print("Unable to load identity")
return
}
let session = URLSession(configuration: .default, delegate: URLSessionPinningDelegate(identity: identity), delegateQueue: nil)
guard let url = URL(string: "https://global.azure-devices-provisioning.net/[scopeId]/registrations/[registrationId]/register?api-version=2021-06-01") else {
print("Invalid URL")
return
}
var request = URLRequest(url: url)
request.httpMethod = "PUT"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("utf-8", forHTTPHeaderField: "Content-Encoding")
let body = ["registrationId": "registrationId"]
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: [])
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
print("Request failed: \(error)")
} else if let data = data, let responseString = String(data: data, encoding: .utf8) {
print("Response: \(responseString)")
}
}
task.resume()
}
}
I am using xcode 15.3 and macOS Sonoma 14.5
Stack trace for crash:
* frame #0: 0x000000019e78b038 libobjc.A.dylib`objc_msgSend + 56
frame #1: 0x00000001af0be964 Security`SecIdentityCopyCertificate + 24
frame #2: 0x00000001d7e3fd2c libboringssl.dylib`boringssl_identity_create_from_identity + 92
frame #3: 0x00000001d7e50488 libboringssl.dylib`boringssl_context_set_identity + 284
frame #4: 0x00000001d7e500dc libboringssl.dylib`__boringssl_context_certificate_request_callback_block_invoke_3 + 1048
frame #5: 0x00000001a6de6230 Network`nw_queue_context_async_if_needed + 88
frame #6: 0x00000001d7e4fc9c libboringssl.dylib`__boringssl_context_certificate_request_callback_block_invoke_2 + 148
frame #7: 0x00000001a7b43668 CFNetwork`___lldb_unnamed_symbol8855 + 576
frame #8: 0x00000001a7bdab08 CFNetwork`___lldb_unnamed_symbol12666 + 204
frame #9: 0x00000001a7b43b08 CFNetwork`___lldb_unnamed_symbol8863 + 700
frame #10: 0x00000001a7b86738 CFNetwork`___lldb_unnamed_symbol10375 + 84
frame #11: 0x00000001a7b869d0 CFNetwork`___lldb_unnamed_symbol10379 + 36
frame #12: 0x00000001079e0b98 libdispatch.dylib`_dispatch_call_block_and_release + 32
frame #13: 0x00000001079e27bc libdispatch.dylib`_dispatch_client_callout + 20
frame #14: 0x00000001079ea66c libdispatch.dylib`_dispatch_lane_serial_drain + 832
frame #15: 0x00000001079eb43c libdispatch.dylib`_dispatch_lane_invoke + 460
frame #16: 0x00000001079ecabc libdispatch.dylib`_dispatch_workloop_invoke + 2336
frame #17: 0x00000001079f8404 libdispatch.dylib`_dispatch_root_queue_drain_deferred_wlh + 328
frame #18: 0x00000001079f7a38 libdispatch.dylib`_dispatch_workloop_worker_thread + 444
frame #19: 0x0000000203763934 libsystem_pthread.dylib`_pthread_wqthread + 288
Please help. Thanks in Advance!!!