Exemplo n.º 1
0
def encrypt_rsa15(public_key, data):
    ciphertext = public_key.encrypt(
        data,
        padding.PKCS1v15()
    )
    return ciphertext
Exemplo n.º 2
0
 def Sign(self, data):
   return self.rsa_key.sign(
     data,
     padding.PKCS1v15(),
     hashes.SHA1()
   )
def update(firmware, v, assinatura_falsa=False):
    if (firmware > 2 and firmware < 1):
        return print("Modelo inválido")

    if firmware == 1:
        with open('../firmware_tipo1.bin', 'rb') as file:
            fw = file.read()
    if firmware == 2:
        with open('../firmware_tipo2.bin', 'rb') as file:
            fw = file.read()

    with open('../chave_privada.pem', 'rb') as file:
        chave_privada = serialization.load_pem_private_key(file.read(),
                                                           password=None)

    v = v.to_bytes(8, byteorder='big')
    sha256 = hashlib.sha256()
    sha256.update(fw)
    fw_digested = sha256.digest()
    size = len(fw)
    size = size.to_bytes(8, byteorder='big')

    quadros = []

    num_quadros = math.floor(len(fw) / 480)
    for i in range(num_quadros):
        quadros.append(fw[i * 480:(i + 1) * 480])
    mod = len(fw) % 480
    quadros.append(fw[num_quadros * 480:num_quadros * 480 + mod])
    fw_sig = chave_privada.sign(fw + v, padding.PKCS1v15(), hashes.SHA256())
    if assinatura_falsa:
        if firmware == 2:
            with open('../firmware_tipo1.bin', 'rb') as file:
                fw = file.read()
        if firmware == 1:
            with open('../firmware_tipo2.bin', 'rb') as file:
                fw = file.read()

        fw_sig = chave_privada.sign(fw + v, padding.PKCS1v15(),
                                    hashes.SHA256())

    assets = fw_digested + fw_sig + size + v
    T = len(assets)
    T = T.to_bytes(4, byteorder='big')
    assets = bytes([4]) + T + assets
    ser = serial.Serial('COM21')
    print("Iniciando upload do novo firmware...")
    ser.write(assets)

    total = 100 / len(quadros)
    completo = 0
    print(f"Completado: {completo}%")
    for quadro in quadros:
        T = len(quadro)
        T = T.to_bytes(4, byteorder='big')
        codigo = bytes([5]) + T + quadro
        ser.write(codigo)
        flag = 1
        while flag == 1:
            r = ser.read(1)
            if r == bytes([0]):
                flag = 0
                completo = completo + total
                print(f"Completado: {completo}%")

    print("Transmissão finalizada")
    fim = bytes([6])
    T = 1
    T = T.to_bytes(4, byteorder='big')

    (ser.write(fim + T))
Exemplo n.º 4
0
def check_timestamp(tst, certificate=None, data=None, digest=None, hashname=None, nonce=None):
    hashname = hashname or 'sha1'
    hashobj = hashlib.new(hashname)
    if digest is None:
        if not data:
            raise ValueError("check_timestamp requires data or digest argument")
        hashobj.update(data)
        digest = hashobj.digest()

    if not isinstance(tst, rfc3161ng.TimeStampToken):
        tst, substrate = decoder.decode(tst, asn1Spec=rfc3161ng.TimeStampToken())
        if substrate:
            raise ValueError("extra data after tst")
    signed_data = tst.content
    certificate = load_certificate(signed_data, certificate)
    if nonce is not None and int(tst.tst_info['nonce']) != int(nonce):
        raise ValueError('nonce is different or missing')
    # check message imprint with respect to locally computed digest
    message_imprint = tst.tst_info.message_imprint
    if message_imprint.hash_algorithm[0] != get_hash_oid(hashname) or bytes(message_imprint.hashed_message) != digest:
        raise ValueError('Message imprint mismatch')
    if not len(signed_data['signerInfos']):
        raise ValueError('No signature')
    # We validate only one signature
    signer_info = signed_data['signerInfos'][0]
    # check content type
    if tst.content['contentInfo']['contentType'] != rfc3161ng.id_ct_TSTInfo:
        raise ValueError("Signed content type is wrong: %s != %s" % (
            tst.content['contentInfo']['contentType'], rfc3161ng.id_ct_TSTInfo
        ))

    # check signed data digest
    content = bytes(decoder.decode(bytes(tst.content['contentInfo']['content']), asn1Spec=univ.OctetString())[0])
    # if there is authenticated attributes, they must contain the message
    # digest and they are the signed data otherwise the content is the
    # signed data
    if len(signer_info['authenticatedAttributes']):
        authenticated_attributes = signer_info['authenticatedAttributes']
        signer_digest_algorithm = signer_info['digestAlgorithm']['algorithm']
        signer_hash_class = get_hash_class_from_oid(signer_digest_algorithm)
        signer_hash_name = get_hash_from_oid(signer_digest_algorithm)
        content_digest = signer_hash_class(content).digest()
        for authenticated_attribute in authenticated_attributes:
            if authenticated_attribute[0] == id_attribute_messageDigest:
                try:
                    signed_digest = bytes(decoder.decode(bytes(authenticated_attribute[1][0]), asn1Spec=univ.OctetString())[0])
                    if signed_digest != content_digest:
                        raise ValueError('Content digest != signed digest')
                    s = univ.SetOf()
                    for i, x in enumerate(authenticated_attributes):
                        s.setComponentByPosition(i, x)
                    signed_data = encoder.encode(s)
                    break
                except PyAsn1Error:
                    raise
        else:
            raise ValueError('No signed digest')
    else:
        signed_data = content
    # check signature
    signature = signer_info['encryptedDigest']
    public_key = certificate.public_key()
    hash_family = getattr(hashes, signer_hash_name.upper())
    public_key.verify(
        bytes(signature),
        signed_data,
        padding.PKCS1v15(),
        hash_family(),
    )
    return True
Exemplo n.º 5
0
 def _sign(self, msg):
     if not self._signing_key:
         return None
     return self._signing_key.sign((self._queue + msg).encode('utf-8'),
                                   padding.PKCS1v15(), hashes.SHA256())
Exemplo n.º 6
0
    def test_rsa(self):
        backend = MultiBackend([DummyRSABackend()])

        backend.generate_rsa_private_key(key_size=1024, public_exponent=65537)

        backend.create_rsa_signature_ctx("private_key", padding.PKCS1v15(),
                                         hashes.MD5())

        backend.create_rsa_verification_ctx("public_key", "sig",
                                            padding.PKCS1v15(), hashes.MD5())

        backend.mgf1_hash_supported(hashes.MD5())

        backend.rsa_padding_supported(padding.PKCS1v15())

        backend.generate_rsa_parameters_supported(65537, 1024)

        backend.encrypt_rsa("public_key", "encryptme", padding.PKCS1v15())

        backend.decrypt_rsa("private_key", "encrypted", padding.PKCS1v15())

        backend.load_rsa_private_numbers("private_numbers")

        backend.load_rsa_public_numbers("public_numbers")

        backend = MultiBackend([])
        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.generate_rsa_private_key(key_size=1024, public_exponent=3)

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.create_rsa_signature_ctx("private_key", padding.PKCS1v15(),
                                             hashes.MD5())

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.create_rsa_verification_ctx("public_key", "sig",
                                                padding.PKCS1v15(),
                                                hashes.MD5())

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.mgf1_hash_supported(hashes.MD5())

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.rsa_padding_supported(padding.PKCS1v15())

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.generate_rsa_parameters_supported(65537, 1024)

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.encrypt_rsa("public_key", "encryptme", padding.PKCS1v15())

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.decrypt_rsa("private_key", "encrypted", padding.PKCS1v15())

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.load_rsa_private_numbers("private_numbers")

        with raises_unsupported_algorithm(
                _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM):
            backend.load_rsa_public_numbers("public_numbers")
