Handoff and Universal Links failed on iOS 9 - ios

I am setting up my apple-app-site-association file follow this tutorial:
Handoff works on iOS 8 but handoff does not work on iOS 9.
I setup a free hosting site and upload the apple-app-site-association file onto the root of website: universallink.net46.net
1. I created a JSON file and named it handoff.json:
{
"activitycontinuation":
{
"apps": ["XXXXXXXXXX.com.home.handoff"]
},
"applinks":
{
"apps":[],
"details":
{
"XXXXXXXXXX.com.home.handoff":
{
"paths":["*"]
}
}
}
}
The XXXXXXXXXX here is the team id of the Distribution provisioning profile
I used Keychain Access app to export a iPhone Distribution certificate to a Certificates.p12 key.
I signed the JSON file with these commands:
Create a certificate in the openssl command.
openssl pkcs12 -in Certificates.p12 -clcerts -nokeys -out output_crt.pem
Create a secret key.
openssl pkcs12 -in Certificates.p12 -nocerts -nodes -out output_key.pem
Create an intermediate certificate.
openssl pkcs12 -in Certificates.p12 -cacerts -nokeys -out sample.ca-bundle
Sign the handoff.json file with the following command.
cat handoff.json | openssl smime -sign -inkey output_key.pem -signer output_crt.pem -certfile sample.ca-bundle -noattr -nodetach -outform DER> apple-app-site-association
I uploaded the signed file "apple-app-site-association" onto the root of website universallink
I configured the entitlement:
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
<string>activitycontinuation:www.universallink.net46.net</string>
<string>activitycontinuation:universallink.net46.net</string>
<string>applinks:www.universallink.net46.net</string>
<string>applinks:universallink.net46.net</string>
</array>
</dict>
I implement the function application:continueActivity.... and return YES.
I installed the app on the iOS 9 beta 4 device and also installed the Certificates.p12 at step 3 into the device.
I sent a message to myself the link of universallink website
I expected my app would be launched but actually, it was Safari.
I don't know if I did something wrong.

You are signing it wrong. You need a
certificate and key for an identity issued by a certificate authority trusted by iOS
See apples official documentation here: https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/Handoff/AdoptingHandoff/AdoptingHandoff.html#//apple_ref/doc/uid/TP40014338-CH2-SW10

I Think This:
"details":
{
"XXXXXXXXXX.com.home.handoff":
{
"paths":["*"]
}
}
Should be this:
"details": [{
"appID": "XXXXXXXXXX.com.home.handoff",
"paths": ["*"]
}]

I was trying to make it work by using a local server (an OTA https python server) with a self created certificate using SSL and it didnĀ“t work. I could track the communications and listen to the channel but in the different tests I tried, the json file was never asked for, so there is the problem, the SSL certificate.
Go to : https://support.apple.com/en-gb/HT205205 as "not all the root certificates" are supported by apple (most of them are though).

Related

How do I configure possitiveSSL on embedded yaws?

I bought a possitiveSSL certificate from ComodoSSL
these are the files I was received from them
Root CA Certificate - AddTrustExternalCARoot.crt
Intermediate CA Certificate - COMODORSAAddTrustCA.crt
Intermediate CA Certificate - COMODORSADomainValidationSecureServerCA.crt
Your PositiveSSL Certificate - domain_com.crt
How do I replace these files with the following embedded yaws configuration?
{ssl,[{keyfile, "/home/user/Develop/yaws-2.0.2/etc/yaws/yaws-key.pem"},
{certfile, "/home/user/Develop/yaws-2.0.2/etc/yaws/yaws-cert.pem"},
{depth,0},{dhfile,"/home/yser/Develop/yaws-2.0.2/etc/yaws/dhparams.pem"}]},
I have solved this problem by combining the following files into one filename.crt:
Root CA Certificate - AddTrustExternalCARoot.crt
Intermediate CA Certificate - COMODORSAAddTrustCA.crt
Intermediate CA Certificate - COMODORSADomainValidationSecureServerCA.crt
Your PositiveSSL Certificate - domain_com.crt
Then I added the key signature I used to request the ssl certificate into a file.key file.
so the result is something like this:
{port, 443}
{ssl,[{keyfile, "/home/file.key"},
{certfile, "/home/filename.crt"},
{depth,0}]}

