bbcert.c 3.76 KB
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <getopt.h>
#include <bbtoolsapi.h>

int
main(int argc, char* argv[]) {
    BbId bbid = 1;
    BbEccPrivateKey pvt;
    BbEccPublicKey pub;
    BbServerName issuername;
    BbServerSuffix subjectname;
    BbEccCert cert;
    FILE* fp = stdout;
    int c, i, usepub = 0, dump = 0, verbose = 0, fix = 0, bbidmunge = 0;

    /*XXXblythe default values from v2Create.c*/
    pvt[0] = (0xa8190276);
    pvt[1] = (0x7e25db17);
    pvt[2] = (0x0f3449c5);
    pvt[3] = (0xd94b162f);
    pvt[4] = (0xa8190276);
    pvt[5] = (0x7e25db17);
    pvt[6] = (0x0f3449c5);
    pvt[7] = (0xd94b162f);

    while ((c = getopt(argc, argv, "b:p:P:hdfvB")) != EOF) {
        switch (c) {
        case 'b':
            bbid = strtoul(optarg, 0, 0); break;
        case 'p':
            for(i = 0; i < sizeof pvt/4; i++)
		sscanf(optarg+8*i, "%08lx", pvt+i);
	    break;
	case 'P':
            for(i = 0; i < sizeof pub/4; i++) 
		sscanf(optarg+8*i, "%08lx", pub+i);
	    usepub++;
	    break;
	case 'd':
	    dump = 1; break;
	case 'f':
	    fix = 1; break;
	case 'B':
	    bbidmunge = 1; break;
	case 'v':
	    verbose = 1; break;
        case 'h':  /* Help */
        default:
	usage:
            fprintf(stderr, "Usage: bbcert [-b bbid] [-p private_key | -P public_key] [-d -v] [-f] [-B] [file]\n");
            return 1;
        }
    }

    if (dump) {
	int i;
	time_t t;
	if (optind >= argc)
	    fp = stdin;
	else if ((fp = fopen(argv[optind], "r")) == NULL) {
	    perror(argv[1]);
	    return 1;
	}
	fread(&cert, sizeof cert, 1, fp);
	if (!verbose) {
	    printf("%ld ", strtoul(cert.certId.name.bbid+2, 0, 16));
	    for(i = 0; i < sizeof cert.publicKey/4; i++)
		printf("%08x", (int)ntohl(cert.publicKey[i]));
	    printf("\n");
	    return 0;
	}
	printf("cert type: %x\n", (int)cert.certId.certType);
	printf("sig type: %x\n", (int)cert.certId.sigType);
	t = ntohl(cert.certId.date);
	printf("expire date: %s", ctime(&t));
	printf("issuer: %s\n", cert.certId.issuer);
	printf("name: %s\n", cert.certId.name.bbid);
	printf("public key:\n    ");
	for(i = 0; i < sizeof cert.publicKey/sizeof cert.publicKey[0]; i++) {
	    printf("%08x ", (int)ntohl(cert.publicKey[i]));
	    if (i%16 == 7) printf("\n    ");
	}
	printf("\nsig:\n    ");
	for(i = 0; i < sizeof cert.signature.ecc/sizeof cert.signature.ecc[0]; i++) {
	    printf("%08x ", (int)ntohl(cert.signature.ecc[i]));
	    if (i%16 == 7) printf("\n    ");
	}
	printf("\n");

	return 0;
    } else if (fix || bbidmunge) {
	if (optind >= argc) goto usage;
	if ((fp = fopen(argv[optind], "r+")) == NULL) {
	    perror(argv[1]);
	    return 1;
	}
	fread(&cert, sizeof cert, 1, fp);
        if(fix){
	    for(i = 0; i < sizeof pub/4; i++)
	        cert.publicKey[i] = htonl(cert.publicKey[i]);
        }
        else{
            BbName tmp;
            long unsigned int c;
            strcpy((char *)&tmp,(char *)&cert.certId.name.bbid);
            tmp[0]='0';
            tmp[1]='x';
            c = strtoul(tmp,0,0);
            c ^= 1;
            sprintf(cert.certId.name.bbid+2,"%08lx",c);
        }
	fseek(fp, 0L, SEEK_SET);
	fwrite(&cert, sizeof cert, 1, fp);
	fclose(fp);
	return 0;
    } else {
	if (optind < argc && (fp = fopen(argv[optind], "w")) == NULL) {
	    perror(argv[optind]);
	    return 1;
	}
    }

    memset(issuername, 0, sizeof issuername);
    strcpy(issuername, "Root-MSCA00010203-MS0a0b0c0d");
    memset(subjectname, 0, sizeof subjectname);
    sprintf(subjectname, "BB%08lx", bbid);

    generateUnsignedBbCert(BB_CERT_TYPE_BB,
	    BB_SIG_TYPE_RSA2048,
	    0x09062003,
	    subjectname,
	    issuername, pvt, (u32*)&cert, sizeof cert);
    
    if (usepub) {
	for(i = 0; i < sizeof pub/4; i++)
	    cert.publicKey[i] = htonl(pub[i]);
    }
    fwrite(&cert, sizeof cert, 1, fp);
    return 0;
}