Linux安全體系的OMA數(shù)字版權(quán)保護(hù)(DRM)的實(shí)現(xiàn) - ShangShuWu1_第1頁
Linux安全體系的OMA數(shù)字版權(quán)保護(hù)(DRM)的實(shí)現(xiàn) - ShangShuWu1_第2頁
Linux安全體系的OMA數(shù)字版權(quán)保護(hù)(DRM)的實(shí)現(xiàn) - ShangShuWu1_第3頁
Linux安全體系的OMA數(shù)字版權(quán)保護(hù)(DRM)的實(shí)現(xiàn) - ShangShuWu1_第4頁
Linux安全體系的OMA數(shù)字版權(quán)保護(hù)(DRM)的實(shí)現(xiàn) - ShangShuWu1_第5頁
已閱讀5頁,還剩91頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

\o"Linux安全體系的OMA數(shù)字版權(quán)保護(hù)(DRM)的實(shí)現(xiàn)"\o"用戶:Njlts"\o"Special:用戶貢獻(xiàn)/Njlts"\o"Special:用戶貢獻(xiàn)/42"Linux安全體系的OMA數(shù)字版權(quán)保護(hù)(DRM)的實(shí)現(xiàn)\o"查看頁面內(nèi)容[c]"頁面\o"關(guān)于頁面正文的討論[t]"討論更多文章模板注釋W(xué)iki可信性\o"此頁面的早前修訂版本[h]"歷史出自ShangShuWu未檢查跳轉(zhuǎn)到:<<str<<′\n′;}return0;}

下面程序執(zhí)行的結(jié)果列出如下:Exceptionraised:Memoryallocationfailure!程序可以有多個(gè)try、throw和catch語句,與throw參數(shù)相匹配的catch語句才能運(yùn)行,如果沒有與匹配的catch語句,則運(yùn)行缺省(2)命名空間缺省下,C++使用單一的全局變量命名空間,如果用戶定義的一個(gè)全局變量名與源代碼不可見的庫的全局變量名發(fā)生重名沖突,程序?qū)⒖赡馨l(fā)生不可預(yù)知的錯(cuò)誤。為了克服這個(gè)問題,C++可以采用關(guān)鍵字namespace指定程序的命名空間,在不同命名空間的重名全局變量相互不影響,但程序使用全局變量名時(shí)必須指定全局變量名的命名空間。指定命名空間的方法有兩種,一種是在程序文件的前面指定命名空間,如:usingnamespacestd指定了本文件使用標(biāo)準(zhǔn)C++的命名空間。另一種是在全局變量名前加上命名空間,這樣,不管全局變量放在哪個(gè)程序文件中都可以識(shí)別到命名空間。如:全局變量std::test,表示test是命名空間std的全局變量。定義命名空間的樣例如下:namespacemyspace{ stringglobal_var="test"; }

上面的語句定義了myspace命名空間,定義了myspace命名空間的全局變量global_var。程序文件在文件頭部可以如下指定命名空間:#include<iostream>#include<string>usingnamespacemyspace;

文件頭部指定命名空間后,這個(gè)文件使用的所有全局變量global_var都屬于myspace命名空間。如果不在文件頭部用usingnamespacemyspace指定命名空間,還可以在任何文件中使用myspace::global_var表示這個(gè)全局變量屬于myspace命名空間。(3)類工廠類工廠是用于創(chuàng)建類的實(shí)例的類,給共享庫中定義的類提供對(duì)外統(tǒng)一的接口,這樣,只要類工廠不變,實(shí)現(xiàn)功能的類可以變化,編譯共享庫,而應(yīng)用程序不需要再編譯就可以使用。類工廠的常用定義方法如下:classClassFactory{publicstaticProductCreateProductA(){returnnewProductA();}

publicstaticProductCreateProductB(){retunnewProductB();}}

下面以O(shè)penIPMP軟件包中的XMLFactory類工廠說明它的定義及使用方法。類工廠需要向外輸出類的符號(hào)變量名,它通過庫的輸出符號(hào)變量定義來定義這些輸出的類名,XMLFactory類工廠的輸出的符號(hào)變量定義如下(在src/DRMPlugin/XMLFactory/XMLFactory.h中):#ifdefined(WIN32)#ifdefinedXMLFACTORY_EXPORTS#defineXMLFACTORY_EXPORT__declspec(dllexport)#else#defineXMLFACTORY_EXPORT__declspec(dllimport)#endif//XMLFACTORY_EXPORTS#elifdefined(LINUX)#defineXMLFACTORY_EXPORT#else#defineXMLFACTORY_EXPORT#endifXMLFactory類工廠的成員函數(shù)DecodeDocumentFromFile創(chuàng)建了IXMLDocument類的實(shí)例,其定義如下(在src/DRMPlugin/XMLFactory/XMLFactory.h中):namespaceDRMPlugin{classXMLFactory{public:staticXMLFACTORY_EXPORTIXMLDocument*DecodeDocumentFromFile(conststd::string&fname,DRMLogger&logger);}};}//namespaceDRMPlugin

XMLFactory類工廠的成員函數(shù)DecodeDocumentFromFile實(shí)現(xiàn)方法如下(在src/DRMPlugin/XMLFactory/XMLFactory.cpp中):IXMLDocument*XMLFactory::DecodeDocumentFromFile(conststd::string&fname,DRMLogger&logger){returnDecodeDocument(xml,logger);}IXMLDocument*XMLFactory::DecodeDocument(conststd::string&xml,DRMLogger&logger){try{returnnewXMLDocument(xml,logger);}catch(...){logger.UpdateLog("XMLFactory::DecodeDocument:unknownexception...");return0;}}