Exemplo n.º 7
0
def jku_vulnerability(jwt=None, url=None, file=None, pem=None):
    """
    Check jku Vulnerability.

    Parameters
    ----------
    jwt: str
        your jwt.
    url: str
        your url.
    file: str
        your output json file name
    pem: str
       pem file name

    Returns
    -------
    str
        your new jwt.
    """
    if not is_valid_jwt(jwt):
        raise InvalidJWT("Invalid JWT format")

    jwt_json = jwt_to_json(jwt)

    if "jku" not in jwt_json[HEADER]:
        raise InvalidJWT("Invalid JWT format JKU missing")

    if file is None:
        file = "jwk-python.json"
    jwks = requests.get(jwt_json[HEADER]["jku"]).json()

    jwt_json[HEADER]["alg"] = "RS256"
    if ".json" not in file:
        file += ".json"
    if not url.endswith("/"):
        url += "/"
    jwt_json[HEADER]["jku"] = f"{url}{file}"
    if pem is None:
        key = crypto.PKey()
        key.generate_key(type=crypto.TYPE_RSA, bits=2048)
    else:
        key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(pem).read())
    priv = key.to_cryptography_key()
    pub = priv.public_key()

    e = pub.public_numbers().e
    n = pub.public_numbers().n

    jwks["keys"][0]["e"] = (base64.urlsafe_b64encode(
        e.to_bytes(e.bit_length() // 8 + 1,
                   byteorder="big"), ).decode("UTF-8").rstrip("="))
    jwks["keys"][0]["n"] = (base64.urlsafe_b64encode(
        n.to_bytes(n.bit_length() // 8 + 1,
                   byteorder="big"), ).decode("UTF-8").rstrip("="))

    f = open(file, "w")
    f.write(json.dumps(jwks))
    f.close()

    s = encode_jwt(jwt_json)

    sign = priv.sign(
        bytes(s, encoding="UTF-8"),
        algorithm=hashes.SHA256(),
        padding=padding.PKCS1v15(),
    )

    return s + "." + base64.urlsafe_b64encode(sign).decode("UTF-8").rstrip("=")
 def encrypt_text(text):
     public_key = pm._rsa_verifier.public_key()
     encrypted_key = public_key.encrypt(text.encode('ascii'),
                                        padding.PKCS1v15())
     return base64.b64encode(bytes(encrypted_key))
    def create_signup_info(cls, originator_public_key_hash, nonce):
        with cls._lock:
            # First we need to create a public/private key pair for the PoET
            # enclave to use.
            cls._poet_private_key = signing.generate_privkey()
            cls._poet_public_key = \
                signing.generate_pubkey(cls._poet_private_key)
            cls._active_wait_timer = None

            # Simulate sealing (encrypting) the signup data.
            signup_data = {
                'poet_public_key': cls._poet_public_key,
                'poet_private_key': cls._poet_private_key
            }
            sealed_signup_data = \
                base64.b64encode(bytes(dict2json(signup_data).encode()))

            # Build up a fake SGX quote containing:
            # 1. The basename
            # 2. The report body that contains:
            #    a. The enclave measurement
            #    b. The report data SHA256(SHA256(OPK)|PPK)
            sgx_basename = \
                sgx_structs.SgxBasename(name=cls.__VALID_BASENAME__)
            sgx_measurement = \
                sgx_structs.SgxMeasurement(
                    m=cls.__VALID_ENCLAVE_MEASUREMENT__)

            hash_input = \
                '{0}{1}'.format(
                    originator_public_key_hash.upper(),
                    cls._poet_public_key.upper()).encode()
            report_data = hashlib.sha256(hash_input).digest()
            sgx_report_data = sgx_structs.SgxReportData(d=report_data)
            sgx_report_body = \
                sgx_structs.SgxReportBody(
                    mr_enclave=sgx_measurement,
                    report_data=sgx_report_data)

            sgx_quote = \
                sgx_structs.SgxQuote(
                    basename=sgx_basename,
                    report_body=sgx_report_body)

            # Create a fake PSE manifest.  A base64 encoding of the
            # originator public key hash should suffice.
            pse_manifest = \
                base64.b64encode(originator_public_key_hash.encode())

            timestamp = datetime.datetime.now().isoformat()

            # Fake our "proof" data.
            verification_report = {
                'epidPseudonym':
                originator_public_key_hash,
                'id':
                base64.b64encode(
                    hashlib.sha256(
                        timestamp.encode()).hexdigest().encode()).decode(),
                'isvEnclaveQuoteStatus':
                'OK',
                'isvEnclaveQuoteBody':
                base64.b64encode(sgx_quote.serialize_to_bytes()).decode(),
                'pseManifestStatus':
                'OK',
                'pseManifestHash':
                base64.b64encode(
                    hashlib.sha256(
                        pse_manifest).hexdigest().encode()).decode(),
                'nonce':
                nonce,
                'timestamp':
                timestamp
            }

            # Serialize the verification report, sign it, and then put
            # in the proof data
            verification_report_json = dict2json(verification_report)
            signature = \
                cls._report_private_key.sign(
                    verification_report_json.encode(),
                    padding.PKCS1v15(),
                    hashes.SHA256())

            proof_data_dict = {
                'evidence_payload': {
                    'pse_manifest': pse_manifest.decode()
                },
                'verification_report': verification_report_json,
                'signature': base64.b64encode(signature).decode()
            }
            proof_data = dict2json(proof_data_dict)

            return \
                EnclaveSignupInfo(
                    poet_public_key=signup_data['poet_public_key'],
                    proof_data=proof_data,
                    anti_sybil_id=originator_public_key_hash,
                    sealed_signup_data=sealed_signup_data)
Exemplo n.º 10
0
 def verify(self, msg, key, sig):
     try:
         key.verify(sig, msg, padding.PKCS1v15(), self.hash_alg())
         return True
     except InvalidSignature:
         return False
Exemplo n.º 11
0
from sys import argv, stderr, exit
from tempfile import mkstemp
from os import makedirs, remove, close
from os.path import dirname
from errno import EEXIST
import gzip
from shutil import copyfileobj
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding, utils
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.exceptions import InvalidSignature

MAGIC = b'WPK256\0'
HASH = hashes.SHA256()
PADDING = padding.PKCS1v15()
SIGLEN = 2048 // 8
BUFLEN = 4096


class FormatError(Exception):
    pass


def unsign(source, target):
    hasher = hashes.Hash(HASH, default_backend())

    with open(source, 'rb') as filein:
        if filein.read(len(MAGIC)) != MAGIC:
            raise FormatError
Exemplo n.º 12
0
 def sign(self, msg, key):
     return key.sign(msg, padding.PKCS1v15(), self.hash_alg())
