Video playback through HTTPS with client certificate

Hello!

We have HLS-streaming server secured with client SSL certificate. How we can play our secured m3u8 in tvOS(Swift)/iOS(Objective-C)?


Our content API secured with client certificates too. And we created logic to work with it by using Authentication challenge.


When we tried to implement something similar to content API using AVPlayer View Delegate:

class PlayerViewDelegate: NSObject, AVAssetResourceLoaderDelegate {

    func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForResponseTo authenticationChallenge: URLAuthenticationChallenge) -> Bool {

        if authenticationChallenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {
      
            let credential:URLCredential = URLCredential(trust: serverTrust)
     
            authenticationChallenge.sender?.use(credential, for: authenticationChallenge)
     
            authenticationChallenge.sender?.use(URLCredential(trust: authenticationChallenge.protectionSpace.serverTrust!), for: authenticationChallenge)

        }
        else if authenticationChallenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate
        {
     
            let path: String = Bundle.main.path(forResource: "client", ofType: "pfx")!
            let PKCS12Data = try! Data(contentsOf: URL(fileURLWithPath: path))
     
            let identityAndTrust:IdentityAndTrust = ApplicationSecurity.ExtractIdentity(PKCS12Data, password: "PASS");
     
            let urlCredential:URLCredential = URLCredential(
                identity: identityAndTrust.identity,
                certificates: identityAndTrust.certArray as? [AnyObject],
                persistence: URLCredential.Persistence.permanent);
     
            authenticationChallenge.sender?.use(urlCredential, for: authenticationChallenge)
        }
        else
        {
            authenticationChallenge.sender?.continueWithoutCredential(for: authenticationChallenge)
        }

        return true

}
}

nothing happens, resourceLoader not occurs.


(At the server side, server didn't see the client certificate)


We also add our CA certificate at keychain on application start:


let result: UnsafeMutablePointer<CFTypeRef?>? = nil
var error = noErr

let rootCertPath = Bundle.main.path(forResource: "server", ofType: "der")
let rootCertData = NSData(contentsOfFile: rootCertPath!)!

let rootCert = SecCertificateCreateWithData(kCFAllocatorDefault, rootCertData)

let kSecClassValue = NSString(format: kSecClass)
let kSecClassCertificateValue = NSString(format: kSecClassCertificate)
let kSecValueRefValue = NSString(format: kSecValueRef)

let dict =
  [
  kSecClassValue: kSecClassCertificateValue,
  kSecValueRefValue: rootCert.unsafelyUnwrapped
  ] as [NSString : Any]

error = SecItemAdd(dict as CFDictionary, result)

return false


but still nothing. Playback doesn't work and Delegate method with challenge not handled!


Thanks!

Replies

This is outside of my direct experiene, but have you read Technical Note TN2232 "HTTPS Server Trust Evaluation" https://developer.apple.com/library/content/technotes/tn2232/_index.html

Hi Sergey


did you find a solution for this?


Thanks