/usr/lib/python3/dist-packages/asyncssh/ed25519.py is in python3-asyncssh 1.3.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | # Copyright (c) 2015 by Ron Frederick <ronf@timeheart.net>.
# All rights reserved.
#
# This program and the accompanying materials are made available under
# the terms of the Eclipse Public License v1.0 which accompanies this
# distribution and is available at:
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Ron Frederick - initial implementation, API, and documentation
"""Ed25519 public key encryption handler"""
from .packet import String, SSHPacket
from .public_key import SSHKey, SSHCertificateV01, KeyExportError
from .public_key import register_public_key_alg, register_certificate_alg
# Short variable names are used here, matching names in the spec
# pylint: disable=invalid-name
class _Ed25519Key(SSHKey):
"""Handler for Ed25519 public key encryption"""
algorithm = b'ssh-ed25519'
def __init__(self, vk, sk):
self._vk = vk
self._sk = sk
def __eq__(self, other):
# This isn't protected access - both objects are _Ed25519Key instances
# pylint: disable=protected-access
return (isinstance(other, self.__class__) and
self._vk == other._vk and self._sk == other._sk)
def __hash__(self):
return hash(self._vk)
@classmethod
def make_private(cls, vk, sk):
"""Construct an Ed25519 private key"""
return cls(vk, sk)
@classmethod
def make_public(cls, vk):
"""Construct an Ed25519 public key"""
return cls(vk, None)
@classmethod
def decode_ssh_private(cls, packet):
"""Decode an SSH format Ed25519 private key"""
vk = packet.get_string()
sk = packet.get_string()
return vk, sk
@classmethod
def decode_ssh_public(cls, packet):
"""Decode an SSH format Ed25519 public key"""
vk = packet.get_string()
return (vk,)
def encode_ssh_private(self):
"""Encode an SSH format Ed25519 private key"""
if self._sk is None:
raise KeyExportError('Key is not private')
return b''.join((String(self._vk), String(self._sk)))
def encode_ssh_public(self):
"""Encode an SSH format Ed25519 public key"""
return String(self._vk)
def sign(self, data):
"""Return a signature of the specified data using this key"""
if self._sk is None:
raise ValueError('Private key needed for signing')
sig = libnacl.crypto_sign(data, self._sk)
return b''.join((String(self.algorithm), String(sig[:-len(data)])))
def verify(self, data, sig):
"""Verify a signature of the specified data using this key"""
try:
packet = SSHPacket(sig)
if packet.get_string() != self.algorithm:
return False
sig = packet.get_string()
packet.check_end()
return libnacl.crypto_sign_open(sig + data, self._vk) == data
except ValueError:
return False
try:
import libnacl
except (ImportError, OSError): # pragma: no cover
pass
else:
register_public_key_alg(b'ssh-ed25519', _Ed25519Key)
register_certificate_alg(b'ssh-ed25519-cert-v01@openssh.com',
_Ed25519Key, SSHCertificateV01)
|