I tried to set up app attestation between my app and php but I rarely find any other source of explaination than Apple's own documentation, which let me stuck quite at an early state. So far I got the following steps:
On the client side, following https://developer.apple.com/documentation/devicecheck/establishing_your_app_s_integrity, I creted my attestation as a base64 encoded string:
attestation.base64EncodedString()
I then send that string to the server, following https://developer.apple.com/documentation/devicecheck/validating_apps_that_connect_to_your_server from now on.
The documentation says, that the attestation is in the CBOR format. I therefor first decode the base64 encoded string and parse it using (https://github.com/Spomky-Labs/cbor-php).
<?php
use CBOR\Decoder;
use CBOR\OtherObject;
use CBOR\Tag;
use CBOR\StringStream;
$otherObjectManager = new OtherObject\OtherObjectManager();
$tagManager = new Tag\TagObjectManager();
$decoder = new Decoder($tagManager, $otherObjectManager);
$data = base64_decode(/* .. base64 encoded attestation string as send from the client (see swift snippet above) */);
$stream = new StringStream($data);
$object = $decoder->decode($stream);
$norm = $object->getNormalizedData();
$fmt = $norm['fmt'];
$x5c = $norm['attStmt']['x5c'];
From the documentation, the normalized object should have the following format:
{
fmt: 'apple-appattest',
attStmt: {
x5c: [
<Buffer 30 82 02 cc ... >,
<Buffer 30 82 02 36 ... >
],
receipt: <Buffer 30 80 06 09 ... >
},
authData: <Buffer 21 c9 9e 00 ... >
}
which it does:
$fmt == "apple-appattest" // true
Then the next according to the documentation is described as:
Verify that the x5c array contains the intermediate and leaf certificates for App Attest, starting from the credential certificate in the first data buffer in the array (credcert). Verify the validity of the certificates using Apple’s App Attest root certificate.
However, I don't know how to proceed further on this. The content of e.g. $norm['attStmt']['x5c'][0]
is a mix of readable chars and glyphs. To give you an idea, this is a random substring from the content of $norm['attStmt']['x5c'][0]
: "Certification Authority10U Apple Inc.10 UUS0Y0*�H�=*�H�=B��c�}�". That's why I'm not really sure wheather I have to perform any further encodeing/decoding steps.
I tried parsing the certificate but without any luck (both var_dump return false):
$cert = openssl_x509_read($x5c[0]);
var_dump($cert); // false - indicating that reading the cert failed
$parsedCert = openssl_x509_parse($cert, false);
var_dump($parsedCert); // false - of course, since the prior step did not succeed
Any ideas, guidance or alternative ressources are highly appreciated. Thank you!
After a while I came up with the following solution. The $x5c field contains a list of certificates, all in binary form. I wrote the folowing converter to create a ready-to-use certificate in PEM format, which does the following:
the following then works: