メインページ | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkcSafeFileSystem.c

説明を見る。
00001 
00008 #include "dkcSafeFileSystem.h"
00009 #include "dkcMath.h"
00010 #include "dkcStdio.h"
00011 
00012 static DKC_INLINE int HeaderWrite(DKC_STREAM *p,DKC_FILE_HEADER_FILE_WITH_SIGNATURE  *header)
00013 {
00014     BYTE isLE = (BYTE)dkcIsLittleEndian();
00015     if(header->little_endian != isLE)
00016     {//ココバグっているかも・・・。
00017         header->sig = dkcReverseEndian32(header->sig);
00018         header->filesize = dkcReverseEndian64(header->filesize);
00019     }
00020     return dkcStreamWrite(p,header,sizeof(DKC_FILE_HEADER_FILE_WITH_SIGNATURE));
00021 }
00022 
00023 
00024 static DKC_INLINE int GetHeader(
00025     DKC_FILE_HEADER_FILE_WITH_SIGNATURE *header,
00026     const char *filename)
00027 {
00028     size_t readsize = 0;
00029     size_t mustsize = sizeof(DKC_FILE_HEADER_FILE_WITH_SIGNATURE);
00030     int r = edk_FAILED;
00031     FILE *fp = NULL;
00032     BYTE isLE = (BYTE)dkcIsLittleEndian();
00033     //BYTE get_flag;
00034     const char *mode = "rb";
00035 
00036     fp = dkcFOpen(filename,mode);
00037     if(NULL==fp){
00038         goto Exit;
00039     }
00040     fseek(fp,0,SEEK_SET);
00041     //readsize = fread(header,1,mustsize,fp);
00042     readsize = dkcFReadAll(header,mustsize,fp);
00043     if(mustsize != readsize){
00044         goto Exit;
00045     }
00046 
00047     if(header->little_endian != isLE)
00048     {//エンディアンが違ったらリバース
00049         header->sig = dkcReverseEndian32(header->sig);
00050         header->filesize = dkcReverseEndian64(header->filesize);
00051     }
00052 
00053     
00054     r = edk_SUCCEEDED;
00055 Exit:
00056     dkcFClose(&fp);
00057     return r;
00058     /*
00059     DKC_STREAM *fsp;
00060 
00061     //読み込み時
00062     fsp = dkcAllocStreamFileType(edkcStreamRead,filename,mode);
00063     if(NULL==fsp){
00064         return edk_FAILED;
00065     }
00066     r = dkcStreamRead(fsp,header,mustsize,&readsize);
00067     if(DKUTIL_FAILED(r)){
00068         return r;
00069     }
00070     if(readsize != mustsize){
00071         return edk_FAILED;
00072     ]
00073     dkcFreeStream(&fsp);
00074     */
00075 }
00076 
00077 
00078 //flagにはエンディアンを
00079 /*
00080 int WINAPI dkcFileWithSignatureCheckCheatFile(UINT flag,const char *filename){
00081     //チェックオブジェクト
00082     DKC_STREAM *sp;
00083     DKC_SHA1 *sha;
00084     //戻り値
00085     int r;
00086     //バッファとか
00087     BYTE buff[2048];
00088     size_t i;
00089 
00090     flag |= edkcStreamProcessAsOrdered;
00091     
00092     sp = dkcAllocStreamFileType(flag,filename,"rb");
00093     
00094     if(NULL==sp){
00095         return edk_FAILED;
00096     }
00097     sha = dkcAllocSHA1();
00098     if(NULL==sha){
00099         goto Exit;
00100     }
00101     
00102     dkcStreamRead(sp,buff,sizeof(buff),
00103 Exit:
00104     dkcFreeSHA1(&sha);
00105     dkcFreeStream(&sp);
00106     return r;
00107 }*/
00108 
00109 #ifdef _MSC_VER
00110 #   pragma warning(disable:4701)
00111 #endif
00112 
00113 DKC_FILE_WITH_SIGNATURE *WINAPI dkcOpenFileWithSignature(
00114 /*
00115     UINT flag,size_t size,
00116     const char *filename,const char *mode,
00117     const void *dustbin,size_t dustbin_size
00118 */
00119     UINT stream_flag,
00120     const char *filename,const char *mode,
00121     const void *dustbin,size_t dustbin_size,
00122     UINT signature
00123 )
00124 {
00125     DKC_STREAM *sp = NULL;
00126     void *tp = NULL;
00127     DKC_BUFFER *mbp = NULL;
00128     DKC_FILE_WITH_SIGNATURE *p = NULL;
00129     
00130     DKC_FILE_HEADER_FILE_WITH_SIGNATURE header;
00131 
00132     BOOL isWrite = FALSE;
00133     BYTE isLE = (BYTE)dkcIsLittleEndian();
00134 
00135     //UINT stream_flag = edkcStreamInitFile;
00136     
00137     //フラグの変更
00138     stream_flag |= edkcStreamInitFile;
00139     
00140     DKUTIL_FLAG_DOWN(stream_flag,edkcStreamInitMemory);
00141     
00142     DKUTIL_FLAG_DOWN(stream_flag,edkcStreamProcessDefault);
00143 
00144     DKUTIL_FLAG_UP(stream_flag,edkcStreamProcessAsOrdered);
00145 
00146     //size_t stream_size;
00147 
00148 
00149     //エラーチェック
00150     if(NULL==dustbin ||  0 == dustbin_size){
00151         return NULL;
00152     }
00153 
00154     if(NULL==mode || NULL==filename){
00155         return NULL;
00156     }
00157     if(NULL != strchr(mode,'a')){//共通モードでは開けない
00158         return NULL;
00159     }
00160     if(NULL != strchr(mode,'t')){//テキストモードでは開けない。
00161         return NULL;
00162     }
00163 
00164 
00165     //領域取得
00166 
00167     p = dkcAllocate(sizeof(DKC_FILE_WITH_SIGNATURE));
00168     if(NULL==p){
00169         return NULL;
00170     }
00171     tp = (DKC_SHA1 *)dkcAllocSHA1();
00172     if(NULL==tp){
00173         goto Error;
00174     }
00175 
00176     //ライトモードかどうか。
00177     isWrite = (NULL==strchr(mode,'r'));
00178 
00179     if(isWrite){
00180         //書き込みモードの時
00181         p->mWriteMode = TRUE;   
00182     }else{
00183         if(DKUTIL_FAILED(GetHeader(&header,filename))){
00184             goto Error;
00185         }
00186 
00187         if(header.little_endian){
00188             stream_flag |= edkcStreamLittleEndian;
00189         }else{
00190             stream_flag |= edkcStreamBigEndian;
00191         }
00192 
00193         p->mWriteMode = FALSE;
00194         //とりあえず、コピーしておかないと支障が出る。
00195         memcpy(&(p->mFileHeader),&header,sizeof(header));
00196     }
00197 
00198 
00199     sp = dkcAllocStreamFileType( stream_flag,filename,mode);
00200     if(NULL==sp){
00201         goto Error;
00202     }
00203     //update
00204     p->mStream = sp;
00205 
00206     if(isWrite){
00207         //ヘッダ分を書き込んでおく。
00208         memset(&header,0,sizeof(header));
00209         dkcStreamWrite(sp,&header,sizeof(header));
00210 
00211 
00212         //ヘッダの設定
00213 
00214         //エンディアン設定
00215         if(isLE){
00216             if(FALSE==p->mStream->mChangeEndian){
00217                 p->mFileHeader.little_endian = TRUE;
00218             }else{
00219                 p->mFileHeader.little_endian = FALSE;
00220             }
00221         }else{
00222             if(TRUE==p->mStream->mChangeEndian){
00223                 p->mFileHeader.little_endian = TRUE;
00224             }else{
00225                 p->mFileHeader.little_endian = FALSE;
00226             }
00227         }
00228         //シグネチャを設定
00229         p->mFileHeader.sig = signature;
00230     }
00231 
00232     mbp = dkcAllocBuffer(dustbin,dustbin_size);
00233     if(NULL==mbp){
00234         goto Error;
00235     }
00236 
00237 
00238 
00239     p->mSHA1 = tp;
00240     p->mDustbin = mbp;
00241 
00242     //とりあえず、ゴミ値をSHA1にロード
00243     dkcSHA1Load(p->mSHA1,dustbin,dustbin_size);
00244 
00245     if(isWrite==FALSE){
00246         //ストリームをデータ部にシーク
00247         dkcStreamSeek(p->mStream,sizeof(DKC_FILE_HEADER_FILE_WITH_SIGNATURE),edkcStreamSeekSet);
00248     }
00249         
00250 
00251     return p;
00252 Error:
00253     dkcFreeStream(&sp);
00254     dkcFreeSHA1((DKC_SHA1 **)&tp);
00255     dkcFree(&p);
00256     return NULL;
00257 }
00258 
00259 #ifdef _MSC_VER
00260 #   pragma warning(default:4701)
00261 #endif
00262 
00264 static DKC_INLINE BOOL FileWithSignatureIsFinalized(DKC_FILE_WITH_SIGNATURE *ptr){
00265     return ptr->mSHA1->mFinalized;
00266 }
00267 
00269 static DKC_INLINE int FileWithSignatureGetDigest(DKC_FILE_WITH_SIGNATURE *ptr
00270                                                                                                  //,BYTE *buff,size_t size
00271                                                                                                  )
00272 {
00273     dkcSHA1Load(
00274         ptr->mSHA1,
00275         dkcBufferPointer(ptr->mDustbin),
00276         dkcBufferSize(ptr->mDustbin)
00277     );
00278     return dkcSHA1FinalDigest(
00279         ptr->mSHA1,
00280         ptr->mFileHeader.hash_value,
00281         sizeof(ptr->mFileHeader.hash_value)
00282     );
00283 }
00284 
00285 int WINAPI dkcCloseFileWithSignature(DKC_FILE_WITH_SIGNATURE **p){
00286     DKC_FILE_WITH_SIGNATURE *ptr;
00287     //BYTE buff[SHA1_BUFFER_SIZE];
00288 
00289     //size_t offset = SM_OFFSET(DKC_FILE_HEADER_FILE_WITH_SIGNATURE,hash_value);
00290 
00291     if(NULL==p){
00292         return edk_FAILED;
00293     }
00294 
00295     ptr = *p;
00296     
00297     if(ptr->mWriteMode)
00298     {//書き込みモード時のみ
00299         
00300         //メッセージダイジェストを取得
00301         //FileWithSignatureGetDigest(ptr,buff,sizeof(buff));
00302         FileWithSignatureGetDigest(ptr);
00303         //ファイルサイズ取得
00304         ptr->mFileHeader.filesize = (ULONGLONG)dkcStreamTell(ptr->mStream);
00305         //ptr->mFileHeader.datasize = ptr->mFileHeader.filesize - sizeof(DKC_FILE_HEADER_FILE_WITH_SIGNATURE);
00306 
00307         //メッセージダイジェスト領域の位置を取得
00308         dkcStreamSeek(ptr->mStream,0,edkcStreamSeekSet);
00309         //メッセージダイジェストを書き込む
00310         //dkcStreamWrite(ptr->mStream,buff,sizeof(buff));
00311         HeaderWrite(ptr->mStream,&(ptr->mFileHeader));
00312     }
00313     dkcFreeBuffer(&(ptr->mDustbin));
00314 
00315     dkcFreeStream(&(ptr->mStream));
00316     
00317     dkcFreeSHA1(&(ptr->mSHA1));
00318 
00319     return dkcFree(p);
00320 }
00321 
00322 typedef int (WINAPI *CALLBACK_WRITE_F_T)(DKC_STREAM *,const void *,size_t);
00323 
00324 typedef struct FileWithSigCallBackSend{
00325     DKC_FILE_WITH_SIGNATURE *psig;
00326     size_t readsize;
00327     CALLBACK_WRITE_F_T callback;
00328 }FWS_CALLBACK_SEND;
00329 
00330 static int WINAPI WriteCallback(DKC_STREAM *ptr,void *buffer,size_t size,void *data){
00331     int r;
00332     FWS_CALLBACK_SEND *pfws = data;
00333     CALLBACK_WRITE_F_T callback = pfws->callback;
00334 
00335     r = callback(ptr,buffer,size);
00336     
00337     if(DKUTIL_FAILED(r)){
00338         return r;
00339     }
00340     dkcSHA1Load(pfws->psig->mSHA1,buffer,size);
00341     return r;
00342 }
00343 
00344 static int WINAPI ReadCallback(DKC_STREAM *ptr,void *buffer,size_t size,void *data){
00345 
00346     int r;
00347     FWS_CALLBACK_SEND *pfws = data;
00348     size_t readsize;
00349     
00350     r = dkcStreamRead(ptr,buffer,size,&readsize);
00351     (pfws->readsize) = readsize;
00352 
00353     if(DKUTIL_FAILED(r)){
00354         return r;
00355     }
00356     dkcSHA1Load(pfws->psig->mSHA1,buffer,readsize);
00357 
00358     return r;
00359 }
00360 
00361 
00362 static DKC_INLINE int FileWithSignatureReadLogic(DKC_FILE_WITH_SIGNATURE *p,
00363                                                                         void *data,size_t size,size_t *readsize){
00364     FWS_CALLBACK_SEND send;
00365     int r;
00366     send.callback = NULL;
00367     send.psig = p;
00368     send.readsize = 0;
00369     r = dkcStreamProcess(p->mStream,data,size,ReadCallback,(void *)&send);                                                                  
00370     if(readsize){
00371         *readsize = send.readsize;
00372     }
00373     return r;
00374     /*
00375     int r;
00376     size_t readsize_ = 0;
00377     if(NULL==readsize){
00378         readsize = &readsize_;
00379     }
00380     
00381     r = dkcStreamRead(p->mStream,data,size,readsize);
00382     if(DKUTIL_FAILED(r)){
00383         return r;
00384     }
00385     dkcSHA1Load(p->mSHA1,data,*readsize);
00386     return r;
00387     */
00388 }
00389 
00390 static DKC_INLINE int FileWithSignatureWriteLogic(DKC_FILE_WITH_SIGNATURE *p,
00391                                                                          const void *data,size_t size,CALLBACK_WRITE_F_T callback)
00392 {
00393     //return WriteCallback(p->mStream,data,size,&send);
00394     /*int r;
00395     r = callback(p->mStream,data,size);
00396     if(DKUTIL_FAILED(r)){
00397         return r;
00398     }
00399     dkcSHA1Load(p->mSHA1,data,size);
00400     
00401     return r;
00402     */
00403 }
00404 
00405 
00406 static DKC_INLINE int ReadEOFCheck(DKC_FILE_WITH_SIGNATURE *p){
00407     ULONGLONG filesize = p->mFileHeader.filesize;
00408     ULONGLONG stream_size = dkcStreamTell(p->mStream);
00409     if(filesize == stream_size || TRUE==p->mAllLoad)
00410     {
00411         p->mAllLoad = TRUE;
00412         return edk_EndProcess;
00413     }
00414     return edk_SUCCEEDED;
00415 }
00416 
00417 int WINAPI dkcFileWithSignatureRead(DKC_FILE_WITH_SIGNATURE *p,
00418                                                                         void *data,size_t size,size_t *readsize){
00419     size_t tsize;
00420     ULONGLONG filesize = p->mFileHeader.filesize;
00421     ULONGLONG stream_size = dkcStreamTell(p->mStream);
00422     int r = edk_FAILED;
00423 
00424     if(readsize){
00425         //とりあえず、明示的にまだ読み込んでいない事を告げる。
00426         *readsize = 0;
00427     }
00428 
00429     if(p->mWriteMode){//書き込みモードじゃねぇかよ。
00430         return edk_LogicError;
00431     }
00432 
00433     if(filesize == stream_size || TRUE==p->mAllLoad)
00434     {
00435         p->mAllLoad = TRUE;
00436         return edk_EndProcess;
00437     }
00438     //ファイルに冗長なモノが引っ付いている。
00439     if(filesize < stream_size){
00440         p->mAllLoad = TRUE;
00441         return edk_FileCheated_Addition;
00442     }
00443     //読み取りサイズをフィルターする
00444     if(stream_size + size > filesize){
00445         tsize = (size_t)(ULONGLONG)(filesize - stream_size);
00446     }else{
00447         tsize = size;
00448     }
00449     
00450     r = FileWithSignatureReadLogic(
00451         p,data,tsize,readsize);
00452     
00453 
00454     if(DKUTIL_FAILED(r)){
00455         return r;
00456     }
00457         
00458     return ReadEOFCheck(p);
00459     //return dkcStreamRead(p->mStream,data,tsize,readsize);
00460 }
00461 
00462 
00463 int WINAPI dkcFileWithSignatureWrite(DKC_FILE_WITH_SIGNATURE *p,
00464                                                                          const void *data,size_t size)
00465 {
00466     FWS_CALLBACK_SEND send;
00467     send.callback = dkcStreamWrite;
00468     send.psig = p;
00469     send.readsize = 0;
00470     return dkcStreamProcess(p->mStream,(void *)data,size,WriteCallback,&send);
00471     //return FileWithSignatureWriteLogic(p,data,size,dkcStreamWrite);
00472 
00473 }
00474 
00475 int WINAPI dkcFileWithSignatureWrite16(DKC_FILE_WITH_SIGNATURE *p,
00476                                                                              const void *data,size_t size)
00477 {
00478     FWS_CALLBACK_SEND send;
00479     send.callback = dkcStreamWrite16;
00480     send.psig = p;
00481     send.readsize = 0;
00482     return dkcStreamProcess(p->mStream,(void *)data,size,WriteCallback,&send);
00483     //return FileWithSignatureWriteLogic(p,data,size,dkcStreamWrite16);
00484 }
00485 
00486 
00487 
00488 int WINAPI dkcFileWithSignatureWrite32(DKC_FILE_WITH_SIGNATURE *p,
00489                                                                                                 const void *data,size_t size)
00490 {
00491     FWS_CALLBACK_SEND send;
00492     send.callback = dkcStreamWrite32;
00493     send.psig = p;
00494     send.readsize = 0;
00495     return dkcStreamProcess(p->mStream,(void *)data,size,WriteCallback,&send);
00496     //return FileWithSignatureWriteLogic(p,data,size,dkcStreamWrite32);
00497 }
00498 
00499 int WINAPI dkcFileWithSignatureWrite64(DKC_FILE_WITH_SIGNATURE *p,
00500                                                                                                 const void *data,size_t size)
00501 {
00502     FWS_CALLBACK_SEND send;
00503     send.callback = dkcStreamWrite64;
00504     send.psig = p;
00505     send.readsize = 0;
00506     return dkcStreamProcess(p->mStream,(void *)data,size,WriteCallback,&send);
00507     //return FileWithSignatureWriteLogic(p,data,size,dkcStreamWrite64);
00508 }
00509 
00510 int WINAPI dkcFileWithSignatureCheckCheat(DKC_FILE_WITH_SIGNATURE *p){
00511     ULONGLONG filesize = p->mFileHeader.filesize;
00512     ULONGLONG stream_size = dkcStreamTell(p->mStream);
00513     BYTE buff[SHA1_BIN_BUFFER_SIZE];
00514     int r;
00515 
00516     if(FALSE==p->mAllLoad){//すべて読み込んでいない。
00517         return edk_LogicError;
00518     }
00519     if(TRUE==p->mWriteMode){//書き込みモード時は使用できない。
00520         return edk_LogicError;
00521     }
00522 
00523     dkcSHA1Load(p->mSHA1,
00524         dkcBufferPointer(p->mDustbin),
00525         dkcBufferSize(p->mDustbin)
00526     );
00527 
00528     //メッセージダイジェストが欲しい。(二回呼び出されてもOK)
00529     dkcSHA1FinalDigest(p->mSHA1,buff,sizeof(buff));
00530     
00531     r = dkc_memcmp(
00532         buff,sizeof(buff),
00533         p->mFileHeader.hash_value,sizeof(p->mFileHeader.hash_value));
00534 
00535     if(DKUTIL_FAILED(r)){//違うみたい~~。
00536         return edk_FileSignatureException;
00537     }
00538 
00539     if(filesize < stream_size){//サイズが違う~~。へんなもの引っ付いている~~。
00540         return edk_FileCheated_Addition;
00541     }
00542     if(filesize == stream_size){
00543         return edk_SUCCEEDED;
00544     }
00545     //誰だよ、チートしたのは・・・。
00546     return edk_FAILED;
00547 
00548 }
00549 
00550 /*
00551 
00552 BOOL WINAPI dkcFileWithSignatureIsEOF(DKC_FILE_WITH_SIGNATURE *p);
00553 
00554 BOOL WINAPI dkcFileWithSignatureIsError(DKC_FILE_WITH_SIGNATURE *p);
00555 
00556 //@return 改竄されていたらTRUE
00557 BOOL WINAPI dkcFileWithSignatureIsCheated(DKC_FILE_WITH_SIGNATURE *p){
00558     if(p->mSHA1->mFinalized){
00559         dkcmNOT_ASSERT("ERROR");
00560         return edk_LogicError;
00561     }
00562     p->mSHA1
00563 
00564 }
00565                                                                                                                  
00566 */

dkutil_cに対してSun Jul 18 22:45:21 2004に生成されました。 doxygen 1.3.6