/* 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_RA.cpp: implementation of the Entity_RA class. // ////////////////////////////////////////////////////////////////////// #include "Entity_RA.h" #include "svintl.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// Entity_RA::Entity_RA(ENTITY_CONSTRUCTOR_PARAMETERS): Entity(ENTITY_CONSTRUCTOR_PARAM_PASSTHRU, &myConf, &RaProfilesStore), RaProfilesStore(EntityName, e) { LdapSynch.SetEventHandler(&RaProfilesStore); } Entity_RA::~Entity_RA() { m_Jobs.StopAll(); } bool Entity_RA::Create(const EntityCreationDatas & Params, AdminResponseBody & response) { if(!Params) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(Params.get_type() != ENTITY_TYPE_RA) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!Params.get_entityKey()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } //We create the database if(!Common_Create(Params.get_entityKey(), NULL)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!response.get_creEntity().set_type(ENTITY_TYPE_RA)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); Destroy(); return false; } if(!response.get_creEntity().set_entityPubKey(m_EntityKey.GetPublicKey())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_MALLOC); Destroy(); return false; } return true; } bool Entity_RA::Load() { if(!Common_Load()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!IsFullyInit()) { return true; } LdapSynch.SetLogging(m_Logging); RaProfilesStore.SetAclValidator(&AclValidator); //Start the conf synch if(!m_Jobs.StartConfSync()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::Init(const EntitySignatureResp & init_datas) { if(IsFullyInit()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!init_datas) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(init_datas.get_body().get_type() != ENTITY_TYPE_RA) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PARAM); return false; } if(!Common_Init(init_datas.get_body().get_entitycert(), init_datas)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::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_RA; return true; } void Entity_RA::LogoutUser(const UserHandle & hUser) { } bool Entity_RA::ParseNewConf() { mString Err; if(!m_Policies.From_POLICY_VALUE(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_policies())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!RaProfilesStore.SetGroups(myConf.get_conf().get_groups())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } RaProfilesStore.SetMinPasswdLen(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_minpwdlen()); if(ASN1_BIT_STRING_get_bit(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), ALLOW_LDAP_PROFILE_IMPORT)) { if(!LdapClient.Connect(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapServer(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapPort(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUsername(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapPassword(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapBase(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapAttrName(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUtf8())) { ERR_to_mstring(Err); m_Logging->LogMessage(LOG_STATUS_TYPE_FAILURE, LOG_MESSAGE_TYPE_LDAP_CONNECTION, 0, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUsername().c_str(), LOG_NO_OBJECTID, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapServer().c_str(), Err.c_str()); } else { m_Logging->LogMessage(LOG_STATUS_TYPE_SUCCESS, LOG_MESSAGE_TYPE_LDAP_CONNECTION, 0, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUsername().c_str(), LOG_NO_OBJECTID, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapServer().c_str()); } if(ASN1_BIT_STRING_get_bit(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), ALLOW_LDAP_AUTO_SYNCH)) { if(!LdapSynch.SetOptions( (ASN1_BIT_STRING_get_bit(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), REMOVE_UNKNOWN_DN_FIELDS) == 1), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_dnspecs(), m_Policies, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapProfilesGroup(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapFilters())) { ERR_to_mstring(Err); m_Logging->LogMessage(LOG_STATUS_TYPE_FAILURE, LOG_MESSAGE_TYPE_LDAP_AUTO_SYNCH_START, 0, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUsername().c_str(), LOG_NO_OBJECTID, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapServer().c_str(), Err.c_str()); } else { if(!LdapSynch.Start(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapServer(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapPort(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUsername(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapPassword(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapBase(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapAttrName(), myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUtf8())) { ERR_to_mstring(Err); m_Logging->LogMessage(LOG_STATUS_TYPE_FAILURE, LOG_MESSAGE_TYPE_LDAP_AUTO_SYNCH_START, 0, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUsername().c_str(), LOG_NO_OBJECTID, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapServer().c_str(), Err.c_str()); } else { m_Logging->LogMessage(LOG_STATUS_TYPE_SUCCESS, LOG_MESSAGE_TYPE_LDAP_AUTO_SYNCH_START, 0, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapUsername().c_str(), LOG_NO_OBJECTID, myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapServer().c_str()); } } } else { LdapSynch.Stop(); } } else { LdapSynch.Stop(); } return true; } bool Entity_RA::Upgrade(const char * Version) { return true; } void Entity_RA::GetACL_List(mVector & acl_list) { int i; static ACL_TYPE list_acls[] = { ACL_TYPE_VIEW_LOGS, ACL_TYPE_SEND_ADMIN_MAIL, ACL_TYPE_RA_MANAGE_PROFILES, ACL_TYPE_RA_DELEGATE_PROFILE_OWNERSHIP, ACL_TYPE_RA_REQUEST_CERT, ACL_TYPE_RA_REVOKE_CERT, (ACL_TYPE)0 }; for(i=0; list_acls[i]; i++) { acl_list.push_back(list_acls[i]); } } bool Entity_RA::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; } return Private_ParseAdminCommand(true, this, LogsType, response, ClientCert, AdminRequest, GetUserHandle()); } bool Entity_RA::Private_ParseAdminCommand(bool ExecuteCmd, Entity * me_this, mVector & mLogsType, AdminResponseBody & response, const PKI_CERT & ClientCert, const AdminRequest & AdminRequest, UserHandle & hUser) { PARSER_COMMAND_BEGIN(Entity_RA, response, 0, AdminRequest, ClientCert, hUser, ExecuteCmd, me_this, mLogsType) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_ENTITY_GET_MY_CONF) 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_CERT_SIG_RESP) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_CERT_REV_RESP) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_CERT_RNW_RESP) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_LDAP_AUTO_SYNCH_START) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_LDAP_AUTO_SYNCH_IMPRT) PARSER_ADD_LOG_ENTRY(LOG_MESSAGE_TYPE_LDAP_CONNECTION) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_LOGIN, Entity_RA::UserLogin, LOG_MESSAGE_TYPE_USER_LOGIN, (ClientCert)?(char*)ClientCert.GetStringName():NULL, LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_ENUM_LOGS, Entity_RA::EnumLogs) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_LOGS_COUNT, Entity_RA::GetLogsCount) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_MY_ACL, Entity_RA::GetMyACL) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_LOGS_TYPE, Entity_RA::GetLogsType) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_SEND_ADMIN_MAIL, Entity_RA::AdminSendMail, LOG_MESSAGE_TYPE_ADD_ADMIN_MAIL_QUEUE, _sv("none"), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_CHECK_LOGS, Entity_RA::CheckLogsIntegrity) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_GET_LOCAL_CONF, Entity_RA::GetLocalConf, LOG_MESSAGE_TYPE_GET_LOCAL_CONF, _sv("none"), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_GET_GROUPS, Entity_RA::GetUsersGroups) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_IMPORT_PROFILE, Entity_RA::ImportProfile, LOG_MESSAGE_TYPE_IMPORT_PROFILE, _sv("none"), LOG_NO_OBJECTID) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_ENUM_PROFILES, Entity_RA::EnumProfiles) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_REQUEST_CERT, Entity_RA::RequestCert, LOG_MESSAGE_TYPE_CERT_REQUEST, "", body.get_certRequest().get_profileId()) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_REVOKE_CERT, Entity_RA::RevokeCert, LOG_MESSAGE_TYPE_CERT_REVOCATION, "", body.get_serial()) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_DELETE_PKCS12, Entity_RA::DeletePkcs12, LOG_MESSAGE_TYPE_DELETE_PKCS12, "", body.get_serial()) PARSER_COMMAND_ENTRY( ADMIN_REQ_TYPE_SEARCH_LDAP, Entity_RA::SearchLdap) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_CHANGE_PROFILE_UID, Entity_RA::ChangeProfileUID, LOG_MESSAGE_TYPE_PROFILE_CHANGE_UID, "", body.get_profileUid().get_profileId()) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_CHANGE_PROFILE_OWNER, Entity_RA::ChangeProfileOwner, LOG_MESSAGE_TYPE_PROFILE_CHANGE_OWNER, "", body.get_profileOwner().get_profileId()) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_DELETE_PROFILE, Entity_RA::DeleteProfile, LOG_MESSAGE_TYPE_DELETE_PROFILE, "", body.get_profileId()) PARSER_COMMAND_ENTRY_LOG( ADMIN_REQ_TYPE_CHANGE_PROFILE_DN, Entity_RA::ChangeProfileDN, LOG_MESSAGE_TYPE_PROFILE_CHANGE_DN, "", body.get_profileDn().get_profileId()) PARSER_COMMAND_END(Entity_RA) } void Entity_RA::LogsTypeGet(mVector & cLogsType) { Private_ParseAdminCommand(false, NULL, cLogsType, AdminResponseBody::EmptyInstance, PKI_CERT::EmptyInstance, AdminRequest::EmptyInstance, UserHandle::EmptyInstance); } bool Entity_RA::GetLocalConf(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(AclValidator.ValidateCert(UserCert) != INTERNAL_CA_TYPE_USER) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_LOCAL_ENTITY_CONF)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockRead(); if( !response.set_localEntityConf(myConf.get_conf()) ) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockRead(); return false; } ConfAccessLock.UnlockRead(); // We don't send the LDAP info, those are very private datas response.get_localEntityConf().get_body().get_raConf().RA_CONF_PTR.set_ldapServer(""); response.get_localEntityConf().get_body().get_raConf().RA_CONF_PTR.set_ldapUsername(""); response.get_localEntityConf().get_body().get_raConf().RA_CONF_PTR.set_ldapPassword(""); response.get_localEntityConf().get_body().get_raConf().RA_CONF_PTR.set_ldapBase(""); response.get_localEntityConf().get_body().get_raConf().RA_CONF_PTR.set_ldapPort(0); response.get_localEntityConf().get_body().get_raConf().RA_CONF_PTR.set_ldapProfilesGroup(0); response.get_localEntityConf().get_body().get_raConf().RA_CONF_PTR.set_ldapFilters(""); response.get_localEntityConf().get_body().get_raConf().RA_CONF_PTR.set_ldapAttrName(""); return true; } bool Entity_RA::GetUsersGroups(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(AclValidator.ValidateCert(UserCert) != INTERNAL_CA_TYPE_USER) { 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(); if(!response.set_groups(myConf.get_conf().get_groups())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockRead(); return false; } ConfAccessLock.UnlockRead(); return true; } bool Entity_RA::ImportProfile(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_MANAGE_PROFILES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } // Did the user delegate ownership of profile, // and is he allowed to ? if(body.get_profile().get_ownerGroupSerial() && !AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_DELEGATE_PROFILE_OWNERSHIP)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); ERR_add_error_data(1, _sv("Delegate profile's ownership")); return false; } long ProfileId; HashTable_Dn Dn; if(!Dn.From_X509_NAME(body.get_profile().get_dn())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } //Let's check the policy ConfAccessLock.LockRead(); if(!Dn.ValidateAgainstPolicy(m_Policies)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockRead(); return false; } ConfAccessLock.UnlockRead(); // Make sure we have an email address for this profile // so the EE can send the email if(body.get_profile().get_eeValidation()) { if(Dn.SeekEntryName("emailAddress", -1) == HASHTABLE_NOT_FOUND) { NEWPKIerr(PKI_ERROR_TXT, ERROR_DN_FIELD_UNPRESENT); ERR_set_error_data("emailAddress", ERR_TXT_STRING); return false; } } if(!response.set_type(ADMIN_RESP_TYPE_PROFILE_ID)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } // TODO: Reorder the DN ! if(!RaProfilesStore.InsertProfile(UserCert, body.get_profile(), ProfileId)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } // If we require user validation on this profile // then we must send the profile to the EE if(body.get_profile().get_eeValidation()) { // TODO: Créer une requete de publication du profil sur l'EE /* if((!SendEE_Req()) { } */ } response.set_id(ProfileId); return true; } bool Entity_RA::EnumProfiles(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_MANAGE_PROFILES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!response.set_type(ADMIN_RESP_TYPE_PROFILES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!RaProfilesStore.EnumProfiles(UserCert, response.get_profiles(), body.get_enumObjects().get_index(), body.get_enumObjects().get_num())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::SearchLdap(COMMAND_PARAMETERS) { mString Filters; if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_MANAGE_PROFILES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!LdapClient) { NEWPKIerr(PKI_ERROR_TXT, ERROR_LDAP_NOT_CONFIGURED); return false; } ConfAccessLock.LockRead(); if(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapFilters().size()) { Filters.sprintf("(&%s%s)", myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_ldapFilters().c_str(), body.get_ldapSearch().c_str()); } else { Filters = body.get_ldapSearch(); } ConfAccessLock.UnlockRead(); if(!response.set_type(ADMIN_RESP_TYPE_LDAP_RESULTS)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!LdapClient.Search(Filters, response.get_ldapResults())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::RequestCert(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_REQUEST_CERT)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } mString ldap_uid, ttDatas; int keylen; NewpkiRequest Request; size_t i; unsigned long CertReqId; const X509_PUBKEY * recipient=NULL; EVP_PKEY * tmpKey; PKI_CSR req; // Is the type set ? if(!body.get_certRequest().get_type()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_DATAS); return false; } ConfAccessLock.LockRead(); // Are we allowed to request certs from this CA ? for(i=0; i < myConf.get_conf().get_cas().get_list().size(); i++) { if(myConf.get_conf().get_cas().get_list()[i].get_name() == body.get_certRequest().get_caName()) { recipient = myConf.get_conf().get_cas().get_list()[i].get_cassl().GetX509_PUBKEY(); if(!recipient) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockRead(); return false; } break; } } // Did we find the CA ? if(i == myConf.get_conf().get_cas().get_list().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); ConfAccessLock.UnlockRead(); return false; } // We now verify if the request respects the policy constraints switch(body.get_certRequest().get_request().get_type()) { case REQUEST_CERT_BODY_PKCS10: if(!ASN1_BIT_STRING_get_bit(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), ALLOW_PKCS10_IMPORT)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); ConfAccessLock.UnlockRead(); return false; } tmpKey = X509_PUBKEY_get(body.get_certRequest().get_request().get_pkcs10().GetX509_REQ()->req_info->pubkey); if(!tmpKey) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockRead(); return false; } keylen = EVP_PKEY_size(tmpKey)*8; EVP_PKEY_free(tmpKey); break; case REQUEST_CERT_BODY_PKCS12: if(!ASN1_BIT_STRING_get_bit(myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_flags(), ALLOW_SERVER_SIDE_RA_KEY_GEN)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); ConfAccessLock.UnlockRead(); return false; } // If we're supposed to generate the PKCS#12 paswword we don't // do a length verification if(!ASN1_BIT_STRING_get_bit((ASN1_BIT_STRING*)body.get_certRequest().get_flags(), REQUEST_CERT_FLAG_RA_GENERATE_P12_PASSWD)) { ttDatas = body.get_certRequest().get_request().get_p12Privdatas().get_passwd(); //Let's verify the password length if(ttDatas.size() < myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_minpwdlen() ) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_PASSWORD_LEN); ttDatas = myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_minpwdlen(); ERR_add_error_data(1, ttDatas.c_str()); ConfAccessLock.UnlockRead(); return false; } } keylen = body.get_certRequest().get_request().get_p12Privdatas().get_keylen(); break; default: NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_DATAS); ConfAccessLock.UnlockRead(); return false; } //Let's verify the key length if(keylen < (int)myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_minkeylen()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_BAD_KEY_LEN); ttDatas.sprintf("%ld", myConf.get_conf().get_body().get_raConf().RA_CONF_PTR.get_minkeylen()); ERR_add_error_data(1, ttDatas.c_str()); ConfAccessLock.UnlockRead(); return false; } ConfAccessLock.UnlockRead(); // Generate the requests if(!Request.set_type(NEWPKI_REQUEST_TYPE_CERT)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } if(!response.set_type(ADMIN_RESP_TYPE_REQ_ID)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } // Generate the CSR if(!RaProfilesStore.RequestCertificate(UserCert, body.get_certRequest(), Request.get_certRequest().get_request(), ldap_uid, CertReqId)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } response.set_id(CertReqId); // We set the LDAP UID Request.get_certRequest().set_ldapUid(ldap_uid); // We set the request id Request.get_certRequest().set_id(CertReqId); // We set the validity len Request.get_certRequest().set_validity(body.get_certRequest().get_validity()); if(!m_Jobs.InsertRequest(CertReqId, Request, recipient)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RaProfilesStore.DeleteCertReq(CertReqId); return false; } return true; } bool Entity_RA::Responder_TreatRequest(const NewpkiRequest & Request, const mString & SenderName, NewpkiResponse & Response) { return true; } bool Entity_RA::Responder_ValidateRequest(const NewpkiRequest & Request, const X509_PUBKEY * Requester, mString & SenderName) { return true; } bool Entity_RA::Requester_OnNewResponse(const Asn1OctetString & transactionID, const X509_PUBKEY * sender, const NewpkiResponse & Response) { NewpkiProfileDatasCert cert; size_t i; mString ca_name; if(!RaProfilesStore.GetCertReq(transactionID, cert)) { return false; } ConfAccessLock.LockRead(); // Now search the CA, to make sure it is the real signer ! for(i=0; i < myConf.get_conf().get_cas().get_list().size(); i++) { // Is it the CA ? if( !(myConf.get_conf().get_cas().get_list()[i].get_name() == cert.get_caName()) ) continue; // Are the public keys the same ? if(myConf.get_conf().get_cas().get_list()[i].get_cassl() == sender) { ca_name = myConf.get_conf().get_cas().get_list()[i].get_name(); break; } } cert.Clear(); // We didn't find the CA if(i == myConf.get_conf().get_cas().get_list().size()) { ConfAccessLock.UnlockRead(); return true; } ConfAccessLock.UnlockRead(); return RaProfilesStore.InsertResponse(ca_name, transactionID, Response); } bool Entity_RA::RevokeCert(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_REVOKE_CERT)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } mString ttDatas; PKI_CSR req; PKI_RSA privKey; NewpkiRequest Request; size_t i; HashTable_Dn Dn; const X509_PUBKEY * recipient=NULL; unsigned long cert_serial; mString ca_name; mString ldap_uid; if(!response.set_type(ADMIN_RESP_TYPE_NONE)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } // Suspend the cert and get usefull info if(!RaProfilesStore.SuspendCertificate(UserCert, body.get_serial(), cert_serial, ca_name, ldap_uid)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } ConfAccessLock.LockRead(); // Are we allowed to request certs from this CA ? for(i=0; i < myConf.get_conf().get_cas().get_list().size(); i++) { if(myConf.get_conf().get_cas().get_list()[i].get_name() == ca_name) { recipient = myConf.get_conf().get_cas().get_list()[i].get_cassl().GetX509_PUBKEY(); if(!recipient) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); ConfAccessLock.UnlockRead(); RaProfilesStore.UnsuspendCertificate(body.get_serial()); return false; } break; } } // Did we find the CA ? if(i == myConf.get_conf().get_cas().get_list().size()) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); ConfAccessLock.UnlockRead(); RaProfilesStore.UnsuspendCertificate(body.get_serial()); return false; } ConfAccessLock.UnlockRead(); // Generate the request if(!Request.set_type(NEWPKI_REQUEST_TYPE_REV)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RaProfilesStore.UnsuspendCertificate(body.get_serial()); return false; } Request.get_revRequest().set_ldapUid(ldap_uid); Request.get_revRequest().set_id(body.get_serial()); Request.get_revRequest().set_reason(0); Request.get_revRequest().set_serial(cert_serial); if(!m_Jobs.InsertRequest(body.get_serial(), Request, recipient)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); RaProfilesStore.UnsuspendCertificate(body.get_serial()); return false; } return true; } bool Entity_RA::DeletePkcs12(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_REQUEST_CERT)) { 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(!RaProfilesStore.DeletePKCS12(UserCert, body.get_serial())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::ChangeProfileUID(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_MANAGE_PROFILES)) { 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(!RaProfilesStore.ChangeProfileUID(UserCert, body.get_profileUid().get_profileId(), body.get_profileUid().get_ldapUid())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::ChangeProfileOwner(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_MANAGE_PROFILES)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_DELEGATE_PROFILE_OWNERSHIP)) { 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(!RaProfilesStore.ChangeProfileOwner(UserCert, body.get_profileOwner().get_profileId(), body.get_profileOwner().get_ownerGroupSerial())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::ChangeProfileDN(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_MANAGE_PROFILES)) { 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(!RaProfilesStore.ChangeProfileDN(UserCert, body.get_profileDn().get_profileId(), body.get_profileDn().get_dn())) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::DeleteProfile(COMMAND_PARAMETERS) { if(!hUser) { NEWPKIerr(PKI_ERROR_TXT, ERROR_NOT_ALLOWED); return false; } if(!AclValidator.CanUserPerform(UserCert, ACL_TYPE_RA_MANAGE_PROFILES)) { 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(!RaProfilesStore.DeleteProfile(UserCert, body.get_profileId(), true)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool Entity_RA::PrepareConfToWrite() { return true; }