Esempio n. 1
0
    def _get_user_credentials(self, user_id):
        """
        Get all credentials associated with a user in the current mode from the
        database
        :param user_id: The id of the user
        :return: List of AttestedCredentialData
        """
        if not user_id:
            return []

        cursor = self._db_connection.cursor()

        sql_command = """
        SELECT credential_id, aaguid, public_key
        FROM credentials
        WHERE user_id=(?) AND mode=(?)
        """
        cursor.execute(sql_command, (user_id, int(self.mode)))
        results = cursor.fetchall()
        cursor.close()

        credentials = []
        if results and len(results) > 0:
            for result in results:
                credential_id = result[0]
                aaguid = result[1]
                public_key = CoseKey.parse(loads(result[2])[0])
                credential = AttestedCredentialData.create(
                    aaguid, credential_id, public_key)
                credentials.append(credential)

        return credentials
Esempio n. 2
0
def complete_reg(request):
    try:
        data = cbor.loads(request.body)[0]

        client_data = ClientData(data['clientDataJSON'])
        att_obj = AttestationObject((data['attestationObject']))
        server = getServer()
        auth_data = server.register_complete(request.session['fido_state'],
                                             client_data, att_obj)
        encoded = websafe_encode(auth_data.credential_data)
        uk = User_Keys()
        uk.username = request.user.username
        uk.properties = {
            "device": encoded,
            "type": att_obj.fmt,
        }
        uk.key_type = "FIDO2"
        uk.save()
        return HttpResponse(simplejson.dumps({'status': 'OK'}))
    except Exception as exp:
        from raven.contrib.django.raven_compat.models import client
        import traceback
        client.captureException()
        return HttpResponse(
            simplejson.dumps({
                'status':
                'ERR',
                "message":
                "Error on server, please try again later"
            }))
Esempio n. 3
0
def authenticate_complete(request):
    credentials = []
    username=request.session.get("base_username",request.user.username)
    server=getServer()
    credentials=getUserCredentials(username)
    data = cbor.loads(request.body)[0]
    credential_id = data['credentialId']
    client_data = ClientData(data['clientDataJSON'])
    auth_data = AuthenticatorData(data['authenticatorData'])
    signature = data['signature']

    cred = server.authenticate_complete(
        request.session.pop('fido_state'),
        credentials,
        credential_id,
        client_data,
        auth_data,
        signature
    )
    keys = User_Keys.objects.filter(username=username, key_type="FIDO2",enabled=1)
    import random
    for k in keys:
        if AttestedCredentialData(websafe_decode(k.properties["device"])).credential_id == cred.credential_id:
            k.last_used = timezone.now()
            k.save()
            mfa = {"verified": True, "method": "FIDO2"}
            if getattr(settings, "MFA_RECHECK", False):
                mfa["next_check"] = int((datetime.datetime.now()+ datetime.timedelta(
                seconds=random.randint(settings.MFA_RECHECK_MIN, settings.MFA_RECHECK_MAX))).strftime("%s"))
            request.session["mfa"] = mfa
            res=login(request)
            return HttpResponse(simplejson.dumps({'status':"OK","redirect":res["location"]}),content_type="application/json")
    return HttpResponse(simplejson.dumps({'status': "err"}))
Esempio n. 4
0
 def test_vectors(self):
     for (data, value) in _TEST_VECTORS:
         try:
             self.assertEqual(cbor.loads(a2b_hex(data)), (value, b''))
             self.assertEqual(cbor2hex(value), data)
         except Exception:
             print('\nERROR in test vector, %s' % data)
             raise
Esempio n. 5
0
def authenticate_complete():
    data = cbor.loads(request.get_data())[0]
    credential_id = data['credentialId']
    client_data = ClientData(data['clientDataJSON'])
    auth_data = AuthenticatorData(data['authenticatorData'])
    signature = data['signature']

    credentials = session['userobj']['credentials']
    fidoserver.authenticate_complete(credentials, credential_id,
                                 session.pop('challenge'), client_data,
                                 auth_data, signature)
    return cbor.dumps({'status': 'OK'})
