I am trying to process a server-to-server notification from Apple’s app store. The following notes detail what I have discovered, and I welcome any correction that is needed.
The notification is received in a JSON packet and the “signedPayload” can be extracted from it. The signedPayload is in the form of a JWT and can therefore be split into the Header, Payload and Signature.
When the Header is base64 decoded it results in another JSON packet which contains two fields: “alg” and “x5c”. The algorithm field has the value ES256 and the x5c field contains a chain of three certificates separated by commas.
The Payload can be base64 decoded and then interpreted according to the information here: https://developer.apple.com/documentation/appstoreservernotifications/responsebodyv2decodedpayload
That part is simple. However the payload should not be actioned until the signature is verified.
The Signature is kept for later in the process.
Back to the certificate chain. The last certificate in the chain (certificate 3) is Apple’s root certificate AppleRootCA-G3 certificate. This can be downloaded from https://www.apple.com/certificateauthority/ The cer file can be converted to a pem file using openssl as follows:
openssl x509 -inform der -in AppleRootCA-G3.cer -outform pem -out AppleRootCA-G3.pem
Comparing the pem file with certificate 3 in the chain will confirm that they are identical.
Similarly, the middle certificate in the chain (certificate 2) is Apple’s intermediate certificate AppleWWDRCAG6.cer. Converting it to a pem file will confirm they are identical.
The first certificate in the chain (certificate 1) is the entity certificate.
The root and intermediate certificates can be converted to text using openssl as follows:
openssl x509 -text -in AppleRootCA-G3.pem
openssl x509 -text -in AppleWWDRCAG6.pem
This will reveal the issuer and subject of each certificate. I understand that for the certificate chain to be valid, the subject of the root must match the issuer of the intermediate, the subject of the intermediate must match the issuer of the entity and the subject and issuer of the root must be the same. https://docs.apigee.com/how-to-guides/validating-certificate-chain#splitcertchain
This is the case. So far, so good.
I am not sure what to do from this point onwards. My thinking is that I need to complete the validation of the certificate chain and then somehow calculate a signature which needs to match the Signature which formed part of the signed payload. How should this be done? I am also unclear as to whether I need the shared secret from our Apple developer’s account, and if so how is it used? The encoding algorithm ES256 must also be used somewhere but again I'm not sure where or how.