/* 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 */ // X509_ACL_Validator.cpp: implementation of the X509_ACL_Validator class. // ////////////////////////////////////////////////////////////////////// #include "X509_ACL_Validator.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// X509_ACL_Validator::X509_ACL_Validator() { } X509_ACL_Validator::~X509_ACL_Validator() { } bool X509_ACL_Validator::SetGroups(const mVector & groups) { AccessLock.LockWrite(); m_groups = groups; AccessLock.UnlockWrite(); return true; } bool X509_ACL_Validator::SetACL(const X509Acl & acl) { AccessLock.LockWrite(); if(!(m_acl = acl)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); AccessLock.UnlockWrite(); return false; } AccessLock.UnlockWrite(); return true; } bool X509_ACL_Validator::SetCRL(const InternalPkiCrl & crl) { AccessLock.LockWrite(); if(!(m_crls = crl)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); AccessLock.UnlockWrite(); return false; } AccessLock.UnlockWrite(); return true; } bool X509_ACL_Validator::SetCA(const InternalPkiCa & ca) { AccessLock.LockWrite(); if(!(m_certs = ca)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); AccessLock.UnlockWrite(); return false; } AccessLock.UnlockWrite(); return true; } int X509_ACL_Validator::ValidateCert(const PKI_CERT & usercert) const { int IssuerType; time_t currTime; PKI_CRL IssuerCrl; if(!usercert) { return -1; } AccessLock.LockRead(); //Is it the PKI cert ? if(usercert == m_certs.get_pkicert()) { AccessLock.UnlockRead(); return 0; } //Is certificate valid ? time_gmt(&currTime); if( (usercert.GetStartDate() > currTime) || (currTime >= usercert.GetEndDate())) { AccessLock.UnlockRead(); return -1; } //Get issuer type if(X509_verify(usercert.GetX509(), (EVP_PKEY*)m_certs.get_entitiesca().GetPublicKey()) > 0) { IssuerType = INTERNAL_CA_TYPE_ENTITY; IssuerCrl = m_crls.get_entitiescacrl(); if(m_crls.get_rootcacrl().IsRevoked(m_certs.get_entitiesca())) { AccessLock.UnlockRead(); ERR_clear_error(); return -1; } } else if(X509_verify(usercert.GetX509(), (EVP_PKEY*)m_certs.get_usersca().GetPublicKey()) > 0) { IssuerType = INTERNAL_CA_TYPE_USER; IssuerCrl = m_crls.get_userscacrl(); if(m_crls.get_rootcacrl().IsRevoked(m_certs.get_usersca())) { AccessLock.UnlockRead(); ERR_clear_error(); return -1; } } else if(X509_verify(usercert.GetX509(), (EVP_PKEY*)m_certs.get_rootca().GetPublicKey()) > 0) { IssuerType = INTERNAL_CA_TYPE_ROOT; IssuerCrl = m_crls.get_rootcacrl(); } else if(X509_verify(usercert.GetX509(), (EVP_PKEY*)m_certs.get_ocspca().GetPublicKey()) > 0) { IssuerType = INTERNAL_CA_TYPE_OCSP; IssuerCrl = m_crls.get_ocspcacrl(); if(m_crls.get_rootcacrl().IsRevoked(m_certs.get_ocspca())) { AccessLock.UnlockRead(); ERR_clear_error(); return -1; } } else { AccessLock.UnlockRead(); ERR_clear_error(); return -1; } if(IssuerCrl.IsRevoked(usercert)) { AccessLock.UnlockRead(); ERR_clear_error(); return -1; } AccessLock.UnlockRead(); ERR_clear_error(); return IssuerType; } bool X509_ACL_Validator::CanUserPerform(const PKI_CERT & usercert, int command, bool CheckCert) const { size_t i; size_t j; AclEntry currAcl; if(CheckCert && ValidateCert(usercert) != INTERNAL_CA_TYPE_USER) { return false; } AccessLock.LockRead(); //This is the PKI admin if(IsPkiAdministrator(usercert)) { AccessLock.UnlockRead(); return true; } currAcl = FindAcl(ACL_ENTRY_TYPE_USER, usercert.GetSerial()); if(!currAcl) { AccessLock.UnlockRead(); return false; } //We check the ACL if(ASN1_BIT_STRING_get_bit(currAcl.get_acls(), command)) { AccessLock.UnlockRead(); return true; } else { //Check the groups rights for(i=0; ilength > max_len) max_len = acl.get_acls()->length; } acl = FindAcl(ACL_ENTRY_TYPE_USER, serial); if(!acl) { NEWPKIerr(PKI_ERROR_TXT, ERROR_UNKNOWN); AccessLock.UnlockRead(); return false; } if(acl.get_acls()->length > max_len) max_len = acl.get_acls()->length; if(max_len) { buffer = (unsigned char*)malloc(max_len); if(!buffer) { NEWPKIerr(PKI_ERROR_TXT, ERROR_MALLOC); AccessLock.UnlockRead(); return false; } memset(buffer, 0, max_len); if(!ASN1_BIT_STRING_set(resAcl, buffer, max_len)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); AccessLock.UnlockRead(); return false; } free(buffer); } // Initialize the response acl with the user's // by default for(i=0; (int)ilength; i++) { resAcl->data[i] |= acl.get_acls()->data[i]; } for(i=0; ilength < resAcl->length)?acl.get_acls()->length:resAcl->length; for(k=0; (int)kdata[k] |= acl.get_acls()->data[k]; } //Next group break; } } AccessLock.UnlockRead(); return true; } bool X509_ACL_Validator::IsPkiAdministrator(const PKI_CERT & usercert) const { bool ret; AccessLock.LockRead(); ret = IsPkiAdministrator(usercert.GetSerial()); AccessLock.UnlockRead(); return ret; } bool X509_ACL_Validator::IsPkiAdministrator(long serial) const { bool ret; AccessLock.LockRead(); ret = Static_IsPkiAdministrator(serial, m_acl.get_adminserials()); AccessLock.UnlockRead(); return ret; } bool X509_ACL_Validator::Static_IsPkiAdministrator(const X509 *cert, const mVector & AdminSerials) { return Static_IsPkiAdministrator(ASN1_INTEGER_GET(X509_get_serialNumber((X509*)cert)), AdminSerials); } bool X509_ACL_Validator::Static_IsPkiAdministrator(long serial, const mVector & AdminSerials) { size_t i; for(i=0; i