Ejemplo n.º 1
0
    def export_recovery_seed(self, allow_algs):
        for alg in allow_algs:
            if alg == 0:
                if self._recovery_seed_pri_key is None:
                    self._initialize_recovery_seed()

                S = fastecdsa.keys.get_public_key(self._recovery_seed_pri_key, P256)
                S_enc = encode_pub(S)

                signed_data = struct.pack('>B16s65s', alg, self._aaguid, S_enc)
                sig = DEREncoder.encode_signature(
                    *ecdsa.sign(
                        signed_data,
                        self._attestation_key,
                        hashfunc=hashlib.sha256
                    )
                )
                payload = {
                    1: alg,
                    2: [],
                    3: self._aaguid,
                    4: sig,
                    -1: S_enc,
                }
                return cbor.encode(payload)

        raise UnknownKeyAgreementScheme(allow_algs)
Ejemplo n.º 2
0
def sign(signing_key: SigningKey, message_digest_bytes: bytes) -> bytes:
    r, s = ecdsa.sign(
        message_digest_bytes.hex(),
        signing_key,
        curve=curve.secp256k1,
        prehashed=True,
    )
    return DEREncoder.encode_signature(r, s)
Ejemplo n.º 3
0
    def signVote(self, privateKey):
        # Assina a cédula
        r, s = ecdsa.sign(self.voteHash,
                          privateKey,
                          curve=curve.secp256k1,
                          hashfunc=hl.sha256)

        # Transforma a assinatura para DER
        self.signature = DEREncoder.encode_signature(r, s)
Ejemplo n.º 4
0
    def authenticator_make_credential(self, args_cbor):
        args = cbor.decode(args_cbor)
        clientDataJSON_hash = args[0x01]
        rp_id = args[0x02]['id']
        extension_inputs = args[0x06]
        rp_id_hash = sha256(rp_id.encode('utf-8'))
        flags = 0b11000001  # ED, AT, UP
        sign_count = 0

        credential_id = secrets.token_bytes(32)
        (credential_private_key, credential_public_key) = fastecdsa.keys.gen_keypair(P256)

        self._credentials[credential_id] = credential_private_key

        attested_cred_data = pack_attested_credential_data(
            self._aaguid,
            credential_id,
            credential_public_key,
        )

        authData_without_extensions = struct.pack(
            f'>32sBL{len(attested_cred_data)}s',
            rp_id_hash,
            flags,
            sign_count,
            attested_cred_data,
        )

        extensions = {}

        if "recovery" in extension_inputs:
            extensions["recovery"] = self.process_recovery_extension(
                rp_id,
                authData_without_extensions,
                clientDataJSON_hash,
                extension_inputs["recovery"],
            )

        authData = authData_without_extensions + cbor.encode(extensions)
        attStmt = {
            0x01: 'packed',
            0x02: authData,
            0x03: {
                'alg': -7,
                'sig': DEREncoder.encode_signature(
                    *ecdsa.sign(
                        authData + clientDataJSON_hash,
                        credential_private_key,
                        hashfunc=hashlib.sha256
                    )
                ),
            },
        }
        return cbor.encode(attStmt)
Ejemplo n.º 5
0
    def test_encode_decode_all_curves(self):
        for curve in CURVES:
            d = randint(1, curve.q)
            Q = d * curve.G
            r, s = sign("sign me", d, curve=curve)

            encoded = DEREncoder.encode_signature(r, s)
            decoded_r, decoded_s = DEREncoder.decode_signature(encoded)

            self.assertEqual(decoded_r, r)
            self.assertEqual(decoded_s, s)
Ejemplo n.º 6
0
    def build_authorization_header(self):
        """Build authorization headers."""
        if len(self.required_authorization_headers) > 0:
            self.authorization_parameters['headers'] = '{}'.format(' '.join([
                header.lower()
                for header in self.required_authorization_headers
            ]))
        self.build_signing_string()
        signing_bytestring = self.signing_string.encode(self.encoding)
        if self.signing_algorithm == 'RSA':
            signer = RSA.import_key(self.private_key_string)
            if self.hashing_algorithm == 'SHA256':
                hash_obj = SHA256.new(signing_bytestring)
            elif self.hashing_algorithm == 'SHA512':
                hash_obj = SHA512.new(signing_bytestring)
            else:
                raise Exception("Invalid key type")
            signature = pkcs1_15.new(signer).sign(hash_obj)
        else:
            private_key, public_key = PEMEncoder.decode_private_key(
                self.private_key_string)
            if self.hashing_algorithm == 'SHA256':
                hash_function = hashlib.sha256
            elif self.hashing_algorithm == 'SHA512':
                hash_function = hashlib.sha512
            else:
                raise Exception("Invalid key type")

            if self.signing_algorithm.lower() == 'p256':
                r, s = ecdsa.sign(signing_bytestring,
                                  private_key,
                                  curve=curve.P256,
                                  hashfunc=hash_function)
            else:
                raise Exception("Invalid key type")
            signature = DEREncoder.encode_signature(r, s)
        base64_signature = base64.b64encode(signature).decode(self.encoding)
        self.authorization_parameters['signature'] = '{}'.format(
            base64_signature)
        authorization_rows = []
        for key, value in self.authorization_parameters.items():
            if isinstance(value, str):
                authorization_rows.append('{}="{}"'.format(key, value))
            elif isinstance(value, int) or isinstance(value, float):
                authorization_rows.append('{}={}'.format(key, value))
            elif isinstance(value, bool):
                if value is True:
                    authorization_rows.append('{}=true')
                else:
                    authorization_rows.append('{}=false')
        authorization_header = 'Signature {}'.format(
            ','.join(authorization_rows))
        self.headers['Authorization'] = authorization_header