Esempio n. 6
0
def register_complete():
    data = cbor.loads(request.get_data())[0]
    client_data = ClientData(data['clientDataJSON'])
    att_obj = AttestationObject(data['attestationObject'])
    print('clientData', client_data)
    print('AttestationObject:', att_obj)

    auth_data = server.register_complete(session['state'], client_data,
                                         att_obj)

    credentials.append(auth_data.credential_data)
    print('REGISTERED CREDENTIAL:', auth_data.credential_data)
    return cbor.dumps({'status': 'OK'})
Esempio n. 7
0
def u2f_complete():
    data = cbor.loads(request.get_data())[0]
    client_data = ClientData.from_b64(data['clientData'])
    reg_data = RegistrationData.from_b64(data['registrationData'])
    print('clientData', client_data)
    print('U2F RegistrationData:', reg_data)
    att_obj = AttestationObject.from_ctap1(sha256(b'https://localhost:5000'),
                                           reg_data)
    print('AttestationObject:', att_obj)

    auth_data = att_obj.auth_data

    credentials.append(auth_data.credential_data)
    print('REGISTERED U2F CREDENTIAL:', auth_data.credential_data)
    return cbor.dumps({'status': 'OK'})
Esempio n. 8
0
def authenticate_complete():
    if not credentials:
        abort(404)

    data = cbor.loads(request.get_data())[0]
    credential_id = data['credentialId']
    client_data = ClientData(data['clientDataJSON'])
    auth_data = AuthenticatorData(data['authenticatorData'])
    signature = data['signature']
    print('clientData', client_data)
    print('AuthenticatorData', auth_data)

    server.authenticate_complete(session.pop('state'), credentials,
                                 credential_id, client_data, auth_data,
                                 signature)
    print('ASSERTION OK')
    return cbor.dumps({'status': 'OK'})
Esempio n. 9
0
File: fido2.py Progetto: utzig/solo
    def test_get_info(self, ):
        with Test("Get info"):
            info = self.ctap.get_info()
            print(bytes(info))
            print(cbor.loads(bytes(info)))

        with Test("Check FIDO2 string is in VERSIONS field"):
            assert "FIDO_2_0" in info.versions

        with Test("Check pin protocols field"):
            if len(info.pin_protocols):
                assert sum(info.pin_protocols) > 0

        with Test("Check options field"):
            for x in info.options:
                assert info.options[x] in [True, False]

        if "uv" in info.options:
            if info.options["uv"]:
                self.testMC(
                    "Send MC request with uv set to true, expect SUCCESS",
                    cdh,
                    rp,
                    user,
                    key_params,
                    other={"options": {
                        "uv": True
                    }},
                    expectedError=CtapError.ERR.SUCCESS,
                )
        if "up" in info.options:
            if info.options["up"]:
                self.testMC(
                    "Send MC request with up set to true, expect INVALID_OPTION",
                    cdh,
                    rp,
                    user,
                    key_params,
                    other={"options": {
                        "up": True
                    }},
                    expectedError=CtapError.ERR.INVALID_OPTION,
                )
Esempio n. 10
0
def register_complete():

    data = cbor.loads(request.get_data())[0]
    client_data = ClientData(data['clientDataJSON'])
    att_obj = AttestationObject(data['attestationObject'])


    val = session['challenge']
    auth_data = fidoserver.register_complete(val, client_data, att_obj)

    # Check if key has already been registered

    certificateid = att_obj.auth_data.credential_data.credential_id

    fileid = session['userobj']['userid'] + "_" + b2a_hex(certificateid).decode()

    pickle.dump(att_obj.auth_data.credential_data, open("./users/" + fileid + ".p", "wb"))

    return cbor.dumps({'status': 'OK'})
Esempio n. 11
0
    def _add_token_to_user(self, registration_data, state):
        data = registration_data + (b'=' * (len(registration_data) % 4)) 
        data = base64.urlsafe_b64decode(data)
        data = cbor.loads(data)[0]
        client_data = ClientData(data['clientDataJSON'])
        attestation = data['attestationObject']
        att_obj = AttestationObject(attestation)
        server = get_webauthn_server(self.app.config.get('FIDO2_RP_ID'))
        auth_data = server.register_complete(state, client_data, att_obj)
        cred_data = auth_data.credential_data
        cred_id = cred_data.credential_id

        credential = Webauthn(
            keyhandle = cred_id.hex(),
            credential_data = base64.urlsafe_b64encode(cred_data).decode('ascii'),
            app_id = self.app.config['FIDO2_RP_ID'],
            attest_obj = base64.b64encode(attestation).decode('ascii'),
            description = 'ctap1 token',
            application = 'test_security'
            )
        self.test_user.credentials.add(credential)
        self.app.central_userdb.save(self.test_user, check_sync=False)
        return credential
