79 lines
2.7 KiB
Python
79 lines
2.7 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
import hashlib
|
|
|
|
from libcloud.utils.py3 import hexadigits
|
|
from libcloud.utils.py3 import b
|
|
from libcloud.utils.py3 import base64_decode_string
|
|
|
|
__all__ = [
|
|
'get_pubkey_openssh_fingerprint',
|
|
'get_pubkey_ssh2_fingerprint',
|
|
'get_pubkey_comment'
|
|
]
|
|
|
|
try:
|
|
from cryptography.hazmat.backends import default_backend
|
|
from cryptography.hazmat.primitives import serialization
|
|
cryptography_available = True
|
|
except ImportError:
|
|
cryptography_available = False
|
|
|
|
|
|
def _to_md5_fingerprint(data):
|
|
hashed = hashlib.md5(data).digest()
|
|
return ":".join(hexadigits(hashed))
|
|
|
|
|
|
def get_pubkey_openssh_fingerprint(pubkey):
|
|
# We import and export the key to make sure it is in OpenSSH format
|
|
if not cryptography_available:
|
|
raise RuntimeError('cryptography is not available')
|
|
public_key = serialization.load_ssh_public_key(
|
|
b(pubkey),
|
|
backend=default_backend()
|
|
)
|
|
pub_openssh = public_key.public_bytes(
|
|
encoding=serialization.Encoding.OpenSSH,
|
|
format=serialization.PublicFormat.OpenSSH,
|
|
)[7:] # strip ssh-rsa prefix
|
|
return _to_md5_fingerprint(base64_decode_string(pub_openssh))
|
|
|
|
|
|
def get_pubkey_ssh2_fingerprint(pubkey):
|
|
# This is the format that EC2 shows for public key fingerprints in its
|
|
# KeyPair mgmt API
|
|
if not cryptography_available:
|
|
raise RuntimeError('cryptography is not available')
|
|
public_key = serialization.load_ssh_public_key(
|
|
b(pubkey),
|
|
backend=default_backend()
|
|
)
|
|
pub_der = public_key.public_bytes(
|
|
encoding=serialization.Encoding.DER,
|
|
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
|
)
|
|
return _to_md5_fingerprint(pub_der)
|
|
|
|
|
|
def get_pubkey_comment(pubkey, default=None):
|
|
if pubkey.startswith("ssh-"):
|
|
# This is probably an OpenSSH key
|
|
return pubkey.strip().split(' ', 3)[2]
|
|
if default:
|
|
return default
|
|
raise ValueError('Public key is not in a supported format')
|