Azure Key Vault - Certificate generation

I am using the following script to generate a new ROOT CA that will be used to generate sub-ca's and client certificates.
New-SelfSignedCertificate -CertStoreLocation "cert:\CurrentUser\My" -Subject "CN=$certificateCleanName" -KeySpec Signature -KeyUsage CertSign -TextExtension #("2.5.29.19 ={critical} {text}ca=1")
This works perfectly, but I would prefer to generate them in the Key Vault Directly (via Powershell).
I know you can generate a self signed certificate in the key vault directly with this command:
$manualPolicy = New-AzureKeyVaultCertificatePolicy -SubjectName "CN=something.com" -ValidityInMonths 24 -IssuerName Self -RenewAtNumberOfDaysBeforeExpiry 100
$certificate = Add-AzureKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $manualPolicy
However, with the command above, I am not able to generate the exact same certificate properties as in the first command that use to generate the certificate locally.
Any idea how I can specify the following arguments to create the certificate with the exact same settings directly in the KeyVault?
-KeyUsage CertSign -TextExtension #("2.5.29.19 ={critical} {text}ca=1")

APNS Provider API and Postman

I'm trying to use Postman to create and test Apple Notifications in my iOS app.
For a reason I don't get, requests I send from Postman to either https://api.development.push.apple.com/3/device/<token-device> or https://api.push.apple.com/3/device/<token-device> fail without getting any HTTP response.
What I've done so far:
1 - created and exported a APNS certificate from my developer.apple.com account (as explained there).
2 - converted this .p12 certificate with a recent version of openssl (1.0.2l) to a .pem cert and key like this:
openssl pkcs12 -in apns.p12 -out apns.crt.pem -clcerts -nokeys
openssl pkcs12 -in apns.p12 -out apns.key.pem -nocerts -nodes
3 - configured Postman (Preferences > certificates) to use these .pem files for both Provider API urls (dev and prod)
4 - setup a POST request to those Provider API endpoint for my device token with a apns-topic header that has my bundle id for value, and a HTTP body like this:
{
"aps" : {
"alert" : {
"title" : "Game Request",
"body" : "Bob wants to play poker"
}
}
}
It fails with "Could not get any response, blablabla".
If I check what happens it the Postman console, I see:
POST
https://api.development.push.apple.com/3/device/12340e529f85a145b567736e7fd84c9d7e42a43a3c343ec378c2ff071011e4
06:18:08.236
Error: Parse Error
Client Certificate:
keyPath:"/Users/thomas/wksp_myproj/apns.key.pem"
pemPath:"/Users/thomas/wksp_myproj/apns.crt.pem"
Request Headers:
cache-control:"no-cache"
Postman-Token:"99615df2-b2aa-4a51-8d15-8ce27f4e8ca9"
Content-Type:"application/json"
apns-topic:"myproj.app"
Also, when I test with openssl as explained there:
openssl s_client -connect api.development.push.apple.com:443 -cert apns.pem -debug -showcerts -CAfile GeoTrust_Global_CA.pem
I get a lot of outputs with at the end:
HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 0aread from 0x7f9445c215c0 [0x7f9446015c03] (5 bytes => 0 (0x0))
read:errno=0
What's going wrong?
OK, forget about Postman, I've ended up using curl with http2 and an updated version of openssl (1.0.2l) and it's working just fine. For those who would like to see an curl command example, it's here.

APNS_CERTIFICATE - Push Notification does not send in production