Esempio n. 12
0
def TestCborKeysSorted(cbor_obj):
    # Cbor canonical ordering of keys.
    # https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#ctap2-canonical-cbor-encoding-form

    if isinstance(cbor_obj, bytes):
        cbor_obj = cbor.loads(cbor_obj)[0]

    if isinstance(cbor_obj, dict):
        l = [x for x in cbor_obj]
    else:
        l = cbor_obj

    l_sorted = sorted(l[:], key=cmp_to_key(cmp_cbor_keys))

    for i in range(len(l)):

        if not isinstance(l[i], (str, int)):
            raise ValueError(f"Cbor map key {l[i]} must be int or str for CTAP2")

        if l[i] != l_sorted[i]:
            raise ValueError(f"Cbor map item {i}: {l[i]} is out of order")

    return l
Esempio n. 13
0
# data = b'this is some data Id like to sign'
# print(b2a_hex(data))
data2 = b'0021F5FC0B85CD22E60623BCD7D1CA48948909249B4776EB515154E57B66AE12010000002C' + b'7B89F12A9088B0F5EE0EF8F6718BCCC374249C31AEEBAEB79BD0450132CD536C'

signature = private_key.sign(data2, ec.ECDSA(hashes.SHA256()))
print(signature)
public_key.verify(signature, data2, ec.ECDSA(hashes.SHA256()))