Ejemplo n.º 7
0
def sign(signing_key: SigningKey, message_digest_bytes: bytes) -> bytes:
    r, s = ecdsa.sign(
        message_digest_bytes,
        signing_key,
        curve=curve.secp256k1,
        prehashed=True,
    )
    # Both (r, s) and (r, -s mod q = q - s) are valid, canonical signatures.
    # (r, s) is fully canonical only when s <= q - s.
    s_inverse = curve.secp256k1.q - s
    if s > s_inverse:
        s = s_inverse
    return DEREncoder.encode_signature(r, s)
Ejemplo n.º 8
0
def der_encode_sig(r, s):
    """
    Create DER encoded signature string with signature r and s value

    :param r: r value of signature
    :type r: int
    :param s: s value of signature
    :type s: int

    :return bytes:
    """
    if USE_FASTECDSA:
        return DEREncoder.encode_signature(r, s)
    else:
        ecdsa.der.sigencode_der(r, s)
Ejemplo n.º 9
0
def sign(message: bytes, private_key: PrivateKey) -> Signature:
    digest = hashes.sha512half(message)
    signing_key = int.from_bytes(private_key, byteorder='big')
    r, s = ecdsa.sign(
        digest.hex(),
        signing_key,
        curve=curve.secp256k1,
        prehashed=True,
    )
    # Both (r, s) and (r, -s mod G = G - s) are valid, canonical signatures.
    # (r, s) is fully canonical only when s <= G - s.
    s_inverse = GROUP_ORDER - s
    if s > s_inverse:
        s = s_inverse
    signature = DEREncoder.encode_signature(r, s)
    return t.cast(Signature, signature)
Ejemplo n.º 10
0
    def authenticator_get_assertion(self, args_cbor):
        args = cbor.decode(args_cbor)
        rp_id = args[0x01]
        clientDataJSON_hash = args[0x02]
        extension_inputs = args[0x04]
        rp_id_hash = sha256(rp_id.encode('utf-8'))
        flags = 0b10000001  # ED, UP
        sign_count = 0

        extensions = {}

        authData_without_extensions = struct.pack(
            f'>32sBL',
            rp_id_hash,
            flags,
            sign_count,
        )

        if "recovery" in extension_inputs:
            extensions["recovery"] = self.process_recovery_extension(
                rp_id,
                authData_without_extensions,
                clientDataJSON_hash,
                extension_inputs["recovery"]
            )

        authData = authData_without_extensions + cbor.encode(extensions)

        sig = None
        for cred_descriptor in args[0x03]:
            if cred_descriptor['id'] in self._credentials:
                sig = DEREncoder.encode_signature(
                    *ecdsa.sign(
                        authData + clientDataJSON_hash,
                        self._credentials[cred_descriptor['id']],
                        hashfunc=hashlib.sha256
                    )
                )
                break
        if sig is None:
            raise NoCredentialAvailable()

        return cbor.encode({
            0x01: cred_descriptor,
            0x02: authData,
            0x03: sig,
        })
Ejemplo n.º 11
0
def der_encode_sig(r, s):
    """
    Create DER encoded signature string with signature r and s value.

    :param r: r value of signature
    :type r: int
    :param s: s value of signature
    :type s: int

    :return bytes:
    """
    if USE_FASTECDSA:
        return DEREncoder.encode_signature(r, s)
    else:
        rb = ecdsa.der.encode_integer(r)
        sb = ecdsa.der.encode_integer(s)
        return ecdsa.der.encode_sequence(rb, sb)
