Search code examples
iosswiftrestcertificate

How to make a REST API request, with a certificate provided as String, in swift?


I have to make a POST request to an endpoint, where that request should be included with the client certificate. The problem here is, I receive the client certificate cert-chain as a string(the format as below).

-----BEGIN CERTIFICATE-----

MIID9jCCAt6gAwIBAgIQNwHqBnL+445eqCUKVWroxDANBgkqhkiG9w0BAQsFADCB

XufZCQ4mDV3MU0z+wsS4alR7b410V5Wet36pjUkrWtHEI2dBWZFzCOay19Vpb2V2

0M/zl07YpoZYxw==

-----END CERTIFICATE-----

Note: The string is much bigger :)

I tried to convert the string to NSData object and create a PKCS12 object. But converting to NSData itself fails.

How I converted is

let dataDecoded = Data(base64Encoded: certChainString, options: .ignoreUnknownCharacters)

This returns empty data object as the size of dataDecoded is 0 bytes.

How can I send the POST request with the certificate when the certChainString is provided?


Solution

  • Are you trying to convert it while it still includes -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----?

    It isn't valid base64 with those included, so remove them first.

    let certChainString = """
    -----BEGIN CERTIFICATE-----
    
    ...
    
    -----END CERTIFICATE-----
    """
    let certString = certChainString
                          .replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "")
                          .replacingOccurrences(of: "-----END CERTIFICATE-----", with: "")
    
    let dataDecoded  = Data(base64Encoded: certString, options: .ignoreUnknownCharacters)
    

    If the API request returns important data, please consider reading more on Security topic first or use frameworks.

    Edit:

    import Foundation
    
    let certChainString = """
    -----BEGIN CERTIFICATE-----
    
    ... cert here ...
    
    -----END CERTIFICATE-----
    """
    let certString = certChainString
                          .replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "")
                          .replacingOccurrences(of: "-----END CERTIFICATE-----", with: "")
    
    private var key: SecKey?
    
    if let dataDecoded  = Data(base64Encoded: certString, options: .ignoreUnknownCharacters),
       let certificate = SecCertificateCreateWithData(nil, dataDecoded as CFData)
    {
        var trust: SecTrust?
        let policy = SecPolicyCreateBasicX509()
        let status = SecTrustCreateWithCertificates(certificate, policy, &trust)
    
        if status == errSecSuccess, let trust {
            key = SecTrustCopyKey(trust)
        }
    }
    
    print(key)