Skip to content

Commit

Permalink
Add support for Metadata property in Key.Activate (#67)
Browse files Browse the repository at this point in the history
* First commit

* Update

* Update internal.py

* Update internal.py

* Update models.py

* Update setup.py
  • Loading branch information
artemlos authored Feb 7, 2024
1 parent c4db4bf commit 3df4ae2
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
30 changes: 26 additions & 4 deletions licensing/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,33 @@ def RSAVP1(pair, s):
return pow(s, e, n)

@staticmethod
def EMSA_PKCS1_V15_ENCODE(M, emLen):
def EMSA_PKCS1_V15_ENCODE(M, emLen, hlen = 256):
import hashlib
h = hashlib.sha256()
if hlen == 512:
h = hashlib.sha512()
h.update(M)
H = h.digest()

T = bytes([0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20]) + H
if hlen == 512:
T = bytes([0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40]) + H

tLen = len(T)
if emLen < tLen + 11:
return None
PS = bytes([0xff for _ in range(emLen - tLen - 3)])
return b"".join([b"\x00\x01", PS, b"\x00", T])

@staticmethod
def RSAASSA_PKCS1_V15_VERIFY(pair, M, S):
def RSAASSA_PKCS1_V15_VERIFY(pair, M, S, l=256):
n, e = pair
s = HelperMethods.OS2IP(S)
m = HelperMethods.RSAVP1((n,e), s)
if m is None: return False
EM = HelperMethods.I2OSP(m, 256)
if EM is None: return False
EM2 = HelperMethods.EMSA_PKCS1_V15_ENCODE(M, 256)
EM2 = HelperMethods.EMSA_PKCS1_V15_ENCODE(M, 256, l)
if EM2 is None: return False

try:
Expand All @@ -114,6 +119,23 @@ def verify_signature(response, rsaPublicKey):

return HelperMethods.RSAASSA_PKCS1_V15_VERIFY((n,e), m, r)

@staticmethod
def verify_signature_metadata(signature, rsaPublicKey):

import base64
import json

n = HelperMethods.OS2IP(base64.b64decode(rsaPublicKey.modulus))
e = HelperMethods.OS2IP(base64.b64decode(rsaPublicKey.exponent))

data = json.loads(base64.b64decode(signature))

d = base64.b64decode(data["Data"])
s = base64.b64decode(data["Signature"])

return [HelperMethods.RSAASSA_PKCS1_V15_VERIFY((n,e), d,s, l=512), d]


@staticmethod
def int2base64(num):
return base64.b64encode(int.to_bytes(num), byteorder='big')
Expand Down
16 changes: 15 additions & 1 deletion licensing/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,21 @@ def activate(token, rsa_pub_key, product_id, key, machine_code, fields_to_return
else:
try:
if HelperMethods.verify_signature(response, pubkey):
return (LicenseKey.from_response(response), response.message)
if metadata:

try:
metadata_s = HelperMethods.verify_signature_metadata(response.metadata["signature"], pubkey)

if metadata_s[0]:
return (LicenseKey.from_response(response), response.message, json.loads(metadata_s[1]))
else:
return (LicenseKey.from_response(response), response.message, "Signature check for metadata object failed.")
except:
return (LicenseKey.from_response(response), response.message, "Signature check for metadata object failed.")


else:
return (LicenseKey.from_response(response), response.message)
else:
return (None, "The signature check failed.")
except Exception as ex:
Expand Down
11 changes: 9 additions & 2 deletions licensing/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,12 @@ def __load_activated_machines(obj):

class Response:

def __init__(self, license_key, signature, result, message):
def __init__(self, license_key, signature, result, message, metadata=None):
self.license_key = license_key
self.signature = signature
self.result = result
self.message = message
self.metadata = metadata

@staticmethod
def from_string(responseString):
Expand All @@ -178,6 +179,7 @@ def from_string(responseString):
signature = ""
result = 0
message = ""
metadata = None

if "licensekey" in obj:
licenseKey = obj["licensekey"]
Expand All @@ -192,8 +194,13 @@ def from_string(responseString):
result = obj["result"]
else:
result = 1

if "metadata" in obj:
metadata = obj["metadata"]



return Response(licenseKey, signature, result, message)
return Response(licenseKey, signature, result, message, metadata)

class RSAPublicKey:

Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
setup(
name = 'licensing', # How you named your package folder (MyLib)
packages = ['licensing'], # Chose the same as "name"
version = '0.41', # Start with a small number and increase it with every change you make
version = '0.42', # Start with a small number and increase it with every change you make
license='MIT', # Chose a license from here: https://help.github.com/articles/licensing-a-repository
description = 'Client library for Cryptolens licensing Web API.', # Give a short description about your library
author = 'Cryptolens AB', # Type in your name
author_email = '[email protected]', # Type in your E-Mail
url = 'https://cryptolens.io', # Provide either the link to your github or to your website
download_url = 'https://github.com/Cryptolens/cryptolens-python/archive/v_41.tar.gz', # I explain this later on
download_url = 'https://github.com/Cryptolens/cryptolens-python/archive/v_42.tar.gz', # I explain this later on
keywords = ['software licensing', 'licensing library', 'cryptolens'], # Keywords that define your package best
classifiers=[
#'Development Status :: 5 - Stable', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package
Expand Down

0 comments on commit 3df4ae2

Please sign in to comment.