/* Copyright (C) 2003 Frédéric Giudicelli (contact_nos@yahoo.com). All rights reserved. This product includes cryptographic software written by Eric Young (eay@cryptsoft.com) This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Entity_PKI.cpp: implementation of the Entity_PKI class. // ////////////////////////////////////////////////////////////////////// #include "Entity_CA.h" #include "Entity_RA.h" #include "Entity_KEYSTORE.h" #include "Entity_BACKUP.h" #include "Entity_PUBLICATION.h" #include "Entity_REPOSITORY.h" #include #include #include #include "Entity_PKI.h" #include "svintl.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// Entity_PKI::Entity_PKI(ENTITY_CONSTRUCTOR_PARAMETERS):Entity(ENTITY_CONSTRUCTOR_PARAM_PASSTHRU, &pki_conf, NULL) { RootCa = NULL; UsersCa = NULL; EntitiesCa = NULL; OcspCa = NULL; try { RootCa = new CA_Handler(EntityName, INTERNAL_CA_TYPE_ROOT); } catch(ExceptionNewPKI e) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); throw ExceptionNewPKI(); } try { UsersCa = new CA_Handler(EntityName, INTERNAL_CA_TYPE_USER); } catch(ExceptionNewPKI e) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); throw ExceptionNewPKI(); } try { EntitiesCa = new CA_Handler(EntityName, INTERNAL_CA_TYPE_ENTITY); } catch(ExceptionNewPKI e) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); throw ExceptionNewPKI(); } try { OcspCa = new CA_Handler(EntityName, INTERNAL_CA_TYPE_OCSP); } catch(ExceptionNewPKI e) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); throw ExceptionNewPKI(); } if(!RootCa || !UsersCa || !EntitiesCa || !OcspCa) { NEWPKIerr(PKI_ERROR_TXT, ERROR_MALLOC); throw ExceptionNewPKI(); } RootCa->set_ENGINE(m_Engine); UsersCa->set_ENGINE(m_Engine); EntitiesCa->set_ENGINE(m_Engine); OcspCa->set_ENGINE(m_Engine); } Entity_PKI::~Entity_PKI() { m_Jobs.StopAll(); Free_PkiConf(); if(RootCa) delete RootCa; if(UsersCa) delete UsersCa; if(EntitiesCa) delete EntitiesCa; if(OcspCa) delete OcspCa; } bool Entity_PKI::Create(const EntityCreationDatas & Params, AdminResponseBody & response) { if(!Params) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(Params.get_type() != ENTITY_TYPE_PKI) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } mString Cn; EntityLinks link; unsigned long serial; if(!Params.get_pkiCreate()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!response.get_creEntity().set_type(ENTITY_TYPE_PKI)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } //We create the database if(!Common_Create(Params.get_pkiCreate().get_entityKey(), NULL)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!CA_Handler::CreateTables(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!RootCa->SetDbConn(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!UsersCa->SetDbConn(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!EntitiesCa->SetDbConn(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!OcspCa->SetDbConn(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } //Initialize it link struct link.get_src().set_name(m_EntityName); link.get_src().set_type(ENTITY_TYPE_PKI); pki_conf.get_links().push_back(link); //Initialize the pki conf if(!pki_conf.get_conf().get_body().set_type(ENTITY_TYPE_PKI)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } pki_conf.get_conf().set_name(m_EntityName); if(!pki_conf.get_conf().get_body().get_pkiConf().set_type(PKI_CONF_VERSION)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } pki_conf.get_conf().get_body().get_pkiConf().PKI_CONF_PTR.set_offline(0); pki_conf.get_conf().set_version(0); // We now create the internal CAs and // the PKI admin certificate //Create ROOT CA Cn = m_EntityName; Cn += " - Internal ROOT CA"; if(!InternalCA_Create(INTERNAL_CA_TYPE_ROOT, Params.get_pkiCreate().get_rootCa(), Params.get_pkiCreate().get_dn(), Cn.c_str(), Params.get_pkiCreate().get_validity())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } //We create initial CRL if(!InternalCA_Revoke(INTERNAL_CA_TYPE_ROOT, 0)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!pki_conf.get_cas().set_rootca(*RootCa->get_CaCert())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); Destroy(); return false; } //Create USERS CA Cn = m_EntityName; Cn += " - Internal USERS CA"; if(!InternalCA_Create(INTERNAL_CA_TYPE_USER, Params.get_pkiCreate().get_usersCa(), Params.get_pkiCreate().get_dn(), Cn.c_str(), Params.get_pkiCreate().get_validity())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } //We create initial CRL if(!InternalCA_Revoke(INTERNAL_CA_TYPE_USER, 0)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!pki_conf.get_cas().set_usersca(*UsersCa->get_CaCert())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); Destroy(); return false; } //Create ENTITIES CA Cn = m_EntityName; Cn += " - Internal ENTITIES CA"; if(!InternalCA_Create(INTERNAL_CA_TYPE_ENTITY, Params.get_pkiCreate().get_entitiesCa(), Params.get_pkiCreate().get_dn(), Cn.c_str(), Params.get_pkiCreate().get_validity())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } //We create initial CRL if(!InternalCA_Revoke(INTERNAL_CA_TYPE_ENTITY, 0)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!pki_conf.get_cas().set_entitiesca(*EntitiesCa->get_CaCert())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); Destroy(); return false; } //Create OCSP CA Cn = m_EntityName; Cn += " - Internal OCSP CA"; if(!InternalCA_Create(INTERNAL_CA_TYPE_OCSP, Params.get_pkiCreate().get_ocspCa(), Params.get_pkiCreate().get_dn(), Cn.c_str(), Params.get_pkiCreate().get_validity())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } //We create initial CRL if(!InternalCA_Revoke(INTERNAL_CA_TYPE_OCSP, 0)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!pki_conf.get_cas().set_ocspca(*OcspCa->get_CaCert())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); Destroy(); return false; } //We now create the PKI Entity certificate //Load entity's private key // m_EntityKey has been loaded/created by Common_Create if(!InternalCA_SignForceDn(INTERNAL_CA_TYPE_ENTITY, m_EntityKey.GetPublicKey(), m_EntityName.c_str(), Params.get_pkiCreate().get_email().c_str(), m_EntityCert)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!pki_conf.get_cas().set_pkicert(m_EntityCert)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); Destroy(); return false; } // We init the entity if(!Common_Init(m_EntityCert, EntitySignatureResp::EmptyInstance)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } //We now create the PKI administrator certificate Cn = m_EntityName; Cn += " - PKI Administrator"; ((EntityCreationDatas &)Params).get_pkiCreate().get_admincreate().set_cn(Cn); ((EntityCreationDatas &)Params).get_pkiCreate().get_admincreate().set_pkiadmin(1); if(!CreatePkiUser(Params.get_pkiCreate().get_admincreate(), response.get_creEntity().get_pkiCreate(), serial)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } Free_PkiConf(); return true; } bool Entity_PKI::Init(const EntitySignatureResp & init_datas) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } bool Entity_PKI::Load() { if(!Common_Load()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!IsFullyInit()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); return false; } //We load the CAs if(!RootCa->SetDbConn(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!UsersCa->SetDbConn(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!EntitiesCa->SetDbConn(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!OcspCa->SetDbConn(m_DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!RootCa->Load()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!UsersCa->Load()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!EntitiesCa->Load()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!OcspCa->Load()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //Start the conf synch if(!m_Jobs.StartConfPush(false)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } // Synch the conf ConfAccessLock.LockRead(); if(pki_conf.get_cryptConfs().get_sig()->digest && pki_conf.get_cryptConfs().get_sig()->algor && pki_conf.get_cryptConfs().get_sig()->algor->algorithm) { if(!m_Jobs.SetPkiConf(pki_conf.get_cryptConfs())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockRead(); return false; } } ConfAccessLock.UnlockRead(); return true; } bool Entity_PKI::Upgrade(const char * Version) { return true; } bool Entity_PKI::InternalCA_Create(INTERNAL_CA_TYPE Type, const GenPrivateKey & KeyGen, const X509_NAME * Dn, const char * Cn, int days) { PKI_CERT ResultCert; PKI_CSR csr; PKI_RSA privKey; HashTable_Dn dn; HashTable_String Exts; Exts.AllowDuplicateNames(); CA_Handler * currCa; InternalCaKey caKey; if(!KeyGen || !Dn || !Cn || !days) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!dn.From_X509_NAME(Dn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!dn.Add("commonName", Cn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); return false; } if(!CA_Handler::GEN_PRIVATE_KEY_load(KeyGen, privKey, caKey, m_Engine)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!csr.GenerateCSR(dn, privKey)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(Type != INTERNAL_CA_TYPE_ROOT) { //This is a sub CA not ROOT CA if(!InternalCA_Sign(INTERNAL_CA_TYPE_ROOT, csr, ResultCert, days, true)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } } else { Exts.Add("basicConstraints", "critical, CA:TRUE"); Exts.Add("nsComment", "NewPKI Generated CA Certificate"); Exts.Add("subjectKeyIdentifier", "hash"); Exts.Add("authorityKeyIdentifier", "keyid:always"); Exts.Add("nsCertType", "sslCA, emailCA, objCA"); Exts.Add("keyUsage", "keyCertSign, cRLSign, digitalSignature, nonRepudiation, keyEncipherment"); if(!ResultCert.CreateSelfSigned(csr, &Exts, days, 1)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } } if(!ResultCert.SetPrivateKey(privKey)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //We have the key and the cert we can create the corresponding //database entry currCa = GetInternalCA(Type); if(!currCa) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //We physicaly "create" it if(!currCa->Create(ResultCert, caKey)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_PKI::InternalCA_SignForceDn(INTERNAL_CA_TYPE Type, const X509_PUBKEY * pubKey, const mString & cn, const mString & email, PKI_CERT & ResultCert) { time_t currTime; CA_Handler * currCa; PKI_CSR csrK; PKI_CERT * caCert; int days; currCa = GetInternalCA(Type); if(!currCa) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } caCert = currCa->get_CaCert(); if(!caCert) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } const PKI_RSA & caKey = caCert->GetPrivateKey(); if(!caKey) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //We format the CSR DN with the parent DN if(!Format_CSR(cn, email, pubKey, csrK, caCert->GetX509())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } // Calculate maximum life time for the cert time_gmt(&currTime); days = (caCert->GetEndDate() - currTime) / (3600*24) - 1; //We sign the cert if(!InternalCA_Sign(Type, csrK, ResultCert, days, false)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_PKI::Format_CSR(const mString & strCn, const mString & strEmail, const X509_PUBKEY * pubKey, PKI_CSR & csrK, const X509 * parent_cert) { X509_REQ * csr; HashTable_Dn dn; int pos; X509_NAME * tmpDN; EVP_PKEY * tmpKey; if(!strCn.size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } csr = X509_REQ_new(); if(!csr) { NEWPKIerr(PKI_ERROR_TXT, ERROR_MALLOC); return false; } tmpKey = X509_PUBKEY_get((X509_PUBKEY *)pubKey); if(!tmpKey) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); X509_REQ_free(csr); return false; } if(X509_PUBKEY_set(&csr->req_info->pubkey, tmpKey) <= 0) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); EVP_PKEY_free(tmpKey); X509_REQ_free(csr); return false; } EVP_PKEY_free(tmpKey); dn.From_X509_NAME(parent_cert->cert_info->subject); pos = -1; while( (pos = dn.SeekEntryName("commonName", pos)) != HASHTABLE_NOT_FOUND) { dn.Delete(pos); } dn.Add("commonName", strCn.c_str()); pos = -1; while( (pos = dn.SeekEntryName("emailAddress", pos)) != HASHTABLE_NOT_FOUND) { dn.Delete(pos); } if(strEmail.size()) { dn.Add("emailAddress", strEmail.c_str()); } tmpDN = X509_NAME_new(); if(!tmpDN) { NEWPKIerr(PKI_ERROR_TXT, ERROR_MALLOC); X509_REQ_free(csr); return false; } if(!dn.To_X509_NAME(tmpDN)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); X509_NAME_free(tmpDN); X509_REQ_free(csr); return false; } if(X509_NAME_set(&csr->req_info->subject, tmpDN) <= 0) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); X509_NAME_free(tmpDN); X509_REQ_free(csr); return false; } X509_NAME_free(tmpDN); if(!csrK.SetCSR(csr)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); X509_REQ_free(csr); return false; } X509_REQ_free(csr); return true; } bool Entity_PKI::InternalCA_Sign(INTERNAL_CA_TYPE Type, const PKI_CSR & csr, PKI_CERT & ResultCert, int Days, bool check_sig) { HashTable_String Exts; Exts.AllowDuplicateNames(); CA_Handler * currCa; switch(Type) { case INTERNAL_CA_TYPE_ROOT: Exts.Add("basicConstraints", "critical, CA:TRUE"); Exts.Add("nsComment", "NewPKI Internal CA Certificate"); Exts.Add("subjectKeyIdentifier", "hash"); Exts.Add("authorityKeyIdentifier", "keyid:always"); Exts.Add("nsCertType", "sslCA, emailCA, objCA"); Exts.Add("keyUsage", "keyCertSign, cRLSign, digitalSignature, nonRepudiation, keyEncipherment"); break; case INTERNAL_CA_TYPE_USER: Exts.Add("basicConstraints", "CA:FALSE"); Exts.Add("nsComment", "NewPKI Internal CA EndUser Certificate"); Exts.Add("subjectKeyIdentifier", "hash"); Exts.Add("authorityKeyIdentifier", "keyid:always"); Exts.Add("nsCertType", "client"); Exts.Add("keyUsage", "digitalSignature, nonRepudiation, keyEncipherment"); Exts.Add("extendedKeyUsage", "clientAuth"); break; case INTERNAL_CA_TYPE_ENTITY: Exts.Add("basicConstraints", "CA:FALSE"); Exts.Add("nsComment", "NewPKI Internal CA Entity Certificate"); Exts.Add("subjectKeyIdentifier", "hash"); Exts.Add("authorityKeyIdentifier", "keyid:always"); Exts.Add("nsCertType", "client, email"); Exts.Add("keyUsage", "digitalSignature, nonRepudiation, keyEncipherment"); Exts.Add("extendedKeyUsage", "clientAuth, emailProtection"); break; case INTERNAL_CA_TYPE_OCSP: Exts.Add("basicConstraints", "CA:FALSE"); Exts.Add("nsComment", "NewPKI Internal CA OCSP-Server Certificate"); Exts.Add("subjectKeyIdentifier", "hash"); Exts.Add("authorityKeyIdentifier", "keyid:always"); Exts.Add("extendedKeyUsage", "OCSPSigning"); break; default: NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; break; } //Search corresponding CA_Handler currCa = GetInternalCA(Type); if(!currCa) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!currCa->Sign(csr, ResultCert, "", Days, &Exts, check_sig)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_PKI::InternalCA_Revoke(INTERNAL_CA_TYPE Type, unsigned long serial) { CA_Handler * currCa; PKI_CRL resCrl; PKI_CERT revCert; CERT_STATE CertState; time_t revdate; mString uid; currCa = GetInternalCA(Type); if(!currCa) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!currCa->Revoke(serial, revCert, CertState, revdate, uid)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!currCa->Generate_CRL(resCrl, 30, 0, NULL, "sha1")) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockWrite(); //Copy result CRL into destination switch(Type) { case INTERNAL_CA_TYPE_ROOT: if(!pki_conf.get_conf().get_crls().set_rootcacrl(resCrl)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } break; case INTERNAL_CA_TYPE_USER: if(!pki_conf.get_conf().get_crls().set_userscacrl(resCrl)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } break; case INTERNAL_CA_TYPE_ENTITY: if(!pki_conf.get_conf().get_crls().set_entitiescacrl(resCrl)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } break; case INTERNAL_CA_TYPE_OCSP: if(!pki_conf.get_conf().get_crls().set_ocspcacrl(resCrl)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } break; default: NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); ConfAccessLock.UnlockWrite(); return false; break; } ConfAccessLock.UnlockWrite(); return true; } void Entity_PKI::Free_PkiConf() { ConfAccessLock.LockWrite(); pki_conf.Clear(); ConfAccessLock.UnlockWrite(); } bool Entity_PKI::ParseAdminCommand(AdminResponseBody & response, const PKI_CERT & ClientCert, const AdminRequest & AdminRequest) { //We only accept SSLv3 connection if(!ClientCert) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); ERR_to_ADMIN_RESPONSE(response); return false; } PARSER_COMMAND_BEGIN(Entity_PKI, response, 0, AdminRequest, ClientCert, GetUserHandle(), true, this, LogsType) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_SEND_ADMIN_MAIL) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_SEND_MAIL) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_CONFIG_PUSH) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_LOGIN, Entity_PKI::UserLogin, LOG_MESSAGE_TYPE_USER_LOGIN, (ClientCert)?ClientCert.GetStringName():"", LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_ENUM_LOGS, Entity_PKI::EnumLogs) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_LOGS_COUNT, Entity_PKI::GetLogsCount) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_ENUM_ENTITIES, Entity_PKI::EnumEntities) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SIGN_ENTITY, Entity_PKI::SignEntity, LOG_MESSAGE_TYPE_SIGN_ENTITY, body.get_signEntity().get_name(), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_ENUM_USERS, Entity_PKI::EnumUsers) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_CREATE_PKI_USER, Entity_PKI::CreateUser, LOG_MESSAGE_TYPE_USER_ADD, body.get_createPkiUser().get_cn(), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_REVOKE_USER, Entity_PKI::RevokeUserCert, LOG_MESSAGE_TYPE_USER_REVOCATION, "", body.get_serial()) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_REVOKE_ENTITY, Entity_PKI::RevokeEntityCert, LOG_MESSAGE_TYPE_ENTITY_REVOCATION, "", body.get_serial()) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SET_OFFLINE, Entity_PKI::SetOfflineState, LOG_MESSAGE_TYPE_SET_OFFLINE, "", body.get_offline()) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_OFFLINE, Entity_PKI::GetOfflineState) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_MY_ACL, Entity_PKI::GetMyACL) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_GET_CONFIG, Entity_PKI::GetConfiguration, LOG_MESSAGE_TYPE_GET_CONFIGURATION, _sv("none"), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_ENTITY_CONF, Entity_PKI::GetEntityConf) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SET_ENTITY_CONF, Entity_PKI::SetEntityConf, LOG_MESSAGE_TYPE_SET_ENTITY_CONF, body.get_entityConf().get_entityCert().GetStringName(), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_REPOSITORIES, Entity_PKI::GetRepositoriesList) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SET_REPOSITORIES, Entity_PKI::SetRepositoriesList, LOG_MESSAGE_TYPE_SET_REPOSITORIES, _sv("none"), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_LOGS_TYPE, Entity_PKI::GetLogsType) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_LOCK_RESOURCE, Entity_PKI::UserLockResourse, LOG_MESSAGE_TYPE_LOCK_RESOURCE, body.get_resourceName(), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_UNLOCK_RESOURCE, Entity_PKI::UserUnlockResourse, LOG_MESSAGE_TYPE_UNLOCK_RESOURCE, body.get_resourceName(), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_ENTITY_ACL, Entity_PKI::GetEntityAcl) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SET_ENTITY_ACL, Entity_PKI::SetEntityAcl, LOG_MESSAGE_TYPE_SET_ENTITY_ACL, body.get_entityAcl().get_entityCert()?body.get_entityAcl().get_entityCert().GetStringName():"PKI Entity", LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_ENTITY_MAIL_CONF, Entity_PKI::GetEntityMailConf) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SET_ENTITY_MAIL_CONF, Entity_PKI::SetEntityMailConf, LOG_MESSAGE_TYPE_SET_ENTITY_MAIL_CONF, body.get_entityMailConf().get_entityCert()?body.get_entityMailConf().get_entityCert().GetStringName():"PKI Entity", LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SEND_ADMIN_MAIL, Entity_PKI::AdminSendMail, LOG_MESSAGE_TYPE_ADD_ADMIN_MAIL_QUEUE, _sv("none"), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_ENTITY_AUDITS, Entity_PKI::GetEntityAudits) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SET_ENTITY_AUDITS, Entity_PKI::SetEntityAudits, LOG_MESSAGE_TYPE_SET_ENTITY_AUDITS, body.get_entityAudits().get_entityCert()?body.get_entityAudits().get_entityCert().GetStringName():"PKI Entity", LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_ENTITY_LOGS_TYPE, Entity_PKI::GetEntityLogsType) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_ENTITIES_LINKS, Entity_PKI::GetEntitiesLinks) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SET_ENTITIES_LINKS, Entity_PKI::SetEntitiesLinks, LOG_MESSAGE_TYPE_SET_ENTITIES_LINKS, _sv("none"), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_GROUPS, Entity_PKI::GetGroups) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SET_GROUPS, Entity_PKI::SetGroups, LOG_MESSAGE_TYPE_SET_GROUPS, _sv("none"), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_ADD_GROUP, Entity_PKI::AddGroup, LOG_MESSAGE_TYPE_ADD_GROUP, body.get_groupName(), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_DEL_GROUP, Entity_PKI::DelGroup, LOG_MESSAGE_TYPE_DEL_GROUP, "", body.get_groupId()) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_REN_GROUP, Entity_PKI::RenameGroup, LOG_MESSAGE_TYPE_REN_GROUP, "", body.get_renameGroup().get_id()) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_CHECK_LOGS, Entity_PKI::CheckLogsIntegrity) PARSER_COMMAND_END(Entity_PKI) } bool Entity_PKI::LoginUser(UserHandle & hUser, int & UserType) { if(!AclValidator.CanUserPerform(hUser.GetUserCert(), ACL_TYPE_AUTHENTICATE_ON_ENTITY)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } UserType = USER_TYPE_PKI; return true; } void Entity_PKI::LogoutUser(const UserHandle & hUser) { } bool Entity_PKI::SignEntity(COMMAND_PARAMETERS) { EntitySignatureResp sign_entity; PKI_CERT resCert; const X509_PUBKEY * pubKey; RepEntryInfo repository; PubEntryInfo publication; EntityConfCrypted ExportedConf; unsigned long entity_cert_serial=0; unsigned long ocsp_cert_serial=0; X509 * EntityCert = NULL; if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_ENTITIES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!body.get_signEntity().get_name().size() || !body.get_signEntity().get_email().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } ConfAccessLock.LockWrite(); //Doing basic verification switch(body.get_signEntity().get_body().get_type()) { case ENTITY_TYPE_KEY_STORE: case ENTITY_TYPE_RA: case ENTITY_TYPE_CA: case ENTITY_TYPE_BACKUP: //We need to make sur there is a repository available if(!pki_conf.get_repositories().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NO_REPOSITORY); ConfAccessLock.UnlockWrite(); return false; } pubKey = body.get_signEntity().get_body().get_entitypubkey(); break; case ENTITY_TYPE_PUBLICATION: //We need to make sur there is a repository available if(!pki_conf.get_repositories().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NO_REPOSITORY); ConfAccessLock.UnlockWrite(); return false; } pubKey = body.get_signEntity().get_body().get_signPub().get_entitypubkey(); break; case ENTITY_TYPE_REPOSITORY: pubKey = body.get_signEntity().get_body().get_signRep().get_entitypubkey(); break; default: NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); ConfAccessLock.UnlockWrite(); return false; break; } if(!response.set_type(ADMIN_RESP_TYPE_SIGN_ENTITY)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } //Generate entity cert if(!InternalCA_SignForceDn(INTERNAL_CA_TYPE_ENTITY, pubKey, body.get_signEntity().get_name(), body.get_signEntity().get_email(), resCert)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } entity_cert_serial = resCert.GetSerial(); if(!response.get_signEntity().get_body().set_type(body.get_signEntity().get_body().get_type())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_MALLOC); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } //Generate the real signature response switch(body.get_signEntity().get_body().get_type()) { case ENTITY_TYPE_RA: case ENTITY_TYPE_CA: case ENTITY_TYPE_REPOSITORY: case ENTITY_TYPE_KEY_STORE: case ENTITY_TYPE_BACKUP: if(!response.get_signEntity().get_body().set_entitycert(resCert)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } EntityCert = response.get_signEntity().get_body().get_entitycert().GetX509(); break; case ENTITY_TYPE_PUBLICATION: if(!response.get_signEntity().get_body().get_signPub().set_entitycert(resCert)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } EntityCert = response.get_signEntity().get_body().get_signPub().get_entitycert().GetX509(); //Now we generate the OCSP cert if(!InternalCA_SignForceDn(INTERNAL_CA_TYPE_OCSP, body.get_signEntity().get_body().get_signPub().get_ocsppubkey(), body.get_signEntity().get_name(), body.get_signEntity().get_email(), resCert)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } ocsp_cert_serial = resCert.GetSerial(); if(!response.get_signEntity().get_body().get_signPub().set_ocspcert(resCert)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); Private_RevokeEntityCert(ocsp_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } break; } //If we just created a publication, we add it to the list if(body.get_signEntity().get_body().get_type() == ENTITY_TYPE_PUBLICATION) { publication.set_name(body.get_signEntity().get_name()); if(!publication.set_pubocsp(response.get_signEntity().get_body().get_signPub().get_ocspcert())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); Private_RevokeEntityCert(ocsp_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } if(!publication.set_pubssl(response.get_signEntity().get_body().get_signPub().get_entitycert())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); Private_RevokeEntityCert(ocsp_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } pki_conf.get_publications().get_list().push_back(publication); publication.Clear(); } else if(body.get_signEntity().get_body().get_type() == ENTITY_TYPE_REPOSITORY) { //If we just created a repository, we add it to the list repository.set_name(body.get_signEntity().get_name()); repository.set_address(body.get_signEntity().get_body().get_signRep().get_address()); repository.set_port(body.get_signEntity().get_body().get_signRep().get_port()); if(!repository.set_repositoryssl(response.get_signEntity().get_body().get_entitycert())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } pki_conf.get_repositories().push_back(repository); repository.Clear(); } //Creating a default conf for the new entity if(!Add_ENTITY_CONF(body.get_signEntity().get_name(), EntityCert, body.get_signEntity().get_body().get_type())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); if(ocsp_cert_serial) Private_RevokeEntityCert(ocsp_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } //writing conf to Database if(!WritePersonnalConf()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); if(ocsp_cert_serial) Private_RevokeEntityCert(ocsp_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } //We copy the exported conf to the response if(!EXPORTED_PKI_CONF_get_conf(EntityCert, response.get_signEntity().get_conf())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); if(ocsp_cert_serial) Private_RevokeEntityCert(ocsp_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } //We copy the internal ca certs to the signature response if( !(response.get_signEntity().get_cas() = pki_conf.get_cas()) ) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); NewPKI_LockErr(); Private_RevokeEntityCert(entity_cert_serial); if(ocsp_cert_serial) Private_RevokeEntityCert(ocsp_cert_serial); NewPKI_UnlockErr(); ConfAccessLock.UnlockWrite(); return false; } ConfAccessLock.UnlockWrite(); return true; } bool Entity_PKI::EnumEntities(COMMAND_PARAMETERS) { size_t i, v_index; if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_ENUM_ENTITIES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockRead(); v_index = 0; for(i=0; i certs; bool IsAdmin; bool UserIsAdmin; IsAdmin = AclValidator.IsPkiAdministrator(UserCert); currCa = GetInternalCA(INTERNAL_CA_TYPE_USER); if(!currCa) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!response.set_type(ADMIN_RESP_TYPE_ENUM_USERS_CERT)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!currCa->get_Certs(certs, CERT_STATE_VALID)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } v_index = 0; for(i=0; i & acl_list) { int i; static ACL_TYPE list_acls[] = { ACL_TYPE_MANAGE_USERS, ACL_TYPE_MANAGE_ENTITIES, ACL_TYPE_VIEW_LOGS, ACL_TYPE_MANAGE_ACLS, ACL_TYPE_MODIFY_PKI_STATUS, ACL_TYPE_SEND_ADMIN_MAIL, (ACL_TYPE)0 }; for(i=0; list_acls[i]; i++) { acl_list.push_back(list_acls[i]); } } bool Entity_PKI::GetConfiguration(COMMAND_PARAMETERS) { if(!response.set_type(ADMIN_RESP_TYPE_CONF)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockRead(); if(!response.set_conf(pki_conf.get_cryptConfs())) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.UnlockRead(); return true; } bool Entity_PKI::GetEntityConf(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_ENTITY_CONF)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockRead(); EntityConf & conf = GetEntityConfiguration(body.get_entityCert()); if(!conf) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN_ENTITY); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_ENTITIES)) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(body.get_entityCert().GetStringName())) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_entityConf(conf.get_body())) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } ConfAccessLock.UnlockRead(); return true; } bool Entity_PKI::SetEntityConf(COMMAND_PARAMETERS) { bool ret; EntityConfBody tmpConf; if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_ENTITIES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(body.get_entityConf().get_entityCert().GetStringName())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_NONE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } size_t i; ConfAccessLock.LockWrite(); for(i=0; i < pki_conf.get_confs().size(); i++) { if(pki_conf.get_confs()[i].get_certificate() == body.get_entityConf().get_entityCert()) { if(! (tmpConf = body.get_entityConf().get_conf()) ) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //Verify entity conf switch(tmpConf.get_type()) { case ENTITY_TYPE_CA: ret = CheckCaConf(tmpConf.get_caConf()); break; case ENTITY_TYPE_RA: ret = CheckRaConf(tmpConf.get_raConf()); break; case ENTITY_TYPE_REPOSITORY: ret = CheckRepositoryConf(tmpConf.get_repConf()); break; default: ret = true; break; } if(!ret) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!pki_conf.get_confs()[i].get_conf().set_body(tmpConf)) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //We update the crypted conf if(!UpdateEntityConfs(0, pki_conf.get_confs()[i].get_conf(), true)) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!WritePersonnalConf()) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.UnlockWrite(); return true; } } ConfAccessLock.UnlockWrite(); return true; } bool Entity_PKI::CheckRepositoryConf(EntityConfBodyRep &Conf) { return true; } bool Entity_PKI::CheckRaConf(EntityConfBodyRa & Conf) { size_t i, j; bool ret; PolicyValue newPolicy; //We check the validity of the DN fields ret = true; for(i=0; i tmpRep1; mVector tmpRep2; if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_ENTITIES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(PKI_REPOSITORIES_RESOURCE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_NONE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockWrite(); tmpRep1 = pki_conf.get_repositories(); tmpRep2 = body.get_repositories(); // We validate the repositories, to make sure // the user didn't send something phoney for(i=0; i 0 || tmpRep2.size() > 0) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_DATAS); return false; } if(!pki_conf.set_repositories(body.get_repositories())) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //Yell to other entities the new repositories list if(!UpdateEntityConfs(ENTITY_CONF_UPDATE_LINKS)) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!WritePersonnalConf()) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.UnlockWrite(); return true; } X509_ACL_INIT Entity_PKI::X509_ACL_init(X509Acl & acls, int EntityType) { bool Modified = false; size_t i, j; CA_Handler * usersCa; bool Found; mVector certs; AclEntry newAcl; usersCa = GetInternalCA(INTERNAL_CA_TYPE_USER); if(!usersCa) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return X509_ACL_INIT_ERROR; } if(!usersCa->get_Certs(certs)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return X509_ACL_INIT_ERROR; } for(i=0; i::iterator newConf; mVector< EntityLinks >::iterator LinkIndex; //Adding the new entity to the list of available one newConf = pki_conf.get_confs().insert(pki_conf.get_confs().end()); //Copy entity cert if(!newConf->get_certificate().SetCert(EntityCert)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); return false; } newConf->get_conf().set_name(EntityName); //Copy default PKI email conf if(!newConf->get_conf().set_mailConf(pki_conf.get_conf().get_mailConf())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); return false; } //Allocate a default conf if(!newConf->get_conf().get_body().set_type(Type)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); return false; } switch(Type) { case ENTITY_TYPE_CA: if(!newConf->get_conf().get_body().get_caConf().set_type(CA_CONF_VERSION)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); return false; } break; case ENTITY_TYPE_RA: if(!newConf->get_conf().get_body().get_raConf().set_type(RA_CONF_VERSION)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); return false; } newDnSpecs.set_name("commonName"); newDnSpecs.set_default(""); newDnSpecs.set_comment("Common Name (eg(YOUR name)"); newDnSpecs.set_min(0); newDnSpecs.set_max(64); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_dnspecs().push_back(newDnSpecs); newDnSpecs.set_name("emailAddress"); newDnSpecs.set_default(""); newDnSpecs.set_comment("Email Address"); newDnSpecs.set_min(2); newDnSpecs.set_max(40); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_dnspecs().push_back(newDnSpecs); newDnSpecs.set_name("countryName"); newDnSpecs.set_default(""); newDnSpecs.set_comment("Country Name"); newDnSpecs.set_min(2); newDnSpecs.set_max(2); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_dnspecs().push_back(newDnSpecs); newDnSpecs.set_name("stateOrProvinceName"); newDnSpecs.set_default(""); newDnSpecs.set_comment("State or Province Name (full name)"); newDnSpecs.set_min(0); newDnSpecs.set_max(0); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_dnspecs().push_back(newDnSpecs); newDnSpecs.set_name("localityName"); newDnSpecs.set_default(""); newDnSpecs.set_comment("Locality Name (eg(city)"); newDnSpecs.set_min(0); newDnSpecs.set_max(0); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_dnspecs().push_back(newDnSpecs); newDnSpecs.set_name("organizationName"); newDnSpecs.set_default(""); newDnSpecs.set_comment("Organization Name (eg(company)"); newDnSpecs.set_min(0); newDnSpecs.set_max(0); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_dnspecs().push_back(newDnSpecs); newDnSpecs.set_name("organizationalUnitName"); newDnSpecs.set_default(""); newDnSpecs.set_comment("Organizational Unit Name (eg(section)"); newDnSpecs.set_min(0); newDnSpecs.set_max(0); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_dnspecs().push_back(newDnSpecs); CheckRaConf(newConf->get_conf().get_body().get_raConf()); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.set_defaultValidity(365); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.set_minkeylen(1024); newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.set_minpwdlen(6); ASN1_BIT_STRING_set_bit((ASN1_BIT_STRING*)newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), ALLOW_SERVER_SIDE_RA_KEY_GEN, 1); ASN1_BIT_STRING_set_bit((ASN1_BIT_STRING*)newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), ALLOW_PKCS10_IMPORT, 1); ASN1_BIT_STRING_set_bit((ASN1_BIT_STRING*)newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), ALLOW_RA_OP_SC_KEY_GEN, 1); ASN1_BIT_STRING_set_bit((ASN1_BIT_STRING*)newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), PUSH_KEYS_TO_KEY_ESCROW, 1); ASN1_BIT_STRING_set_bit((ASN1_BIT_STRING*)newConf->get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), REMOVE_UNKNOWN_DN_FIELDS, 1); break; case ENTITY_TYPE_PUBLICATION: if(!newConf->get_conf().get_body().get_pubConf().set_type(PUB_CONF_VERSION)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); return false; } newConf->get_conf().get_body().get_pubConf().PUB_CONF_PTR.set_ocspenabled(0); break; case ENTITY_TYPE_KEY_STORE: case ENTITY_TYPE_BACKUP: break; case ENTITY_TYPE_REPOSITORY: if(!newConf->get_conf().get_body().get_repConf().set_type(REP_CONF_VERSION)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); return false; } newConf->get_conf().get_body().get_repConf().REP_CONF_PTR.set_enabled(0); break; } newConf->get_conf().set_version(0); //Initialize its link struct newLink.get_src().set_name(EntityName); newLink.get_src().set_type(Type); // We add by default all the repositories to the list, it // will allow the newly created entity to go seek // its conf for(i=0; i < pki_conf.get_repositories().size(); i++) { //Is it me ? if(EntityName == pki_conf.get_repositories()[i].get_name()) continue; newLinkEntry.set_name(pki_conf.get_repositories()[i].get_name()); newLinkEntry.set_type(ENTITY_TYPE_REPOSITORY); newLink.get_dsts().push_back(newLinkEntry); } //Are we creating a repository? if yes then //we let all other reps know we exists newLinkEntry.set_name(EntityName); newLinkEntry.set_type(ENTITY_TYPE_REPOSITORY); if(Type == ENTITY_TYPE_REPOSITORY) { for(i=0; i < pki_conf.get_links().size(); i++) { //Is it a rep if(pki_conf.get_links()[i].get_src().get_type() != ENTITY_TYPE_REPOSITORY) continue; //Is it me ? if(EntityName == pki_conf.get_links()[i].get_src().get_name()) continue; pki_conf.get_links()[i].get_dsts().push_back(newLinkEntry); } } //add new link entry to list LinkIndex = pki_conf.get_links().insert(pki_conf.get_links().end(), newLink); newConf->get_conf().set_isOK(); if(!UpdateEntityConfs(ENTITY_CONF_UPDATE_ALL, newConf->get_conf())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); pki_conf.get_links().erase(LinkIndex); // This will delete the added link entries if(Type == ENTITY_TYPE_REPOSITORY) UpdateEntityConfs(ENTITY_CONF_UPDATE_LINKS); return false; } // We synchronize the links of the modified entities if(Type == ENTITY_TYPE_REPOSITORY && !UpdateEntityConfs(ENTITY_CONF_UPDATE_LINKS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); pki_conf.get_confs().erase(newConf); pki_conf.get_links().erase(LinkIndex); return false; } return true; } bool Entity_PKI::UserLockResourse(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_ENTITIES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_NONE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!ResourceLock(body.get_resourceName())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_PKI::UserUnlockResourse(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_ENTITIES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_NONE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ResourceUnlock(body.get_resourceName()); return true; } bool Entity_PKI::GetEntityAcl(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_ACLS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockRead(); EntityConf & conf = GetEntityConfiguration(body.get_entityCert()); if(!conf) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN_ENTITY); return false; } if(!AclValidator.CanUserPerform(UserCert, (conf.get_body().get_type() != ENTITY_TYPE_PKI?ACL_TYPE_MANAGE_ENTITIES:ACL_TYPE_MODIFY_PKI_STATUS))) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(body.get_entityCert().GetStringName())) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_aclsConf(conf.get_acls())) { ConfAccessLock.UnlockRead(); NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } ConfAccessLock.UnlockRead(); return true; } bool Entity_PKI::SetEntityAcl(COMMAND_PARAMETERS) { size_t i, j; if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_NONE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockWrite(); EntityConf & conf = GetEntityConfiguration(body.get_entityAcl().get_entityCert()); if(!conf) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN_ENTITY); return false; } if(!AclValidator.CanUserPerform(UserCert, (conf.get_body().get_type() != ENTITY_TYPE_PKI?ACL_TYPE_MANAGE_ENTITIES:ACL_TYPE_MODIFY_PKI_STATUS))) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(body.get_entityAcl().get_entityCert().GetStringName())) { ConfAccessLock.UnlockWrite(); NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } for(i=0; i certs; ConfAccessLock.LockWrite(); if(!OneConf || OneConf.get_body().get_type() == ENTITY_TYPE_PKI) { // We update for the local pki conf // with what was requested //Shall we synchronize the groups ? if(What & ENTITY_CONF_UPDATE_ALL || What & ENTITY_CONF_UPDATE_GROUPS) { //We remove any revoke cert usersCa = GetInternalCA(INTERNAL_CA_TYPE_USER); if(!usersCa) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } if(!usersCa->get_Certs(certs)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } for(i=0; iSetAudit(conf.get_audits())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } } else { //We update the crypted conf if(!UpdateEntityConfs(0, conf, true)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } } if(!WritePersonnalConf()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } ConfAccessLock.UnlockWrite(); return true; } bool Entity_PKI::GetEntityLogsType(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_ENTITIES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_LOGS_TYPE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } switch(body.get_entityType()) { case ENTITY_TYPE_PKI: response.set_logsType(LogsType); break; case ENTITY_TYPE_REPOSITORY: Entity_REPOSITORY::LogsTypeGet(response.get_logsType()); break; case ENTITY_TYPE_RA: Entity_RA::LogsTypeGet(response.get_logsType()); break; case ENTITY_TYPE_PUBLICATION: Entity_PUBLICATION::LogsTypeGet(response.get_logsType()); break; case ENTITY_TYPE_KEY_STORE: Entity_KEYSTORE::LogsTypeGet(response.get_logsType()); break; case ENTITY_TYPE_BACKUP: Entity_BACKUP::LogsTypeGet(response.get_logsType()); break; case ENTITY_TYPE_CA: Entity_CA::LogsTypeGet(response.get_logsType()); break; default: NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } return true; } EntityConf & Entity_PKI::GetEntityConfiguration(const PKI_CERT & EntityCert) { if(EntityCert == pki_conf.get_cas().get_pkicert()) { return pki_conf.get_conf(); } return STORED_ENTITY_CONF_get(pki_conf.get_confs(), EntityCert).get_conf(); } bool Entity_PKI::GetEntitiesLinks(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MODIFY_PKI_STATUS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(PKI_ENTITIES_LINKS_RESOURCE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_ENTITIES_LINKS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockRead(); if(!response.set_entitiesLinks(pki_conf.get_links())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockRead(); return false; } ConfAccessLock.UnlockRead(); return true; } bool Entity_PKI::IsEntityKnown(const mString & Name, int Type) { size_t i; //Check corresponding entity for(i=0; i Links; Links = body.get_entitiesLinks(); ConfAccessLock.LockWrite(); //Check that all conf are there FoundCtr = 0; for(i=0; iget_src().get_type() == pki_conf.get_confs()[i].get_conf().get_body().get_type()) { FoundCtr++; } } if(FoundCtr != (int)pki_conf.get_confs().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_DATAS); ConfAccessLock.UnlockWrite(); return false; } //Is the PKI present in the links ? currEntry = get_EntityLink(Links, pki_conf.get_conf().get_name()); if( !currEntry || currEntry->get_src().get_type() != ENTITY_TYPE_PKI) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_DATAS); ConfAccessLock.UnlockWrite(); return false; } // Check that the user didn't add some unknown entities // And that it links to some known entities for(i=0; iget_flags(), REP_ENTRY_INFO_FLAG_FIREWALLED, 1); ASN1_BIT_STRING_set_bit(currLink2->get_flags(), REP_ENTRY_INFO_FLAG_SHOULD_FULL_SYNCHRO, 0); ASN1_BIT_STRING_set_bit(Links[i].get_dsts()[j].get_flags(), REP_ENTRY_INFO_FLAG_FIREWALLED, 0); } else if(ASN1_BIT_STRING_get_bit(Links[i].get_dsts()[j].get_flags(), REP_ENTRY_INFO_FLAG_FIREWALLED)) { // If its firewalled to me then it should full synchro for me ASN1_BIT_STRING_set_bit(currLink2->get_flags(), REP_ENTRY_INFO_FLAG_FIREWALLED, 0); ASN1_BIT_STRING_set_bit(currLink2->get_flags(), REP_ENTRY_INFO_FLAG_SHOULD_FULL_SYNCHRO, 1); ASN1_BIT_STRING_set_bit(Links[i].get_dsts()[j].get_flags(), REP_ENTRY_INFO_FLAG_SHOULD_FULL_SYNCHRO, 0); } else { // both repositories can access each other ASN1_BIT_STRING_set_bit(currLink2->get_flags(), REP_ENTRY_INFO_FLAG_FIREWALLED, 0); ASN1_BIT_STRING_set_bit(currLink2->get_flags(), REP_ENTRY_INFO_FLAG_SHOULD_FULL_SYNCHRO, 0); } } } } if(!pki_conf.set_links(Links)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } //Yell to other entities the new repositories list if(!UpdateEntityConfs(ENTITY_CONF_UPDATE_LINKS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } if(!WritePersonnalConf()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } ConfAccessLock.UnlockWrite(); return true; } bool Entity_PKI::ParseNewConf() { return true; } bool Entity_PKI::DeclarePkiAdminCert(const PKI_CERT & cert, const mString & Email) { PkiAdminEntry entry; entry.set_serial(cert.GetSerial()); entry.set_email(Email); pki_conf.get_conf().get_acls().get_adminserials().push_back(entry); return true; } bool Entity_PKI::GetGroups(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_USERS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(PKI_ENTITIES_GROUPS_RESOURCE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_GROUPS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockRead(); response.set_groups(pki_conf.get_conf().get_groups()); ConfAccessLock.UnlockRead(); return true; } bool Entity_PKI::SetGroups(COMMAND_PARAMETERS) { size_t i, j; if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_USERS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(PKI_ENTITIES_GROUPS_RESOURCE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_NONE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockWrite(); for(i=0; i newSerial) newSerial = pki_conf.get_conf().get_groups()[i].get_serial(); } newSerial++; newGroup.set_serial(newSerial); newGroup.set_name(body.get_groupName()); pki_conf.get_conf().get_groups().push_back(newGroup); if(!UpdateEntityConfs(ENTITY_CONF_UPDATE_GROUPS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } if(!WritePersonnalConf()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockWrite(); return false; } ConfAccessLock.UnlockWrite(); return true; } bool Entity_PKI::DelGroup(COMMAND_PARAMETERS) { size_t i; size_t j; if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_MANAGE_USERS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!ResourceOwnerIsMe(PKI_ENTITIES_GROUPS_RESOURCE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_NONE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockWrite(); for(i=0; icert_info->key->public_key->length == pki_conf.get_cryptConfs().get_confs().get_allConfs()[i].get_recipient()->public_key->length && memcmp(cert->cert_info->key->public_key->data, pki_conf.get_cryptConfs().get_confs().get_allConfs()[i].get_recipient()->public_key->data, pki_conf.get_cryptConfs().get_confs().get_allConfs()[i].get_recipient()->public_key->length) == 0) { if(! (conf = pki_conf.get_cryptConfs().get_confs().get_allConfs()[i]) ) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } } NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } StoredEntityConf & Entity_PKI::STORED_ENTITY_CONF_get(mVector< StoredEntityConf > & entities, const PKI_CERT & cert) { size_t i; for(i=0; i < entities.size(); i++) { if(entities[i].get_certificate() == cert) return entities[i]; } return StoredEntityConf::EmptyInstance; } bool Entity_PKI::CreatePkiUser(const CreatePkiUserRequest & request, CreatePkiUserResponse & response, unsigned long & serial) { PKI_CERT certUser; PKI_RSA privKey; const X509_PUBKEY * pubkeyUser; HashTable_String ParentCerts; int What2Update = ENTITY_CONF_UPDATE_ACL; if(!request || !request.get_cn().size() || !request.get_email().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } switch(request.get_ukey().get_type()) { case PKI_USER_KEY_TYPE_SOFTKEY: if(!request.get_ukey().get_softkey().get_password().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!privKey.GenerateKey(request.get_ukey().get_softkey().get_keylen(), m_Engine)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } pubkeyUser = privKey.GetPublicKey(); if(!pubkeyUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } break; case PKI_USER_KEY_TYPE_PUBKEY: pubkeyUser = request.get_ukey().get_pubkey(); if(!pubkeyUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_DATAS); return false; } break; default: NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_DATAS); return false; } // Generate the certificate if(!InternalCA_SignForceDn(INTERNAL_CA_TYPE_USER, pubkeyUser, request.get_cn(), request.get_email(), certUser)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } serial = certUser.GetSerial(); // Create the response switch(request.get_ukey().get_type()) { case PKI_USER_KEY_TYPE_SOFTKEY: // We must generate a PKCS#12 if(!response.set_type(PKI_USER_KEY_TYPE_SOFTKEY)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); RevokePkiUser(serial); return false; } if(!ParentCerts.Add(RootCa->get_CaCert()->GetStringName(), RootCa->get_CaCert()->GetCertPEM().c_str())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); RevokePkiUser(serial); return false; } if(!ParentCerts.Add(UsersCa->get_CaCert()->GetStringName(), UsersCa->get_CaCert()->GetCertPEM().c_str())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); RevokePkiUser(serial); return false; } response.get_p12().SetEndUserCert(certUser); response.get_p12().SetEndUserKey(privKey); response.get_p12().SetParentCerts(ParentCerts); if(!response.get_p12().Generate(request.get_ukey().get_softkey().get_password().c_str())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); return false; } break; case PKI_USER_KEY_TYPE_PUBKEY: // We must generate a PKCS#7 if(!response.set_type(PKI_USER_KEY_TYPE_PUBKEY)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); RevokePkiUser(serial); return false; } if(!response.get_p7b().AddCert(RootCa->get_CaCert()->GetX509())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); return false; } if(!response.get_p7b().AddCert(UsersCa->get_CaCert()->GetX509())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); return false; } if(!response.get_p7b().AddCert(certUser.GetX509())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); return false; } if(!response.get_p7b().Generate()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); return false; } break; } ConfAccessLock.LockWrite(); if(request.get_pkiadmin()) { if(!DeclarePkiAdminCert(certUser, request.get_email())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); ConfAccessLock.UnlockWrite(); return false; } //Update my own ACL handler if(!AclValidator.SetACL(pki_conf.get_conf().get_acls())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); ConfAccessLock.UnlockWrite(); return false; } //Yell to other entities the new admin What2Update |= ENTITY_CONF_UPDATE_ADMINS; } ConfAccessLock.UnlockWrite(); //Yell to other entities the new ACL if(!UpdateEntityConfs(What2Update)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); return false; } if(!WritePersonnalConf()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RevokePkiUser(serial); return false; } return true; } bool Entity_PKI::RevokePkiUser(unsigned long serial) { size_t i; int What2Update = ENTITY_CONF_UPDATE_ACL | ENTITY_CONF_UPDATE_CRL | ENTITY_CONF_UPDATE_GROUPS; if(AclValidator.IsPkiAdministrator(serial)) { //We remove it from the list ConfAccessLock.LockWrite(); for(i=0; i < pki_conf.get_conf().get_acls().get_adminserials().size() ; i++) { if(pki_conf.get_conf().get_acls().get_adminserials()[i].get_serial() == serial) { pki_conf.get_conf().get_acls().get_adminserials().erase(pki_conf.get_conf().get_acls().get_adminserials().begin() + i); break; } } ConfAccessLock.UnlockWrite(); What2Update |= ENTITY_CONF_UPDATE_ADMINS; } if(!InternalCA_Revoke(INTERNAL_CA_TYPE_USER, serial)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } // Yell to other entities the new ACL and the new CRL if(!UpdateEntityConfs(What2Update)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //Remove user from the ACLs if(!WritePersonnalConf()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_PKI::PrepareConfToWrite() { EXPORTED_PKI_CONF_BODY * lBody = NULL; pki_conf.get_cryptConfs().get_confs().set_version(pki_conf.get_cryptConfs().get_confs().get_version() + 1); if(!pki_conf.get_cryptConfs().get_confs().give_Datas(&lBody)) { if(lBody) ASN1_item_free((ASN1_VALUE*)lBody, ExportedPkiConfBody::get_ASN1_ITEM()); NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } // Signing the global conf //Ok, we have crypted and sign every conf //let's sign the whole thing with the PKI Entity Key if(ASN1_item_sign(ExportedPkiConfBody::get_ASN1_ITEM(), pki_conf.get_cryptConfs().get_sig()->algor, NULL, pki_conf.get_cryptConfs().get_sig()->digest, (char*)lBody, (EVP_PKEY*)m_EntityKey.GetRsaKey(), EVP_sha1()) <= 0) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ASN1_item_free((ASN1_VALUE*)lBody, ExportedPkiConfBody::get_ASN1_ITEM()); return false; } ASN1_item_free((ASN1_VALUE*)lBody, ExportedPkiConfBody::get_ASN1_ITEM()); if(!pki_conf.get_conf().get_body().get_pkiConf().PKI_CONF_PTR.get_offline()) { if(!m_Jobs.SetPkiConf(pki_conf.get_cryptConfs())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } } return true; }