static gnutls_x509_privkey_t infinoted_startup_load_key(InfinotedLog* log, gboolean create_key, const gchar* key_file, GError** error) { gnutls_x509_privkey_t key; if(create_key == TRUE) { if(infinoted_util_create_dirname(key_file, error) == FALSE) return NULL; /* TODO: Open the key file beforehand */ infinoted_log_info(log, _("Generating 4096 bit RSA private key...")); key = inf_cert_util_create_private_key(GNUTLS_PK_RSA, 4096, error); if(key == NULL) return NULL; if(inf_cert_util_write_private_key(key, key_file, error) == FALSE) { gnutls_x509_privkey_deinit(key); return NULL; } } else { key = inf_cert_util_read_private_key(key_file, error); } return key; }
void Gobby::CertificateManager::load_key() { const std::string& filename = m_preferences.security.key_file; if(!filename.empty()) { GError* error = NULL; gnutls_x509_privkey_t key = inf_cert_util_read_private_key( filename.c_str(), &error); set_private_key(key, error); if(error != NULL) g_error_free(error); } else { set_private_key(NULL, NULL); } }
static InfdXmppServer* inf_test_certificate_setup_server(InfIo* io, const char* key_file, const char* cert_file, GError** error) { InfdTcpServer* tcp; InfdXmppServer* xmpp; gnutls_x509_privkey_t key; GPtrArray* certs; InfCertificateCredentials* creds; guint i; int res; key = inf_cert_util_read_private_key(key_file, error); if(!key) return NULL; certs = inf_cert_util_read_certificate(cert_file, NULL, error); if(!certs) { gnutls_x509_privkey_deinit(key); return NULL; } creds = inf_certificate_credentials_new(); res = gnutls_certificate_set_x509_key( inf_certificate_credentials_get(creds), (gnutls_x509_crt_t*)certs->pdata, certs->len, key ); gnutls_x509_privkey_deinit(key); for(i = 0; i < certs->len; ++i) gnutls_x509_crt_deinit(certs->pdata[i]); g_ptr_array_free(certs, TRUE); if(res != 0) { inf_certificate_credentials_unref(creds); inf_gnutls_set_error(error, res); return NULL; } tcp = g_object_new( INFD_TYPE_TCP_SERVER, "io", io, "local-port", 6524, NULL ); if(infd_tcp_server_open(tcp, error) == FALSE) { inf_certificate_credentials_unref(creds); return NULL; } xmpp = infd_xmpp_server_new( tcp, INF_XMPP_CONNECTION_SECURITY_ONLY_TLS, creds, NULL, NULL ); /* Keep client connections alive */ g_signal_connect( G_OBJECT(xmpp), "new-connection", G_CALLBACK(inf_test_certificate_validate_new_connection_cb), NULL ); inf_certificate_credentials_unref(creds); return xmpp; }
static gboolean infinoted_plugin_certificate_auth_initialize(InfinotedPluginManager* manager, gpointer plugin_info, GError** error) { InfinotedPluginCertificateAuth* plugin; InfCertificateCredentials* creds; GPtrArray* read_certs; int res; guint i; gnutls_x509_crt_t* sign_certs; InfCertificateChain* sign_chain; gnutls_x509_privkey_t super_key; InfCertUtilDescription desc; gnutls_x509_crt_t super_cert; InfAclAccountId super_id; gnutls_x509_crt_t chain[2]; gboolean written; InfdDirectory* directory; InfBrowserIter iter; InfAclSheetSet sheet_set; InfAclSheet sheet; InfRequest* request; plugin = (InfinotedPluginCertificateAuth*)plugin_info; plugin->manager = manager; creds = infinoted_plugin_manager_get_credentials(manager); if(creds == NULL) { g_set_error( error, infinoted_plugin_certificate_auth_error_quark(), INFINOTED_PLUGIN_CERTIFICATE_AUTH_ERROR_NO_CREDENTIALS, "%s", _("The certificate-auth plugin can only be used when TLS is enabled " "and a server certificate has been set.") ); return FALSE; } read_certs = inf_cert_util_read_certificate(plugin->ca_list_file, NULL, error); if(read_certs == NULL) return FALSE; if(read_certs->len == 0) { g_set_error( error, infinoted_plugin_certificate_auth_error_quark(), INFINOTED_PLUGIN_CERTIFICATE_AUTH_ERROR_NO_CAS, _("File \"%s\" does not contain any CA certificates"), plugin->ca_list_file ); g_ptr_array_free(read_certs, TRUE); return FALSE; } plugin->n_cas = read_certs->len; plugin->cas = (gnutls_x509_crt_t*)g_ptr_array_free(read_certs, FALSE); res = gnutls_certificate_set_x509_trust( inf_certificate_credentials_get(creds), plugin->cas, plugin->n_cas ); if(res < 0) { inf_gnutls_set_error(error, res); return FALSE; } if(plugin->ca_key_file != NULL) { plugin->ca_key = inf_cert_util_read_private_key(plugin->ca_key_file, error); if(plugin->ca_key == NULL) return FALSE; /* Walk through certificates and find the certificate that the key * belongs to. */ for(i = 0; i < plugin->n_cas; ++i) if(inf_cert_util_check_certificate_key(plugin->cas[i], plugin->ca_key)) break; if(i == plugin->n_cas) { gnutls_x509_privkey_deinit(plugin->ca_key); plugin->ca_key = NULL; g_set_error( error, infinoted_plugin_certificate_auth_error_quark(), INFINOTED_PLUGIN_CERTIFICATE_AUTH_ERROR_NO_CA_FOR_KEY, "%s", _("The given CA key does not match with any of the CA certificates") ); return FALSE; } plugin->ca_key_index = i; /* Set the signing certificate of the directory, so that it can handle * account creation requests. Note that this takes ownership of the * certificate, so we take special care in the cleanup code in * infinoted_plugin_certificate_auth_deinitialize(). */ sign_certs = g_malloc(sizeof(gnutls_x509_crt_t)); sign_certs[0] = plugin->cas[plugin->ca_key_index]; sign_chain = inf_certificate_chain_new(sign_certs, 1); infd_directory_set_certificate( infinoted_plugin_manager_get_directory(plugin->manager), plugin->ca_key, sign_chain ); inf_certificate_chain_unref(sign_chain); } if(plugin->super_user != NULL) { if(plugin->ca_key == NULL) { g_set_error( error, infinoted_plugin_certificate_auth_error_quark(), INFINOTED_PLUGIN_CERTIFICATE_AUTH_ERROR_NO_CA_KEY, "%s", _("Cannot generate a superuser certificate without CA key") ); return FALSE; } /* Create a private key and certificate for the super user. */ infinoted_log_info( infinoted_plugin_manager_get_log(plugin->manager), _("Creating 4096-bit RSA private key for the super user account...") ); super_key = inf_cert_util_create_private_key(GNUTLS_PK_RSA, 4096, error); if(super_key == NULL) return FALSE; desc.validity = 12 * 3600; /* 12 hours */ desc.dn_common_name = "Super User"; desc.san_dnsname = NULL; super_cert = inf_cert_util_create_signed_certificate( super_key, &desc, plugin->cas[plugin->ca_key_index], plugin->ca_key, error ); if(super_cert == NULL) { gnutls_x509_privkey_deinit(super_key); return FALSE; } super_id = infd_directory_create_acl_account( infinoted_plugin_manager_get_directory(plugin->manager), _("Super User"), TRUE, /* transient */ &super_cert, 1, error ); if(super_id == 0) { gnutls_x509_crt_deinit(super_cert); gnutls_x509_privkey_deinit(super_key); return FALSE; } plugin->super_id = super_id; chain[0] = super_cert; chain[1] = plugin->cas[plugin->ca_key_index]; written = inf_cert_util_write_certificate_with_key( super_key, chain, 2, plugin->super_user, error ); gnutls_x509_crt_deinit(super_cert); gnutls_x509_privkey_deinit(super_key); if(written == FALSE) return FALSE; inf_browser_get_root( INF_BROWSER(infinoted_plugin_manager_get_directory(plugin->manager)), &iter ); directory = infinoted_plugin_manager_get_directory(plugin->manager); sheet.account = super_id; sheet.mask = INF_ACL_MASK_ALL; infd_directory_get_support_mask(directory, &sheet.perms); sheet_set.n_sheets = 1; sheet_set.own_sheets = NULL; sheet_set.sheets = &sheet; request = inf_browser_set_acl( INF_BROWSER(directory), &iter, &sheet_set, infinoted_plugin_certificate_auth_set_acl_cb, plugin ); if(request != NULL) { plugin->set_acl_request = request; g_object_ref(plugin->set_acl_request); } } return TRUE; }