Exemplo n.º 13
0
    def rsaPkcsSigs(self, session, pubkey, privkey):
        mechs = [
            {
                "name": "CKM_SHA1_RSA_PKCS",
                "h": hashes.SHA1(),
                "m": PyKCS11.CKM_SHA1_RSA_PKCS,
                "di": SHA1_DI,
            },
            {
                "name": "CKM_SHA256_RSA_PKCS",
                "h": hashes.SHA256(),
                "m": PyKCS11.CKM_SHA256_RSA_PKCS,
                "di": SHA256_DI,
            },
            {
                "name": "CKM_SHA384_RSA_PKCS",
                "h": hashes.SHA384(),
                "m": PyKCS11.CKM_SHA384_RSA_PKCS,
                "di": SHA384_DI,
            },
            {
                "name": "CKM_SHA512_RSA_PKCS",
                "h": hashes.SHA512(),
                "m": PyKCS11.CKM_SHA512_RSA_PKCS,
                "di": SHA512_DI,
            },
        ]
        for mech in mechs:
            self.assertIn(mech["name"], self.mechs)
            info = self.pkcs11.getMechanismInfo(self.slot, mech["name"])
            self.assertGreaterEqual(2048, info.ulMinKeySize)
            self.assertLessEqual(2048, info.ulMaxKeySize)

            tosign = os.urandom(2000)
            digest = hashes.Hash(mech["h"], backend=default_backend())
            hashed = mech["di"]
            digest.update(tosign)
            hashed += digest.finalize()

            signature = session.sign(
                privkey, tosign, PyKCS11.Mechanism(mech["m"], None)
            )

            res = session.verify(
                pubkey, tosign, signature, PyKCS11.Mechanism(mech["m"], None)
            )
            self.assertTrue(res)

            key = self.pubobjToKey(pubkey, session)
            key2 = serialization.load_der_public_key(
                bytes(session.getAttributeValue(pubkey, [PyKCS11.CKA_VALUE])[0]),
                default_backend(),
            )
            self.assertEqual(key.public_numbers(), key2.public_numbers())

            key.verify(
                bytes(signature), tosign, padding.PKCS1v15(), mech["h"]
            )

            signature = session.sign(
                privkey, hashed, PyKCS11.Mechanism(PyKCS11.CKM_RSA_PKCS, None)
            )

            res = session.verify(
                pubkey, hashed, signature, PyKCS11.Mechanism(PyKCS11.CKM_RSA_PKCS, None)
            )
            self.assertTrue(res)

            key.verify(
                bytes(signature), tosign, padding.PKCS1v15(), mech["h"]
            )
Exemplo n.º 14
0
def recv_thread():
    global stock, stock_ix, ok, cheated, initialHands, rsa_priv_key, over, game_thr
    host = "0.0.0.0"

    crypto.init(shuffle.iv)

    with open('rsa_private_key', 'rb') as kf:
        rsa_priv_key = serialization.load_pem_private_key(
            kf.read(), None, default_backend())

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    s.bind((host, port))
    print("[socket] bound to port", port)

    s.listen(5)
    print("[socket] began listening")

    game_thr = Killable_Thread(target=game_thread)
    game_thr.start()

    while True:
        if len(players) < players_num:
            read_ready, _, _ = select.select(
                [p.socket for p in players.values()] + [s], [], [], 1)
        else:
            read_ready, _, _ = select.select(
                [p.socket for p in players.values()], [], [])

        for sock in read_ready:
            if sock is s and len(players) < players_num:
                c, addr = s.accept()
                print('[socket]', addr[0], ':', addr[1], '-', 'Connected')
                start_new_thread(register_thread, (
                    c,
                    addr,
                ))
            else:
                try:
                    rec = b''
                    while True:
                        part = sock.recv(1024)
                        rec += part
                        if len(part) < 1024:
                            break

                    data = json.loads(rec.decode('ascii'))
                    mac = crypto.encrypt(
                        hashlib.sha256(
                            data['message'].encode('ascii')).digest(),
                        players[sock].session_key)
                    if (mac.hex() if mac is not None else mac) != data['mac']:
                        print("Ignored message with erroneous MAC")
                        continue

                    message = json.loads(data['message'])

                    if message['type'] == messages.ACTION_REPLY:
                        try:
                            players[sock].rsa_pub_key.verify(
                                bytes.fromhex(message['sig']),
                                hashlib.sha256(
                                    str(message['action']).encode(
                                        'ascii')).digest(),
                                padding.PSS(
                                    mgf=padding.MGF1(hashes.SHA256()),
                                    salt_length=padding.PSS.MAX_LENGTH),
                                hashes.SHA256())
                        except:
                            print(
                                "Ignored ACTION_REPLY with invalid signature")
                            continue

                    print("[socket]", players[sock].name, "sent message:",
                          data)

                    if message['type'] == messages.ROUTING:
                        if message['destination'] in pseudo_players:
                            dst = message['destination']
                            del message['destination']
                            message['source'] = players[sock].name
                            pseudo_players[dst].send(message)
                    elif message['type'] == messages.SELECTION_REPLY:
                        stock_ix = message['tiles']
                        stock = [deck[ix] for ix in stock_ix]
                        for player in players.values():
                            if players[sock] is not player:
                                player.send({'type': messages.SELECTION_END})
                    elif message['type'] == messages.OK:
                        ok.add(players[sock].name)
                    elif message['type'] == messages.DE_ANON_PREP_REPLY:
                        shuffle.de_pseudonymize(list(players.values()),
                                                message['array'], deck_ix,
                                                deck, stock_ix)
                    elif message['type'] == messages.COMPLAIN:
                        if message['cheater'] is not None:
                            cheated = True, players[sock].name, message[
                                'cheater'], 'playing his own tile'
                        else:
                            raise GameEndedException()
                    elif message['type'] == messages.INITIAL_HAND_REPLY:
                        initialHands[
                            players[sock].name] = message['initial_hand']
                    elif message['type'] == messages.CLAIM_POINTS_REQUEST:
                        try:
                            cert_pem = bytes.fromhex(message['certificate'])
                            certificate = ssl_crypto.load_certificate(
                                ssl_crypto.FILETYPE_PEM, cert_pem)
                            x509_name = certificate.get_subject(
                            ).get_components()
                            name = x509_name[len(x509_name) -
                                             1][1].decode('ascii')
                            print("\nPlayer", players[sock].name, "is:", name)

                            pubKey_object = certificate.get_pubkey()
                            pubKeyString = ssl_crypto.dump_publickey(
                                ssl_crypto.FILETYPE_PEM, pubKey_object)
                            pubKey = serialization.load_pem_public_key(
                                pubKeyString, None)
                            pubKey.verify(players[sock].signature,
                                          bytes(players[sock].name, 'utf-8'),
                                          padding.PKCS1v15(), hashes.SHA1())
                            cert_date = date.today()
                            validate_chain(cert_pem, cert_date)
                            print('\nVerification succeeded - Player',
                                  players[sock].name)

                            points_db[name] = points_db[name] + players[
                                sock].points if name in points_db else players[
                                    sock].points

                            players[sock].send({
                                'type': messages.CLAIM_POINTS_REPLY,
                                'name': name,
                                'points': points_db[name]
                            })

                        except:
                            print('\nVerification failed - Player',
                                  players[sock].name)
                            players[sock].send({
                                'type': messages.CLAIM_POINTS_REPLY,
                                'name': None,
                                'points': None
                            })

                        del players[sock]

                    else:
                        players[sock].message = message
                        players[sock].lock.release()

                except json.decoder.JSONDecodeError:
                    print(
                        "\nClient unexpectedly disconnected. Restarting game")
                    kill_game(1, sock)

                except GameEndedException:
                    print(
                        "\nClient reported deck distribution / draw cheating. Restarting game"
                    )
                    kill_game(2, sock)

                except:
                    print('comms exception')
                    return
