SSL Public Key Hash Pinning" ...
"The Mobile SDK extracts the public keys from the certificate from the server and validates against a list of strings that contains pinned public key hashes in base-64 format."
This works as documented on Android, but does not work as expected on iOS.
You can use an incorrect key hash in the MSSO Configuration file, and it still all works!
Sample MSSO Config file shown below.
The endpoint is "gateway.domain.com" ... the key hashes are from an entirely different PTSB endpoint.
The expected result is a Certificate Pinning Failure
Mobile SDK Version on iOS is 2.4
{
"server": {
"hostname": "gateway.domain.com",
"port": 443,
"prefix": "",
"server_certs": []
},
"oauth": {
"client": {
"organization": "CA Technologies",
"description": "Example application for Mobile SSO demonstrations",
"client_name": "AppA",
"client_type": "confidential",
"registered_by": "admin",
"client_custom": {},
"client_ids": [
{
"client_id": "1234edb0-1234-1234-1234-1234140bd797",
"client_secret": "",
"scope": "openid msso phone profile address email msso_register",
"redirect_uri": "https://ios.ssosdk.domain.com/ios",
"environment": "SAMPLE",
"status": "ENABLED",
"registered_by": "admin",
"service_ids": "",
"account_plan_mapping_ids": "",
"client_key_custom": {}
}
]
},
"system_endpoints": {
"authorization_endpoint_path": "/auth/oauth/v2/authorize",
"token_endpoint_path": "/auth/oauth/v2/token",
"token_revocation_endpoint_path": "/auth/oauth/v2/token/revoke",
"usersession_logout_endpoint_path": "/connect/session/logout",
"usersession_status_endpoint_path": "/connect/session/status"
},
"oauth_protected_endpoints": {
"userinfo_endpoint_path": "/openid/connect/v1/userinfo"
}
},
"mag": {
"system_endpoints": {
"device_register_endpoint_path": "/connect/device/register",
"device_renew_endpoint_path": "/connect/device/renew",
"device_client_register_endpoint_path": "/connect/device/register/client",
"device_remove_endpoint_path": "/connect/device/remove",
"client_credential_init_endpoint_path": "/connect/client/initialize",
"authenticate_otp_endpoint_path": "/auth/generateOTP"
},
"oauth_protected_endpoints": {
"enterprise_browser_endpoint_path": "/connect/enterprise/browser",
"device_list_endpoint_path": "/connect/device/list",
"device_metadata_endpoint_path": "/connect/device/metadata"
},
"mobile_sdk": {
"sso_enabled": true,
"location_enabled": false,
"location_provider": "network",
"msisdn_enabled": true,
"trusted_public_pki": false,
"enable_public_key_pinning": true,
"trusted_cert_pinned_public_key_hashes": ["EDITEDMz5WntXeLCXNv8vXuA_DAaU_mpnDsz80Qh-wE=","EDITEDpHr1YAS0DugvLGsrI9Vm1yEkZAyllKxemXXf4=","EDITEDvh0OioIruIfFR4kMPnBqrS2rdiVPl_s2uC_CY="],
"client_cert_rsa_keybits": 2048
},
"ble": {
"msso_ble_service_uuid": "12342f36-1234-1234-1234-1234a5b093db",
"msso_ble_characteristic_uuid": "123434cc-1234-1234-1234-aa07a512343db",
"msso_ble_rssi": -80
}
},
"custom": {
"oauth_demo_protected_api_endpoint_path": "/oauth/v2/protectedapi/foo",
"mag_demo_products_endpoint_path": "/protected/resource/products"
}
}
Mobile SDK 2.4
The SDK does not behave in-line with the documentation - if you set the SSL Public Key Hash Pinning and trusted_cert_hashes[] in the msso_config.json file, then pinning is not enforced: even invalid certificates will work.
1) What does work is to set the pinning mode in the App code.
- The Public Key Hash in msso_config.json for Android (Base 64 URL encoded) the Public Key Hash needs to be Base64 encoded.
See sample command and code below:
NSString *url = @"https://auth-domain.com:443"; // URL of the MAG Server including port.
MASSecurityConfiguration *secConfig = [MASConfiguration securityConfigurationForDomain:[NSURL URLWithString:url]]
secConfig.pinningMode = MASSecuritySSLPinningModePublicKeyHash;
2) Then add the Base64 hashes to the msso_config.json file
openssl x509 -in auth-cert.domain.crt -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
"trusted_cert_pinned_public_key_hashes": ["Tux4BFMz5WEDITEDCXNv8vXuA/DAaU/mpnDsz80Qh+wE=","w9I8WrpHr1EDITEDgvLGsrI9Vm1yEkZAyllKxemXXf4=","i7WTqTvh0OioIruIfEDITEDnBqrS2rdiVPl/s2uC/CY="],
[MASConfiguration setSecurityConfiguration:secConfig error:&error];
if (error)
{
// check for an error
NSLog( @"Config Error, Woopsie: %ld - %@", (long)error.code, error.localizedDescription);
}
else {
// security configuration is successfully set
}
- If configuring as above , then positive and negative cases work as expected : incorrect hash pins cause pinning error, correct hash pins is okay.