XMLFactory類工廠及具體的功能實(shí)現(xiàn)類都在目錄src/DRMPlugin/XMLFactory下,經(jīng)編譯生成庫libXMLFactory.la。這里使用了靜態(tài)庫,改變了類工廠的功能實(shí)現(xiàn)類,需要編譯靜態(tài)庫和應(yīng)用程序。但類工廠抽象出接口,每個(gè)類工廠完成一種類型的工作,這種抽象使程序結(jié)構(gòu)清晰。類工廠在應(yīng)用程序中的使用方法與一般的類一樣,XMLFactory類工廠在主函數(shù)main中的調(diào)用方法如下(在src\DRMPlugin\OMADRM\Test\OMADRMTest\Test.cpp中):intmain(intargc,char*argv[]){//Encodetest.DRMPlugin::IXMLDocument*encagentxml=XMLFactory::DecodeDocumentFromFile("OMADRMEncoderInfo.xml",logger);if(encagentxml==0){std::cout<<"Encodetestfailed!"<<std::endl;return-1;}if(encagentxml->GetRootElement()->AddChildElement("License")==0){deleteencagentxml;std::cout<<"Encodetestfailed!"<<std::endl;return-1;}}(4)類模板模板是實(shí)現(xiàn)代碼可重用性的一種方法,它將類型定義為參數(shù),模板實(shí)現(xiàn)的方法對(duì)參數(shù)指定的類型都適用。類模板將模板的參數(shù)類型定義為類,例如:類模板類模板的定義列出如下:template<typenameT>class類模板SPtr{public: SPtr<T>(T*p=0){ pointer=p;if(pointer!=0)pointer->UpCount(); }}3.3多線程類工廠ThreadSyncFactory(1)線程互斥鎖的類多線程共享數(shù)據(jù)時(shí)會(huì)使用線程互斥鎖。為了使用方便,OpenIPMP提供了互斥鎖的基類IMutex,將C庫的線程互斥鎖操作封裝為PThreadsMutex類,基類IMutex抽象了互斥鎖的行為,提供了互斥鎖操作的純虛函數(shù),類PThreadsMutex從基類IMutex繼承,重載了基類的函數(shù),用C庫的線程互斥鎖的操作函數(shù)實(shí)現(xiàn)這些重載函數(shù)?;怚Mutex的實(shí)現(xiàn)列出如下(在src\DRMPlugin\include\IThreadSync.h中):classThreadSyncException{//用于線程和同步對(duì)象的錯(cuò)誤,由語句throw使用};

classIMutex{public:virtual~IMutex(){}virtualboolLock(unsignedinttimeout)=0;//等待獲得互斥鎖,直到timeout超時(shí),獲得互斥鎖,返回truevirtualboolLock()=0;//無限期等待,直到獲得互斥鎖,獲得互斥鎖,返回truevirtualboolRelease()=0;//釋放互斥鎖,釋放成功返回true};

類PThreadsMutex從類IMutex繼承,重裝了類IMutex中的虛函數(shù)。類PThreadsMutex的實(shí)現(xiàn)列出如下(在src\DRMPlugin\ThreadSyncFactory\PThreadsThreadSync.h中):/*!線程使用的互斥鎖*/classPThreadsMutex:publicIMutex{public:/*!構(gòu)造函數(shù)*/PThreadsMutex(DRMLogger&logger);//創(chuàng)建互斥鎖,若失敗,給出ThreadSyncException信號(hào)

/*!析構(gòu)函數(shù)*/virtual~PThreadsMutex();virtualboolLock(unsignedinttimeout);virtualboolLock();virtualboolRelease();

private:DRMLogger&mutexLogger;pthread_mutex_tid;//線程互斥鎖};

PThreadsMutex::PThreadsMutex(DRMLogger&logger):id(),mutexLogger(logger){ pthread_mutexattr_tattr; pthread_mutexattr_init(&attr);//用默認(rèn)的屬性來初始化attr if(pthread_mutex_init(&id,&attr)!=0){//初始化互斥鎖idmutexLogger.UpdateLog("PThreadsMutex::ctor:cannotinitialize...");//記錄log信息throwThreadSyncException(); }}

PThreadsMutex::~PThreadsMutex(){if(pthread_mutex_destroy(&id)<0){//銷毀互斥鎖idmutexLogger.UpdateLog("PThreadsMutex::dtor:cannotdestroymutex...");throwThreadSyncException();}}

boolPThreadsMutex::Lock(unsignedinttimeout){returnLock();}

boolPThreadsMutex::Lock(){if(pthread_mutex_lock(&id)<0){//加線程鎖mutexLogger.UpdateLog("PThreadsMutex::Lock:cannotlock...");returnfalse;}returntrue;}

boolPThreadsMutex::Release(){if(pthread_mutex_unlock(&id)<0){//釋放線程鎖mutexLogger.UpdateLog("PThreadsMutex::Release:cannotrelease...");returnfalse;}returntrue;}(2)線程同步機(jī)制的類標(biāo)準(zhǔn)C庫提供了多線程之間同步機(jī)制的實(shí)現(xiàn)函數(shù),OpenIPMP為了使用方便,用類IEvent和其子類PThreadsEvent封裝了這些函數(shù)。基類IEvent定義了用虛函數(shù)定義了同步機(jī)制所需要的操作函數(shù),子類PThreadsEvent重載基類的函數(shù),利用C庫的函數(shù)實(shí)現(xiàn)線程的同步功能。類IEvent和其子類PThreadsEvent的實(shí)現(xiàn)分別列出如下:cclassIEvent{public:virtual~IEvent(){}

/*!等待事件通知,等待直到超時(shí)*/virtualboolWait(unsignedinttimeout)=0;/*!無限期地等待事件通知*/virtualboolWait()=0;/*!設(shè)置等待條件*/virtualboolSet()=0;/*!取消等待條件*/virtualboolUnset()=0;};

staticboolWaitForEvents(conststd::vector<IEvent*>&events){for(unsignedinti=0;i<events.size();i++){if(events[i]->Wait()==false){returnfalse;}}returntrue;}

classPThreadsEvent:publicIEvent{public:PThreadsEvent(DRMLogger&logger);//構(gòu)造函數(shù)

virtual~PThreadsEvent();//析構(gòu)函數(shù)virtualboolWait(unsignedinttimeout);virtualboolWait();virtualboolSet();virtualboolUnset();

private:DRMLogger&eventLogger;pthread_mutex_tmtex;pthread_cond_tcond;//線程等待的條件boolsignaled;//signaled表示條件滿足,不用再等待};

PThreadsEvent::PThreadsEvent(DRMLogger&logger):mtex(),cond(),signaled(false),eventLogger(logger){pthread_mutexattr_tattr;pthread_mutexattr_init(&attr);//初始化線程互斥鎖屬性值為缺省值if(pthread_mutex_init(&mtex,&attr)!=0){//初始化線程互斥鎖mtexeventLogger.UpdateLog("PThreadsEvent::ctor:cannotinitialize...");throwThreadSyncException();}pthread_condattr_tcattr;pthread_condattr_init(&cattr);//初始化一個(gè)條件變量屬性對(duì)象cattrif(pthread_cond_init(&cond,&cattr)!=0){//初始化一個(gè)條件變量condeventLogger.UpdateLog("PThreadsEvent::ctor:cannotinitialize...");throwThreadSyncException();//發(fā)出異常消息ThreadSyncException()}}

PThreadsEvent::~PThreadsEvent(){//析構(gòu)函數(shù),銷毀mtex和condif(pthread_mutex_destroy(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::ctor:cannotdestroymutex...");throwThreadSyncException();}if(pthread_cond_destroy(&cond)<0){eventLogger.UpdateLog("PThreadsEvent::ctor:cannotdestroyconditionvariable...");throwThreadSyncException();}}/*線程等待條件cond滿足,直到超時(shí)*/boolPThreadsEvent::Wait(unsignedinttimeout){//timeout為ms單位if(pthread_mutex_lock(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::Wait:cannotlockmutex...");returnfalse;}if(signaled==true){//signaled表示條件滿足,不用再等待return(pthread_mutex_unlock(&mtex)>=0);}structtimevalnow;structtimezonezone;structtimespectout;gettimeofday(&now,&zone);//得到當(dāng)前的時(shí)間和本地的時(shí)區(qū)tout.tv_sec=now.tv_sec+(timeout/1000);tout.tv_nsec=(now.tv_usec+(timeout%1000)*1000)*1000;//轉(zhuǎn)換成ns單位if(pthread_cond_timedwait(&cond,&mtex,&tout)!=0){//條件等待直到超時(shí)//eventLogger.UpdateLog("PThreadsEvent::Wait:waitfailed...");pthread_mutex_unlock(&mtex);returnfalse;}if(pthread_mutex_unlock(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::Wait:cannotunlockmutex...");returnfalse;}returntrue;}

boolPThreadsEvent::Wait(){if(pthread_mutex_lock(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::Wait:cannotlockmutex...");returnfalse;}if(signaled==true){//signaled表示條件滿足,不用再等待return(pthread_mutex_unlock(&mtex)>=0);}if(pthread_cond_wait(&cond,&mtex)!=0){//線程睡眠直到特定條件cond發(fā)生//eventLogger.UpdateLog("PThreadsEvent::Wait:waitfailed...");pthread_mutex_unlock(&mtex);returnfalse;}if(pthread_mutex_unlock(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::Wait:cannotunlockmutex...");returnfalse;}returntrue;}

/*線程等待條件滿足,設(shè)置signaled為true,并喚醒睡眠的線程*/boolPThreadsEvent::Set(){if(pthread_mutex_lock(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::Set:cannotlockmutex...");returnfalse;}signaled=true;//signaled表示條件滿足,不用再等待if(pthread_mutex_unlock(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::Set:cannotunlockmutex...");returnfalse;}if(pthread_cond_broadcast(&cond)!=0){//條件cond滿足,喚醒所有掛起的線程eventLogger.UpdateLog("PThreadsEvent::Set:broadcastfailed...");returnfalse;}returntrue;}

/*設(shè)置signaled為false,表示線程等待條件不滿足,需要等待線程等待條件的滿足*/boolPThreadsEvent::Unset(){if(pthread_mutex_lock(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::Unset:cannotlockmutex...");returnfalse;}signaled=false;//signaled為true時(shí),表示條件滿足,不用再等待if(pthread_mutex_unlock(&mtex)<0){eventLogger.UpdateLog("PThreadsEvent::Unset:cannotunlockmutex...");returnfalse;}returntrue;}(3)線程類OpenIPMP將標(biāo)準(zhǔn)C庫中線程的創(chuàng)建與運(yùn)行封裝成類PThreadsThread,方便了程序使用創(chuàng)建線程。類PThreadsThread及它所繼承的基類IThread列出如下:classIThread{public:virtual~IThread(){}};

classPThreadsThread:publicIThread{public:/*構(gòu)造函數(shù)PThreadsThread創(chuàng)建線程,沒有安全屬性,使用缺省的堆棧屬性,并立即啟動(dòng)線程。其參數(shù)start是線程啟動(dòng)的功能函數(shù),參數(shù)par線程功能函數(shù)的參數(shù),參數(shù)logger是用于讀寫log信息的類對(duì)象*/PThreadsThread(void(*start)(void*),void*par,DRMLogger&logger);virtual~PThreadsThread();

private:pthread_thandle;};

構(gòu)造函數(shù)PThreadsThread創(chuàng)建線程,運(yùn)行功能函數(shù),其列出如下:PThreadsThread::PThreadsThread(void(*start)(void*),void*par,DRMLogger&logger):handle(){pthread_attr_ttype;if(pthread_attr_init(&type)!=0){//初始化線程屬性為缺省值logger.UpdateLog("PThreadsThread::ctor:cannotinitialize...");throwThreadSyncException();}PThreadParams*pars=newPThreadParams();pars->start=start;pars->par=par;//創(chuàng)建線程,線程運(yùn)行功能函數(shù),運(yùn)行完后,線程退出if(pthread_create(&handle,&type,PThreadRun,pars)!=0){logger.UpdateLog("PThreadsThread::ctor:cannotcreatethread...");deletepars;//銷毀對(duì)象throwThreadSyncException();}}

PThreadsThread::~PThreadsThread(){//析構(gòu)函數(shù)}

結(jié)構(gòu)PThreadParams封閉了線程運(yùn)行函數(shù)的參數(shù),通過它可將函數(shù)PThreadRun的參數(shù)解析為一個(gè)函數(shù)和參數(shù),其列出如下:structPThreadParams{void(*start)(void*);void*par;};

函數(shù)PThreadRun是線程運(yùn)行函數(shù),它執(zhí)行具體的功能函數(shù),執(zhí)行完后,退出線程。這里使用線程運(yùn)行函數(shù)嵌套執(zhí)行具體的功能函數(shù),是為了將線程處理與功能函數(shù)完全分開,功能函數(shù)不必考慮線程的處理。函數(shù)PThreadRun列出如下:staticvoid*PThreadRun(void*par){PThreadParams*str=(PThreadParams*)par;void(*tstart)(void*)=str->start;void*tpar=str->par;tstart(tpar);//運(yùn)行線線程功能函數(shù)deletestr;pthread_exit(0);//功能函數(shù)運(yùn)行完后退出線程return0;}線程類工廠ThreadSyncFactoryWindow和Linux平臺(tái)上線程實(shí)現(xiàn)調(diào)用的函數(shù)是不一樣的,線程類工廠ThreadSyncFactory屏蔽了這種實(shí)現(xiàn)的差異性,向外提供了統(tǒng)一的接口?;コ怄i、事件及線程都抽象出了基類,然后分別用從基類繼承的子類實(shí)現(xiàn)標(biāo)準(zhǔn)C庫線程的功能,線程類工廠ThreadSyncFactory向外公開的接口函數(shù)返回類型都是基類的類型,這樣,屏蔽了類的具體實(shí)現(xiàn)方法,統(tǒng)一了接口。類工廠還把它所包含的類的異常信息捕捉下來,統(tǒng)一在類工廠中由catch語句進(jìn)行處理,這樣,具體的類不必關(guān)心如何處理log信息。因此,類工廠的主要作用是向外提供統(tǒng)一的接口,管理具體的類實(shí)現(xiàn),抽象具體的類共有的特性。具體的類完成著指定的功能。改變具體的類后,只要類工廠不變,調(diào)用類工廠的應(yīng)用程序就不用改變。這較好地實(shí)現(xiàn)了程序的分層。類工廠ThreadSyncFactory的定義列出如下(在src\DRMPlugin\ThreadSyncFactory\ThreadSyncFactory.h中):classThreadSyncFactory{public:/*!創(chuàng)建線程互斥鎖類對(duì)象,創(chuàng)建成功,返回類對(duì)象,創(chuàng)建失敗,返回0。創(chuàng)建的類對(duì)象是Imutex的子類對(duì)象,返回的是基類的類型,這屏蔽了子類的差異性,統(tǒng)一了接口*/staticTHREADSYNCFACTORY_EXPORTIMutex*GetMutex(DRMLogger&logger);

/*!創(chuàng)建全局的互斥鎖類對(duì)象*/staticTHREADSYNCFACTORY_EXPORTIMutex*GetGlobalMutex();

/*!創(chuàng)建線程的事件對(duì)象*/staticTHREADSYNCFACTORY_EXPORTIEvent*GetEvent(DRMLogger&logger);

/*!創(chuàng)建線程對(duì)象*/staticTHREADSYNCFACTORY_EXPORTIThread*GetThread(void(*start)(void*),void*par,DRMLogger&logger);};

類工廠ThreadSyncFactory的實(shí)現(xiàn)列出如下(在src\DRMPlugin\ThreadSyncFactory\ThreadSyncFactory.cpp中):IMutex*ThreadSyncFactory::GetMutex(DRMLogger&logger){try{returnnewPThreadsMutex(logger);}catch(ThreadSyncException){return0;}catch(...){//捕捉所有語句throw給出的異常信息logger.UpdateLog("ThreadSyncFactory::GetMutex:unknownexception...");return0;}}

IMutex*ThreadSyncFactory::GetGlobalMutex(){try{returnnewPThreadsGlobalMutex();}catch(ThreadSyncException){return0;}catch(...){return0;}}

IEvent*ThreadSyncFactory::GetEvent(DRMLogger&logger){try{returnnewPThreadsEvent(logger);//創(chuàng)建線程事件對(duì)象}catch(ThreadSyncException){return0;}catch(...){//捕捉所有語句throw給出的異常信息logger.UpdateLog("ThreadSyncFactory::GetEvent:unknownexception...");return0;}}

IThread*ThreadSyncFactory::GetThread(void(*start)(void*),void*par,DRMLogger&logger){try{returnnewPThreadsThread(start,par,logger);//創(chuàng)建線程}catch(ThreadSyncException){return0;}catch(...){//捕捉所有語句throw給出的異常信息logger.UpdateLog("ThreadSyncFactory::GetThread:unknownexception...");return0;}}

4用類工廠封裝PKI4.1XML類工廠XMLFactoryOMADRM在使用ROAP(RightObjectAcquisitionProtocol)申請(qǐng)權(quán)利對(duì)象以及使用OCSP(OnlineCertificateStatusProtocol)進(jìn)行證書狀態(tài)驗(yàn)證時(shí),協(xié)議消息使用XML(ExtensibleMarkupLanguage)格式進(jìn)行描述。XML的功能是描述內(nèi)容的數(shù)據(jù)形式和結(jié)構(gòu),被廣泛用于與網(wǎng)頁瀏覽器相關(guān)的協(xié)議的數(shù)據(jù)傳輸和交互。DOM(DocumentObjectModel,文檔對(duì)象模型)是W3C組織制定的規(guī)范,用于標(biāo)準(zhǔn)HTML和XML文檔的編程接口,是詳細(xì)描述HTML/XML文件對(duì)象規(guī)則的API,將網(wǎng)頁和腳本或編程語言連接了起來。它定義了HTML或XML檔的邏輯結(jié)構(gòu)以及訪問操作這些文檔的方法。它將文檔的邏輯結(jié)構(gòu)定義由節(jié)點(diǎn)組成的樹形結(jié)構(gòu),程序通過遍歷樹的節(jié)點(diǎn),可以增、刪、改節(jié)點(diǎn)及內(nèi)容。DOM規(guī)范只定義了操作HTML/XML文檔的接口,而沒有指定實(shí)現(xiàn)這些接口的方法。Xerces-C庫是ApacheSoftwareFoundation提供的C++函數(shù)庫,是XML分析器,提供了讀寫XML文檔的API函數(shù)。它符合于XML1.1規(guī)范和DOMLevel2CoreSpecification規(guī)范。OpenIPMP使用類工廠XMLFactory分別定義了基類IXMLAttribute、IXMLElement和IXMLDocument抽象出XML文檔的元素屬性、元素和XML文檔的操作函數(shù),使用了分別從這些基類繼承的子類XMLAttribute、XMLElement和XMLDocument,封裝了Xerces-C庫中的類DOMParser、DOM_Document、DOM_Node、DOM_Element和DOM_Attr,完成對(duì)XML文檔的具體讀寫操作。類工廠XMLFactory提供了對(duì)類XMLAttribute、XMLElement和XMLDocument的管理及向外的統(tǒng)一接口。xercesc庫源代碼可從/xerces-c/download.cgi下載,其API函數(shù)使用方法請(qǐng)參考xercesc庫源代碼所帶的文檔說明。下面僅列出XMLFactory類的實(shí)現(xiàn)和XMLDocument的構(gòu)造函數(shù)。類工廠XMLFactory的定義列出如下(在src\DRMPlugin\XMLFactory\XMLFactory.h中):classXMLFactory{public:/*!用給定名字的根節(jié)點(diǎn)創(chuàng)建一個(gè)新的XML文檔。參數(shù)name為根節(jié)點(diǎn)名,也是文檔的名字,參數(shù)logger為記錄log信息的類對(duì)象。創(chuàng)建成功返回新的XML文檔,創(chuàng)建失敗返回0*/staticXMLFACTORY_EXPORTIXMLDocument*CreateDocument(conststd::string&name,DRMLogger&logger);/*!從一個(gè)編碼的XML字符串創(chuàng)建新XML文檔。參數(shù)xml為編碼的XML字符串*/staticXMLFACTORY_EXPORTIXMLDocument*DecodeDocument(conststd::string&xml,DRMLogger&logger);/*!從一個(gè)文件創(chuàng)建新XML文檔*/staticXMLFACTORY_EXPORTIXMLDocument*DecodeDocumentFromFile(conststd::string&fname,DRMLogger&logger);};類工廠XMLFactory的實(shí)現(xiàn)列出如下(在src\DRMPlugin\XMLFactory\XMLFactory.cpp中):IXMLDocument*XMLFactory::CreateDocument(conststd::string&name,DRMLogger&logger){try{returnnewXMLDocument("<"+name+"></"+name+">",logger);}catch(...){logger.UpdateLog("XMLFactory::CreateDocument:unknownexception...");return0;}}

IXMLDocument*XMLFactory::DecodeDocument(conststd::string&xml,DRMLogger&logger){try{returnnewXMLDocument(xml,logger);}catch(...){logger.UpdateLog("XMLFactory::DecodeDocument:unknownexception...");return0;}}IXMLDocument*XMLFactory::DecodeDocumentFromFile(conststd::string&fname,DRMLogger&logger){FILE*fp=fopen(fname.data(),"rb");//打開文件if(fp==NULL){logger.UpdateLog("XMLFactory::DecodeDocumentFromFile:cannotopen"+fname+"...");return0;}structstattstat;stat(fname.data(),&tstat);char*xmlText=(char*)malloc(tstat.st_size+1);fread(xmlText,tstat.st_size,1,fp);//讀取文件到緩存xmlText xmlText[tstat.st_size]='\0';fclose(fp);std::stringxml=xmlText;free(xmlText);returnDecodeDocument(xml,logger);//由xmlText字符串構(gòu)建XML文檔對(duì)象}類XMLDocument定義如下(在src\DRMPlugin\XMLFactory\XMLDocument.h中):classXMLDocument:publicIXMLDocument{public:/*!構(gòu)造函數(shù),參數(shù)xml為編碼的XML字符串*/XMLDocument(conststd::string&xml,DRMLogger&logger);virtual~XMLDocument();

/*!得到根元素*/virtualIXMLElement*GetRootElement();

/*!編譯成字符串*/virtualstd::stringEncode();

private:IXMLElement*root;DOMParser*parser;//xercesc庫的類,是XML文檔分析器,封裝了各種解析函數(shù)DOM_Documentdoc;//xercesc庫的類,代表了XML文檔DRMLogger&docLogger;};類XMLDocument構(gòu)造函數(shù)通過參數(shù)xml字符串構(gòu)建DOM_Document對(duì)象,解析出節(jié)點(diǎn)樹,得到根節(jié)點(diǎn)root,這樣,通過遍歷節(jié)點(diǎn)樹,可對(duì)DOM_Document對(duì)象進(jìn)行讀寫操作。其列出如下:XMLDocument::XMLDocument(conststd::string&xml,DRMLogger&logger):root(0),parser(0),doc(),docLogger(logger){try{MemBufInputSourcebyteInput((constXMLByte*const)xml.data(),(constunsignedint)xml.size(),(char*const)"xmldocument");parser=newDOMParser();parser->parse(byteInput);doc=parser->getDocument();DOM_Elementelem=doc.getDocumentElement();root=newXMLElement(elem,docLogger);//根節(jié)點(diǎn)元素}catch(...){docLogger.UpdateLog("XMLDocument::ctor:xerceserror...");if(parser!=0)deleteparser;throwXMLException();}}4.2公鑰加密工廠PublicCryptoFactory類工廠PublicCryptoFactory是管理PKI公鑰加密的各種算法的管理器,它屏蔽了算法的實(shí)現(xiàn)細(xì)節(jié),對(duì)應(yīng)用程序提供了統(tǒng)一的接口。例如:對(duì)于Hash算法,OpenIPMP在src\DRMPlugin\include\IPublicCrypto.h文件中定義了基類IHasher,其他具體的Hash算法對(duì)應(yīng)的類從它繼承,如:SHA1OpenSSLHasher。不管具體的Hash算法類如何實(shí)現(xiàn),類工廠PublicCryptoFactory的函數(shù)可以返回IHasher類型指針指向具體的Hash算法類對(duì)象。類工廠PublicCryptoFactory提供了Hash算法、簽名、證書驗(yàn)證等與公鑰相關(guān)的算法類,其定義列出如下(在src\DRMPlugin\PublicCryptoFactory\PublicCryptoFactory.h中):classPublicCryptoFactory{public:/*!創(chuàng)建MD5Hash算法的類對(duì)象*/staticPUBLICCRYPTOFACTORY_EXPORTIHasher*GetMD5Hasher(DRMLogger&logger);/*!創(chuàng)建SHA1Hash算法的類對(duì)象*/staticPUBLICCRYPTOFACTORY_EXPORTIHasher*GetSHA1Hasher(DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從密鑰數(shù)據(jù)中分析公鑰解密器,參數(shù)data為輸入的數(shù)據(jù),datalen為數(shù)據(jù)長度*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicDecryptor*ParsePublicDecryptorFromKeyData(ByteT*data,unsignedintdatalen,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從密鑰數(shù)據(jù)中分析公鑰簽名*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicSigner*ParsePublicSignerFromKeyData(ByteT*data,unsignedintdatalen,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從密鑰數(shù)據(jù)中分析公鑰解密器和簽名*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicDecryptorSigner*ParsePublicDecryptorSignerFromKeyData(ByteT*data,unsignedintdatalen,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,從密鑰文件中分析公鑰解密器,參數(shù)fname為文件路徑名*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicDecryptor*ParsePublicDecryptorFromKeyFile(conststd::string&fname,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從密鑰文件中分析簽名*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicSigner*ParsePublicSignerFromKeyFile(conststd::string&fname,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從密鑰文件中分析公鑰解密器和簽名*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicDecryptorSigner*ParsePublicDecryptorSignerFromKeyFile(conststd::string&fname,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于證書驗(yàn)證*/staticPUBLICCRYPTOFACTORY_EXPORTICertVerifier*GetCertificateVerifier(DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從證書數(shù)據(jù)中分析公鑰加密器證書*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicEncryptorCertificate*ParsePublicEncryptorCertificateFromData(ByteT*data,unsignedintdatalen,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從證書文件中分析公鑰加密器證書*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicEncryptorCertificate*ParsePublicEncryptorCertificateFromFile(conststd::string&fname,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從證書數(shù)據(jù)中分析公鑰驗(yàn)證器證書*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicVerifierCertificate*ParsePublicVerifierCertificateFromData(ByteT*data,unsignedintdatalen,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從證書文件中分析公鑰驗(yàn)證器證書*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicVerifierCertificate*ParsePublicVerifierCertificateFromFile(conststd::string&fname,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從證書數(shù)據(jù)中分析公鑰加密器和驗(yàn)證器證書*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicEncryptorVerifierCertificate*ParsePublicEncryptorVerifierCertificateFromData(ByteT*data,unsignedintdatalen,DRMLogger&logger);/*!創(chuàng)建類對(duì)象,用于從證書文件中分析公鑰加密器和驗(yàn)證器證書*/staticPUBLICCRYPTOFACTORY_EXPORTIPublicEncryptorVerifierCertificate*ParsePublicEncryptorVerifierCertificateFromFile(conststd::string&fname,DRMLogger&logger);};OpenIPMP采用openssl庫作為它的密碼算法庫,OpenIPMP用類封裝了各種公鑰算法,它們封裝方法類似,下面僅列出MD5hash算法的類封裝實(shí)現(xiàn)。類工廠PublicCryptoFactory的函數(shù)GetMD5Hasher創(chuàng)建一個(gè)hash算法類實(shí)例返回。該類實(shí)例的hash計(jì)算函數(shù)Hashe調(diào)用openssl的摘要計(jì)算接口函數(shù)。函數(shù)GetMD5Hasher列出如下(在src\DRMPlugin\PublicCryptoFactory\PublicCryptoFactory.cpp中):IHasher*PublicCryptoFactory::GetMD5Hasher(DRMLogger&logger){returnnewMD5OpenSSLHasher();}類MD5OpenSSLHasher封裝了hash算法,用于計(jì)算數(shù)據(jù)序列的摘要,其定義列出如下(在src\DRMPlugin\PublicCryptoFactory\OpenSSLPublicCrypto.h中):classMD5OpenSSLHasher:publicIHasher{public:virtual~MD5OpenSSLHasher(){}

/*計(jì)算摘要,參數(shù)data為需要hash計(jì)算的字節(jié)序列,hash為計(jì)算結(jié)果的字節(jié)序列*/virtualboolHash(constByteSeq&data,ByteSeq&hash);};MD5hash算法函數(shù)Hash調(diào)用openssl庫的EVP加密算法接口函數(shù)EVP_Digest來實(shí)現(xiàn)摘要計(jì)算,計(jì)算的結(jié)果封裝成類ByteSeq實(shí)例,通過函數(shù)Hash的參數(shù)hash返回。函數(shù)Hash列出如下(在src\DRMPlugin\PublicCryptoFactory\OpenSSLPublicCrypto.cpp中):boolMD5OpenSSLHasher::Hash(constByteSeq&data,ByteSeq&hash){/*ByteT定義為unsignedchar類型*/ByteT*hhash=(ByteT*)malloc(EVP_md5()->md_size);if(hhash==NULL){returnfalse;}intret=1;unsignedinthashlen=0;/*調(diào)用openssl庫的接口函數(shù)EVP_Digest計(jì)算摘要*//*(void*)data.GetFirst()得到字節(jié)數(shù)組的第一個(gè)字節(jié)地址,即得到字節(jié)串的起始地址*/ret=EVP_Digest((void*)data.GetFirst(),(unsignedint)data.GetLength(),hhash,&hashlen,EVP_md5(),/*ENGINE*impl*/0);if(ret!=1){free(hhash);returnfalse;}hash=ByteSeq(hhash,hashlen);//創(chuàng)建字節(jié)序列類ByteSeq實(shí)例free(hhash);

returntrue;}4.3Base64類工廠Base64FactoryBase64類工廠Base64Factory封裝了Base64編碼和解碼算法,OpenIPMP自己實(shí)現(xiàn)了Base64的編碼/解碼算法。類工廠Base64Factory定義列出如下(在src\DRMPlugin\Base64Factory\Base64Factory.h中):classBase64Factory{public:/*Base64編碼算法,參數(shù)data為輸入的字節(jié)流,參數(shù)b64為編碼后的字節(jié)流*/staticboolEncode(constByteSeq&data,Base64StringT&b64);

/*Base64解碼算法,參數(shù)b64為輸入的Base64字節(jié)流,參數(shù)data為輸出的解碼字節(jié)流*/staticboolDecode(constBase64StringT&b64,ByteSeq&data);};4.4密碼算法類工廠CipherFactory密碼算法類工廠CipherFactory管理隨機(jī)器產(chǎn)生器和各種對(duì)稱密碼算法,封裝了Crypto++庫的密碼算法函數(shù)。其列出如下(在src\DRMPlugin\CipherFactory\CipherFactory.h中):classCipherFactory{public:/*產(chǎn)生用于密碼短語的隨機(jī)數(shù),存放隨機(jī)數(shù)的緩沖區(qū)由這個(gè)函數(shù)分配*/staticboolRndGenerate(UInt32Tpassphrase,ByteT**k,UInt32Tklen);

/*產(chǎn)生隨機(jī)數(shù),存放隨機(jī)數(shù)的緩沖區(qū)由這個(gè)函數(shù)分配*/staticboolRndGenerate(ByteT**k,UInt32Tklen);

/*得到新創(chuàng)建的blowfish加密器對(duì)象*/staticBlowfishEncryptor*GetBlowfishEncryptor(ByteT*k,UInt32TkSize,DRMLogger&logger);

/*得到新創(chuàng)建的AES128CBC加密器對(duì)象*/staticAES128CBCEncryptor*GetAES128CBCEncryptor(ByteT*k,UInt32TkSize,ByteT*iv,DRMLogger&logger);

/*得到新創(chuàng)建的AES128CTR加密器對(duì)象*/staticAES128CTREncryptor*GetAES128CTREncryptor(ByteT*k,UInt32TkSize,ByteT*iv,DRMLogger&logger);

/*得到新創(chuàng)建的AES128ICM加密器對(duì)象*/staticAES128ICMEncryptor*GetAES128ICMEncryptor(ByteT*k,UInt32TkSize,DRMLogger&logger);

/*得到新創(chuàng)建的blowfish解密器對(duì)象*/staticBlowfishDecryptor*GetBlowfishDecryptor(ByteT*k,UInt32TkSize,DRMLogger&logger);

/*得到新創(chuàng)建的AES128CBC解密器對(duì)象*/staticAES128CBCDecryptor*GetAES128CBCDecryptor(ByteT*k,UInt32TkSize,DRMLogger&logger);

/*得到新創(chuàng)建的AES128CTR解密器對(duì)象*/staticAES128CTRDecryptor*GetAES128CTRDecryptor(ByteT*k,UInt32TkSize,DRMLogger&logger);

/*得到新創(chuàng)建的AES128ICM解密器對(duì)象*/staticAES128ICMDecryptor*GetAES128ICMDecryptor(ByteT*k,UInt32TkSize,DRMLogger&logger);};密碼算法類工廠CipherFactory的密碼算法函數(shù)封裝了Crypto++庫的函數(shù),下面僅說明AES算法的實(shí)現(xiàn)。Crypto++是一個(gè)用標(biāo)準(zhǔn)C++編寫的密碼類庫開放源代碼軟件,實(shí)現(xiàn)了各種公鑰算法、對(duì)稱加密算法、數(shù)字簽名算法、信息摘要算法以及其相關(guān)的其它密碼算法等。AES對(duì)稱密碼算法包括ECB、CBC、CFB、OFB和CTR幾種工作模式,AES對(duì)稱密碼算法采用標(biāo)準(zhǔn)的Rijndael算法,CBC模式AES加密算法用類CPPAES128CBCEncryptor進(jìn)行封裝。類CPPAES128CBCEncryptor使用了Crypto++庫的Rijndael算法加密類CBC_Mode<CryptoPP::Rijndael>::Encryption實(shí)現(xiàn)加密算法,其列出如下(在src\DRMPlugin\CipherFactory\BlockCipher.h中):classCPPAES128CBCEncryptor:publicAES128CBCEncryptor{public:/*構(gòu)造函數(shù),參數(shù)k為密鑰,參數(shù)kSize為密鑰大小,參數(shù)i為初始化向量,參數(shù)logger為消息日志,如果失敗,會(huì)拋出異常CipherException*/CPPAES128CBCEncryptor(ByteT*k,UInt32TkSize,ByteT*i,DRMLogger&logger);

virtual~CPPAES128CBCEncryptor();

/*加密字符串,參數(shù)in為輸入的字符串,參數(shù)inSize為輸入字符串大小,參數(shù)out為加密后輸出的字符串,參數(shù)outLen為加密字符串的大小,加密成功時(shí),函數(shù)返回true,否則返回false*/ virtualboolEncrypt(ByteT*in,UInt32TinSize,ByteT**out,UInt32T*outLen);

/*得到用于下一個(gè)包加密的初始化向量IV。參數(shù)par為輸出的初始化向量,參數(shù)parLen為初始化向量長度*/ virtualboolNextIV(ByteT**par,UInt32T*parLen);

private: ByteT*key;//密鑰UInt32TkeySize;//密鑰大小 ByteT*iv;//IV向量//CBC模式,標(biāo)準(zhǔn)AES的Rijndael算法,CryptoPP為命名空間CryptoPP::CBC_Mode<CryptoPP::Rijndael>::Encryptionenc; /*這里用std::string,因?yàn)椴荒艽_信需要多大緩沖區(qū)用于填充*/ std::stringencData;/*流過濾器StreamTransformationFilter對(duì)工作模式CBC進(jìn)行包裝,需要時(shí)流過濾器將緩沖區(qū)數(shù)據(jù)阻塞*/ CryptoPP::StreamTransformationFilterfilter;};構(gòu)造函數(shù)CPPAES128CBCEncryptor創(chuàng)建CBC模式Rijndael算法加密對(duì)象enc,創(chuàng)建流過濾器對(duì)象,設(shè)置加密數(shù)據(jù)輸出變量encData,設(shè)置密鑰和IV向量。其列出如下(src\DRMPlugin\CipherFactory\BlockCipher.cpp):CPPAES128CBCEncryptor::CPPAES128CBCEncryptor(ByteT*k,UInt32TkSize,ByteT*i,DRMLogger&logger):key(k),keySize(kSize),iv(i),enc(),encData(),filter(enc,newCryptoPP::StringSink(encData),//將encData將加密數(shù)據(jù)輸出#ifdefined(WIN32)CryptoPP::StreamTransformationFilter::BlockPaddingScheme::PKCS_PADDING){#elifdefined(LINUX)CryptoPP::StreamTransformationFilter::PKCS_PADDING){#elseCryptoPP::StreamTransformationFilter::PKCS_PADDING){#endif

if(kSize!=16){if(key!=0)free(key);key=0;if(iv!=0)free(iv);iv=0;logger.UpdateLog("CPPAES128CBCEncryptor::ctor:wrongkeysize.");throwCipherException();} enc.SetKeyWithIV((unsignedchar*)key,keySize,(unsignedchar*)iv);//設(shè)置密鑰和IV向量}函數(shù)Encrypt對(duì)字符串進(jìn)行加密計(jì)算,并返回加密的字符串。其列出如下:boolCPPAES128CBCEncryptor::Encrypt(ByteT*in,UInt32TinSize,ByteT**out,UInt32T*outLen){ encData=""; filter.Put((unsignedchar*)in,inSize);//對(duì)輸入進(jìn)行處理,然后調(diào)用加密對(duì)象對(duì)字符串進(jìn)行加密 filter.MessageEnd();//輸入的結(jié)束性標(biāo)志 enc.Resynchronize((unsignedchar*)iv); enc.GetNextIV((unsignedchar*)iv);//得到下一個(gè)IV,用于計(jì)算下一個(gè)包 enc.SetKeyWithIV((unsignedchar*)key,keySize,(unsignedchar*)iv);//設(shè)置密鑰的IV

*out=(ByteT*)malloc(encData.size());if(*out==NULL){returnfalse;}memcpy(*out,encData.c_str(),encData.size());//拷貝加密的字符串*outLen=encData.size();returntrue;}5ROAP消息處理5.1權(quán)利對(duì)象RO的類描述OMADRM的域RO可以被分開發(fā)送,權(quán)利發(fā)布者對(duì)請(qǐng)求的ROAP回應(yīng)消息含有權(quán)利描述,域的權(quán)利描述樣例列出如下:<roap:protectedROxmlns:roap="urn:oma:bac:dldrm:roap-1.0"http://xmlns:roap表示定義的命名空間roapxmlns:ds="/2000/09/xmldsig#"http://表示ds所在命名空間為文件xmldsigxmlns:xenc="/2001/04/xmlenc#"xmlns:o-ex="/1.1/ODRL-EX"xmlns:o-dd="/1.1/ODRL-DD"xmlns:xsi="/2001/XMLSchema-instance"><rightso-ex:id="REL1"><o-ex:context><o-dd:version>2.0</o-dd:version>//類ODDVersion<o-dd:uid>RightsObjectID</o-dd:uid>//類RightsODDUID</o-ex:context><o-ex:agreement><o-ex:asset><o-ex:context><o

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論