📄 loadsave.c
字号:
fwrite( &td, sizeof(TOKEN_DATA), 1, fp ); fclose(fp); rc = CKR_OK;done: XProcUnLock( xproclock );out_nolock: return rc;}////CK_RVsave_token_object( OBJECT *obj ){ FILE * fp = NULL; CK_BYTE line[100]; CK_RV rc; CK_BYTE fname[2048]; if (object_is_private(obj) == TRUE) rc = save_private_token_object( obj ); else rc = save_public_token_object( obj ); if (rc != CKR_OK){ st_err_log(104, __FILE__, __LINE__); return rc; } // update the index file if it exists // sprintf((char *)fname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR,PK_LITE_OBJ_IDX); //fp = fopen( "/tmp/TOK_OBJ/OBJ.IDX", "r" ); fp = fopen( (char *)fname, "r" ); if (fp) { set_perm(fileno(fp)); while (!feof(fp)) { fgets((char *)line, 50, fp ); if (!feof(fp)) { line[ strlen((char *)line)-1 ] = 0; if (strcmp((char *)line,(char *)( obj->name)) == 0) { fclose(fp); return CKR_OK; // object is already in the list } } } fclose(fp); } // we didn't find it...either the index file doesn't exist or this // is a new object... // //fp = fopen("/tmp/TOK_OBJ/OBJ.IDX", "a"); fp = fopen((char *)fname, "a"); if (!fp){ st_err_log(4, __FILE__, __LINE__, __FUNCTION__); return CKR_FUNCTION_FAILED; } set_perm(fileno(fp)); set_perm(fileno(fp)); fprintf( fp, "%s\n", obj->name ); fclose(fp); return CKR_OK;}// this is the same as the old version. public token objects are stored in the// clear//CK_RVsave_public_token_object( OBJECT *obj ){ FILE * fp = NULL; CK_BYTE * cleartxt = NULL; CK_BYTE fname[2048]; CK_ULONG cleartxt_len; CK_BBOOL flag = FALSE; CK_RV rc; CK_ULONG_32 total_len; //strcpy( fname, "/tmp/TOK_OBJ/" ); sprintf( (char *)fname,"%s/%s/", pk_dir,PK_LITE_OBJ_DIR); strncat( (char *)fname, (char *) obj->name, 8 ); rc = object_flatten( obj, &cleartxt, &cleartxt_len ); if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } set_perm(fileno(fp)); total_len = cleartxt_len + sizeof(CK_ULONG_32) + sizeof(CK_BBOOL); fwrite( &total_len, sizeof(CK_ULONG_32), 1, fp ); fwrite( &flag, sizeof(CK_BBOOL), 1, fp ); fwrite( cleartxt, cleartxt_len, 1, fp ); fclose( fp ); free( cleartxt ); return CKR_OK;error: if (fp) fclose( fp ); if (cleartxt) free( cleartxt ); return rc;}////CK_RVsave_private_token_object( OBJECT *obj ){ FILE * fp = NULL; CK_BYTE * obj_data = NULL; CK_BYTE * cleartxt = NULL; CK_BYTE * ciphertxt = NULL; CK_BYTE * ptr = NULL; CK_BYTE fname[100]; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_BYTE hash_md5[MD5_HASH_SIZE]; CK_BYTE des3_key[3 * DES_KEY_SIZE]; CK_ULONG obj_data_len,cleartxt_len, ciphertxt_len, hash_len, tmp, tmp2; CK_ULONG padded_len; CK_BBOOL flag; CK_RV rc; CK_ULONG_32 obj_data_len_32; CK_ULONG_32 total_len; rc = object_flatten( obj, &obj_data, &obj_data_len ); obj_data_len_32 = obj_data_len; if (rc != CKR_OK){ st_err_log(101, __FILE__, __LINE__); goto error; } // // format for the object file: // private flag // ---- begin encrypted part <--+ // length of object data | // object data +---- sensitive part // SHA of (object data) | // ---- end encrypted part <--+ // compute_sha( obj_data, obj_data_len, hash_sha ); // encrypt the sensitive object data. need to be careful. // if I use the normal high-level encryption routines I'll need to // create a tepmorary key object containing the master key, perform the // encryption, then destroy the key object. There is a race condition // here if the application is multithreaded (if a thread-switch occurs, // the other application thread could do a FindObject and be able to access // the master key object. // // So I have to use the low-level encryption routines. // memcpy( des3_key, master_key, 3*DES_KEY_SIZE ); cleartxt_len = sizeof(CK_ULONG_32) + obj_data_len_32 + SHA1_HASH_SIZE; padded_len = DES_BLOCK_SIZE * (cleartxt_len / DES_BLOCK_SIZE + 1); cleartxt = (CK_BYTE *)malloc( padded_len ); ciphertxt = (CK_BYTE *)malloc( padded_len ); if (!cleartxt || !ciphertxt) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } ciphertxt_len = padded_len; ptr = cleartxt; memcpy( ptr, &obj_data_len_32, sizeof(CK_ULONG_32) ); ptr += sizeof(CK_ULONG_32); memcpy( ptr, obj_data, obj_data_len_32 ); ptr += obj_data_len_32; memcpy( ptr, hash_sha, SHA1_HASH_SIZE ); add_pkcs_padding( cleartxt + cleartxt_len, DES_BLOCK_SIZE, cleartxt_len, padded_len );#ifndef CLEARTEXT rc = ckm_des3_cbc_encrypt( cleartxt, padded_len, ciphertxt, &ciphertxt_len, "10293847", (char *) des3_key );#else bcopy(cleartxt,ciphertxt,padded_len); rc = CKR_OK;#endif if (rc != CKR_OK){ st_err_log(105, __FILE__, __LINE__); goto error; } //strcpy( (char *)fname, "/tmp/TOK_OBJ/" ); sprintf( (char *)fname,"%s/%s/", pk_dir,PK_LITE_OBJ_DIR); strncat( (char *)fname,(char *) obj->name, 8 ); fp = fopen( (char *)fname, "w" ); if (!fp) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; } set_perm(fileno(fp)); total_len = sizeof(CK_ULONG_32) + sizeof(CK_BBOOL) + ciphertxt_len; flag = TRUE; fwrite( &total_len, sizeof(CK_ULONG_32), 1, fp ); fwrite( &flag, sizeof(CK_BBOOL), 1, fp ); fwrite( ciphertxt, ciphertxt_len, 1, fp ); fclose( fp ); free( obj_data ); free( cleartxt ); free( ciphertxt ); return CKR_OK;error: if (fp) fclose( fp ); if (obj_data) free( obj_data ); if (cleartxt) free( cleartxt ); if (ciphertxt) free( ciphertxt ); return rc;}////CK_RVload_public_token_objects( void ){ FILE *fp1 = NULL, *fp2 = NULL; CK_BYTE *buf = NULL; CK_BYTE tmp[2048], fname[2048],iname[2048]; CK_BBOOL priv; CK_ULONG_32 size; sprintf((char *)iname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); //fp1 = fopen("/tmp/TOK_OBJ/OBJ.IDX", "r"); fp1 = fopen((char *)iname, "r"); if (!fp1) return CKR_OK; // no token objects while (!feof(fp1)) { fgets( (char *)tmp, 50, fp1 ); if (!feof(fp1)) { tmp[ strlen((char *)tmp)-1 ] = 0; //strcpy(fname,"/tmp/TOK_OBJ/"); sprintf((char *)fname,"%s/%s/",pk_dir, PK_LITE_OBJ_DIR); strcat((char *)fname, (char *)tmp ); fp2 = fopen( (char *)fname, "r" ); if (!fp2) continue; fread( &size, sizeof(CK_ULONG_32), 1, fp2 ); fread( &priv, sizeof(CK_BBOOL), 1, fp2 ); if (priv == TRUE) { fclose( fp2 ); continue; } // size--; size = size -sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); buf = (CK_BYTE *)malloc(size); if (!buf) { fclose(fp1); fclose(fp2); st_err_log(0, __FILE__, __LINE__); return CKR_HOST_MEMORY; } fread( buf, size, 1, fp2 ); // ... grab object mutex here. MY_LockMutex(&obj_list_mutex); object_mgr_restore_obj( buf, NULL ); MY_UnlockMutex(&obj_list_mutex); free( buf ); fclose( fp2 ); } } fclose(fp1); return CKR_OK;}////CK_RVload_private_token_objects( void ){ FILE *fp1 = NULL, *fp2 = NULL; CK_BYTE *buf = NULL; CK_BYTE tmp[2048], fname[2048],iname[2048]; CK_BYTE sha_hash[SHA1_HASH_SIZE], old_hash[SHA1_HASH_SIZE]; CK_BBOOL priv; CK_ULONG_32 size; CK_RV rc; sprintf((char *)iname,"%s/%s/%s",pk_dir,PK_LITE_OBJ_DIR, PK_LITE_OBJ_IDX); //fp1 = fopen("/tmp/TOK_OBJ/OBJ.IDX", "r"); fp1 = fopen((char *)iname, "r"); if (!fp1) return CKR_OK; // no token objects while (!feof(fp1)) { fgets((char *) tmp, 50, fp1 ); if (!feof(fp1)) { tmp[ strlen((char *)tmp)-1 ] = 0; //strcpy(fname,"/tmp/TOK_OBJ/"); sprintf((char *)fname,"%s/%s/",pk_dir,PK_LITE_OBJ_DIR); strcat((char *)fname,(char *) tmp ); fp2 = fopen( (char *)fname, "r" ); if (!fp2) continue; fread( &size, sizeof(CK_ULONG_32), 1, fp2 ); fread( &priv, sizeof(CK_BBOOL), 1, fp2 ); if (priv == FALSE) { fclose( fp2 ); continue; } //size--; size = size - sizeof(CK_ULONG_32) - sizeof(CK_BBOOL); buf = (CK_BYTE *)malloc(size); if (!buf) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto error; } rc = fread( (char *)buf, size, 1, fp2 ); if (rc != 1) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto error; }// Grab object list mutex MY_LockMutex(&obj_list_mutex); rc = restore_private_token_object( buf, size, NULL ); MY_UnlockMutex(&obj_list_mutex); if (rc != CKR_OK){ st_err_log(107, __FILE__, __LINE__); goto error; } free( buf ); fclose( fp2 ); } } fclose(fp1); return CKR_OK;error: if (buf) free( buf ); if (fp1) fclose( fp1 ); if (fp2) fclose( fp2 ); return rc;}////CK_RVrestore_private_token_object( CK_BYTE * data, CK_ULONG len, OBJECT * pObj ){ CK_BYTE * cleartxt = NULL; CK_BYTE * obj_data = NULL; CK_BYTE * ciphertxt = NULL; CK_BYTE * ptr = NULL; CK_BYTE des3_key[3 * DES_KEY_SIZE]; CK_BYTE hash_sha[SHA1_HASH_SIZE]; CK_MECHANISM mech; DIGEST_CONTEXT digest_ctx; ENCR_DECR_CONTEXT encr_ctx; CK_ULONG hash_len, cleartxt_len, obj_data_len; CK_RV rc; // format for the object data: // (private flag has already been read at this point) // ---- begin encrypted part // length of object data // object data // SHA of object data // ---- end encrypted part // cleartxt_len = len; cleartxt = (CK_BYTE *)malloc(len); if (!cleartxt) { st_err_log(0, __FILE__, __LINE__); rc = CKR_HOST_MEMORY; goto done; } ciphertxt = data; // decrypt the encrypted chunk // memcpy( des3_key, master_key, 3*DES_KEY_SIZE );#ifndef CLEARTEXT rc = ckm_des3_cbc_decrypt( ciphertxt, len, cleartxt, &len, "10293847", des3_key );#else bcopy(ciphertxt,cleartxt,len); rc = CKR_OK;#endif if (rc != CKR_OK){ st_err_log(106, __FILE__, __LINE__); goto done; } strip_pkcs_padding( cleartxt, len, &cleartxt_len ); // if the padding extraction didn't work it means the object was tampered with or // the key was incorrect // if (cleartxt_len > len) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } ptr = cleartxt; obj_data_len = *(CK_ULONG_32 *)ptr; ptr += sizeof(CK_ULONG_32); obj_data = ptr; // check the hash // compute_sha( ptr, obj_data_len, hash_sha ); ptr += obj_data_len; if (memcmp(ptr, hash_sha, SHA1_HASH_SIZE) != 0) { st_err_log(4, __FILE__, __LINE__, __FUNCTION__); rc = CKR_FUNCTION_FAILED; goto done; } // okay. at this point, we're satisfied that nobody has tampered with the // token object...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -