Esempio n. 1
0
    def register(self, facet, app_id, request):
        """
        RegisterRequest = {
            "version": "U2F_V2",
            "challenge": string, //b64 encoded challenge
            "appId": string, //app_id
        }
        """

        if not isinstance(request, RegisterRequest):
            request = RegisterRequest(request)

        if request.version != 'U2F_V2':
            raise ValueError('Unsupported U2F version: %s' % request.version)

        # Client data
        client_data = ClientData(
            typ=Type.REGISTER.value,
            challenge=request['challenge'],
            origin=facet
        )
        client_data = client_data.json.encode('utf-8')
        client_param = sha_256(client_data)

        # ECC key generation
        priv_key = ec.generate_private_key(CURVE, default_backend())
        pub_key = priv_key.public_key().public_bytes(
            Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
        pub_key = pub_key[-65:]

        # Store
        key_handle = os.urandom(64)
        app_param = sha_256(app_id.encode('idna'))
        self.keys[key_handle] = (priv_key, app_param)

        # Attestation signature
        cert_priv = load_pem_private_key(
            CERT_PRIV, password=None, backend=default_backend())
        cert = CERT
        data = b'\x00' + app_param + client_param + key_handle + pub_key
        signer = cert_priv.signer(ec.ECDSA(hashes.SHA256()))
        signer.update(data)
        signature = signer.finalize()

        raw_response = (b'\x05' + pub_key + six.int2byte(len(key_handle)) +
                        key_handle + cert + signature)

        return RegisterResponse(
            version=request.version,
            registrationData=websafe_encode(raw_response),
            clientData=websafe_encode(client_data),
        )
Esempio n. 2
0
    def register(self, facet, app_id, request):
        """
        RegisterRequest = {
            "version": "U2F_V2",
            "challenge": string, //b64 encoded challenge
            "appId": string, //app_id
        }
        """

        if not isinstance(request, RegisterRequest):
            request = RegisterRequest(request)

        if request.version != "U2F_V2":
            raise ValueError("Unsupported U2F version: %s" % request.version)

        # Client data
        client_data = ClientData(typ=Type.REGISTER.value,
                                 challenge=request['challenge'],
                                 origin=facet)
        client_data = client_data.json.encode('utf-8')
        client_param = sha_256(client_data)

        # ECC key generation
        priv_key = ec.generate_private_key(CURVE, default_backend())
        pub_key = priv_key.public_key().public_bytes(
            Encoding.DER, PublicFormat.SubjectPublicKeyInfo)
        pub_key = pub_key[-65:]

        # Store
        key_handle = os.urandom(64)
        app_param = sha_256(app_id.encode('idna'))
        self.keys[key_handle] = (priv_key, app_param)

        # Attestation signature
        cert_priv = load_pem_private_key(CERT_PRIV,
                                         password=None,
                                         backend=default_backend())
        cert = CERT
        data = b'\x00' + app_param + client_param + key_handle + pub_key
        signer = cert_priv.signer(ec.ECDSA(hashes.SHA256()))
        signer.update(data)
        signature = signer.finalize()

        raw_response = (b'\x05' + pub_key + six.int2byte(len(key_handle)) +
                        key_handle + cert + signature)

        return RegisterResponse(
            version=request.version,
            registrationData=websafe_encode(raw_response),
            clientData=websafe_encode(client_data),
        )
Esempio n. 3
0
 def verify_signature(self, pubkey):
     data = self.app_param + self.user_presence + self.counter + \
         self.chal_param
     digest = sha_256(data)
     pub_key = pub_key_from_der(pubkey)
     if not pub_key.verify_dsa_asn1(digest, self.signature) == 1:
         raise Exception('Challenge signature verification failed!')
Esempio n. 4
0
    def verify_csr_signature(self):
        data = (chr(0x00) + self.app_param + self.chal_param +
                self.key_handle + self.pub_key)
        digest = sha_256(data)
        pub_key = self.certificate.public_key()

        verify_ecdsa_signature(digest, pub_key, self.signature)
Esempio n. 5
0
    def verify_signature(self, pubkey):
        data = (self.app_param + self.user_presence + self.counter +
                self.chal_param)
        digest = sha_256(data)
        pub_key = pub_key_from_der(pubkey)

        verify_ecdsa_signature(digest, pub_key, self.signature)
Esempio n. 6
0
 def verify_signature(self, pubkey):
     data = self.app_param + self.user_presence + self.counter + \
         self.chal_param
     digest = sha_256(data)
     pub_key = pub_key_from_der(pubkey)
     if not pub_key.verify_dsa_asn1(digest, self.signature) == 1:
         raise Exception('Challenge signature verification failed!')
Esempio n. 7
0
    def create(cls, app_id, devices, challenge=None):
        # When the challenge is set we encode and hash it to be used in the signature
        if challenge is not None:
            encoded_challenge = challenge.encode('ascii')
            challenge = sha_256(encoded_challenge)

        if challenge is None:
            challenge = os.urandom(32)

        return cls(appId=app_id,
                   registeredKeys=devices,
                   challenge=websafe_encode(challenge))
    def getAssertion(self, request, facet="https://www.example.com",
                     touch=False):
        """
        signData = {
            'version': "U2F_V2",
            'challenge': websafe_encode(self.challenge),
            'appId': self.binding.app_id,
            'keyHandle': websafe_encode(self.binding.key_handle),
        }
        """

        if not isinstance(request, SignRequest):
            request = SignRequest(request)

        if request.version != "U2F_V2":
            raise ValueError("Unsupported U2F version: %s" % request.version)

        key_handle = websafe_decode(request.keyHandle)
        if key_handle not in self.keys:
            raise ValueError("Unknown key handle!")

        # Client data
        client_data = ClientData(
            typ="navigator.id.getAssertion",
            challenge=request['challenge'],
            origin=facet
        )
        client_data = client_data.json.encode('utf-8')
        client_param = sha_256(client_data)

        # Unwrap:
        priv_key, app_param = self.keys[key_handle]

        # Increment counter
        self.counter += 1

        # Create signature
        touch = int2byte(1 if touch else 0)
        counter = struct.pack('>I', self.counter)

        data = app_param + touch + counter + client_param
        signer = priv_key.signer(ec.ECDSA(hashes.SHA256()))
        signer.update(data)
        signature = signer.finalize()
        raw_response = touch + counter + signature

        return SignResponse(
            clientData=websafe_encode(client_data),
            signatureData=websafe_encode(raw_response),
            keyHandle=request.keyHandle
        )
Esempio n. 9
0
    def getAssertion(self, request, facet="https://www.example.com"):
        """
        signData = {
            'version': "U2F_V2",
            'challenge': websafe_encode(self.challenge),
            'appId': self.binding.app_id,
            'keyHandle': websafe_encode(self.binding.key_handle),
        }
        """

        if not isinstance(request, SignRequest):
            request = SignRequest(request)

        if request.version != "U2F_V2":
            raise ValueError("Unsupported U2F version: %s" % request.version)

        key_handle = websafe_decode(request.keyHandle)
        if key_handle not in self.keys:
            raise ValueError("Unknown key handle!")

        # Client data
        client_data = ClientData(
            typ="navigator.id.getAssertion",
            challenge=request['challenge'],
            origin=facet
        )
        client_data = client_data.json.encode('utf-8')
        client_param = sha_256(client_data)

        # Unwrap:
        priv_key, app_param = self.keys[key_handle]

        # Increment counter
        self.counter += 1

        # Create signature
        touch = int2byte(1)
        counter = struct.pack('>I', self.counter)

        data = app_param + touch + counter + client_param
        signer = priv_key.signer(ec.ECDSA(hashes.SHA256()))
        signer.update(data)
        signature = signer.finalize()
        raw_response = touch + counter + signature

        return SignResponse(
            clientData=websafe_encode(client_data),
            signatureData=websafe_encode(raw_response),
            keyHandle=request.keyHandle
        )
Esempio n. 10
0
 def retrieve(self, client_id, user_id, transaction_id):
     transaction_id = b2a_hex(sha_256(transaction_id))
     self._delete_expired()
     transaction = Transaction.query \
         .filter(Transaction.transaction_id == transaction_id).first()
     if transaction is None:
         raise ValueError('Invalid transaction')
     if transaction.user.name != user_id or \
             transaction.user.client_id != client_id:
         raise ValueError('Transaction not valid for user_id: %s'
                          % user_id)
     db.session.delete(transaction)
     db.session.commit()
     return transaction.data
Esempio n. 11
0
    def getAssertion(self, facet, app_id, challenge, key, touch_byte=1):
        """
        signData = {
            'version': "U2F_V2",
            'challenge': websafe_encode(self.challenge),
            'appId': self.binding.app_id,
            'keyHandle': websafe_encode(self.binding.key_handle),
        }
        """

        key = RegisteredKey.wrap(key)

        if key.version != 'U2F_V2':
            raise ValueError('Unsupported U2F version: %s' % key.version)

        if key.keyHandle not in self.keys:
            raise ValueError('Unknown key handle!')

        # Client data
        client_data = ClientData(
            typ=Type.SIGN.value,
            challenge=challenge,
            origin=facet
        )
        client_data = client_data.json.encode('utf-8')
        client_param = sha_256(client_data)

        # Unwrap:
        priv_key, app_param = self.keys[key.keyHandle]

        # Increment counter
        self.counter += 1

        # Create signature
        touch = six.int2byte(touch_byte)
        counter = struct.pack('>I', self.counter)

        data = app_param + touch + counter + client_param
        signer = priv_key.signer(ec.ECDSA(hashes.SHA256()))
        signer.update(data)
        signature = signer.finalize()
        raw_response = touch + counter + signature

        return SignResponse(
            clientData=websafe_encode(client_data),
            signatureData=websafe_encode(raw_response),
            keyHandle=key['keyHandle']
        )
Esempio n. 12
0
 def store(self, client_id, user_id, transaction_id, data):
     transaction_id = b2a_hex(sha_256(transaction_id))
     user = User.query \
         .filter(User.client_id == client_id) \
         .filter(User.name == user_id).first()
     if user is None:
         user = User(user_id)
         user.client_id = client_id
         db.session.add(user)
     else:
         self._delete_expired()
         # Delete oldest transactions until we have room for one more.
         for transaction in user.transactions \
                 .offset(self._max_transactions - 1).all():
             db.session.delete(transaction)
     user.transactions.append(Transaction(transaction_id, data))
     db.session.commit()
Esempio n. 13
0
    def getAssertion(self, facet, app_id, challenge, key, touch_byte=1):
        """
        signData = {
            'version': "U2F_V2",
            'challenge': websafe_encode(self.challenge),
            'appId': self.binding.app_id,
            'keyHandle': websafe_encode(self.binding.key_handle),
        }
        """

        key = RegisteredKey.wrap(key)

        if key.version != "U2F_V2":
            raise ValueError("Unsupported U2F version: %s" % key.version)

        if key.keyHandle not in self.keys:
            raise ValueError("Unknown key handle!")

        # Client data
        client_data = ClientData(typ=Type.SIGN.value,
                                 challenge=challenge,
                                 origin=facet)
        client_data = client_data.json.encode('utf-8')
        client_param = sha_256(client_data)

        # Unwrap:
        priv_key, app_param = self.keys[key.keyHandle]

        # Increment counter
        self.counter += 1

        # Create signature
        touch = six.int2byte(touch_byte)
        counter = struct.pack('>I', self.counter)

        data = app_param + touch + counter + client_param
        signer = priv_key.signer(ec.ECDSA(hashes.SHA256()))
        signer.update(data)
        signature = signer.finalize()
        raw_response = touch + counter + signature

        return SignResponse(clientData=websafe_encode(client_data),
                            signatureData=websafe_encode(raw_response),
                            keyHandle=key['keyHandle'])
Esempio n. 14
0
def _fix_cert(der):  # Some early certs have UNUSED BITS incorrectly set.
    if sha_256(der) in CERTS_TO_FIX:
        der = der[:-257] + b'\0' + der[-256:]
    return der
Esempio n. 15
0
 def appParam(self):
     return sha_256(self['appId'].encode('idna'))
Esempio n. 16
0
 def clientParam(self):
     return sha_256(websafe_decode(self['clientData']))
Esempio n. 17
0
 def challengeParameter(self):
     return sha_256(websafe_decode(self['clientData']))
Esempio n. 18
0
 def challengeParameter(self):
     return sha_256(websafe_decode(self['clientData']))
Esempio n. 19
0
 def clientParam(self):
     return sha_256(websafe_decode(self['clientData']))
Esempio n. 20
0
 def applicationParameter(self):
     return sha_256(self['appId'].encode('idna'))
Esempio n. 21
0
 def appParam(self):
     return sha_256(self['appId'].encode('idna'))
Esempio n. 22
0
def _fix_cert(der):  # Some early certs have UNUSED BITS incorrectly set.
    if sha_256(der) in CERTS_TO_FIX:
        der = der[:-257] + b'\0' + der[-256:]
    return der
Esempio n. 23
0
 def applicationParameter(self):
     return sha_256(self['appId'].encode('idna'))