cose_public_key = ES256.from_cryptography_key(public_key)
cose_public_key.verify(data2, signature)
#compre to test pubK
from fido2 import cbor
_ES256_KEY = a2b_hex(
    b'A5010203262001215820A5FD5CE1B1C458C530A54FA61B31BF6B04BE8B97AFDE54DD8CBB69275A8A1BE1225820FA3A3231DD9DEED9D1897BE5A6228C59501E4BCD12975D3DFF730F01278EA61C'
)  # noqa
key = CoseKey.parse(cbor.loads(_ES256_KEY)[0])
key.verify(
    a2b_hex(
        b'0021F5FC0B85CD22E60623BCD7D1CA48948909249B4776EB515154E57B66AE12010000002C'
        +  # noqa
        b'7B89F12A9088B0F5EE0EF8F6718BCCC374249C31AEEBAEB79BD0450132CD536C'
    ),  # noqa
    a2b_hex(
        b'304402202B3933FE954A2D29DE691901EB732535393D4859AAA80D58B08741598109516D0220236FBE6B52326C0A6B1CFDC6BF0A35BDA92A6C2E41E40C3A1643428D820941E0'
    )  # noqa
)
print()
print(
    b'a5010203262001215820643566c206dd00227005fa5de69320616ca268043a38f08bde2e9dc45a5cafaf225820171353b2932434703726aae579fa6542432861fe591e481ea22d63997e1a5290'
)
print(b2a_hex(cbor.dumps(cose_public_key)))
def process_u2fraw_request(raw_request):
    print('process_u2fraw_request - raw_request: ', raw_request)
    try:
        apducmd = decode_apdu_commandROMAN(raw_request)
        print(
            'apducmd = decode_apdu_command(raw_request) passed and apducmd.ins is '
            + str(apducmd.ins) + " with apducmd.cla " + str(apducmd.cla))
        if (apducmd.cla == U2F_REGISTER):
            print("ROMAN apducmd.CLA or .INS == FIDO2_REGISTER")
            print(b2a_hex(apducmd.data))
            cbor_data = cbor.loads(apducmd.data)
            print((cbor_data))
            #print("apducmd.data: " + cbor.loads(apducmd.data.decode()))
            #assert len(apducmd.data) == 64
            # application_parameter = apducmd.data[32:] # parse reg
            # challenge_parameter = apducmd.data[:32]
            #sw, resp = generate_registration_response_message(application_parameter, challenge_parameter) #create response
            sw, resp = generate_registration_response_message(cbor_data)
        elif (apducmd.ins == U2F_REGISTER):
            print("ROMAN_U2F apducmd.INS == U2F_REGISTER")
            print(b2a_hex(apducmd.data))
            # cbor_data = cbor.loads(apducmd.data)
            # print((cbor_data))
            #print("apducmd.data: " + cbor.loads(apducmd.data.decode()))
            #assert len(apducmd.data) == 64
            # application_parameter = apducmd.data[32:] # parse reg
            # challenge_parameter = apducmd.data[:32]
            #sw, resp = generate_registration_response_message(application_parameter, challenge_parameter) #create response
            sw, resp = generate_registration_u2f_response_message(apducmd.data)
        elif apducmd.cla == U2F_AUTHENTICATE:  # and apducmd.p1 == 0x07:
            print("ROMAN apducmd.INS == FIDO2_AUTHENTICATE")
            cbor_data = cbor.loads(apducmd.data)
            print(cbor_data)
            # assert len(apducmd.data) >= 65
            # assert len(apducmd.data[65:]) == apducmd.data[64]
            # print("*************666*************")
            #There are two Auth mode; for check OR full auth;
            # sw, resp = generate_key_handle_checking_response(apducmd.data[32:64], apducmd.data[65:])
            sw, resp = generate_authentication_response_message(cbor_data)
        elif apducmd.cla == U2F_VERSION:
            print("ROMAN apducmd.CLA == FIDO2_CANCEL")
            # assert len(apducmd.data) == 0
            sw, resp = generate_get_version_response_message()
            #sw, resp = SW_INS_NOT_SUPPORTED, b''
        elif apducmd.ins == U2F_VERSION:
            print("apducmd.ins == U2F_VERSION")
            assert len(apducmd.data) == 0
            sw, resp = generate_get_version_response_message()
        elif apducmd.ins == U2F_REGISTER:
            print("apducmd.ins == U2F_REGISTER")
            assert len(apducmd.data) == 64
            application_parameter = apducmd.data[32:]  # parse reg
            challenge_parameter = apducmd.data[:32]
            sw, resp = generate_registration_response_message(
                application_parameter,
                challenge_parameter)  #create response to reg
        elif apducmd.ins == U2F_AUTHENTICATE and apducmd.p1 == 0x07:
            print("apducmd.ins == U2F_AUTHENTICATE")
            assert len(apducmd.data) >= 65
            assert len(apducmd.data[65:]) == apducmd.data[64]
            sw, resp = generate_key_handle_checking_response(
                apducmd.data[32:64], apducmd.data[65:])
        elif apducmd.ins == U2F_AUTHENTICATE and apducmd.p1 == 0x03:
            print("apducmd.ins == U2F_AUTHENTICATE")
            assert len(apducmd.data) >= 65
            assert len(apducmd.data[65:]) == apducmd.data[64]
            sw, resp = generate_authentication_response_message(
                apducmd.data[32:64], apducmd.data[0:32], apducmd.data[65:])
        elif apducmd.ins == U2F_GETINFO:
            print("apducmd.ins == U2F_GETINFO")
            #assert len(apducmd.data) == 0
            sw, resp = generate_get_info_response_message()
        else:
            print("apducmd.ins == ELSE")
            sw, resp = SW_INS_NOT_SUPPORTED, b''

    except AssertionError:
        sw, resp = SW_WRONG_DATA, b''
    # ~ print('***Response from process_u2fraw_request + sw.to_bytes(2, \'big\')***: ', resp + sw.to_bytes(2, 'big') )
    return resp  #+ sw.to_bytes(2, 'big')
def hex2cbor(data):
    return cbor.loads(a2b_hex(data))
Esempio n. 16
0
 def public_key(self):
     return cose.CoseKey.parse(cbor.loads(bytes(self._public_key))[0])
Esempio n. 17
0
 def parse(self, stream, media_type=None, parser_context=None):
     return cbor.loads(stream.read())
Esempio n. 18
0
def _parse_cbor(data):
    resp, rest = cbor.loads(data)
    if rest:
        raise ValueError('Extraneous data')
    return resp