📄 certificateprovider.cpp
字号:
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 + -