python-common/cryptotools: reimplement on top of cryptography
the last change dropped X509Req, but InternalCryptoCaller still uses
pyOpenSSL, which keeps deprecating and removing its OpenSSL.crypto and
OpenSSL.SSL APIs. pyOpenSSL's own README [1] says:
If you are using pyOpenSSL for anything other than making a TLS
connection you should move to cryptography and drop your pyOpenSSL
dependency.
none of this module makes a TLS connection, and we already depend on
cryptography and use it in cephadm/ssl_cert_utils.py.
so reimplement the caller with cryptography:
- create_private_key(): rsa.generate_private_key() dumped as PKCS8 PEM,
the same format pyOpenSSL produced.
- create_self_signed_cert(): x509.CertificateBuilder, with the dname
fields mapped to their NameOIDs.
- _load_cert() and get_cert_issuer_info(): load_pem_x509_certificate()
and cert.issuer.
- certificate_days_to_expire(): cert.not_valid_after.
- verify_tls(): compare the cert's and the key's public keys instead of
loading them into an SSL.Context.
password_hash() and verify_password() already used bcrypt, so they are
left as is. the output formats and error behavior are unchanged, hence
the existing tls tests pass without changes.