You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: crypto.rs
    path of file: ./repos/kanidm/server/core/src
    
    the code of the file until where you have to start completion: //! This module contains cryptographic setup code, a long with what policy
//! and ciphers we accept.

use openssl::ec::{EcGroup, EcKey};
use openssl::error::ErrorStack;
use openssl::nid::Nid;
use openssl::pkey::{PKeyRef, Private};
use openssl::rsa::Rsa;
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use openssl::x509::{
    extension::{
        AuthorityKeyIdentifier, BasicConstraints, ExtendedKeyUsage, KeyUsage,
        SubjectAlternativeName, SubjectKeyIdentifier,
    },
    X509NameBuilder, X509ReqBuilder, X509,
};
use openssl::{asn1, bn, hash, pkey};
use sketching::*;

use crate::config::Configuration;

use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;

const CA_VALID_DAYS: u32 = 30;
const CERT_VALID_DAYS: u32 = 5;

// Basing minimums off https://www.keylength.com setting "year" to 2030 - tested as at 2023-09-25
//
// |Method           |Date     |Symmetric| FM      |DL Key| DL Group|Elliptic Curve|Hash|
// |   ---           |   ---   |   ---   |   ---   | ---  |   ---   |  ---         | ---|
// |Lenstra / Verheul|2030     |  93     |2493^2016|165   | 2493    |  176         | 186|
// |Lenstra Updated  |2030     |  88     |1698^2063|176   | 1698    |  176         | 176|
// |ECRYPT           |2029-2068|  256    |15360    |512   | 15360   |  512         | 512|
// |NIST             |2019-2030|  112    |2048     |224   | 2048    |  224         | 224|
// |ANSSI            |> 2030   |  128    |3072     |200   | 3072    |  256         | 256|
// |NSA              |-        |  2
    
pub fn setup_tls(config: &Configuration) -> Result<Option<SslAcceptor>, ()> {
    match &config.tls_config {
        Some(tls_config) => {
            // Signing algorithm minimums are enforced by the SSLAcceptor - it won't start up with a sha1-signed cert.
            // https://wiki.mozilla.org/Security/Server_Side_TLS
            let mut ssl_builder =
                SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).map_err(|openssl_err| {
                    error!("Failed to start TLS builder");
                    error!(?openssl_err);
                })?;

            ssl_builder
                .set_certificate_chain_file(&tls_config.chain)
                .map_err(|openssl_err| {
                    error!("Failed to access certificate chain file");
                    error!(?openssl_err);
                    let diag = kanidm_lib_file_permissions::diagnose_path(&tls_config.chain);
                    info!(%diag);
                })?;

            ssl_builder
                .set_private_key_file(&tls_config.key, SslFiletype::PEM)
                .map_err(|openssl_err| {
                    error!("Failed to access private key file");
                    error!(?openssl_err);
                    let diag = kanidm_lib_file_permissions::diagnose_path(&tls_config.chain);
                    info!(%diag);
                })?;

            ssl_builder.check_private_key().map_err(|openssl_err| {
                error!("Failed to validate private key");
                error!(?openssl_err);
            })?;

            let acceptor = ssl_builder.build();

            // let's enforce some TLS minimums!
            let privkey = acceptor.context().private_key().ok_or_else(|| {
                error!("Failed to access acceptor private key");
            })?;

            check_privkey_minimums(privkey).map_err(|err| {
                error!("{}", err);
            })?;

            Ok(Some(acceptor))
        }
        None => Ok(None),
    }
}