Exemplo n.º 15
0
def make_signature(payload, private_key) -> bytes:
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import padding

    return private_key.sign(payload, padding.PKCS1v15(), hashes.SHA1())
    def verify_signup_info(cls, signup_info, originator_public_key_hash):
        # Verify the attestation verification report signature
        proof_data_dict = json2dict(signup_info.proof_data)
        verification_report = proof_data_dict.get('verification_report')
        if verification_report is None:
            raise ValueError('Verification report is missing from proof data')

        signature = proof_data_dict.get('signature')
        if signature is None:
            raise ValueError('Signature is missing from proof data')

        try:
            cls._report_public_key.verify(base64.b64decode(signature.encode()),
                                          verification_report.encode(),
                                          padding.PKCS1v15(), hashes.SHA256())
        except InvalidSignature:
            raise ValueError('Verification report signature is invalid')

        verification_report_dict = json2dict(verification_report)

        # Verify that the verification report contains an ID field
        if 'id' not in verification_report_dict:
            raise ValueError('Verification report does not contain an ID')

        # Verify that the verification report contains an EPID pseudonym and
        # that it matches the anti-Sybil ID
        epid_pseudonym = verification_report_dict.get('epidPseudonym')
        if epid_pseudonym is None:
            raise \
                ValueError(
                    'Verification report does not contain an EPID pseudonym')

        if epid_pseudonym != signup_info.anti_sybil_id:
            raise \
                ValueError(
                    'The anti-Sybil ID in the verification report [{0}] does '
                    'not match the one contained in the signup information '
                    '[{1}]'.format(
                        epid_pseudonym,
                        signup_info.anti_sybil_id))

        # Verify that the verification report contains a PSE manifest status
        # and it is OK
        pse_manifest_status = \
            verification_report_dict.get('pseManifestStatus')
        if pse_manifest_status is None:
            raise \
                ValueError(
                    'Verification report does not contain a PSE manifest '
                    'status')
        if pse_manifest_status.upper() != 'OK':
            raise \
                ValueError(
                    'PSE manifest status is {} (i.e., not OK)'.format(
                        pse_manifest_status))

        # Verify that the verification report contains a PSE manifest hash
        pse_manifest_hash = \
            verification_report_dict.get('pseManifestHash')
        if pse_manifest_hash is None:
            raise \
                ValueError(
                    'Verification report does not contain a PSE manifest '
                    'hash')

        # Verify that the proof data contains evidence payload
        evidence_payload = proof_data_dict.get('evidence_payload')
        if evidence_payload is None:
            raise ValueError('Evidence payload is missing from proof data')

        # Verify that the evidence payload contains a PSE manifest and then
        # use it to make sure that the PSE manifest hash is what we expect
        pse_manifest = evidence_payload.get('pse_manifest')
        if pse_manifest is None:
            raise ValueError('Evidence payload does not include PSE manifest')

        expected_pse_manifest_hash = \
            base64.b64encode(
                hashlib.sha256(
                    pse_manifest.encode()).hexdigest().encode()).decode()

        if pse_manifest_hash.upper() != expected_pse_manifest_hash.upper():
            raise \
                ValueError(
                    'PSE manifest hash {0} does not match {1}'.format(
                        pse_manifest_hash,
                        expected_pse_manifest_hash))

        # Verify that the verification report contains an enclave quote status
        # and the status is OK
        enclave_quote_status = \
            verification_report_dict.get('isvEnclaveQuoteStatus')
        if enclave_quote_status is None:
            raise \
                ValueError(
                    'Verification report does not contain an enclave quote '
                    'status')
        if enclave_quote_status.upper() != 'OK':
            raise \
                ValueError(
                    'Enclave quote status is {} (i.e., not OK)'.format(
                        enclave_quote_status))

        # Verify that the verification report contains an enclave quote
        enclave_quote = verification_report_dict.get('isvEnclaveQuoteBody')
        if enclave_quote is None:
            raise \
                ValueError(
                    'Verification report does not contain an enclave quote')

        # The ISV enclave quote body is base 64 encoded, so decode it and then
        # create an SGX quote structure from it so we can inspect
        sgx_quote = sgx_structs.SgxQuote()
        sgx_quote.parse_from_bytes(base64.b64decode(enclave_quote))

        # The report body should be SHA256(SHA256(OPK)|PPK)
        #
        # NOTE - since the code that created the report data is in the enclave
        # code, this code needs to be kept in sync with it.  Any changes to how
        # the report data is created, needs to be reflected in how we re-create
        # the report data for verification.

        hash_input = \
            '{0}{1}'.format(
                originator_public_key_hash.upper(),
                cls._poet_public_key.upper()).encode()
        hash_value = hashlib.sha256(hash_input).digest()
        expected_report_data = \
            hash_value + \
            (b'\x00' *
             (sgx_structs.SgxReportData.STRUCT_SIZE - len(hash_value)))

        if sgx_quote.report_body.report_data.d != expected_report_data:
            raise \
                ValueError(
                    'AVR report data [{0}] not equal to [{1}]'.format(
                        sgx_quote.report_body.report_data.d.hex(),
                        expected_report_data.hex()))

        # Compare the enclave measurement against the expected valid enclave
        # measurement.
        #
        # NOTE - this is only a temporary check.  Instead of checking against
        # a predefined enclave measurement value, we should be configured with
        # a set of one or more enclave measurement values that we will
        # consider as valid.

        if sgx_quote.report_body.mr_enclave.m != \
                cls.__VALID_ENCLAVE_MEASUREMENT__:
            raise \
                ValueError(
                    'AVR enclave measurement [{0}] not equal to [{1}]'.format(
                        sgx_quote.report_body.mr_enclave.m.hex(),
                        cls.__VALID_ENCLAVE_MEASUREMENT__.hex()))

        # Compare the enclave basename in the verification report against the
        # expected enclave basename.
        #
        # NOTE - this is only a temporary check.  Instead of checking against
        # a predefined enclave basenme value, we should be configured with a
        # set of one or more enclave basenames that we will consider as valid.

        if sgx_quote.basename.name != cls.__VALID_BASENAME__:
            raise \
                ValueError(
                    'AVR enclave basename [{0}] not equal to [{1}]'.format(
                        sgx_quote.basename.name.hex(),
                        cls.__VALID_BASENAME__.hex()))
Exemplo n.º 17
0
def _get_rsasig_b64(key, string_to_sign):

    return b64encode(key.sign(
        string_to_sign,
        padding.PKCS1v15(),
        hashes.SHA256()))
Exemplo n.º 18
0
 def signproc(tosign, algosig):
     key = p12.get_privatekey().to_cryptography_key()
     signed_value_signature = key.sign(tosign, padding.PKCS1v15(),
                                       getattr(hashes, algosig.upper())())
     return signed_value_signature
