appTicketFile.c 5.82 KB
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <ctype.h>

#include <getopt.h>

#include <PR/bcp.h>
#include <PR/bbmetadata.h>
#include <PR/bbticket.h>

#define PAGE_SIZE	512
#define AES_BLOCK_SIZE  128

#define H2BE4(a) (htonl((a)))
#define H2BE2(a) (htons((a)))
#define BE2H4(a) (ntohl((a)))

void printUsage()
{
    fprintf(stderr, "\nUsage:\n\n"
            "   appTicketFile [-p] [-v] [-d cid] sys_ticket_file ticket1 [ticket2 ...]\n\n"
            " append ticket1, ..., to sys_ticket_file. outputs to same\n"
            " file. if file doesn't exist, creates.\n\n");
}

int main(int argc, char* argv[]) 
{
    FILE *sysTicketFile,*ticketFile;
    u8 *buffer=NULL, * buffer2 = 0;
    u32 numTickets;
    char c;
    int i = 0, prune = 0, newTickets, oldTickets, verbose = 0;
    u32* cidlist;
    u32 deleteCid=0;
    BbTicket* t1, *t2;

    opterr = 0;
    while((c = getopt(argc, argv, "pvd:")) != (char)-1) {
        switch(c) {
	case 'p':
	    prune = 1; break;
	case 'v':
	    verbose = 1; break;
	case 'd':
	    deleteCid = strtoul(optarg, 0, 0); break;
	default:
            printUsage();
	    return 1;
	}
    }

    if((argc-optind)<1){
        fprintf(stderr,
                "\nError: need at least one arg\n\n");
        printUsage();
        return 1;
    }

 bufferInit:
    if((sysTicketFile = fopen(argv[optind], "r"))!=NULL){
        fread(&numTickets,1,4,sysTicketFile);
        numTickets = BE2H4(numTickets);
        buffer = malloc(numTickets*sizeof(BbTicket));
        fread(buffer,1,numTickets*sizeof(BbTicket),sysTicketFile);
        fclose(sysTicketFile);
    }

    if(buffer!=NULL && deleteCid){
        int deleteIndx;
        for(t1 = (BbTicket*)buffer, deleteIndx=0; 
            deleteIndx<numTickets && ntohl(t1->cmd.head.id) != deleteCid; 
            deleteIndx++, t1++){}
        if(deleteIndx == numTickets){
            perror("bad deletion cid\n");
            return -1;
        }
        if((sysTicketFile = fopen(argv[optind], "w"))==NULL){
            perror(argv[optind]);
            return 1;
        }
        numTickets--;
        numTickets = H2BE4(numTickets);
        fwrite(&numTickets,1,4,sysTicketFile);
        numTickets = BE2H4(numTickets);
        for(i=0;i<numTickets+1;i++){
            if(i!=deleteIndx){
                fwrite(buffer+i*sizeof(BbTicket),1,
                       sizeof(BbTicket),sysTicketFile);
            }
        }
        fclose(sysTicketFile);
        deleteCid = 0;
        free(buffer);
        buffer = NULL;
        goto bufferInit;
    }
    
    newTickets = argc-optind-1;
    if (!newTickets) {
	if (verbose) {
	    t1 = (BbTicket*)buffer;
	    for(i = 0; i < numTickets; i++) {
		u8* p;
		int len;
		printf("bb id: 0x%x\n", ntohl(t1->head.bbId));
		printf("ticket id: 0x%x\n", ntohs(t1->head.tid));
		printf("code: 0x%x\n", ntohs(t1->head.code));
		printf("limit: 0x%x\n", ntohs(t1->head.limit));
		printf("ts: %s\n", t1->head.issuer);
		printf("ts crlv: 0x%x\n", ntohl(t1->head.tsCrlVersion));
		printf("content id: 0x%x\n", ntohl(t1->cmd.head.id));
		printf("content size: 0x%x\n", ntohl(t1->cmd.head.size));
		len = ntohs(*(u16*)t1->cmd.contentDesc);
		p = t1->cmd.contentDesc+2+len;
		if (p < &t1->cmd.contentDesc[BB_CMD_DESC_SIZE] && isprint(*p)) {
		    printf("content desc: ");
		    while(isprint(*p)) putchar(*p++);
		    printf("\n");
		}
		printf("content bb id: 0x%x\n", ntohl(t1->cmd.head.bbid));
		printf("content exec: 0x%x\n", ntohl(t1->cmd.head.execFlags));
		printf("content hw rights: 0x%x\n", ntohl(t1->cmd.head.hwAccessRights));
		printf("content sk rights: 0x%x\n", ntohl(t1->cmd.head.secureKernelRights));
		printf("cp: %s\n", t1->cmd.head.issuer);
		printf("cp crlv: %x\n", ntohl(t1->cmd.head.cpCrlVersion));
		printf("cp ca crlv: %x\n", ntohl(t1->cmd.head.caCrlVersion));
                printf("cp hash:\n");
                printf("  %08x\n",ntohl(t1->cmd.head.hash[0]));
                printf("  %08x\n",ntohl(t1->cmd.head.hash[1]));
                printf("  %08x\n",ntohl(t1->cmd.head.hash[2]));
                printf("  %08x\n",ntohl(t1->cmd.head.hash[3]));
                printf("  %08x\n",ntohl(t1->cmd.head.hash[4]));

		printf("\n");
		t1++;
	    }
	}
	return 0;
    }

    if((sysTicketFile = fopen(argv[optind], "w"))==NULL){
        perror(argv[optind]);
        return 1;
    }

    if(buffer!=NULL && !prune){
        oldTickets = numTickets;
        numTickets += newTickets;
        numTickets = H2BE4(numTickets);
        fwrite(&numTickets,1,4,sysTicketFile);
        fwrite(buffer,1,oldTickets*sizeof(BbTicket),sysTicketFile);
    }
    else {
        newTickets = H2BE4(newTickets);
        fwrite(&newTickets,1,4,sysTicketFile);
        newTickets = BE2H4(newTickets);
    }

    buffer2=malloc(sizeof(BbTicket));
    cidlist = malloc(newTickets*sizeof(BbContentId));
    for(optind++; optind<argc; optind++){
        if ((ticketFile = fopen(argv[optind], "r")) == NULL) {
	    perror(argv[optind]);
	    return 1;
	}
        fread(buffer2,1,sizeof(BbTicket),ticketFile);
        fwrite(buffer2,1,sizeof(BbTicket),sysTicketFile);
	cidlist[i++] = ((BbTicket*)buffer2)->cmd.head.id;
    }

    if (prune && buffer) {
	/* write tickets for non-duplicate cids */
	oldTickets = numTickets;
	numTickets = 0;
	t1 = (BbTicket*)(buffer);
	for(i = 0; i < oldTickets; i++) {
	    int j;
	    t2 = (BbTicket*)buffer2;
	    for(j = 0; j < newTickets; j++, t2++)
		if (t2->cmd.head.id == t1->cmd.head.id) {
		    if (verbose)
			printf("keep %x discard %x\n", ntohs(t1->head.tid), ntohs(t2->head.tid));
		    goto skip;
		}
	    fwrite(t1, sizeof *t1, 1, sysTicketFile);
	    numTickets++;
skip:
	    t1++;
	}
	/* update count */
	fseek(sysTicketFile, 0L, SEEK_SET);
        numTickets = H2BE4(numTickets+newTickets);
	fwrite(&numTickets, sizeof numTickets, 1, sysTicketFile);
    }
    fclose(sysTicketFile);
    free(buffer); free(buffer2); free(cidlist);
    return 0;
}