Esempio n. 1
0
 def parse(cls, der: bytes) -> Signature:
     return cls(secp256k1.ecdsa_signature_parse_der(der))
 def open(self, mode=None):
     """Opens a secure channel.
     Mode can be "es" - ephemeral-static
              or "ee" - ephemeral-ephemenral
     """
     # save mode for later - i.e. reestablish secure channel
     if mode is None:
         mode = self.mode
     else:
         self.mode = mode
     # check if we know pubkey already
     if self.card_pubkey is None:
         self.get_card_pubkey()
     # generate ephimerial key
     secret = get_random_bytes(32)
     host_prv = secret
     host_pub = secp256k1.ec_pubkey_create(secret)
     # ee mode - ask card to create ephimerial key and send it to us
     if mode == "ee":
         data = secp256k1.ec_pubkey_serialize(host_pub,
                                              secp256k1.EC_UNCOMPRESSED)
         # get ephimerial pubkey from the card
         res = self.applet.request(self.OPEN_EE + encode(data))
         s = BytesIO(res)
         data = s.read(65)
         pub = secp256k1.ec_pubkey_parse(data)
         secp256k1.ec_pubkey_tweak_mul(pub, secret)
         shared_secret = hashlib.sha256(
             secp256k1.ec_pubkey_serialize(pub)[1:33]).digest()
         shared_fingerprint = self.derive_keys(shared_secret)
         recv_hmac = s.read(MAC_SIZE)
         h = hmac.new(self.card_mac_key, digestmod="sha256")
         h.update(data)
         expected_hmac = h.digest()[:MAC_SIZE]
         if expected_hmac != recv_hmac:
             raise SecureChannelError("Wrong HMAC.")
         data += recv_hmac
         raw_sig = s.read()
         sig = secp256k1.ecdsa_signature_parse_der(raw_sig)
         # in case card doesn't follow low s rule (but it should)
         sig = secp256k1.ecdsa_signature_normalize(sig)
         if not secp256k1.ecdsa_verify(sig,
                                       hashlib.sha256(data).digest(),
                                       self.card_pubkey):
             raise SecureChannelError("Signature is invalid.")
     # se mode - use our ephimerial key with card's static key
     else:
         data = secp256k1.ec_pubkey_serialize(host_pub,
                                              secp256k1.EC_UNCOMPRESSED)
         # ugly copy
         pub = secp256k1.ec_pubkey_parse(
             secp256k1.ec_pubkey_serialize(self.card_pubkey))
         secp256k1.ec_pubkey_tweak_mul(pub, secret)
         shared_secret = secp256k1.ec_pubkey_serialize(pub)[1:33]
         res = self.applet.request(self.OPEN_SE + encode(data))
         s = BytesIO(res)
         nonce_card = s.read(32)
         recv_hmac = s.read(MAC_SIZE)
         secret_with_nonces = hashlib.sha256(shared_secret +
                                             nonce_card).digest()
         shared_fingerprint = self.derive_keys(secret_with_nonces)
         data = nonce_card
         h = hmac.new(self.card_mac_key, digestmod="sha256")
         h.update(data)
         expected_hmac = h.digest()[:MAC_SIZE]
         if expected_hmac != recv_hmac:
             raise SecureChannelError("Wrong HMAC.")
         data += recv_hmac
         sig = secp256k1.ecdsa_signature_parse_der(s.read())
         # in case card doesn't follow low s rule (but it should)
         sig = secp256k1.ecdsa_signature_normalize(sig)
         if not secp256k1.ecdsa_verify(sig,
                                       hashlib.sha256(data).digest(),
                                       self.card_pubkey):
             raise SecureChannelError("Signature is invalid")
     # reset iv
     self.iv = 0
     self.is_open = True
Esempio n. 3
0
 def read_from(cls, stream):
     der = stream.read(2)
     der += stream.read(der[1])
     return cls(secp256k1.ecdsa_signature_parse_der(der))
Esempio n. 4
0
 def parse(cls, der):
     return cls(secp256k1.ecdsa_signature_parse_der(der))