Inspect certificate pinning in NSAppTransportSecurity configuration (iOS applications)

According to Apple's documentation:

SPKI-SHA256-BASE64: You represent a pinned certificate using the Base64-encoded SHA-256 digest of an X.509 certificate’s DER-encoded ASN.1 Subject Public Key Info (SPKI) structure

NSPinnedDomains: The value for this optional key is a dictionary with keys that specify the domain names for which you want to set the expected certificates. The value for each domain name key is another dictionary that configures the expected certificates for that domain

Get SPKI-SHA256-BASE64 values from Info.plist

cat xy.app/Info.plist | grep -A20 NSAppTransportSecurity
        <key>NSAppTransportSecurity</key>
        <dict>
                <key>NSPinnedDomains</key>
                <dict>
                        <key>google.com</key>
                        <dict>
                                <key>NSPinnedCAIdentities</key>
                                <array>
                                        <dict>
                                                <key>SPKI-SHA256-BASE64</key>
                                                <string>{b64encoded_value}</string>
                                        </dict>
                                        <dict>
                                                <key>SPKI-SHA256-BASE64</key>
                                                <string>{b64encoded_value}</string>
                                        </dict>
                                </array>
                                <key>NSIncludesSubdomains</key>
                                <true/>
                        </dict>
                </dict>

Get SPKI-SHA256-BASE64 values from the pinned domain

Extract domain's cert into a .pem file

openssl s_client -showcerts -connect google.com:443 -servername google.com </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > google.com.pem

Extract the public key from the .pem file

openssl x509 -pubkey -in google.com.pem -noout > google.com.pubkey.pem

Convert the public key into the correct format then compare the values

openssl pkey -in google.com.pubkey.pem -pubin -inform pem -outform der | openssl dgst -sha256 -binary | openssl enc -base64

Reference

Thoughts? Leave a comment