Esempio n. 1
0
    def webauthnGet(self, resp, raw_id, authData, signature, user_handle, client_data_hash):
        logging.debug('===assertion===')
        if authData:
            logging.debug('authData')
            if authData[:32].hex() == hashlib.sha256(rpid_host.encode()).hexdigest():
                logging.debug('\trpidHash ' + str(authData[:32].hex()))
                flags = int.from_bytes(authData[32:33], 'big')
                logging.debug(f'\tflags {bin(flags)}, {bin(flags & 0b0100_0000)}, {bin(flags & 0b1000_0000)}')
                logging.debug('\tsigCount ' + str(int.from_bytes(authData[33:37], 'big')))

                with open(f"./keys/{base64.urlsafe_b64encode(raw_id).decode()}.cbor") as f:
                    public_key = cbor.loads(base64.b64decode(f.readline().encode()))
                if public_key[3] == -7:
                    # TODO: 他のアルゴリズムへの対応
                    verification_data = authData + client_data_hash
                    x = int(codecs.encode(public_key[-2], 'hex'), 16)
                    y = int(codecs.encode(public_key[-3], 'hex'), 16)
                    credential_public_key = EllipticCurvePublicNumbers(x, y, SECP256R1()).public_key(backend=default_backend())
                    try:
                        credential_public_key.verify(signature, verification_data, ECDSA(SHA256()))
                        resp.media = {'status': 'ok'}
                        logging.info('[success] navigator.credentials.get')
                    except InvalidSignature as e:
                        logging.info(f'InvalidSignature {e}')
                        resp.media = {'status': 'ng'}
                else:
                    logging.info('not support type')
                    resp.media = {'status': 'ng'}
            else:
                logging.info('not match RPID')
                logging.debug(f'{authData[:32].hex()}, {hashlib.sha256(rpid_host.encode()).hexdigest()} [{authData[:32].hex() == hashlib.sha256(rpid_host.encode()).hexdigest()}]')
                resp.media = {'status': 'ng'}
        else:
            logging.info('not find authData')
            resp.media = {'status': 'ng'}
Esempio n. 2
0
def verify_signature(signature, data, point):
    public_key = EllipticCurvePublicNumbers(
        *point, curve=SECP256K1).public_key(DEFAULT_BACKEND)

    return public_key.verify(signature, data, ECDSA_SHA256)
Esempio n. 3
0
    def webauthnCreate(self, resp, raw_id, attestation, client_data_hash):
        logging.debug('===attestation===')
        authData = attestation.get('authData')
        if authData:
            logging.debug('authData')
            if authData[:32].hex() == hashlib.sha256(rpid_host.encode()).hexdigest():
                logging.debug('\trpidHash ' + str(authData[:32].hex()))
                flags = int.from_bytes(authData[32:33], 'big')
                logging.debug(f'\tflags {bin(flags)}, {bin(flags & 0b0100_0000)}, {bin(flags & 0b1000_0000)}')
                logging.debug('\tsigCount ' + str(int.from_bytes(authData[33:37], 'big')))
                if flags & 0b0100_0000:
                    logging.debug('attestedCredentialData')
                    logging.debug('\taaguid ' + str(int.from_bytes(authData[37:53], 'big')))
                    credentialIdLength = int.from_bytes(authData[53:55], 'big')
                    logging.debug('\tcredentialIdLength ' + str(credentialIdLength))
                    credentialId = authData[55:55+credentialIdLength]
                    logging.debug('\tcredentialId ' + str(base64.b64encode(credentialId)))
                    credentialPublicKey = cbor.loads(authData[55+credentialIdLength:])
                    logging.debug('\tcredentialPublicKey')
                    logging.debug('\t\tkty ' + str(credentialPublicKey[1]))
                    logging.debug('\t\talg ' + str(credentialPublicKey[3]))
                    logging.debug('\t\tcrv ' + str(credentialPublicKey[-1]))
                    logging.debug('\t\tx ' + str(credentialPublicKey[-2]))
                    logging.debug('\t\ty ' + str(credentialPublicKey[-3]))
                if flags & 0b1000_0000:
                    logging.debug('extensions ' + str(cbor.loads(bytes(authData[37:]))))
                    logging.info('not support flags')
                    resp.media = {'status': 'ng'}
                    return

                logging.debug('fmt ' + str(attestation.get('fmt')))
                attStmt = attestation.get('attStmt')
                logging.debug('attStmt')
                for k in attStmt.keys():
                    logging.debug(f'\t{k} {attStmt[k]}')

                if attestation.get('fmt') == 'packed' and 'x5c' not in attStmt:
                    # TODO: 他のパターンへの対応
                    # TODO: 他のアルゴリズムへの対応
                    signature = attStmt['sig']
                    verification_data = authData + client_data_hash
                    x = int(codecs.encode(credentialPublicKey[-2], 'hex'), 16)
                    y = int(codecs.encode(credentialPublicKey[-3], 'hex'), 16)
                    credential_public_key = EllipticCurvePublicNumbers(x, y, SECP256R1()).public_key(backend=default_backend())
                    try:
                        credential_public_key.verify(signature, verification_data, ECDSA(SHA256()))
                        resp.media = {'status': 'ok'}
                        logging.info('[success] navigator.credentials.create')
                        with open(f'keys/{base64.urlsafe_b64encode(raw_id).decode()}.cbor', 'w') as f:
                            f.write(f'{base64.b64encode(authData[55+credentialIdLength:]).decode()}')
                    except InvalidSignature as e:
                        logging.info(f'InvalidSignature {e}')
                        resp.media = {'status': 'ng'}
                else:
                    logging.info('not support type')
                    resp.media = {'status': 'ng'}
            else:
                logging.info('not match RPID')
                logging.debug(f'{authData[:32].hex()}, {hashlib.sha256(rpid_host.encode()).hexdigest()} [{authData[:32].hex() == hashlib.sha256(rpid_host.encode()).hexdigest()}]')
                resp.media = {'status': 'ng'}
        else:
            logging.info('not find authData')
            resp.media = {'status': 'ng'}