Exemplo n.º 19
0
def verify_enclave_registration_info(connect,
                                     payload,
                                     details,
                                     originator_public_key_hash,
                                     context,
                                     report_public_key_pem,
                                     valid_measurements,
                                     valid_basenames,
                                     verify_pse_manifest=False):
    # Verify the attestation verification report signature
    proof_data_dict = json.loads(details.proof_data)
    verification_report = proof_data_dict.get('verification_report')
    if verification_report is None:
        raise ValueError('Verification report is missing from proof data')

    signature = proof_data_dict.get('signature')
    if signature is None:
        raise ValueError('Signature is missing from proof data')

    # If we cannot parse it, fail verification.
    try:
        report_public_key = \
            serialization.load_pem_public_key(
                report_public_key_pem.encode(),
                backend=backends.default_backend())
    except (TypeError, ValueError) as error:
        raise ValueError('Failed to parse public key: {}'.format(error))

    # Convert the comma-delimited list of valid enclave measurement values.
    # If it is not there, or fails to parse correctly, fail verification.
    try:
        valid_enclave_measurements = \
            [bytes.fromhex(m) for m in valid_measurements.split(',')]
    except ValueError as error:
        raise \
            ValueError(
                'Failed to parse enclave measurement: {}'.format(error))

    # Convert the comma-delimited list of valid enclave basename values.
    # If it is not there, or fails to parse correctly, fail verification.
    try:
        valid_enclave_basenames = \
            [bytes.fromhex(b) for b in valid_basenames.split(',')]
    except ValueError as error:
        raise \
            ValueError(
                'Failed to parse enclave basename: {}'.format(error))

    try:
        report_public_key.verify(
            base64.b64decode(signature.encode()),
            verification_report.encode(),
            padding.PKCS1v15(),
            hashes.SHA256())
    except InvalidSignature:
        raise ValueError('Verification report signature is invalid')

    verification_report_dict = json.loads(verification_report)

    # Verify that the verification report contains an ID field
    if 'id' not in verification_report_dict:
        raise ValueError('Verification report does not contain an ID')

    # Verify that the verification report contains an EPID pseudonym and
    # that it matches the enclave_persistent_id
    epid_pseudonym = verification_report_dict.get('epidPseudonym')
    if epid_pseudonym is None:
        raise \
            ValueError(
                'Verification report does not contain an EPID pseudonym')

    if epid_pseudonym != details.enclave_persistent_id:
        raise \
            ValueError(
                'The epid pseudonym in the verification report [{0}] does '
                'not match the one contained in the registration information '
                '[{1}]'.format(
                    epid_pseudonym,
                    details.enclave_persistent_id))

    if verify_pse_manifest:
        # Verify that the verification report contains a PSE manifest status
        # and it is OK
        pse_manifest_status = \
            verification_report_dict.get('pseManifestStatus')
        if pse_manifest_status is None:
            raise \
                ValueError(
                    'Verification report does not contain a PSE manifest '
                    'status')
        if pse_manifest_status.upper() != 'OK':
            if pse_manifest_status.upper() == 'OUT_OF_DATE':
                LOGGER.warning('Peer has out of date (but not revoked)'
                               ' hardware, pseManifestStatus: %s',
                               pse_manifest_status)
            else:
                raise \
                    ValueError(
                        'PSE manifest status is {} (i.e., not OK)'.format(
                            pse_manifest_status))

        # Verify that the verification report contains a PSE manifest hash
        pse_manifest_hash = \
            verification_report_dict.get('pseManifestHash')
        if pse_manifest_hash is None:
            raise \
                ValueError(
                    'Verification report does not contain a PSE manifest '
                'hash')
    else:
        pse_manifest_hash = ""

    if verify_pse_manifest:
        # Verify that the proof data contains evidence payload
        evidence_payload = proof_data_dict.get('evidence_payload')
        if evidence_payload is None:
            raise ValueError('Evidence payload is missing from proof data')
        # Verify that the evidence payload contains a PSE manifest and then
        # use it to make sure that the PSE manifest hash is what we expect
        pse_manifest = evidence_payload.get('pse_manifest')
        if pse_manifest is None:
            raise ValueError('Evidence payload does not include PSE manifest')

        expected_pse_manifest_hash = \
            hashlib.sha256(
                base64.b64decode(pse_manifest.encode())).hexdigest()
        if pse_manifest_hash.upper() != expected_pse_manifest_hash.upper():
            raise \
                ValueError(
                    'PSE manifest hash {0} does not match {1}'.format(
                        pse_manifest_hash,
                        expected_pse_manifest_hash))

    # Verify that the verification report contains an enclave quote and
    # that its status is OK
    enclave_quote_status = \
        verification_report_dict.get('isvEnclaveQuoteStatus')
    if enclave_quote_status is None:
        raise \
            ValueError(
                'Verification report does not contain an enclave quote '
                'status')
    if enclave_quote_status.upper() != 'OK':
        if enclave_quote_status.upper() == 'GROUP_OUT_OF_DATE':
            LOGGER.warning('Peer has out of date (but not revoked)'
                           ' hardware, isvEnclaveQuoteStatus: %s',
                           str(enclave_quote_status))
        else:
            raise \
                ValueError(
                    'Enclave quote status is {} (i.e., not OK)'.format(
                        enclave_quote_status))

    # Verify that the verification report contains an enclave quote
    enclave_quote = verification_report_dict.get('isvEnclaveQuoteBody')
    if enclave_quote is None:
        raise \
            ValueError(
                'Verification report does not contain an enclave quote')

    # The ISV enclave quote body is base 64 encoded, so decode it and then
    # create an SGX quote structure from it so we can inspect
    sgx_quote = SgxQuote()
    sgx_quote.parse_from_bytes(base64.b64decode(enclave_quote))

    # NOTE - since the code that created the report data is in the enclave
    # code, this code needs to be kept in sync with it.  Any changes to how
    # the report data is created, needs to be reflected in how we re-create
    # the report data for verification.

    hash_input = \
        '{0}{1}{2}'.format(
            payload.verifying_key,
            details.encryption_key,
            originator_public_key_hash).encode()
    LOGGER.debug("quote hash input: %s", hash_input)

    hash_value = hashlib.sha256(hash_input).digest()
    expected_report_data = \
        hash_value + \
        (b'\x00' *
        (SgxReportData.STRUCT_SIZE - len(hash_value)))

    if sgx_quote.report_body.report_data.d != expected_report_data:
        raise \
            ValueError(
                'AVR report data [{0}] not equal to [{1}]'.format(
                    sgx_quote.report_body.report_data.d.hex(),
                    expected_report_data.hex()))

    # Verify that the enclave measurement is in the list of valid
    # enclave measurements.
    if sgx_quote.report_body.mr_enclave.m not in \
            valid_enclave_measurements:
        raise \
            ValueError(
                'AVR enclave measurement [{}] not in list of valid '
                'enclave measurements [{}]'.format(
                    sgx_quote.report_body.mr_enclave.m.hex(),
                    valid_measurements))

    # Verify that the enclave basename is in the list of valid
    # enclave basenames
    if sgx_quote.basename.name not in valid_enclave_basenames:
        raise \
            ValueError(
                'AVR enclave basename [{}] not in list of valid '
                'enclave basenames [{}]'.format(
                    sgx_quote.basename.name.hex(),
                    valid_basenames))

    # Verify that the nonce in the verification report matches
    # registration_block_context in the transaction payload submitted
    nonce = verification_report_dict.get('nonce', '')
    if nonce != details.registration_block_context:
        raise \
            ValueError(
                'AVR nonce [{0}] does not match registration_block_context in the '
                'registration info [{1}]'.format(
                    nonce,
                    details.registration_block_context))
