⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 certificateprovider.cpp

📁 Pegasus is an open-source implementationof the DMTF CIM and WBEM standards. It is designed to be por
💻 CPP
📖 第 1 页 / 共 5 页
字号:
String CertificateProvider::_getNewCertificateFileName(String trustStore, unsigned long hashVal) {    PEG_METHOD_ENTER(TRC_CONTROLPROVIDER, "CertificateProvider::_getNewCertificateFileName");    //The files are looked up by the CA subject name hash value.     //If more than one CA certificate with the same name hash value exists,     //the extension must be different (e.g. 9d66eef0.0, 9d66eef0.1 etc)    char hashBuffer[32];    sprintf(hashBuffer, "%08lx", hashVal);    String hashString = "";    for (int j = 0; j < 32; j++)    {        if (hashBuffer[j] != '\0')        {            hashString.append(hashBuffer[j]);        } else        {            break; // end of hash string        }    }    PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL4, "Searching for files like " + hashString);    Uint32 index = 0;    FileSystem::translateSlashes(trustStore);     if (FileSystem::isDirectory(trustStore) && FileSystem::canWrite(trustStore))    {        Array<String> trustedCerts;        if (FileSystem::getDirectoryContents(trustStore, trustedCerts))        {            for (Uint32 i = 0; i < trustedCerts.size(); i++)            {                //                // Check if another certificate with the same                // subject name already exists. If yes, error out.                //                if (String::compare(trustedCerts[i],                     hashString, hashString.size()) == 0)                {                    PEG_TRACE_STRING(TRC_CONTROLPROVIDER,                         Tracer::LEVEL3,                         "Error: Certificate with the same subject already exists.");                    MessageLoaderParms parms( "ControlProviders."                        "CertificateProvider.CERT_WITH_SAME_SUBJECT",                        "Another certificate with the"                        " same subject name already exists.");                    throw CIMException(CIM_ERR_ALREADY_EXISTS, parms);                }            }        } else        {            PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL3, "Error: Could not read truststore directory.");            MessageLoaderParms parms("ControlProviders.CertificateProvider.COULD_NOT_READ_DIRECTORY",                                     "Cannot read directory $0.", trustStore);            throw CIMException(CIM_ERR_FAILED, parms);        }    } else    {        PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL3, "Error: sslCRLStore is not a valid directory.");        MessageLoaderParms parms("ControlProviders.CertificateProvider.INVALID_DIRECTORY",                                 "Invalid directory $0.", trustStore);        throw CIMException(CIM_ERR_FAILED, parms);    }    char filename[1024];    sprintf(filename, "%s/%s.%d",             (const char*)trustStore.getCString(),            (const char*)hashString.getCString(),             index);    PEG_METHOD_EXIT();    return (String(filename));}/** Calls an extrinsic method on the class. */ void CertificateProvider::invokeMethod(    const OperationContext & context,    const CIMObjectPath & cimObjectPath,    const CIMName & methodName,    const Array<CIMParamValue> & inParams,    MethodResultResponseHandler & handler){    PEG_METHOD_ENTER(TRC_CONTROLPROVIDER,"CertificateProvider::invokeMethod");    //verify authorization    const IdentityContainer container = context.get(IdentityContainer::NAME);    if (!_verifyAuthorization(container.getUserName()))     {        MessageLoaderParms parms("ControlProviders.CertificateProvider.MUST_BE_PRIVILEGED_USER",                                 "Superuser authority is required to run this CIM operation.");        throw CIMException(CIM_ERR_ACCESS_DENIED, parms);    }    CIMName className(cimObjectPath.getClassName());    //verify classname    if (className == PEGASUS_CLASSNAME_CERTIFICATE)    {        // process request        handler.processing();            if (methodName == METHOD_ADD_CERTIFICATE)        {            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4, "CertificateProvider::addCertificate()");                String certificateContents = String::EMPTY;            String userName = String::EMPTY;            Uint16 certType = 0;            CIMValue cimValue;                        cimValue = inParams[0].getValue();            cimValue.get(certificateContents);                        cimValue = inParams[1].getValue();            cimValue.get(userName);                        cimValue = inParams[2].getValue();            cimValue.get(certType);            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"Certificate parameters:\n");            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"\tcertificateContents:" + certificateContents);            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"\tcertificateType:" + certType);            if (userName == String::EMPTY)            {                PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"\tDoes not have an associated username");            }            else            {                PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"\tuserName:" + userName);            }                        //check for a valid username if one is specified            if (userName == String::EMPTY)            {                 PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,                    "The certificate does not have an associated user name");            }            else if ( !System::isSystemUser(userName.getCString()))            {                throw CIMException(CIM_ERR_INVALID_PARAMETER,                  "The user specified by userName is not a valid system user.");            }                //read in the certificate contents            BIO *mem = BIO_new(BIO_s_mem());            BIO_puts(mem, (const char*)certificateContents.getCString());                //            // Read the buffer until no more certificates found.            //            X509 *xCert = NULL;            Uint32 certCount = 0;            while (( xCert = PEM_read_bio_X509(mem, NULL , 0, NULL)))            {                certCount++;                xCert = NULL;            }             //            // If more than one certificate was found, error out.            //            if (certCount > 1)            {                Tracer::trace(TRC_CONTROLPROVIDER, Tracer::LEVEL3, "Error: More than one cert in file : %d", certCount);                BIO_free(mem);                MessageLoaderParms parms("ControlProviders.CertificateProvider.MULTIPLE_CERT_IN_FILE",                                         "Specified certificate file contains more than one certificate.");                throw CIMException(CIM_ERR_FAILED, parms);            }            BIO_free(mem);            //read in the certificate contents            BIO *memCert = BIO_new(BIO_s_mem());            BIO_puts(memCert, (const char*)certificateContents.getCString());            //            // Read the certificate from buffer.            //            xCert = PEM_read_bio_X509(memCert, NULL , 0, NULL);            if (xCert == NULL)            {                BIO_free(memCert);                PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL3, "Error: Could not read x509 PEM format.");                MessageLoaderParms parms("ControlProviders.CertificateProvider.BAD_X509_FORMAT",                                         "Could not read x509 PEM format.");                throw CIMException(CIM_ERR_FAILED, parms);            }            BIO_free(memCert);                        PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"Read x509 certificate...");                        char buf[256];            String issuerName = String::EMPTY;            String serialNumber = String::EMPTY;            String subjectName = String::EMPTY;            CIMDateTime notBefore;            CIMDateTime notAfter;                        //issuer name            X509_NAME_oneline(X509_get_issuer_name(xCert), buf, 256);            issuerName = String(buf);                        //serial number            long rawSerialNumber = ASN1_INTEGER_get(X509_get_serialNumber(xCert));            char serial[256];            sprintf(serial, "%lu", rawSerialNumber);            serialNumber = String(serial);                //subject name            X509_NAME_oneline(X509_get_subject_name(xCert), buf, 256);            subjectName = String(buf);            //validity dates            notBefore = getDateTime(X509_get_notBefore(xCert));            notAfter = getDateTime(X509_get_notAfter(xCert));            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"IssuerName:" + issuerName);            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"SerialNumber:" + serialNumber);            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"SubjectName:" + subjectName);            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"NotBefore:" + notBefore.toString());            PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"NotAfter:" + notAfter.toString());                        //check validity with current datetime            //openssl will reject the certificate if it's not valid even if we add it to the truststore            try            {                if ((CIMDateTime::getDifference(CIMDateTime::getCurrentDateTime(), notBefore) > 0))                {                    PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL3, "Certificate or CRL is not valid yet.  Check the timestamps on your machine.");                    MessageLoaderParms parms("ControlProviders.CertificateProvider.CERT_NOT_VALID_YET",                                             "The certificate is not valid yet.  Check the timestamps on your machine.");                    throw CIMException(CIM_ERR_FAILED, parms);                }                if (CIMDateTime::getDifference(notAfter, CIMDateTime::getCurrentDateTime()) > 0)                 {                    PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL3, "Certificate or CRL is expired.");                    MessageLoaderParms parms("ControlProviders.CertificateProvider.CERT_EXPIRED",                                             "The certificate has expired.");                    throw CIMException(CIM_ERR_FAILED, parms);                }            } catch (DateTimeOutOfRangeException& ex)            {                    PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL3, "Certificate or CRL dates are out of range.");                    MessageLoaderParms parms("ControlProviders.CertificateProvider.BAD_DATE_FORMAT",                                             "The validity dates are out of range.");                    throw CIMException(CIM_ERR_FAILED, parms);            }            AutoMutex lock(_trustStoreMutex);            String certificateFileName = _getNewCertificateFileName(                                             _sslTrustStore,                                              X509_subject_name_hash(xCert));            if (userName != String::EMPTY)            {                PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,                   "Certificate " + certificateFileName +                     " registered to " + userName + "\n");            }            else            {                PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,                   "Certificate " + certificateFileName +                     " does not have a user name associated with it");            }                // build instance            CIMInstance cimInstance(PEGASUS_CLASSNAME_CERTIFICATE);                    cimInstance.addProperty(CIMProperty(ISSUER_NAME_PROPERTY, CIMValue(issuerName)));            cimInstance.addProperty(CIMProperty(SERIAL_NUMBER_PROPERTY, CIMValue(serialNumber)));            cimInstance.addProperty(CIMProperty(SUBJECT_NAME_PROPERTY, CIMValue(subjectName)));            cimInstance.addProperty(CIMProperty(USER_NAME_PROPERTY, CIMValue(userName)));            cimInstance.addProperty(CIMProperty(FILE_NAME_PROPERTY, CIMValue(certificateFileName)));            cimInstance.addProperty(CIMProperty(TRUSTSTORE_TYPE_PROPERTY, CIMValue(PG_SSLCERTIFICATE_TSTYPE_VALUE_SERVER)));            cimInstance.addProperty(CIMProperty(NOT_BEFORE_PROPERTY, CIMValue(notBefore)));            cimInstance.addProperty(CIMProperty(NOT_AFTER_PROPERTY, CIMValue(notAfter)));            cimInstance.addProperty(CIMProperty(CERTIFICATE_TYPE_PROPERTY, CIMValue(certType)));             // set keys    Array<CIMKeyBinding> keys;    CIMKeyBinding key;    key.setName(ISSUER_NAME_PROPERTY.getString());    key.setValue(issuerName);    key.setType(CIMKeyBinding::STRING);    keys.append(key);    key.setName(SERIAL_NUMBER_PROPERTY.getString());			key.setType(CIMKeyBinding::STRING);    key.setValue(String(serialNumber));    keys.append(key);    CIMKeyBinding kb (TRUSTSTORE_TYPE_PROPERTY, PG_SSLCERTIFICATE_TSTYPE_VALUE_SERVER);    keys.append(key);            // set object path for instance            cimInstance.setPath(CIMObjectPath(cimObjectPath.getHost(), cimObjectPath.getNameSpace(), PEGASUS_CLASSNAME_CERTIFICATE, keys));                PEG_TRACE_STRING(TRC_CONTROLPROVIDER,Tracer::LEVEL4,"New certificate COP: " + cimInstance.getPath().toString());                //attempt to add the instance to the repository first; that way if this instance already exist it will take care of throwing             //an error before we add the file to the truststore            _repository->createInstance("root/PG_Internal", cimInstance);                //            // Check if the type of certificate is authority issued end entity.             // If true, the certificate is not added to the truststore.             // A username will be associated with the certificate in the            // repository.            //            if ( ! (certType == TYPE_AUTHORITY_END_ENTITY ))            {                //ATTN: Take care of this conversion                char newFileName[256];                sprintf(newFileName, "%s", (const char*) certificateFileName.getCString());                        //use the ssl functions to write out the client x509 certificate                BIO* outFile = BIO_new(BIO_s_file());                       if (outFile == NULL)                {                    PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL2,                         "Unable to add certificate to truststore. "                         "Error while trying to write certificate, BIO_new returned error");                    MessageLoaderParms parms("ControlProviders.CertificateProvider.ERROR_WRITING_CERT",                        "Unable to add certificate to truststore. Error while trying to write certificate.");                    throw CIMException(CIM_ERR_FAILED, parms);                }                if (!BIO_write_filename(outFile, newFileName))                {                    BIO_free_all(outFile);                    PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL2,                         "Unable to add certificate to truststore. Error while trying to write certificate, "                         "BIO_write_filename returned error");                    MessageLoaderParms parms("ControlProviders.CertificateProvider.ERROR_WRITING_CERT",                        "Unable to add certificate to truststore. Error while trying to write certificate.");                    throw CIMException(CIM_ERR_FAILED, parms);                }                if (!PEM_write_bio_X509(outFile, xCert))                {                    BIO_free_all(outFile);                    PEG_TRACE_STRING(TRC_CONTROLPROVIDER, Tracer::LEVEL2,                         "Unable to add certificate to truststore. "                    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -