Beispiel #1
0
int
ca_cmd(struct tab *t, struct karg *args)
{
	FILE			*f = NULL;
	int			rv = 1, certs = 0, certs_read;
	struct stat		sb;
	gnutls_datum_t		dt;
	gnutls_x509_crt_t	*c = NULL;
	char			*certs_buf = NULL, *s;

	if ((f = fopen(ssl_ca_file, "r")) == NULL) {
		show_oops(t, "Can't open CA file: %s", ssl_ca_file);
		return (1);
	}

	if (fstat(fileno(f), &sb) == -1) {
		show_oops(t, "Can't stat CA file: %s", ssl_ca_file);
		goto done;
	}

	certs_buf = g_malloc(sb.st_size + 1);
	if (fread(certs_buf, 1, sb.st_size, f) != sb.st_size) {
		show_oops(t, "Can't read CA file: %s", strerror(errno));
		goto done;
	}
	certs_buf[sb.st_size] = '\0';

	s = certs_buf;
	while ((s = strstr(s, "BEGIN CERTIFICATE"))) {
		certs++;
		s += strlen("BEGIN CERTIFICATE");
	}

	bzero(&dt, sizeof dt);
	dt.data = (unsigned char *)certs_buf;
	dt.size = sb.st_size;
	c = g_malloc(sizeof(gnutls_x509_crt_t) * certs);
	certs_read = gnutls_x509_crt_list_import(c, (unsigned int *)&certs, &dt,
	    GNUTLS_X509_FMT_PEM, 0);
	if (certs_read <= 0) {
		show_oops(t, "No cert(s) available");
		goto done;
	}
	show_certs(t, c, certs_read, "Certificate Authority Certificates");
done:
	if (c)
		g_free(c);
	if (certs_buf)
		g_free(certs_buf);
	if (f)
		fclose(f);

	return (rv);
}
int main(
	int   argc,
	char *argv[]
){
	const struct option options[]={
		{ "help",     0, NULL, 'h' },
		{ "verbose",  0, NULL, 'v' },
		{ "reader",   1, NULL, 'r' },
		{ "pin",      1, NULL, 'p' },
		{ "puk",      1, NULL, 'u' },
		{ "pin0",     1, NULL, '0' },
		{ "pin1",     1, NULL, '1' },
		{ NULL, 0, NULL, 0 }
	};
	sc_context_t *ctx;
	sc_context_param_t ctx_param;
	sc_card_t *card;
	int do_help=0, do_unblock=0, do_change=0, do_nullpin=0, do_readcert=0, do_writecert=0;
	u8 newpin[32];
	char *certfile=NULL, *p;
	int r, oerr=0, reader=0, debug=0, newlen=0, pin_nr=-1, cert_nr=-1;
	size_t i;

	while((r=getopt_long(argc,argv,"hvr:p:u:0:1:",options,NULL))!=EOF) switch(r){
		case 'h': ++do_help; break;
		case 'v': ++debug; break;
		case 'r': reader=atoi(optarg); break;
		case 'p': set_pin(pinlist[0].value, &pinlist[0].len, optarg); break;
		case 'u': set_pin(pinlist[1].value, &pinlist[1].len, optarg); break;
		case '0': set_pin(pinlist[2].value, &pinlist[2].len, optarg); break;
		case '1': set_pin(pinlist[3].value, &pinlist[3].len, optarg); break;
		default: ++oerr;
	}
	if(do_help){
		fprintf(stderr,"This is netkey-tool V1.0, May 15 2005, Copyright Peter Koch <*****@*****.**>\n");
		fprintf(stderr,"usage: %s <options> command\n", argv[0]);
		fprintf(stderr,"\nOptions:\n");
		fprintf(stderr,"  -v                       : verbose, may be specified several times\n");
		fprintf(stderr,"  --reader <num>, -r <num> : use reader num (default 0)\n");
		fprintf(stderr,"  --pin <pin>, -p <pin>    : current value of global PIN\n");
		fprintf(stderr,"  --puk <pin>, -u <pin>    : current value of global PUK\n");
		fprintf(stderr,"  --pin0 <pin>, -0 <pin>   : current value of local PIN0\n");
		fprintf(stderr,"  --pin1 <pin>, -1 <pin>   : current value of local PIN1\n");
		fprintf(stderr,"\nCommands:\n");
		fprintf(stderr,"  unblock {pin | pin0 | pin1}\n");
		fprintf(stderr,"  change {pin | puk | pin0 | pin1} <new pin>\n");
		fprintf(stderr,"  nullpin <new pin>\n");
		fprintf(stderr,"  cert <certnum> <filepath>\n");
		fprintf(stderr,"  cert <filepath> <certnum>\n");
		fprintf(stderr,"\nExamples:\n");
		fprintf(stderr,"list PINs and Certs without changing anything. Try this first!!\n");
		fprintf(stderr,"  %s\n", argv[0]);
		fprintf(stderr,"\nlist PINs and Certs and initial PUK-value (after verification of global PIN)\n");
		fprintf(stderr,"  %s --pin 123456\n", argv[0]);
		fprintf(stderr,"\nchange local PIN0 to 654321 after verification of global PIN\n");
		fprintf(stderr,"  %s --pin 123456 change pin0 654321\n", argv[0]);
		fprintf(stderr,"\nchange global PIN from hex 01:02:03:04:05:06 to ascii 123456\n");
		fprintf(stderr,"  %s --pin 01:02:03:04:05:06 change pin 123456\n", argv[0]);
		fprintf(stderr,"\nunblock global PIN with global PUK\n");
		fprintf(stderr,"  %s --puk 12345678 unblock pin\n", argv[0]);
		fprintf(stderr,"\nset global PIN to initial value when in NullPin-state\n");
		fprintf(stderr,"  %s nullpin 123456\n", argv[0]);
		fprintf(stderr,"\nstore Certificate into card at position 2 and read it back into file\n");
		fprintf(stderr,"  %s --pin1 123456 cert /tmp/cert1 2\n", argv[0]);
		fprintf(stderr,"  %s cert 2 /tmp/cert2\n", argv[0]);
		fprintf(stderr,"\nBe carful - this tool may destroy your card\n");
		fprintf(stderr,"\nQuestions? Comments? ==> [email protected]\n");
		exit(1);
	}
	if(optind==argc-2 && !strcmp(argv[optind],"unblock")){
		++optind, do_unblock=1;
		pin_nr=pin_string2int(argv[optind++]);
		if(pin_nr<0 || pin_nr==1) ++oerr;
	}
	if(optind==argc-3 && !strcmp(argv[optind],"change")){
		++optind, do_change=1;
		pin_nr=pin_string2int(argv[optind++]);
		if(pin_nr<0 || pin_nr>3) ++oerr;
		set_pin(newpin,&newlen,argv[optind++]);
	}
	if(optind==argc-2 && !strcmp(argv[optind],"nullpin")){
		++optind, do_nullpin=1;
		set_pin(newpin,&newlen,argv[optind++]);
	}
	if(optind==argc-3 && !strcmp(argv[optind],"cert")){
		++optind;
		cert_nr=strtol(argv[optind],&p,10);
		if(argv[optind][0] && !*p && cert_nr>=0 && cert_nr<(int)(sizeof(certlist)/sizeof(certlist[0]))){
			do_readcert=1, certfile=argv[optind+1];
		} else {
			do_writecert=1, certfile=argv[optind];
			cert_nr=strtol(argv[optind+1],&p,10);
			if(!argv[optind][0] || *p || cert_nr<0 || cert_nr>=(int)(sizeof(certlist)/sizeof(certlist[0]))) ++oerr;
		}
		optind+=2;
	}
	if(oerr || optind!=argc){
		fprintf(stderr,"%s: invalid usage, try --help\n", argv[0]);
		exit(1);
	}

	memset(&ctx_param, 0, sizeof(ctx_param));
	ctx_param.ver      = 0;
	ctx_param.app_name = argv[0];

	r = sc_context_create(&ctx, &ctx_param);
	if(r < 0){
		fprintf(stderr,"Establish-Context failed: %s\n", sc_strerror(r));
		exit(1);
	}
	ctx->debug=debug;
	if(ctx->debug>0)
		printf("Context for application \"%s\" created, Debug=%d\n", ctx->app_name, ctx->debug);

	for(i=0;ctx->card_drivers[i];++i)
		if(!strcmp("tcos", ctx->card_drivers[i]->short_name)) break;
	if(!ctx->card_drivers[i]){
		fprintf(stderr,"Context does not support TCOS-cards\n");
		exit(1);
	}

	printf("%d Reader detected\n", sc_ctx_get_reader_count(ctx));
	for(i=0; i < sc_ctx_get_reader_count(ctx); ++i){
		sc_reader_t *myreader = sc_ctx_get_reader(ctx, i);
		printf("%lu: %s, Driver: %s, %d Slot(s)\n",
			(unsigned long) i, myreader->name,
			myreader->driver->name, myreader->slot_count);
	}
	if(reader < 0 || reader >= (int)sc_ctx_get_reader_count(ctx)){
		fprintf(stderr,"Cannot open reader %d\n", reader);
		exit(1);
	}

	if((r = sc_connect_card(sc_ctx_get_reader(ctx, 0), 0, &card))<0){
		fprintf(stderr,"Connect-Card failed: %s\n", sc_strerror(r));
		exit(1);
	}
	printf("\nCard detected (driver: %s)\nATR:", card->driver->name);
	for(i=0;i<card->atr_len;++i) printf("%c%02X", i?':':' ', card->atr[i]); printf("\n");

	if((r = sc_lock(card))<0){
		fprintf(stderr,"Lock failed: %s\n", sc_strerror(r));
		exit(1);
	}

	show_card(card);

	if(do_unblock || do_change){
		int i1=pinlist[pin_nr].p1, i2=pinlist[pin_nr].p2; 

		if((do_unblock || !pinlist[pin_nr].len) &&
		   (i1<0 || !pinlist[i1].len) && (i2<0 || !pinlist[i2].len)
		){
			fprintf(stderr, "\nNeed %s", do_change ? pinlist[pin_nr].label : pinlist[i1].label);
			if(do_change && i1>=0) fprintf(stderr, " or %s", pinlist[i1].label);
			if(i2>=0) fprintf(stderr, " or %s", pinlist[i2].label);
			fprintf(stderr, " to %s %s\n", do_change ? "change" : "unblock", pinlist[pin_nr].label);
		} else {
			if(do_change && pinlist[pin_nr].len) i1=pin_nr;
			if(i1<0 || !pinlist[i1].len) i1=i2;
			handle_change(card, pin_nr, i1, do_change, newpin, newlen);
		}
	}

	if(do_nullpin){
		handle_nullpin(card, newpin, newlen);
		show_initial_puk(card);
	}

	if(do_readcert) handle_readcert(card, cert_nr, certfile);
	if(do_writecert){
		if(certlist[cert_nr].readonly){
			fprintf(stderr, "\nReadonly-Certificate %d cannot be changed\n", cert_nr);
		} else if(!pinlist[0].len && !pinlist[3].len){
			fprintf(stderr, "\nNeed %s or %s to change Card-Certificate %d\n",
				pinlist[0].label, pinlist[3].label, cert_nr
			);
		} else handle_writecert(card, cert_nr, certfile);
	}

	if(do_unblock+do_change+do_nullpin+do_readcert==0) show_certs(card);

	sc_unlock(card);
	sc_disconnect_card(card,0);
	sc_release_context(ctx);

	exit(0);
}