Rewrite ecdsa-nist256p-challenge using python-cryptography instead of python-ecdsa.

Which is more secure. Closes GH-1389.

It also fixes the protocol/format to use the same one as Atheme.
See also: 8a81224ba8
This commit is contained in:
Valentin Lorentz 2019-12-26 12:14:05 +01:00
parent 864b1759e3
commit ac07b440dc
2 changed files with 19 additions and 8 deletions

View File

@ -6,4 +6,4 @@ feedparser
sqlalchemy sqlalchemy
PySocks PySocks
mock mock
ecdsa cryptography

View File

@ -36,9 +36,16 @@ import textwrap
import collections import collections
try: try:
import ecdsa class crypto:
import cryptography
from cryptography.hazmat.primitives.serialization \
import load_pem_private_key
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric.ec import ECDSA
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
from cryptography.hazmat.primitives.hashes import SHA256
except ImportError: except ImportError:
ecdsa = None crypto = None
try: try:
import pyxmpp2_scram as scram import pyxmpp2_scram as scram
@ -1042,7 +1049,8 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
for mechanism in network_config.sasl.mechanisms(): for mechanism in network_config.sasl.mechanisms():
if mechanism == 'ecdsa-nist256p-challenge' and \ if mechanism == 'ecdsa-nist256p-challenge' and \
ecdsa and self.sasl_username and self.sasl_ecdsa_key: crypto and self.sasl_username and \
self.sasl_ecdsa_key:
self.sasl_next_mechanisms.append(mechanism) self.sasl_next_mechanisms.append(mechanism)
elif mechanism == 'external' and ( elif mechanism == 'external' and (
network_config.certfile() or network_config.certfile() or
@ -1171,12 +1179,15 @@ class Irc(IrcCommandDispatcher, log.Firewalled):
if string == b'': if string == b'':
self.sendSaslString(self.sasl_username.encode('utf-8')) self.sendSaslString(self.sasl_username.encode('utf-8'))
return return
try: try:
with open(self.sasl_ecdsa_key) as fd: with open(self.sasl_ecdsa_key, 'rb') as fd:
private_key = ecdsa.SigningKey.from_pem(fd.read()) private_key = crypto.load_pem_private_key(
authstring = private_key.sign(string) fd.read(),password=None, backend=crypto.default_backend())
authstring = private_key.sign(
string, crypto.ECDSA(crypto.Prehashed(crypto.SHA256())))
self.sendSaslString(authstring) self.sendSaslString(authstring)
except (ecdsa.BadDigestError, OSError, ValueError): except (OSError, ValueError):
self.sendMsg(ircmsgs.IrcMsg(command='AUTHENTICATE', self.sendMsg(ircmsgs.IrcMsg(command='AUTHENTICATE',
args=('*',))) args=('*',)))
self.tryNextSaslMechanism() self.tryNextSaslMechanism()