Ejemplo n.º 12
0
    def _generate_recovery_signature(
            self,
            rp_id,
            authData_without_extensions,
            clientDataHash,
            allow_credentials,
    ):
        if self._recovery_seed_pri_key is None:
            return InvalidState()

        for cred in allow_credentials:
            cred_id = cred['id']
            alg = cred_id[0]

            if alg == 0:
                try:
                    cred_pri = self._derive_private_key(
                        self._recovery_seed_pri_key,
                        cred_id, rp_id)
                    sig = DEREncoder.encode_signature(
                        *ecdsa.sign(
                            authData_without_extensions + clientDataHash,
                            cred_pri,
                            hashfunc=hashlib.sha256
                        )
                    )
                except RpIdMismatch:
                    continue
            else:
                continue

            extension_output = {
                'action': 'recover',
                'credId': cred_id,
                'sig': sig,
                'state': self._state,
            }
            return extension_output

        raise NoCredentialAvailable()
Ejemplo n.º 13
0
    def test_encode_signature(self):
        self.assertEqual(
            DEREncoder.encode_signature(r=1, s=2),
            b"\x30"  # SEQUENCE
            b"\x06"  # Length of Sequence
            b"\x02"  # INTEGER
            b"\x01"  # Length of r
            b"\x01"  # r
            b"\x02"  # INTEGER
            b"\x01"  # Length of s
            b"\x02",  # s
        )

        # Check that we add a zero byte when the number's highest bit is set
        self.assertEqual(DEREncoder.encode_signature(r=128, s=128),
                         b"0\x08\x02\x02\x00\x80\x02\x02\x00\x80")

        # Check a value on a standard curve like secp256k1 works
        # see https://github.com/btccom/secp256k1-go/blob/master/secp256k1/sign_vectors.yaml
        secp256k1_vectors = [
            (
                0x31a84594060e103f5a63eb742bd46cf5f5900d8406e2726dedfc61c7cf43ebad,
                unhexlify(
                    "9e5755ec2f328cc8635a55415d0e9a09c2b6f2c9b0343c945fbbfe08247a4cbe"
                ),
                unhexlify(
                    "30440220132382ca59240c2e14ee7ff61d90fc63276325f4cbe8169fc53ade4a407c2fc802204d86fbe3bde69"
                    "75dd5a91fdc95ad6544dcdf0dab206f02224ce7e2b151bd82ab"),
            ),
            (
                0x7177f0d04c79fa0b8c91fe90c1cf1d44772d1fba6e5eb9b281a22cd3aafb51fe,
                unhexlify(
                    "2d46a712699bae19a634563d74d04cc2da497b841456da270dccb75ac2f7c4e7"
                ),
                unhexlify(
                    "3045022100d80cf7abc9ab601373780cee3733d2cb5ff69ba1452ec2d2a058adf9645c13be0220011d1213b7d"
                    "152f72fd8759b45276ba32d9c909602e5ec89550baf3aaa8ed950"),
            ),
            (
                0x989e500d6b1397f2c5dcdf43c58ac2f14df753eb6089654e07ff946b3f84f3d5,
                unhexlify(
                    "c94f4ec84be928017cbbb447d2ab5b5d4d69e5e5fd03da7eae4378a1b1c9c402"
                ),
                unhexlify(
                    "3045022100d0f5b740cbe3ee5b098d3c5afdefa61bb0797cb4e7b596afbd38174e1c653bb602200329e9f1a09"
                    "632de477664814791ac31544e04715db68f4b02657ba35863e711"),
            ),
            (
                0x39dfc615f2b718397f6903b0c46c47c5687e97d3d2a5e1f2b200f459f7b1219b,
                unhexlify(
                    "dfeb2092955572ce0695aa038f58df5499949e18f58785553c3e83343cd5eb93"
                ),
                unhexlify(
                    "30440220692c01edf8aeab271df3ed4e8d57a170f014f8f9d65031aac28b5e1840acfb5602205075f9d1fdbf5"
                    "079ee052e5f3572d518b3594ef49582899ec44d065f71a55192"),
            ),
        ]

        for private_key, digest, expected in secp256k1_vectors:
            r, s = sign(digest, private_key, curve=secp256k1, prehashed=True)
            encoded = DEREncoder.encode_signature(r, s)
            self.assertEqual(encoded, expected)
Ejemplo n.º 14
0
 def sign(self, message_bytes):
     r, s = ecdsa.sign(message_bytes,
                       self.private_key,
                       curve=self.public_key.curve)
     return DEREncoder.encode_signature(r, s).hex()
Ejemplo n.º 15
0
 def address(self):
     return base64.b64encode(DEREncoder.encode_signature(
         self.public_key.x, self.public_key.y))
Ejemplo n.º 16
0
 def _sign_transaction(self, transaction):
     r, s = ecdsa.sign(transaction.data, self.private_key, curve=Wallet._curve)
     signature = base64.b64encode(DEREncoder.encode_signature(r, s))
     transaction.add_signature(signature)