Exemplo n.º 20
0
class CryptographyRSAKey(Key):
    SHA256 = hashes.SHA256
    SHA384 = hashes.SHA384
    SHA512 = hashes.SHA512

    RSA1_5 = padding.PKCS1v15()
    RSA_OAEP = padding.OAEP(padding.MGF1(hashes.SHA1()), hashes.SHA1(), None)
    RSA_OAEP_256 = padding.OAEP(padding.MGF1(hashes.SHA256()), hashes.SHA256(),
                                None)

    def __init__(self, key, algorithm, cryptography_backend=default_backend):
        if algorithm not in ALGORITHMS.RSA:
            raise JWKError('hash_alg: %s is not a valid hash algorithm' %
                           algorithm)

        self.hash_alg = {
            ALGORITHMS.RS256: self.SHA256,
            ALGORITHMS.RS384: self.SHA384,
            ALGORITHMS.RS512: self.SHA512
        }.get(algorithm)
        self._algorithm = algorithm

        self.padding = {
            ALGORITHMS.RSA1_5: self.RSA1_5,
            ALGORITHMS.RSA_OAEP: self.RSA_OAEP,
            ALGORITHMS.RSA_OAEP_256: self.RSA_OAEP_256
        }.get(algorithm)

        self.cryptography_backend = cryptography_backend

        # if it conforms to RSAPublicKey interface
        if hasattr(key, 'public_bytes') and hasattr(key, 'public_numbers'):
            self.prepared_key = key
            return

        if isinstance(key, dict):
            self.prepared_key = self._process_jwk(key)
            return

        if isinstance(key, str):
            key = key.encode('utf-8')

        if isinstance(key, bytes):
            try:
                if key.startswith(b'-----BEGIN CERTIFICATE-----'):
                    self._process_cert(key)
                    return

                try:
                    self.prepared_key = load_pem_public_key(
                        key, self.cryptography_backend())
                except ValueError:
                    self.prepared_key = load_pem_private_key(
                        key,
                        password=None,
                        backend=self.cryptography_backend())
            except Exception as e:
                raise JWKError(e)
            return

        raise JWKError('Unable to parse an RSA_JWK from key: %s' % key)

    def _process_jwk(self, jwk_dict):
        if not jwk_dict.get('kty') == 'RSA':
            raise JWKError(
                "Incorrect key type. Expected: 'RSA', Received: %s" %
                jwk_dict.get('kty'))

        e = base64_to_long(jwk_dict.get('e', 256))
        n = base64_to_long(jwk_dict.get('n'))
        public = rsa.RSAPublicNumbers(e, n)

        if 'd' not in jwk_dict:
            return public.public_key(self.cryptography_backend())
        else:
            # This is a private key.
            d = base64_to_long(jwk_dict.get('d'))

            extra_params = ['p', 'q', 'dp', 'dq', 'qi']

            if any(k in jwk_dict for k in extra_params):
                # Precomputed private key parameters are available.
                if not all(k in jwk_dict for k in extra_params):
                    # These values must be present when 'p' is according to
                    # Section 6.3.2 of RFC7518, so if they are not we raise
                    # an error.
                    raise JWKError(
                        'Precomputed private key parameters are incomplete.')

                p = base64_to_long(jwk_dict['p'])
                q = base64_to_long(jwk_dict['q'])
                dp = base64_to_long(jwk_dict['dp'])
                dq = base64_to_long(jwk_dict['dq'])
                qi = base64_to_long(jwk_dict['qi'])
            else:
                # The precomputed private key parameters are not available,
                # so we use cryptography's API to fill them in.
                p, q = rsa.rsa_recover_prime_factors(n, e, d)
                dp = rsa.rsa_crt_dmp1(d, p)
                dq = rsa.rsa_crt_dmq1(d, q)
                qi = rsa.rsa_crt_iqmp(p, q)

            private = rsa.RSAPrivateNumbers(p, q, d, dp, dq, qi, public)

            return private.private_key(self.cryptography_backend())

    def _process_cert(self, key):
        key = load_pem_x509_certificate(key, self.cryptography_backend())
        self.prepared_key = key.public_key()

    def sign(self, msg):
        try:
            signature = self.prepared_key.sign(msg, padding.PKCS1v15(),
                                               self.hash_alg())
        except Exception as e:
            raise JWKError(e)
        return signature

    def verify(self, msg, sig):
        if not self.is_public():
            warnings.warn("Attempting to verify a message with a private key. "
                          "This is not recommended.")

        try:
            self.public_key().prepared_key.verify(sig, msg, padding.PKCS1v15(),
                                                  self.hash_alg())
            return True
        except InvalidSignature:
            return False

    def is_public(self):
        return hasattr(self.prepared_key, 'public_bytes')

    def public_key(self):
        if self.is_public():
            return self
        return self.__class__(self.prepared_key.public_key(), self._algorithm)

    def to_pem(self, pem_format='PKCS8'):
        if self.is_public():
            if pem_format == 'PKCS8':
                fmt = serialization.PublicFormat.SubjectPublicKeyInfo
            elif pem_format == 'PKCS1':
                fmt = serialization.PublicFormat.PKCS1
            else:
                raise ValueError("Invalid format specified: %r" % pem_format)
            pem = self.prepared_key.public_bytes(
                encoding=serialization.Encoding.PEM, format=fmt)
            return pem

        if pem_format == 'PKCS8':
            fmt = serialization.PrivateFormat.PKCS8
        elif pem_format == 'PKCS1':
            fmt = serialization.PrivateFormat.TraditionalOpenSSL
        else:
            raise ValueError("Invalid format specified: %r" % pem_format)

        return self.prepared_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=fmt,
            encryption_algorithm=serialization.NoEncryption())

    def to_dict(self):
        if not self.is_public():
            public_key = self.prepared_key.public_key()
        else:
            public_key = self.prepared_key

        data = {
            'alg': self._algorithm,
            'kty': 'RSA',
            'n': long_to_base64(public_key.public_numbers().n).decode('ASCII'),
            'e': long_to_base64(public_key.public_numbers().e).decode('ASCII'),
        }

        if not self.is_public():
            data.update({
                'd':
                long_to_base64(
                    self.prepared_key.private_numbers().d).decode('ASCII'),
                'p':
                long_to_base64(
                    self.prepared_key.private_numbers().p).decode('ASCII'),
                'q':
                long_to_base64(
                    self.prepared_key.private_numbers().q).decode('ASCII'),
                'dp':
                long_to_base64(
                    self.prepared_key.private_numbers().dmp1).decode('ASCII'),
                'dq':
                long_to_base64(
                    self.prepared_key.private_numbers().dmq1).decode('ASCII'),
                'qi':
                long_to_base64(
                    self.prepared_key.private_numbers().iqmp).decode('ASCII'),
            })

        return data

    def wrap_key(self, key_data):
        try:
            wrapped_key = self.prepared_key.encrypt(key_data, self.padding)
        except Exception as e:
            raise JWEError(e)

        return wrapped_key

    def unwrap_key(self, wrapped_key):
        try:
            unwrapped_key = self.prepared_key.decrypt(wrapped_key,
                                                      self.padding)
            return unwrapped_key
        except Exception as e:
            raise JWEError(e)
