@@ -20,19 +20,15 @@ defmodule WebPushElixir do
2020 |> :binary . part ( 0 , length )
2121 end
2222
23- defp encrypt (
24- message ,
25- auth ,
26- p256dh ,
27- vapid_public_key ,
28- vapid_private_key
29- ) do
23+ defp encrypt ( message , p256dh , auth ) do
3024 client_public_key = url_decode ( p256dh )
3125 client_auth_secret = url_decode ( auth )
3226
3327 salt = :crypto . strong_rand_bytes ( 16 )
3428
35- shared_secret = :crypto . compute_key ( :ecdh , client_public_key , vapid_private_key , :prime256v1 )
29+ { local_public_key , local_private_key } = :crypto . generate_key ( :ecdh , :prime256v1 )
30+
31+ shared_secret = :crypto . compute_key ( :ecdh , client_public_key , local_private_key , :prime256v1 )
3632
3733 pseudo_random_key =
3834 hmac_based_key_derivation_function (
@@ -45,7 +41,7 @@ defmodule WebPushElixir do
4541 context =
4642 << 0 , byte_size ( client_public_key ) :: unsigned - big - integer - size ( 16 ) >> <>
4743 client_public_key <>
48- << byte_size ( vapid_public_key ) :: unsigned - big - integer - size ( 16 ) >> <> vapid_public_key
44+ << byte_size ( local_public_key ) :: unsigned - big - integer - size ( 16 ) >> <> local_public_key
4945
5046 content_encryption_key_info = "Content-Encoding: aesgcm" <> << 0 >> <> "P-256" <> context
5147
@@ -60,17 +56,19 @@ defmodule WebPushElixir do
6056 12
6157 )
6258
59+ padded_message = << 0 :: unsigned - big - integer - size ( 16 ) >> <> :binary . copy ( << 0 >> , 0 ) <> message
60+
6361 { cipher_text , cipher_tag } =
6462 :crypto . crypto_one_time_aead (
6563 :aes_128_gcm ,
6664 content_encryption_key ,
6765 nonce ,
68- message ,
69- "" ,
66+ padded_message ,
67+ << >> ,
7068 true
7169 )
7270
73- % { ciphertext: cipher_text <> cipher_tag , salt: salt }
71+ % { ciphertext: cipher_text <> cipher_tag , salt: salt , local_public_key: local_public_key }
7472 end
7573
7674 defp sign_json_web_token ( endpoint , vapid_public_key , vapid_private_key ) do
@@ -100,15 +98,18 @@ defmodule WebPushElixir do
10098 % { endpoint: endpoint , keys: % { auth: auth , p256dh: p256dh } } =
10199 Jason . decode! ( subscription , keys: :atoms )
102100
103- encrypted = encrypt ( message , auth , p256dh , vapid_public_key , vapid_private_key )
101+ encrypted = encrypt ( message , p256dh , auth )
104102
105103 signed_json_web_token =
106104 sign_json_web_token ( endpoint , vapid_public_key , vapid_private_key )
107105
108106 HTTPoison . post ( endpoint , encrypted . ciphertext , % {
109107 "Authorization" => "WebPush #{ signed_json_web_token } " ,
110108 "Content-Encoding" => "aesgcm" ,
111- "Crypto-Key" => "p256ecdsa=#{ url_encode ( vapid_public_key ) } " ,
109+ "Content-Length" => "#{ byte_size ( encrypted . ciphertext ) } " ,
110+ "Content-Type" => "application/octet-stream" ,
111+ "Crypto-Key" =>
112+ "dh=#{ url_encode ( encrypted . local_public_key ) } ;p256ecdsa=#{ url_encode ( vapid_public_key ) } " ,
112113 "Encryption" => "salt=#{ url_encode ( encrypted . salt ) } " ,
113114 "TTL" => "60"
114115 } )
0 commit comments