z_status zb_ds_table_mk::test_record_by_index(size_t index,zb_ds_rec_ptr** cursor) { if( index>=(size_t)_mk_view.GetSize()) return Z_ERROR(zs_out_of_range); if(cursor==0) return Z_ERROR(zs_bad_parameter); c4_StringProp p("field1str"); get_record_by_index(index,cursor); zout << p.Get(_mk_view[index])<<"\n"; c4_RowRef& rr=_mk_view[index]; zout << p.Get(rr)<<"\n"; //Apparently dynamic_cast is slow. change to static for release build zb_rec_ptr_mk* r=dynamic_cast<zb_rec_ptr_mk*>(*cursor); if(r==0) r=z_new zb_rec_ptr_mk(false); r->set(this,index); rr=r->get_row_ref(); zout << p.Get(rr)<<"\n"; return 0; }
void authenticate_decrypt(void* buf, u32 len) { #ifdef GLADMAN_HMAC hmac_sha1_data(buf, len, &hmac); #else if (hmac_process(&hmac, buf, len) != CRYPT_OK) Z_ERROR("Failed to authenticate"); #endif if (ctr_decrypt(buf, buf, len, &ctr) != CRYPT_OK) Z_ERROR("Failed to decrypt"); }
void Encrypt(PK0304* le, AE_EXTRA* ae, char* password) { char *salt, *key1, *key2, *check, digest[40]; u32 key_len = KeySize*2 + 2; u32 dig_len = 40; salt = BUF; key1 = salt+SaltSize; key2 = key1+KeySize; check = key2+KeySize; /* Gets a random salt (8-16 byte) */ sprng_read(salt, SaltSize, 0); /* Generates 2 keys for AES and HMAC, plus 2-byte password verification value */ if (pkcs_5_alg2(password, strlen(password), salt, SaltSize, 1000, 0, key1, &key_len) != CRYPT_OK) Z_ERROR("Failed to derive encryption keys"); // dump("salt", salt, SaltSize); // dump("key", key1, KeySize); if (ctr_start(0, IV, key1, KeySize, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) != CRYPT_OK) Z_ERROR("Failed to setup AES CTR encoder"); #ifdef GLADMAN_HMAC hmac_sha1_begin(&hmac); hmac_sha1_key(key2, KeySize, &hmac); #else if (hmac_init(&hmac, 0, key2, KeySize) != CRYPT_OK) Z_ERROR("Failed to setup HMAC-SHA1"); #endif if (AE2) le->Crc32 = 0; le->Flag |= 1; le->CompMethod = 99; le->ExtraLen += 11; le->CompSize += SaltSize + 12; /* variable salt, fixed password check and hmac */ safeWrite(ZOUT, le, sizeof(PK0304)); fileCopy(ZOUT, ZIN, le->NameLen+le->ExtraLen-11); safeWrite(ZOUT, ae, 11); safeWrite(ZOUT, salt, SaltSize); safeWrite(ZOUT, check, 2); /* encrypt contents */ fileFilter(ZOUT, ZIN, le->CompSize-SaltSize-12); #ifdef GLADMAN_HMAC hmac_sha1_end(digest, dig_len, &hmac); #else if (hmac_done(&hmac, digest, &dig_len) != CRYPT_OK) Z_ERROR("Failed to computate HMAC"); #endif safeWrite(ZOUT, digest, 10); ctr_done(&ctr); }
z_status zb_ds_table_mk::get_record_by_index(size_t index,zb_ds_rec_ptr** cursor) { if( index>=(size_t)_mk_view.GetSize()) return Z_ERROR(zs_out_of_range); if(cursor==0) return Z_ERROR(zs_bad_parameter); zb_rec_ptr_mk* r=dynamic_cast<zb_rec_ptr_mk*>(*cursor); if(r==0) r=z_new zb_rec_ptr_mk(false); r->set(this,index); *cursor=r; //r->get_row_ref()=_mk_view[index]; return zs_ok; }
z_status zb_ds_field_mk_string::get_string(zb_ds_rec_ptr *rec,z_string& s) { zb_rec_ptr_mk* mk_rec=dynamic_cast<zb_rec_ptr_mk*>(rec); if(!mk_rec) return Z_ERROR(zs_bad_parameter); c4_RowRef rr=mk_rec->get_row_ref(); s=(*_pStrProp).Get(rr); return zs_ok; }
z_status zb_ds_field_mk_string::set_string(zb_ds_rec_ptr *rec,ctext s) { zb_rec_ptr_mk* mk_rec=dynamic_cast<zb_rec_ptr_mk*>(rec); if(!mk_rec) return Z_ERROR(zs_bad_parameter); (*_pStrProp).Set(mk_rec->get_row_ref(),s); return zs_ok; }
FILE* topen(char *name) { u16 u, i; FILE *f; for (i=0; i<1000; i++) { sprng_read(&u, 4, 0); sprintf(name, "AE-%05X.TMP", u); f = fopen(name, "w+b"); if (!f) continue; else return f; } Z_ERROR("Can't create a temporary file!"); return 0; /* never reached */ }
int main(int argc,char** argv) { char pm, operation=-1, found=1, pw1[128], pw2[128], ae1[15], ae2[15]; u32 i; PK0102 ce; PK0304 le; PK0506 ed; for (pm=1; pm < argc; pm++) { char opt; if (argv[pm][0] != '/') continue; if (argv[pm][1] == '?') { printf( "Encrypts or decrypts an archive following WinZip(R) 9 specifications.\n\n" \ "ZAES /D | /E:keysize [/2] archive.zip\n\n" \ " /D decrypts AES encrypted entries\n" \ " /E:keysize encrypts with 128, 192 or 256-bit keys (keysize 1, 2 or 3)\n" \ " /2 AE-2 format (sets CRC-32 to zero)\n"); return 1; } opt = toupper(argv[pm][1]); if (opt== 'E') { Mode = atol(&argv[pm][3]); operation = 0; filter = encrypt_authenticate; if (Mode < 1 || Mode > 3) Z_ERROR("Bad encryption mode specified!"); SaltSize = KS[Mode].Salt; KeySize = KS[Mode].Key; found++; continue; } if (opt== 'D') { operation = 1; filter = authenticate_decrypt; found++; continue; } if (opt== '2') { AE2 = 1; found++; printf("WARNING: according to AE-2 specifications, CRC-32 will be set to zero\n"\ "in encrypted entries. Reverting to original archive after decryption will\n"\ "be impossible with this utility!\n"); continue; } } argv+=found; argc-=found; if (operation == -1) Z_ERROR("You must specify /E or /D switch!\nTry ZAES /?"); if (argc < 1) Z_ERROR("You must give a ZIP archive to process!"); register_prng(&sprng_desc); register_cipher(&aes_desc); register_hash(&sha1_desc); //~ printf("DEBUG: sha1 id=%d, aes id=%d\n", find_hash("sha1"), find_cipher("aes")); if ( (ZIN=fopen(argv[0],"rb")) == 0 || (ZIN2=fopen(argv[0],"rb")) == 0 ) Z_ERROR("Can't open input ZIP archive"); if ( (ZOUT=topen(ae1)) == 0 || (ZTMP=topen(ae2)) == 0) Z_ERROR("Can't open temporary output files"); setvbuf(ZIN , 0, _IOFBF, BLOCK); setvbuf(ZOUT, 0, _IOFBF, BLOCK); /* assumiamo uno ZIP senza commento! */ fseek(ZIN2,-22,SEEK_END); safeRead(&ed, ZIN2, sizeof(PK0506)); if (ed.Sig != 0x06054B50) #ifdef HANDLE_COMMENT { fseek(ZIN2, -0xFFFF, SEEK_END); fread(p, 1, 4, ZIN2); #else Z_ERROR("End directory marker not found!"); #endif /* verifica un minimo di coerenza nella ENDDIR */ if (ed.Disk != 0) Z_ERROR("Can't process a spanned archive"); while(1) { printf("Enter password: "******"\rFor your safety, please use a password of 8 characters or more.\n"); continue; } if (operation) { printf("\n"); break; } printf("\rVerify password: "******"Passwords don't match!\n"); continue; } printf("\n"); break; } #define PUTN(x) { fileCopy(stdout, ZIN, x.NameLen); fseek(ZIN, -x.NameLen, SEEK_CUR); } fseek(ZIN2, ed.Offset, SEEK_SET); for (i=0; i < ed.Total; i++) { safeRead(&ce, ZIN2, sizeof(PK0102)); if (ce.Sig != 0x02014B50) Z_ERROR("Expected central directory marker not found"); /* Assume i dati corretti dalla LE */ fseek(ZIN, ce.Offset, SEEK_SET); safeRead(&le, ZIN, sizeof(PK0304)); if (le.Sig != 0x04034B50) Z_ERROR("Expected local entry marker not found"); if ( ((le.Flag & 1) && !operation) || /* doesn't encrypt already encrypted */ (!(le.Flag & 1) && operation) || /* doesn't decrypt already decrypted */ ((le.Flag & 1) && operation && le.CompMethod != 99) || /* doesn't decrypt not AES encrypted */ !le.CompSize ) { ce.Offset = ftell(ZOUT); safeWrite(ZOUT, &le, sizeof(PK0304)); printf(" copying: "); PUTN(le); fileCopy(ZOUT, ZIN, le.NameLen+le.ExtraLen+le.CompSize); printf("\n"); safeWrite(ZTMP, &ce, sizeof(PK0102)); fileCopy(ZTMP, ZIN2, ce.NameLen+ce.ExtraLen); continue; } if (!operation) { AE_EXTRA ae = {0x9901, 7, AE2+1, 0x4541, Mode, 0}; ae.CompMethod = ce.CompMethod; ce.CompMethod = 99; if (AE2) ce.Crc32 = 0; ce.Flag |= 1; ce.ExtraLen += 11; ce.CompSize += SaltSize + 12; /* variable salt, fixed password check and hmac */ ce.Offset = ftell(ZOUT); safeWrite(ZTMP, &ce, sizeof(PK0102)); fileCopy(ZTMP, ZIN2, ce.NameLen+ce.ExtraLen-11); safeWrite(ZTMP, &ae, 11); printf(" encrypting: "); PUTN(le); Encrypt(&le, &ae, pw1); printf("\n"); } else { ce.Offset = ftell(ZOUT); printf(" decrypting: "); PUTN(le); Decrypt(&le, pw1); /* Decrypts contents */ printf("\n"); ce.CompMethod = le.CompMethod; if (AE2) ce.Crc32 = 0; ce.Flag ^= 1; ce.ExtraLen -= 11; ce.CompSize = le.CompSize; safeWrite(ZTMP, &ce, sizeof(PK0102)); /* Copy the extra data (may be LE != CE) */ fileCopy(ZTMP, ZIN2, ce.NameLen); for(ce.ExtraLen+=11; ce.ExtraLen;) { u16 u[2]; safeRead(u, ZIN2, 4); ce.ExtraLen -= (4 + u[1]); if (u[0] == 0x9901) { fseek(ZIN2, u[1], SEEK_CUR); continue; } safeWrite(ZTMP, u, 4); fileCopy(ZTMP, ZIN2, u[1]); } } } ed.Offset = ftell(ZOUT); /* new central directory start */ ed.Size = ftell(ZTMP); /* new central directory size */ fseek(ZTMP, 0, SEEK_SET); fclose(ZIN); fclose(ZIN2); /* Copies central directory */ fileCopy(ZOUT, ZTMP, ed.Size); safeWrite(ZOUT, &ed, sizeof(PK0506)); fclose(ZTMP); fclose(ZOUT); remove(ae2); if (remove(argv[0])) { printf("Can't remove old archive; new one is in file '%s'\n", ae1); } else if (rename(ae1, argv[0])) { printf("Can't rename old archive; new one is in file '%s'\n", ae1); } memset(&BUF, 0, sizeof(BUF)); memset(&ctr, 0, sizeof(ctr)); memset(pw1, 0, 128); memset(pw2, 0, 128); return 0; }
void Decrypt(PK0304 *le, char *password) { char *salt, *key1, *key2, *check, digest[40]; u32 key_len, dig_len = 40, start, xlen; AE_EXTRA ae; start = ftell(ZIN); /* Searches for AE-1 header */ fseek(ZIN, le->NameLen, SEEK_CUR); for(xlen=le->ExtraLen; xlen;) { safeRead(&ae, ZIN, 4); xlen -= (4 + ae.Size); if (ae.Sig == 0x9901) { safeRead(&ae.Version, ZIN, 7); continue; } fseek(ZIN, ae.Size, SEEK_CUR); } if (ae.Sig != 0x9901) Z_ERROR("Fatal! Can't find AE extra header!"); if (ae.Strength < 1 || ae.Strength > 3) Z_ERROR("Bad encryption strength"); SaltSize = KS[ae.Strength].Salt; KeySize = KS[ae.Strength].Key; salt = BUF; key1 = salt+SaltSize; key2 = key1+KeySize; check = key2+KeySize; key_len = KeySize*2+2; /* Loads salt and password check value, and regenerates original crypto material */ fseek(ZIN, start+le->NameLen+le->ExtraLen, SEEK_SET); safeRead(salt, ZIN, SaltSize); safeRead(check+2, ZIN, 2); point1: if (pkcs_5_alg2(password, strlen(password), salt, SaltSize, 1000, 0, key1, &key_len) != CRYPT_OK) Z_ERROR("Failed to derive encryption keys"); if (memcmp(check, check+2, 2)) { printf("\nCan't decrypt data: try another password.\nNew password: "******"\n"); goto point1; } if (ctr_start(0, IV, key1, KeySize, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr) != CRYPT_OK) Z_ERROR("Failed to setup AES CTR decoder"); #ifdef GLADMAN_HMAC hmac_sha1_begin(&hmac); hmac_sha1_key(key2, KeySize, &hmac); #else if (hmac_init(&hmac, 0, key2, KeySize) != CRYPT_OK) Z_ERROR("Failed to setup HMAC-SHA1"); #endif /* Adjusts local header */ le->Flag ^= 1; le->CompMethod = ae.CompMethod; le->ExtraLen -= 11; le->CompSize -= (SaltSize + 12); /* Writes local header and copies extra, except 0x9901 */ safeWrite(ZOUT, le, sizeof(PK0304)); fseek(ZIN, start, SEEK_SET); fileCopy(ZOUT, ZIN, le->NameLen); for(xlen=le->ExtraLen+11; xlen;) { safeRead(&ae, ZIN, 4); xlen -= (4 + ae.Size); if (ae.Sig == 0x9901) { safeRead(&ae.Version, ZIN, 7); continue; } safeWrite(ZOUT, &ae, 4); fileCopy(ZOUT, ZIN, ae.Size); } fseek(ZIN, SaltSize+2, SEEK_CUR); fileFilter(ZOUT, ZIN, le->CompSize); #ifdef GLADMAN_HMAC hmac_sha1_end(digest, dig_len, &hmac); #else if (hmac_done(&hmac, digest, &dig_len) != CRYPT_OK) Z_ERROR("Failed to computate HMAC"); #endif /* Retrieves and checks HMACs */ safeRead(digest+10, ZIN, 10); if (memcmp(digest, digest+10, 10)) printf(" authentication failed, contents were lost!"); ctr_done(&ctr); }
void safeWrite(FILE* Out, void* src, u32 n) { if (fwrite(src,1,n,Out) != n) Z_ERROR("Can't write requested bytes"); }
/* Functions to read/write data and copy file contents */ void safeRead(void* dst, FILE* In, u32 n) { if (fread(dst,1,n,In) != n) Z_ERROR("Can't read requested bytes"); }
void* xmalloc(size_t len) { char* p = (char*) malloc(len); if (!p) Z_ERROR("Can't allocate memory!"); return p; }