Exemplo n.º 21
0
def x5u_vulnerability(jwt=None, url=None, crt=None, pem=None, file=None):
    """
    Check jku Vulnerability.

    Parameters
    ----------
    jwt: str
        your jwt.
    url: str
        your url.
    crt: str
        crt path file
    pem: str
       pem file name
    file: str
        jwks file name

    Returns
    -------
    str
        your new jwt.
    """
    if not is_valid_jwt(jwt):
        raise InvalidJWT("Invalid JWT format")
    if file is None:
        file = "jwks_with_x5c.json"

    jwt_json = jwt_to_json(jwt)
    if "x5u" not in jwt_json[HEADER]:
        raise InvalidJWT("Invalid JWT format JKU missing")
    if crt is None or pem is None:
        crt, pem = create_crt()

    with open(crt) as f:
        content = f.read()
        f.close()

    x5u = requests.get(jwt_json[HEADER]["x5u"]).json()
    x5u["keys"][0]["x5c"] = (content.replace("-----END CERTIFICATE-----",
                                             "").replace(
                                                 "-----BEGIN CERTIFICATE-----",
                                                 "").replace("\n", ""))
    if ".json" not in file:
        file += ".json"
    if not url.endswith("/"):
        url += "/"
    jwt_json[HEADER]["x5u"] = f"{url}{file}"

    f = open(file, "w")
    f.write(json.dumps(x5u))
    f.close()

    s = encode_jwt(jwt_json)
    key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(pem).read())

    priv = key.to_cryptography_key()
    sign = priv.sign(
        bytes(s, encoding="UTF-8"),
        algorithm=hashes.SHA256(),
        padding=padding.PKCS1v15(),
    )

    return s + "." + base64.urlsafe_b64encode(sign).decode("UTF-8").rstrip("=")
Exemplo n.º 22
0
    def _api_endpoint_get(cls, g, request_data):
        """ Handle all GET requests to the api endpoint.

        Currently this is only used for polling.
        :param g: The Flask context
        :param request_data: Dictionary containing the parameters of the request
        :type request_data: dict
        :returns: Result of the polling operation, 'True' if an unanswered and
                  matching challenge exists, 'False' otherwise.
        :rtype: bool
        """
        # By default we allow polling if the policy is not set.
        allow_polling = get_action_values_from_options(
            SCOPE.AUTH, PUSH_ACTION.ALLOW_POLLING,
            options={'g': g}) or PushAllowPolling.ALLOW
        if allow_polling == PushAllowPolling.DENY:
            raise PolicyError('Polling not allowed!')
        serial = getParam(request_data, "serial", optional=False)
        timestamp = getParam(request_data, 'timestamp', optional=False)
        signature = getParam(request_data, 'signature', optional=False)
        # first check if the timestamp is in the required span
        cls._check_timestamp_in_range(timestamp, POLL_TIME_WINDOW)
        # now check the signature
        # first get the token
        try:
            tok = get_one_token(serial=serial, tokentype=cls.get_class_type())
            # If the push_allow_polling policy is set to "token" we also
            # need to check the POLLING_ALLOWED tokeninfo. If it evaluated
            # to 'False', polling is not allowed for this token. If the
            # tokeninfo value evaluates to 'True' or is not set at all,
            # polling is allowed for this token.
            if allow_polling == PushAllowPolling.TOKEN:
                if not is_true(
                        tok.get_tokeninfo(POLLING_ALLOWED, default='True')):
                    log.debug('Polling not allowed for pushtoken {0!s} due to '
                              'tokeninfo.'.format(serial))
                    raise PolicyError('Polling not allowed!')

            pubkey_obj = _build_verify_object(
                tok.get_tokeninfo(PUBLIC_KEY_SMARTPHONE))
            sign_data = u"{serial}|{timestamp}".format(**request_data)
            pubkey_obj.verify(b32decode(signature), sign_data.encode("utf8"),
                              padding.PKCS1v15(), hashes.SHA256())
            # The signature was valid now check for an open challenge
            # we need the private server key to sign the smartphone data
            pem_privkey = tok.get_tokeninfo(PRIVATE_KEY_SERVER)
            # We need the registration URL for the challenge
            registration_url = get_action_values_from_options(
                SCOPE.ENROLL, PUSH_ACTION.REGISTRATION_URL, options={'g': g})
            if not registration_url:
                raise ResourceNotFoundError(
                    'There is no registration_url defined for the '
                    ' pushtoken {0!s}. You need to define a push_registration_url '
                    'in an enrollment policy.'.format(serial))
            options = {'g': g}
            challenges = []
            challengeobject_list = get_challenges(serial=serial)
            for chal in challengeobject_list:
                # check if the challenge is active and not already answered
                _cnt, answered = chal.get_otp_status()
                if not answered and chal.is_valid():
                    # then return the necessary smartphone data to answer
                    # the challenge
                    sp_data = _build_smartphone_data(serial, chal.challenge,
                                                     registration_url,
                                                     pem_privkey, options)
                    challenges.append(sp_data)
            # return the challenges as a list in the result value
            result = challenges
        except (ResourceNotFoundError, ParameterError, InvalidSignature,
                ConfigAdminError, BinasciiError) as e:
            # to avoid disclosing information we always fail with an invalid
            # signature error even if the token with the serial could not be found
            log.debug('{0!s}'.format(traceback.format_exc()))
            log.info('The following error occurred during the signature '
                     'check: "{0!r}"'.format(e))
            raise privacyIDEAError('Could not verify signature!')

        return result
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import utils
from encodings.base64_codec import base64_encode, base64_decode

backend = default_backend()  # set our default backend
#mydata = b'abcdef123!!!!'  # our user data to be read

with open('user1_cert.pem', 'rb') as file:
    certificate = x509.load_pem_x509_certificate(
        data=file.read(),
        backend=backend)
public_key = certificate.public_key()
sig = certificate.signature
data = certificate.tbs_certificate_bytes
myhash = hashes.SHA256()  # Create and call SHA256 hash function
hasher = hashes.Hash(myhash, backend)  # create hash object

hasher.update(data)  # add data to message digest with update function

digest = hasher.finalize()  # finalize hash algorithim digest
pad = padding.PKCS1v15()

public_key.verify(  # verify signature method
    signature=sig,
    data=digest,
    padding=pad, algorithm=utils.Prehashed(myhash))
sig_fname = 'sig.pem'
Exemplo n.º 24
0
 def _rsa_signer(self, message):
     """ Generate a RSA signature for a message """
     return self.crypto_pk.sign(message, padding.PKCS1v15(), hashes.SHA1())
Exemplo n.º 25
0
    ('RSA', 'MD5'): rfc2459.md5WithRSAEncryption,
    ('RSA', 'SHA1'): rfc2459.sha1WithRSAEncryption,
    ('RSA', 'SHA224'): sha224WithRSAEncryption,
    ('RSA', 'SHA256'): sha256WithRSAEncryption,
    ('RSA', 'SHA384'): sha384WithRSAEncryption,
    ('RSA', 'SHA512'): sha512WithRSAEncryption,
    ('DSA', 'SHA1'): rfc2459.id_dsa_with_sha1,
    ('DSA', 'SHA224'): id_dsa_with_sha224,
    ('DSA', 'SHA256'): id_dsa_with_sha256,
}

SIGNING_ALGORITHMS_INV = dict((v, k) for k, v in SIGNING_ALGORITHMS.items())

