def test_sign_01(self): v = Vapid01.from_string(T_DER) claims = {"aud": "https://example.com", "sub": "mailto:[email protected]"} result = v.sign(claims, "id=previous") eq_(result['Crypto-Key'], 'id=previous;p256ecdsa=' + T_PUBLIC_RAW.decode('utf8')) pkey = binascii.b2a_base64( v.public_key.public_bytes( serialization.Encoding.X962, serialization.PublicFormat.UncompressedPoint ) ).decode('utf8').replace('+', '-').replace('/', '_').strip() items = decode(result['Authorization'].split(' ')[1], pkey) for k in claims: eq_(items[k], claims[k]) result = v.sign(claims) eq_(result['Crypto-Key'], 'p256ecdsa=' + T_PUBLIC_RAW.decode('utf8')) # Verify using the same function as Integration # this should ensure that the r,s sign values are correctly formed ok_(Vapid01.verify( key=result['Crypto-Key'].split('=')[1], auth=result['Authorization'] ))
def init_vapid(): vapid = Vapid.from_file(current_app.config.get('VAPID_KEY')) current_app.config['VAPID_PRIVATE_KEY'] = vapid.private_key.private_bytes( encoding=serialization.Encoding.DER, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption()) application_server_key = vapid.public_key.public_numbers().encode_point() current_app.config['VAPID_APPLICATION_SERVER_KEY'] = b64urlencode( application_server_key)
def test_validate(self): v = Vapid01.from_file("/tmp/private") msg = "foobar".encode('utf8') vtoken = v.validate(msg) ok_(v.public_key.verify(base64.urlsafe_b64decode(vtoken), msg, hashfunc=hashlib.sha256)) # test verify ok_(v.verify_token(msg, vtoken))
def gen_application_server_keys(): """ Generate Vapid key pair """ vapid = Vapid() vapid.generate_keys() vapid.save_key(settings.VAPID_PRIVATE_KEY) vapid.save_public_key(settings.VAPID_PUBLIC_KEY)
def test_bad_integration(self): # These values were taken from a test page. DO NOT ALTER! key = ("BDd3_hVL9fZi9Ybo2UUzA284WG5FZR30_95YeZJsiApwXKpNcF1rRPF3foI" "iBHXRdJI2Qhumhf6_LFTeZaNndIo") auth = ("WebPush eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJod" "HRwczovL3VwZGF0ZXMucHVzaC5zZXJ2aWNlcy5tb3ppbGxhLmNvbSIsImV" "4cCI6MTQ5NDY3MTQ3MCwic3ViIjoibWFpbHRvOnNpbXBsZS1wdXNoLWRlb" "W9AZ2F1bnRmYWNlLmNvLnVrIn0.LqPi86T-HJ71TXHAYFptZEHD7Wlfjcc" "4u5jYZ17WpqOlqDcW-5Wtx3x1OgYX19alhJ9oLumlS2VzEvNioZ_BAD") eq_(Vapid01.verify(key=key, auth=auth), False)
def test_validate(self): v = Vapid01.from_file("/tmp/private") msg = "foobar".encode('utf8') vtoken = v.validate(msg) ok_(v.public_key.verify( base64.urlsafe_b64decode(self.repad(vtoken).encode()), msg, ec.ECDSA(hashes.SHA256()))) # test verify ok_(v.verify_token(msg, vtoken))
async def get_application_server_key(): """ Get and prepare application server_key """ vapid = Vapid.from_file(settings.VAPID_PRIVATE_KEY) raw_pub = vapid.public_key.public_bytes( serialization.Encoding.X962, serialization.PublicFormat.UncompressedPoint) return b64urlencode(raw_pub)
def test_sign_01(self): v = Vapid01.from_file("/tmp/private") claims = { "aud": "https://example.com", "sub": "mailto:[email protected]" } result = v.sign(claims, "id=previous") eq_(result['Crypto-Key'], 'id=previous;p256ecdsa=' + T_PUBLIC_RAW.decode('utf8')) pkey = binascii.b2a_base64( v.public_key.public_numbers().encode_point()).decode( 'utf8').replace('+', '-').replace('/', '_').strip() items = decode(result['Authorization'].split(' ')[1], pkey) eq_(items, claims) result = v.sign(claims) eq_(result['Crypto-Key'], 'p256ecdsa=' + T_PUBLIC_RAW.decode('utf8')) # Verify using the same function as Integration # this should ensure that the r,s sign values are correctly formed ok_( Vapid01.verify(key=result['Crypto-Key'].split('=')[1], auth=result['Authorization']))
def setup(): vapid = Vapid01() private_key_path = os.path.join(ntfy_data_dir, 'private_key.pem') public_key_path = os.path.join(ntfy_data_dir, 'public_key.pem') if os.path.exists(private_key_path): print('Loading from ' + private_key_path) vapid = Vapid01.from_file(private_key_path) else: vapid.generate_keys() print('Generating ' + private_key_path) vapid.save_key(private_key_path) print('Generating ' + public_key_path) vapid.save_public_key(public_key_path) raw_pub = vapid.public_key.public_numbers().encode_point() print('') print( 'Open the following url in your browser to continue configuring ntfy-webpush' ) print( 'https://dschep.github.io/ntfy-webpush/#publicKey={0}&privateKeyPath={1}' .format(b64urlencode(raw_pub), private_key_path))
def test_sign_01(self): v = Vapid01.from_file("/tmp/private") claims = {"aud": "example.com", "sub": "*****@*****.**"} result = v.sign(claims, "id=previous") eq_(result['Crypto-Key'], 'id=previous;p256ecdsa=' + T_PUBLIC_RAW) items = jws.verify( result['Authorization'].split(' ')[1], binascii.b2a_base64(v.public_key.to_der()).decode('utf8'), algorithms=["ES256"]) eq_(json.loads(items.decode('utf8')), claims) result = v.sign(claims) eq_(result['Crypto-Key'], 'p256ecdsa=' + T_PUBLIC_RAW)
def test_bad_sign(self): v = Vapid01.from_file("/tmp/private") self.assertRaises(VapidException, v.sign, {}) self.assertRaises(VapidException, v.sign, { 'sub': 'foo', 'aud': "p.example.com" }) self.assertRaises(VapidException, v.sign, { 'sub': 'mailto:[email protected]', 'aud': "p.example.com" }) self.assertRaises(VapidException, v.sign, { 'sub': 'mailto:[email protected]', 'aud': "https://p.example.com:8080/" })
def test_sign_01(self): v = Vapid01.from_file("/tmp/private") claims = {"aud": "https://example.com", "sub": "mailto:[email protected]"} result = v.sign(claims, "id=previous") eq_(result['Crypto-Key'], 'id=previous;p256ecdsa=' + T_PUBLIC_RAW.decode('utf8')) pkey = binascii.b2a_base64( v.public_key.public_numbers().encode_point() ).decode('utf8').replace('+', '-').replace('/', '_').strip() items = decode(result['Authorization'].split(' ')[1], pkey) eq_(items, claims) result = v.sign(claims) eq_(result['Crypto-Key'], 'p256ecdsa=' + T_PUBLIC_RAW.decode('utf8'))
def test_bad_sign(self): v = Vapid01.from_file("/tmp/private") self.assertRaises(VapidException, v.sign, {}) self.assertRaises(VapidException, v.sign, {'sub': 'foo', 'aud': "p.example.com"}) self.assertRaises(VapidException, v.sign, {'sub': 'mailto:[email protected]', 'aud': "p.example.com"}) self.assertRaises(VapidException, v.sign, {'sub': 'mailto:[email protected]', 'aud': "https://p.example.com:8080/"})
def test_init(self): v1 = Vapid01.from_file("/tmp/private") self.check_keys(v1) v2 = Vapid01.from_pem(T_PRIVATE.encode()) self.check_keys(v2) v3 = Vapid01.from_der(T_DER.encode()) self.check_keys(v3) v4 = Vapid01.from_file("/tmp/private.der") self.check_keys(v4) no_exist = '/tmp/not_exist' Vapid01.from_file(no_exist) ok_(os.path.isfile(no_exist)) os.unlink(no_exist)
def test_alt_sign(self): """ecdsa uses a raw key pair to sign, openssl uses a DER.""" v = Vapid01.from_file("/tmp/private") claims = {"aud": "https://example.com", "sub": "mailto:[email protected]", "foo": "extra value"} # Get a signed token. result = v.sign(claims) # Convert the dss into raw. auth, sig = result.get('Authorization').split(' ')[1].rsplit('.', 1) ss = utils.decode_dss_signature(b64urldecode(sig.encode('utf8'))) new_sig = binascii.b2a_base64( binascii.unhexlify("%064x%064x" % ss) ).strip().strip(b'=').decode() new_auth = auth + '.' + new_sig # phew, all that done, now check pkey = result.get("Crypto-Key").split('=')[1] items = decode(new_auth, pkey) eq_(items, claims)
def test_init(self): v1 = Vapid01.from_file("/tmp/private") eq_(v1.private_key.to_pem(), T_PRIVATE.encode('utf8')) eq_(v1.public_key.to_pem(), T_PUBLIC.encode('utf8')) v2 = Vapid01.from_pem(T_PRIVATE) eq_(v2.private_key.to_pem(), T_PRIVATE.encode('utf8')) eq_(v2.public_key.to_pem(), T_PUBLIC.encode('utf8')) v3 = Vapid01.from_der(T_DER) eq_(v3.private_key.to_pem(), T_PRIVATE.encode('utf8')) eq_(v3.public_key.to_pem(), T_PUBLIC.encode('utf8')) v4 = Vapid01.from_file("/tmp/private.der") eq_(v4.private_key.to_pem(), T_PRIVATE.encode('utf8')) eq_(v4.public_key.to_pem(), T_PUBLIC.encode('utf8')) no_exist = '/tmp/not_exist' Vapid01.from_file(no_exist) ok_(os.path.isfile(no_exist)) os.unlink(no_exist)
def test_from_raw(self): v = Vapid01.from_raw(T_RAW) self.check_keys(v)
def test_same_public_key(self): v = Vapid01() v.generate_keys() v.save_public_key("/tmp/p2") os.unlink("/tmp/p2")
def test_public_key(self): v = Vapid01() eq_(v._private_key, None) eq_(v._public_key, None)
def test_private_key(self): v = Vapid01() self.assertRaises(VapidException, lambda: v.private_key)
def test_public_key(self): v = Vapid01() assert v._private_key is None assert v._public_key is None
def test_bad_sign(self): v = Vapid01.from_file("/tmp/private") self.assertRaises(VapidException, v.sign, {'aud': "p.example.com"})
def test_from_string(self): v1 = Vapid01.from_string(T_DER) v2 = Vapid01.from_string(T_RAW.decode()) self.check_keys(v1) self.check_keys(v2)
def test_from_raw(self): v = Vapid01.from_raw(TEST_KEY_PRIVATE_RAW) self.check_keys(v)
def test_from_string(self): v1 = Vapid01.from_string(TEST_KEY_PRIVATE_DER) v2 = Vapid01.from_string(TEST_KEY_PRIVATE_RAW.decode()) self.check_keys(v1) self.check_keys(v2)
def test_from_raw(self): v = Vapid01.from_raw(T_RAW) eq_(v.private_key.to_pem(), T_PRIVATE.encode('utf8')) eq_(v.public_key.to_pem(), T_PUBLIC.encode('utf8'))
def test_gen_key(self): v = Vapid01() v.generate_keys() ok_(v.public_key) ok_(v.private_key)
def test_gen_key(self): v = Vapid01() v.generate_keys() assert v.public_key assert v.private_key