void CDeleteRetrieveCertificate::PerformAction(TRequestStatus& aStatus) { TRequestStatus* status = &aStatus; switch (iState) { case EIdle: //get the certs iState = EDeletingCert; //get the certs GetCerts(aStatus); if (aStatus == KErrNoMemory) { iState = EFinished; } break; case EDeletingCert: { if (iNotificationSubscribed) { iNotifier = CCertStoreChangeNotifier::NewL(iNotifierFlag); iNotifier->StartNotification(); iState = ECheckNotification; } else { iState = EGettingCerts; } //delete the cert DeleteCert(aStatus); break; } case ECheckNotification: { TInt ret=KErrNone; if (!iNotifierFlag) { ret=KErrGeneral; } if (ret!=KErrNone) { iState = EFinished; } else { iState = EGettingCerts; } TRequestStatus* status = &aStatus; User::RequestComplete(status, ret); } break; case EGettingCerts: { iState = EFinished; //get the cert RetrieveCerts(aStatus); break; } case EFinished: { if (aStatus == iExpectedResult) { iResult = ETrue; } else { iResult = EFalse; } if (aStatus == KErrNoMemory) { iState = EIdle; } else { iFinished = ETrue; } User::RequestComplete(status, aStatus.Int()); } break; default: { //some kind of error behaviour } } }
void CDeleteCertificate::PerformAction(TRequestStatus& aStatus) { if (aStatus != KErrNone) { iState = EFinished; } switch (iState) { case EIdle: //get the certs if (iCertInfos.Count() > 0) { iCertInfos.Close(); // JCS added for multiple delete case } iState = EGettingCerts; //get the certs GetCerts(aStatus); break; case EGettingCerts: { if (iNotificationSubscribed) { if (!iNotifier) { iNotifier = CCertStoreChangeNotifier::NewL(iNotifierFlag); iNotifier->StartNotification(); } iState = ECheckNotification; } else { iState = EFinished; } DeleteCert(aStatus); } break; case ECheckNotification: { iState = EFinished; if (iNotifierFlag) { TRequestStatus* status = &aStatus; User::RequestComplete(status, KErrNone); } else { iNotifier->SetCompleteStatus(&aStatus); } } break; case EFinished: { if (aStatus == iExpectedResult) { iResult = ETrue; } else { iResult = EFalse; } if (aStatus == KErrNoMemory) { iState = EIdle; } else { iFinished = ETrue; } TRequestStatus* status = &aStatus; User::RequestComplete(status, aStatus.Int()); } break; default: User::Invariant(); } }
s32 Download_IOS(IOS **ios, u32 iosnr, u32 revision) { s32 ret; ret = Init_IOS(ios); if (ret < 0) { printf("Out of memory\n"); goto err; } tmd *tmd_data = NULL; u32 cnt; //static bool network_initialized = false; char buf[32]; if (!network_initialized) { printf("Initializing network..."); while (1) { ret = net_init (); if (ret < 0) { //if (ret != -EAGAIN) if (ret != -11) { printf ("net_init failed: %d\n", ret); goto err; } } if (!ret) break; usleep(100000); printf("."); } printf("done\n"); network_initialized = true; } printf("Loading certs...\n"); ret = GetCerts(&((*ios)->certs), &((*ios)->certs_size)); if (ret < 0) { printf ("Loading certs from nand failed, ret = %d\n", ret); goto err; } if ((*ios)->certs == NULL || (*ios)->certs_size == 0) { printf("certs error\n"); ret = -1; goto err; } if (!IS_VALID_SIGNATURE((*ios)->certs)) { printf("Error: Bad certs signature!\n"); ret = -1; goto err; } printf("Loading TMD...\n"); sprintf(buf, "tmd.%u", revision); u8 *tmd_buffer = NULL; ret = get_nus_object(1, iosnr, buf, &tmd_buffer, &((*ios)->tmd_size)); if (ret < 0) { printf("Loading tmd failed, ret = %u\n", ret); goto err; } if (tmd_buffer == NULL || (*ios)->tmd_size == 0) { printf("TMD error\n"); ret = -1; goto err; } (*ios)->tmd_size = SIGNED_TMD_SIZE((signed_blob *)tmd_buffer); (*ios)->tmd = MEM2_memalign(32, (*ios)->tmd_size); if ((*ios)->tmd == NULL) { printf("Out of memory\n"); ret = -1; goto err; } memcpy((*ios)->tmd, tmd_buffer, (*ios)->tmd_size); free(tmd_buffer); if (!IS_VALID_SIGNATURE((*ios)->tmd)) { printf("Error: Bad TMD signature!\n"); ret = -1; goto err; } printf("Loading ticket...\n"); u8 *ticket_buffer = NULL; ret = get_nus_object(1, iosnr, "cetk", &ticket_buffer, &((*ios)->ticket_size)); if (ret < 0) { printf("Loading ticket failed, ret = %u\n", ret); goto err; } if (ticket_buffer == NULL || (*ios)->ticket_size == 0) { printf("ticket error\n"); ret = -1; goto err; } (*ios)->ticket_size = SIGNED_TIK_SIZE((signed_blob *)ticket_buffer); (*ios)->ticket = MEM2_memalign(32, (*ios)->ticket_size); if ((*ios)->ticket == NULL) { printf("Out of memory\n"); ret = -1; goto err; } memcpy((*ios)->ticket, ticket_buffer, (*ios)->ticket_size); free(ticket_buffer); if(!IS_VALID_SIGNATURE((*ios)->ticket)) { printf("Error: Bad ticket signature!\n"); ret = -1; goto err; } /* Get TMD info */ tmd_data = (tmd *)SIGNATURE_PAYLOAD((*ios)->tmd); printf("Checking titleid and revision...\n"); if (TITLE_UPPER(tmd_data->title_id) != 1 || TITLE_LOWER(tmd_data->title_id) != iosnr) { printf("IOS has titleid: %08x%08x but expected was: %08x%08x\n", TITLE_UPPER(tmd_data->title_id), TITLE_LOWER(tmd_data->title_id), 1, iosnr); ret = -1; goto err; } if (tmd_data->title_version != revision) { printf("IOS has revision: %u but expected was: %u\n", tmd_data->title_version, revision); ret = -1; goto err; } ret = set_content_count(*ios, tmd_data->num_contents); if (ret < 0) { printf("Out of memory\n"); goto err; } printf("Loading contents"); for (cnt = 0; cnt < tmd_data->num_contents; cnt++) { printf("."); tmd_content *content = &tmd_data->contents[cnt]; /* Encrypted content size */ (*ios)->buffer_size[cnt] = round_up((u32)content->size, 64); sprintf(buf, "%08x", content->cid); ret = get_nus_object(1, iosnr, buf, &((*ios)->encrypted_buffer[cnt]), &((*ios)->buffer_size[cnt])); if ((*ios)->buffer_size[cnt] % 16) { printf("Content %u size is not a multiple of 16\n", cnt); ret = -1; goto err; } if ((*ios)->buffer_size[cnt] < (u32)content->size) { printf("Content %u size is too small\n", cnt); ret = -1; goto err; } (*ios)->decrypted_buffer[cnt] = MEM2_memalign(32, (*ios)->buffer_size[cnt]); if (!(*ios)->decrypted_buffer[cnt]) { printf("Out of memory\n"); ret = -1; goto err; } } printf("done\n"); printf("Reading file into memory complete.\n"); printf("Decrypting IOS...\n"); decrypt_IOS(*ios); tmd_content *p_cr = TMD_CONTENTS(tmd_data); sha1 hash; int i; printf("Checking hashes...\n"); for (i=0;i < (*ios)->content_count;i++) { SHA1((*ios)->decrypted_buffer[i], (u32)p_cr[i].size, hash); if (memcmp(p_cr[i].hash, hash, sizeof hash) != 0) { printf("Wrong hash for content #%u\n", i); ret = -1; goto err; } } goto out; err: free_IOS(ios); out: return ret; }