SIGNER_CONSTRUCTION = {
    rfc2459.md5WithRSAEncryption:
    (lambda key: key.signer(padding.PKCS1v15(), hashes.MD5())),
    rfc2459.sha1WithRSAEncryption:
    (lambda key: key.signer(padding.PKCS1v15(), hashes.SHA1())),
    sha224WithRSAEncryption:
    (lambda key: key.signer(padding.PKCS1v15(), hashes.SHA224())),
    sha256WithRSAEncryption:
    (lambda key: key.signer(padding.PKCS1v15(), hashes.SHA256())),
    sha384WithRSAEncryption:
    (lambda key: key.signer(padding.PKCS1v15(), hashes.SHA384())),
    sha512WithRSAEncryption:
    (lambda key: key.signer(padding.PKCS1v15(), hashes.SHA512())),
    rfc2459.id_dsa_with_sha1: (lambda key: key.signer(hashes.SHA1())),
    id_dsa_with_sha224: (lambda key: key.signer(hashes.SHA224())),
    id_dsa_with_sha256: (lambda key: key.signer(hashes.SHA256())),
}
Exemplo n.º 26
0
    def verify_sig(self,
                   acts,
                   pub,
                   trust_anchors,
                   use_crls,
                   required_names=None):
        """Try to verify this signature.  It can return True or
                None.  None means we didn't know how to verify this signature.
                If we do know how to verify the signature but it doesn't verify,
                then an exception is raised.

                The 'acts' parameter is the iterable of actions against which
                to verify the signature.

                The 'pub' parameter is the publisher that published the
                package this action signed.

                The 'trust_anchors' parameter contains the trust anchors to use
                when verifying the signature.

                The 'required_names' parameter is a set of strings that must
                be seen as a CN in the chain of trust for the certificate."""

        ver = int(self.attrs["version"])
        # If this signature is tagged with variants, if the version is
        # higher than one we know about, or it uses an unrecognized
        # hash algorithm, we can't handle it yet.
        if self.get_variant_template() or \
            ver > generic.Action.sig_version or not self.hash_alg:
            return None
        # Turning this into a list makes debugging vastly more
        # tractable.
        acts = list(acts)
        # If self.hash is None, then the signature is storing a hash
        # of the actions, not a signed value.
        if self.hash is None:
            assert self.sig_alg is None
            h = hashlib.new(self.hash_alg)
            h.update(misc.force_bytes(self.actions_to_str(acts, ver)))
            computed_hash = h.digest()
            # The attrs value is stored in hex so that it's easy
            # to read.
            if misc.hex_to_binary(self.attrs["value"]) != \
                computed_hash:
                raise apx.UnverifiedSignature(
                    self,
                    _("The signature value did not match the "
                      "expected value. action: {0}").format(self))
            return True
        # Verify a signature that's not just a hash.
        if self.sig_alg is None:
            return None
        # Get the certificate paired with the key which signed this
        # action.
        attr, hash_val, hash_func = \
            digest.get_least_preferred_hash(self)
        cert = pub.get_cert_by_hash(hash_val,
                                    verify_hash=True,
                                    hash_func=hash_func)
        # Make sure that the intermediate certificates that are needed
        # to validate this signature are present.
        self.retrieve_chain_certs(pub)
        try:
            # This import is placed here to break a circular
            # import seen when merge.py is used.
            from pkg.client.publisher import CODE_SIGNING_USE
            # Verify the certificate whose key created this
            # signature action.
            pub.verify_chain(cert,
                             trust_anchors,
                             0,
                             use_crls,
                             required_names=required_names,
                             usages=CODE_SIGNING_USE)
        except apx.SigningException as e:
            e.act = self
            raise
        # Check that the certificate verifies against this signature.
        pub_key = cert.public_key()
        hhash = self.__get_hash_by_name(self.hash_alg)
        try:
            pub_key.verify(misc.hex_to_binary(self.attrs["value"]),
                           misc.force_bytes(self.actions_to_str(acts, ver)),
                           padding.PKCS1v15(), hhash())
        except InvalidSignature:
            raise apx.UnverifiedSignature(
                self,
                _("The signature value did not match the expected "
                  "value."))

        return True
Exemplo n.º 27
0
 def handler(message):
     return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())
Exemplo n.º 28
0
 def sign(self, sigdata, hash_alg):
     return self.__privkey__().sign(sigdata, padding.PKCS1v15(), hash_alg)
Exemplo n.º 29
0
    def _api_endpoint_post(cls, request_data):
        """ Handle all POST requests to the api endpoint

        :param request_data: Dictionary containing the parameters of the request
        :type request_data: dict
        :returns: The result of handling the request and a dictionary containing
                  the details of the request handling
        :rtype: (bool, dict)
        """
        details = {}
        result = False

        serial = getParam(request_data, "serial", optional=False)
        if all(k in request_data for k in ("fbtoken", "pubkey")):
            log.debug("Do the 2nd step of the enrollment.")
            try:
                token_obj = get_one_token(serial=serial,
                                          tokentype="push",
                                          rollout_state="clientwait")
                token_obj.update(request_data)
            except ResourceNotFoundError:
                raise ResourceNotFoundError("No token with this serial number "
                                            "in the rollout state 'clientwait'.")
            init_detail_dict = request_data

            details = token_obj.get_init_detail(init_detail_dict)
            result = True
        elif all(k in request_data for k in ("nonce", "signature")):
            log.debug("Handling the authentication response from the smartphone.")
            challenge = getParam(request_data, "nonce")
            signature = getParam(request_data, "signature")

            # get the token_obj for the given serial:
            token_obj = get_one_token(serial=serial, tokentype="push")
            pubkey_obj = _build_verify_object(token_obj.get_tokeninfo(PUBLIC_KEY_SMARTPHONE))
            # Do the 2nd step of the authentication
            # Find valid challenges
            challengeobject_list = get_challenges(serial=serial, challenge=challenge)

            if challengeobject_list:
                # There are valid challenges, so we check this signature
                for chal in challengeobject_list:
                    # verify the signature of the nonce
                    sign_data = u"{0!s}|{1!s}".format(challenge, serial)
                    try:
                        pubkey_obj.verify(b32decode(signature),
                                          sign_data.encode("utf8"),
                                          padding.PKCS1v15(),
                                          hashes.SHA256())
                        # The signature was valid
                        log.debug("Found matching challenge {0!s}.".format(chal))
                        chal.set_otp_status(True)
                        chal.save()
                        result = True
                    except InvalidSignature as _e:
                        pass
        elif all(k in request_data for k in ('new_fb_token', 'timestamp', 'signature')):
            timestamp = getParam(request_data, 'timestamp', optional=False)
            signature = getParam(request_data, 'signature', optional=False)
            # first check if the timestamp is in the required span
            cls._check_timestamp_in_range(timestamp, UPDATE_FB_TOKEN_WINDOW)
            try:
                tok = get_one_token(serial=serial, tokentype=cls.get_class_type())
                pubkey_obj = _build_verify_object(tok.get_tokeninfo(PUBLIC_KEY_SMARTPHONE))
                sign_data = u"{new_fb_token}|{serial}|{timestamp}".format(**request_data)
                pubkey_obj.verify(b32decode(signature),
                                  sign_data.encode("utf8"),
                                  padding.PKCS1v15(),
                                  hashes.SHA256())
                # If the timestamp and signature are valid we update the token
                tok.add_tokeninfo('firebase_token', request_data['new_fb_token'])
                result = True
            except (ResourceNotFoundError, ParameterError, TypeError,
                    InvalidSignature, ConfigAdminError, BinasciiError) as e:
                # to avoid disclosing information we always fail with an invalid
                # signature error even if the token with the serial could not be found
                log.debug('{0!s}'.format(traceback.format_exc()))
                log.info('The following error occurred during the signature '
                         'check: "{0!r}"'.format(e))
                raise privacyIDEAError('Could not verify signature!')
        else:
            raise ParameterError("Missing parameters!")

        return result, details
Exemplo n.º 30
0
def verify_sha256(certificate, data, signature):
    certificate.public_key().verify(
        signature,
        data,
        padding.PKCS1v15(),
        hashes.SHA256())