Skip to content

Latest commit

 

History

History

snippets

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Code Snippets

Name Type Description
Get OAuth token Snippet The SDK supports the ROPC grant flow.
Certificate pinning Snippet Compares a certificate stored in the mobile app as being the same certificate presented by the web server that provides the HTTPS connection.
Key pair generation Snippet Key pairs are used in the SDK to sign challenges, coming from IBM Security Access Manager. The private key remains on the device, whereas the public key gets uploaded to the server as part of the mechanisms enrollment.
Signing data Snippet The public key would be stored on a server and provide the challenge text to the client. The client uses the private key to sign the data which is sent back to the server. The server validates the signed data against the public key to verify the keys have not been tampered with.

Get OAuth token

The SDK supports the ROPC grant flow.

Swift Version

let hostname =  URL(string: "https://yourserver/mga/sps/oauth/oauth20/token")!
let clientId = "yourClientId"
let username = "yourUserName"
let password = "yourPassword"
    
OAuthContext.sharedInstance.authorize(hostname, clientId, username: username, password: password)
{
    token, error in
  
    guard let _ = error else
    {
        print("Error: \(error.errorDescription)")
        return
    }
 
    if let token = token
    {
        // We got the token.
        print("Token: \(token)")
    }
}

Certificate pinning

Compares a certificate stored in the mobile app as being the same certificate presented by the web server that provides the HTTPS connection. Refer to URLSessionDelegate for additional information on session level events.

Assign the class implmentating URLSessionDelegate to serverTrustDelegateargument in function of the OAuthContext class.

To obtain the certificate chain to include into your Xcode project, run the following command:

input=tmpinput && touch $input && openssl s_client -connect sdk.securitypoc.com:443 -showcerts 2>/dev/null <$input | openssl x509 -inform pem -outform der -out sdk_cert.der && rm $input

Ensure the certifcate has been copied into the project folder and added to the project in Xcode. This example demonstrates a custom implementation of URLSessionDelegate. The IBMVerifySDK supports the sample below in PinnedCertificateDelegate.


Swift Version

public class MyPinnedCertificateDelegate: NSObject, URLSessionDelegate
{
    let pinnedCertificateData: Data
    
    // Initialized with the name of the file and the file extension.
    init?(forResource: String, withExtension: String)
    {
        guard let url = Bundle.main.url(forResource: forResource, withExtension: withExtension) else
        {
            return nil
        }
        
        do
        {
            self.pinnedCertificateData = try Data(contentsOf: url)
        }
        catch
        {
            return nil
        }
    }
    
    public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
    {
        guard let serverTrust = challenge.protectionSpace.serverTrust, let presentedCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else
        {
            // Terminate further processing, no certificate at index 0
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }
        
        // Compare the presented certificate to the pinned certificate.
        let presentedCertificateData: NSData = SecCertificateCopyData(presentedCertificate)
        if presentedCertificateData.isEqual(to: pinnedCertificateData)
        {
            completionHandler(.useCredential, URLCredential(trust: serverTrust))
            return
        }
        
        // Don't trust the presented certificate by default.
        completionHandler(.cancelAuthenticationChallenge, nil)
    }
}


private func execute()
{
    let hostname = "https://yourserver/mga/sps/oauth/oauth20/token"
    let clientId = "yourClientId"
    let username = "yourUserName"
    let password = "yourPassword"
    let publicKeyCertificate = "MIIGETCCBPmgAwIBAgISA3NETe9ib0wR69vFjz9Vfil ..."
    
    guard let myPinnedCertificate = MyPinnedCertificateDelegate(forResource: "MyCertficate", withExtension: "cer") else
    {
        print("invalid certificate.")
        return
    }
    
    OAuthContext.sharedInstance.authorize(hostname, clientId, username: username, password: password, serverTrustDelegate: myPinnedCertificate)
    {
        token, error in
  
        guard let _ = error else
        {
            print("Error: \(error.errorDescription)")
            return
        }
 
        if let token = token
        {
            // We got the token.
            print("Token: \(token)")
        }
    }
}
    

Key pair generation

Key pairs are used in the SDK to sign challenges, coming from IBM Security Access Manager. The private key remains on the device, whereas the public key gets uploaded to the server as part of the mechanisms enrollment.

Swift Version

// Create the private and public keys.
KeychainHelper.create("sample")
{
    success, publicKeyData  in

    if success && let data = publicKeyData
    {
        print("Public key: \(KeychainHelper.export(data)!)")
    }
}

// Delete the private key.
KeychainHelper.delete("sample")
{
    result in
    
    print("Private key deleted successful: \(result).")
}

Signing data

The public key would be stored on a server and provide the challenge text to the client. The client uses the private key to sign the data which is sent back to the server. The server validates the signed data against the public key to verify the keys have not been tampered with.

Swift Version

// Create the private and public keys.
KeychainHelper.create("sample")
{
    success, _  in

    print("Private and public keys created successfully: \(success).")
}

// Sign the data.
guard let value = KeychainHelper.sign("sample", value: "hello world") else
{
    print("Unable to sign data with private key.")
    return
}

print("Signed data: \(value)")

// Delete the private key.
KeychainHelper.delete("sample")
{
    result in
    
    print("Private key deleted successful: \(result).")
}