I've had this issue for about 2 weeks, when I suddenly stopped sending notifications in production. I am using the django-push-notifications library and by django admin I can send a test message, but it does not send messages through the system.
On my local computer, everything works flawlessly. I discovered a command to test the certificate:
openssl s_client -connect gateway.push.apple.com:2195 -cert apns-cert.pem
With this one I had the return: Timeout: 7200 (sec) Verify return
code: 20 (unable to get local issuer certificate) Extended master
secret: yes
So with a lot of research, I discovered that I needed to put the path of "CA":
openssl s_client -CApath /etc/ssl/certs/ -connect gateway.push.apple.com:2195 -cert apns-cert.pem
Who was taking me to: Verify return code: 0 (ok)
However, for use in the library, I needed to put the full path of a .pem file. Then I found this command:
ls /etc/ssl/certs/Entrust*
I tested all the .pem files that were there, until I reached what appeared to have worked perfectly:
openssl s_client -CAfile /etc/ssl/certs/Entrust.net_Premium_2048_Secure_Server_CA.pem -connect gateway.push.apple.com:2195 -cert apns-cert.pem
Soon, I formatted my PUSH_NOTIFICATIONS_SETTINGS:
PUSH_NOTIFICATIONS_SETTINGS = {
"GCM_API_KEY": "xxxx",
"APNS_CERTIFICATE": os.path.join(BASE_DIR, "apns-cert.pem"),
"APNS_CA_CERTIFICATES": "/etc/ssl/certs/Entrust.net_Premium_2048_Secure_Server_CA.pem",
"APNS_ERROR_TIMEOUT": 3,
}
IOS_VERIFY_RECEIPT_API = 'https://buy.itunes.apple.com/verifyReceipt'
ANDROID_VERIFY_RECEIPT_API = 'https://www.googleapis.com/androidpublisher/v2/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}'
Unfortunately it still does not send PUSH, and no error because I have configured it to pop errors to send by email.
PS: Remembering that by sending a test text via django admin: OK. Sending via sandbox (debug): OK.
In fact it was not an SSL issue, it was a bulk upload error by the library.
The tokens registered in the system were expired and the library does not know how to work with it and canceled the action, causing no other token to be attempted. I corrected the problem by looping and ignoring the individual error by sending a test to my email:
def send_push(self):
errors = []
# IOS
queryset_ios = APNSDevice.objects.filter(user=self.authentication)
for device in queryset_ios:
try:
device.send_message(self.subject, badge=1, sound=self.kind.sound)
except APNSServerError as e:
errors.append(APNS_ERROR_MESSAGES[e.status])
except Exception:
pass
# ANDROID
queryset_android = GCMDevice.objects.filter(user=self.authentication)
extra = {'notification': self.pk, 'kind': self.kind.kind, 'sound': self.kind.sound}
for device in queryset_android:
try:
queryset_android.send_message(self.subject, badge=1, extra=extra)
except GCMError as e:
errors.append(str(e))
except Exception:
pass
if errors:
send_mail("Push Error",
"Push: %s \n User: %s \n\n Errors: %s" % (self.subject, self.authentication.full_name, errors),
settings.DEFAULT_FROM_EMAIL, ["my#mail.com"])

Getting an error while Connecting to APNS server

source: www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1
Terminal Command:
Initiums-iMac:Desktop initium$ openssl s_client -connect
gateway.sandbox.push.apple.com:2195
-cert PushChatCert.pem -key PushChatKey.pem
Terminal Response:
CONNECTED(00000003) depth=1 /C=US/O=Entrust,
Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009
Entrust, Inc./CN=Entrust Certification Authority - L1C
verify error:num=20:unable to get local issuer certificate
verify return:0
3122:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake
failure:/SourceCache/OpenSSL098/OpenSSL098-47.2/src/ssl/s3_pkt.c:1106:SSL
alert number 40
3122:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake
failure:/SourceCache/OpenSSL098/OpenSSL098-47.2/src/ssl/s23_lib.c:182:
Following the tutorial www.raywenderlich.com/32960, I think I faced the same issue... almost.
Anyways, I think it was because I had goofed up with the .p12 file specifically.
Did you export the correct private key from inside "Keychain Access > Keys"?
This part comes under "Generating the Certificate Signing Request (CSR)" where you have to export the private key as a p12 file.
Delete all the unnecessary certificates and keys, start from scratch and closely follow the tutorial.

Resources