int main(int argc, char **argv) {
	dongleHandle dongle;
	unsigned char in[260];
	unsigned char out[260];
	unsigned char encodedKey[100];
	int encodedKeyLength;
	uint32_t index;
	int result;
	int sw;
	int apduSize;		

	if (argc < 3) {
		fprintf(stderr, "Usage : %s [encoded private key hex] [index (base 16)]\n", argv[0]);
		return 0;
	}
	encodedKeyLength = hexToBin(argv[1], encodedKey, sizeof(encodedKey));
	if (encodedKeyLength < 0) {
		fprintf(stderr, "Invalid encoded key\n");
		return 0;
	}
	errno = 0;
	index = strtoll(argv[2], NULL, 16);
	if (errno != 0) {
		fprintf(stderr, "Invalid index\n");
		return 0;
	}
	initDongle();
	dongle = getFirstDongle();
	if (dongle == NULL) {
		fprintf(stderr, "No dongle found\n");
		return 0;
	}	
	apduSize = 0;
	in[apduSize++] = BTCHIP_CLA;
	in[apduSize++] = BTCHIP_INS_DERIVE_BIP32_KEY;
	in[apduSize++] = 0x00;
	in[apduSize++] = 0x00;
	in[apduSize++] = 0x00;
	in[apduSize++] = encodedKeyLength;
	memcpy(in + apduSize, encodedKey, encodedKeyLength);
	apduSize += encodedKeyLength;
	writeUint32BE(in + apduSize, index);
	apduSize += sizeof(index);
	in[OFFSET_CDATA] = (apduSize - 5);
	result = sendApduDongle(dongle, in, apduSize, out, sizeof(out), &sw);
	closeDongle(dongle);
	exitDongle();
	if (result < 0) {
		fprintf(stderr, "I/O error\n");
		return 0;
	}
	if (sw != SW_OK) {
		fprintf(stderr, "Dongle application error : %.4x\n", sw);
		return 0;
	}	
	printf("Encoded private key : ");
	displayBinary(out, result);	
	return 1;
}
示例#2
0
void constVal(FILE * f, char * s, struct lin y[mxl])
{
    int i;
    for(i = 0; i < mxl; i++)
    {
        hexToBin(f, y[i].val);
        fprintf(f, "\n");
    }
}
示例#3
0
文件: demo.c 项目: monfort/ffTES
int hexStringToBin(unsigned char *binArray, const char *hexString)
{
	for (;*hexString; binArray++)
	{
		int x = hexToBin(*hexString);
		if (x < 0)
			return 0;
		*binArray = x << 4;
		hexString++;
		if (!*hexString)
			break;
		x = hexToBin(*hexString);
		if (x < 0)
			return 0;
		*binArray |= x;
		hexString++;
	}
	return 1;
}
示例#4
0
int main()
{
	char hex1,hex0;
	scanf("%c%c", &hex1,&hex0);

	hexToBin(hex1,hex0);

	printf("");
	return 0;
}
示例#5
0
int main(void) {
	char hex1[ROZMIAR], hex2[ROZMIAR];

	unsigned char *bin1, *bin2;
	int bin1Size, bin2Size, resultSize;

	scanf("%s", hex1);
    	scanf("%s", hex2);
	
	bin1 = hexToBin(hex1,&bin1Size);
	bin2 = hexToBin(hex2,&bin2Size);

	resultSize = (bin1Size>bin2Size)?bin1Size+1:bin2Size+1;
	unsigned char * result = (unsigned char*)malloc(resultSize);

	add(bin1,bin2,result,bin1Size,bin2Size,resultSize);

	showResult(result,resultSize);

	return 0;
}
示例#6
0
void referTable(FILE * f, char * s, struct tableEntry y[mxl])
{
    int i;
    for(i = 0; i < mxl; i++)
    {
        if (strcmp(s, y[i].name) == 0)
        {
            hexToBin(f, y[i].value);
            fprintf(f, "\n");
        }
    }
}
示例#7
0
int findValue(char * s, FILE * f, struct tableEntry t[mxl])
{
    int i;
    for(i = 0; i < mxl; i++)
    {
        if (strcmp(s, t[i].name) == 0)
        {
            hexToBin(f, t[i].value);
            return 1;
        }
    }
    return 0;
}
示例#8
0
int main(int argc, char **argv) {
	dongleHandle dongle;
	unsigned char pin[8];
	unsigned char in[260];
	unsigned char out[260];
	int result;
	int sw;
	int apduSize;	

	if (argc < 2) {
		fprintf(stderr, "Usage : %s [hex PIN]\n", argv[0]);
		return 0;
	}
	result = hexToBin(argv[1], pin, sizeof(pin));
	if (result == 0) {
		fprintf(stderr, "Invalid PIN\n");
		return 0;
	}
	initDongle();
	dongle = getFirstDongle();
	if (dongle == NULL) {
		fprintf(stderr, "No dongle found\n");
		return 0;
	}
	apduSize = 0;
	in[apduSize++] = BTCHIP_CLA;
	in[apduSize++] = BTCHIP_INS_VERIFY_PIN;
	in[apduSize++] = 0x00;
	in[apduSize++] = 0x00;
	in[apduSize++] = result;
	memcpy(in + apduSize, pin, result);
	apduSize += result;
	result = sendApduDongle(dongle, in, apduSize, out, sizeof(out), &sw);
	exitDongle();
	if (result < 0) {
		fprintf(stderr, "I/O error\n");
		return 0;
	}
	if (sw != SW_OK) {
		fprintf(stderr, "Dongle application error : %.4x\n", sw);
		return 0;
	}
	printf("PIN verified\n");
	if ((out[0] & 0x01) != 0) {
		printf("Powercycle to read the generated seed\n");
	}
	return 1;
}
int main(int argc, char **argv) {
	dongleHandle dongle;
	unsigned char in[260];
	unsigned char out[260];
	int result;
	int sw;
	int apduSize;		
	char pin[100];
	uint32_t lockTime;
	unsigned char sigHashType;
	unsigned int keyPath[10];
	int keyPathLength;		
	int i;

	if (argc < 5) {
		fprintf(stderr, "Usage : %s [key path in a/b/c format using n' for hardened nodes] [second factor ascii, or empty string] [locktime or empty for default] [sighashType or empty for SIGHASH_ALL]\n", argv[0]);
		return 0;
	}
	keyPathLength = convertPath(argv[1], keyPath);
	if (keyPathLength < 0) {
		fprintf(stderr, "Invalid key path\n");
		return 0;
	}
	if (strlen(argv[2]) > sizeof(pin) - 1) {
		fprintf(stderr, "Invalid second factor\n");
		return 0;
	}
	pin[sizeof(pin) - 1] = '\0';	
	strncpy(pin, argv[2], sizeof(pin) - 1);
	if (strlen(argv[3]) == 0) {
		lockTime = 0;
	}
	else {
		result = strtol(argv[3], NULL, 10);
		if (result < 0) {
			fprintf(stderr, "Invalid chain index\n");
			return 0;
		}
		lockTime = result;
	}
	if (strlen(argv[4]) == 0) {
		sigHashType = 0x01;
	}
	else {
		result = hexToBin(argv[4], &sigHashType, sizeof(sigHashType));
		if (result < 0) {
			fprintf(stderr, "Invalid sigHashType\n");
			return 0;
		}
	}
	initDongle();
	dongle = getFirstDongle();
	if (dongle == NULL) {
		fprintf(stderr, "No dongle found\n");
		return 0;
	}	
	apduSize = 0;
	in[apduSize++] = BTCHIP_CLA;
	in[apduSize++] = BTCHIP_INS_HASH_SIGN;
	in[apduSize++] = 0x00;
	in[apduSize++] = 0x00;
	in[apduSize++] = 0x00;
	in[apduSize++] = keyPathLength;
	for (i=0; i<keyPathLength; i++) {
		writeUint32BE(in + apduSize, keyPath[i]);
		apduSize += 4;
	}			
	in[apduSize++] = strlen(pin);
	memcpy(in + apduSize, pin, strlen(pin));
	apduSize += strlen(pin);
	writeUint32BE(in + apduSize, lockTime);
	apduSize += sizeof(lockTime);
	in[apduSize++] = sigHashType;
	in[OFFSET_CDATA] = (apduSize - 5);
	printf("Singing, please wait ...\n");
	result = sendApduDongle(dongle, in, apduSize, out, sizeof(out), &sw);
	closeDongle(dongle);
	exitDongle();
	if (result < 0) {
		fprintf(stderr, "I/O error\n");
		return 0;
	}
	if (sw != SW_OK) {
		fprintf(stderr, "Dongle application error : %.4x\n", sw);
		return 0;
	}	
	printf("Signature + hashtype : ");
	displayBinary(out, result);
	return 1;
}
示例#10
0
// Map escape sequences into their equivalent symbols. Return the equivalent
// ASCII character. s is advanced past the escape sequence. If no escape
// sequence is present, the current character is returned and s
// is advanced by one. The following are recognized:
//
//  \b      backspace
//  \f      formfeed
//  \t      tab
//  \n      newline
//  \r      carriage return
//  \s      space
//  \e      ASCII ESC character ('\033')
//  \^C     C = any letter. Control code ie C-'\x40'
//  \xDD    number formed of 1-2 hex digits
//  \DDD    number formed of 1-3 octal digits
UINT escape(const _TUCHAR *&s) {

  UINT asciiVal;

  if(*s != '\\') {
    asciiVal = *(s++);
  } else {
    s++; // Skip the '\'
    switch(toupper(*s)) {
    case 'B' :
      asciiVal = '\b';
      break;
    case 'F' :
      asciiVal = '\f';
      break;
    case 'T' :
      asciiVal = '\t';
      break;
    case 'N' :
      asciiVal = '\n';
      break;
    case 'R' :
      asciiVal = '\r';
      break;
    case 'S' :
      asciiVal = ' ';
      break;
    case 'E' :
      asciiVal = '\033';
      break;
    case '^' :
      s++;
      asciiVal = *s;
      if (asciiVal >= '\40')
        asciiVal = toupper(asciiVal) - '\40';
      break;

    case 'X' :
      asciiVal = 0;
      s++;
      if (isxdigit(*s))
        asciiVal = hexToBin(*(s++));
      if (isxdigit(*s)) {
        asciiVal <<= 4;
        asciiVal |= hexToBin(*(s++));
      }
      s--;
      break;

    default  :
      if (!isOctalDigit(*s)) {
        asciiVal = *s;
      }
      else {
        s++;
        asciiVal = octalToBin(*(s++));
        if (isOctalDigit(*s)) {
          asciiVal <<= 3;
          asciiVal |= octalToBin(*(s++));
        }
        if (isOctalDigit(*s)) {
          asciiVal <<= 3;
          asciiVal |= octalToBin(*(s++));
        }
        s--;
      }
      break;
    }
    s++;
  }
  return asciiVal;
}
示例#11
0
int main()
{
    char * input;
    printf("%s", "Enter the name of the file you wish to open.);
           scanf("%s", input);
           FILE * ip = fopen(input, "r");
           fseek(ip, 0, SEEK_SET);
           char line[mxl];
           struct lin a[mxl];
           int i;
           for(i = 0; fgets(line, mxl, ip); i++)
           {
           char * word;
           word = strtok(line, " \n\0");
           if(word != NULL)
           {strcpy(a[i].op, word);}
           word = strtok(NULL, " \n\0");
           if(word != NULL)
           {strcpy(a[i].reg, word);}
           word = strtok(NULL, " \n\0");
           if(word != NULL)
           {strcpy(a[i].val, word);}
           word = strtok(NULL, " \n\0");
           if(word != NULL)
           {strcpy(a[i].extra, word);}
       }
           struct tableEntry t[mxl];
           int p;
           int q = 0;
           for(p = 0; p < mxl; p++)
           {


           //NOTE: I intended for addresses to be saved
           //as the position in the array where the variable
           //name was found. For some reason, this does not
           //work and thus renders my JMP implementation
           //useless.
           if (strcmp(a[p].reg, "DC") == 0)
           {
           strcpy(t[q].name, a[p].op);
           t[q].address = p;
           strcpy(t[q].value, a[p].val);
           //printf("%s\n", t[q].name);
           q++;
       }
       }
           FILE * op = fopen("Binarycode.txt", "w");
           int li;
           for(li = 0; li <= mxl; li++)
           {
           //I intended to have more lines in the JMP
           //implementation, but they did not work.

           if (strcmp(a[li].op, "HLT") == 0)
           {
           fprintf(op, "001010");
           fprintf(op, "0000000000");
           return;
       }

           if (strcmp(a[li].reg, "DS") == 0)
           {
           int no = atoi(a[li].val);
           int r = findValue(a[li].op, op, t);
           if(!r)
           {
           int s;
           while(s <= no)
           {
           fprintf(op, "0000000000000000");
           fprintf(op, "\n");
       }
       }
       }

           if (strcmp(a[li].reg, "DC") == 0)
           {
           fprintf(op, "00000000");
           hexToBin(op, a[li].val);
           fprintf(op, "\n");
       }

           if (strcmp(a[li].op, "MOV") == 0)
           {
           //moveIt(a, op);
           fprintf(op, "001101");
           Register(op, a[li].reg);
           if (a[li].val[0] == '&')
           {
           fprintf(op, "00010");
           fprintf(op, "\n");
           char * temp = a[li].val+1;
           //printf("%s\n", temp);
           referTable(op, temp, t);
       }
           else if (a[li].val[0] == '#')
           {
           fprintf(op, "00010");
           fprintf(op, "\n");
           char * temp = a[li].val+1;
           constVal(op, temp, a);
       }
           else
           {
           hexToBin(op, a[li].val);
           fprintf(op, "\n");
       }
       }

           if (strcmp(a[li].op, "ADD") == 0)
           {
           fprintf(op, "010000");
           Register(op, a[li].reg);
           Register(op, a[li].val);
           fprintf(op, "\n");
       }

           if (strcmp(a[li].op, "SUB") == 0)
           {
           fprintf(op, "010001");
           Register(op, a[li].reg);
           Register(op, a[li].val);
           fprintf(op, "\n");
       }

           if (strcmp(a[li].op, "NEG") == 0)
           {
           fprintf(op, "000000");
           Register(op, a[li].reg);
           Register(op, a[li].val);
           fprintf(op, "\n");
       }

           if (strcmp(a[li].op, "AND") == 0)
           {
           fprintf(op, "000001");
           Register(op, a[li].reg);
           Register(op, a[li].val);
           fprintf(op, "\n");
       }

           if (strcmp(a[li].op, "OR") == 0)
           {
           fprintf(op, "000011");
           Register(op, a[li].reg);
           Register(op, a[li].val);
           fprintf(op, "\n");
       }

           if (strcmp(a[li].op, "LSR") == 0)
           {
           fprintf(op, "000100");
           Register(op, a[li].reg);
           Register(op, a[li].val);
           fprintf(op, "\n");
       }

           if (strcmp(a[li].op, "LSL") == 0)
           {
           fprintf(op, "000101");
           Register(op, a[li].reg);
           Register(op, a[li].val);
           fprintf(op, "\n");
       }

           if (strcmp(a[li].op, "XOR") == 0)
           {
           fprintf(op, "000010");
           Register(op, a[li].reg);
           Register(op, a[li].val);
           fprintf(op, "\n");
       }
       }
           return 0;
       }
int main(int argc, char **argv)
{
	BlobList				certs;
	BlobList				roots;
	BlobList				crls;
	int 					rtn;
	CSSM_DL_HANDLE 			dlHand;
	int						loop;
	int 					arg;
	char 					*argp;
	CSSM_DL_DB_HANDLE_PTR	crlDbHandPtr = NULL;
	CSSM_DL_DB_LIST			dlDbList;
	CSSM_DL_DB_HANDLE		dlDbHandles[2];
	CSSM_RETURN				crtn;
	CSSM_RETURN				silent = CSSM_FALSE;
	CSSM_BOOL				scriptPause = CSSM_FALSE;
	
	CertVerifyArgs			vfyArgs;
	memset(&vfyArgs, 0, sizeof(vfyArgs));
	
	vfyArgs.version = CERT_VFY_ARGS_VERS;
	vfyArgs.certs = &certs;
	vfyArgs.roots = &roots;
	vfyArgs.crls = &crls;

	/* for historical reasons the defaults for these are true */
	vfyArgs.crlNetFetchEnable = CSSM_TRUE;
	vfyArgs.certNetFetchEnable = CSSM_TRUE;
	
	/* user-specd variables */
	int 					loops = 1;
	const char				*crlDbName = NULL;
	const char				*certDbName = NULL;
	char					*scriptFile = NULL;
	
	if(argc < 2) {
		usage(argv);
	}
	for(arg=1; arg<argc; arg++) {
		argp = argv[arg];
		if(argp[0] != '-') {
			usage(argv);
		}
		switch(argp[1]) {
			case 'l':
				loops = atoi(&argp[3]);
				break;
			case 'r':
				arg++;
				gatherFiles(crls, argv, argc, arg);
				break;
			case 'c':
				arg++;
				gatherFiles(certs, argv, argc, arg);
				break;
			case 'C':
				arg++;
				gatherFiles(roots, argv, argc, arg);
				break;
			case 'v':
				vfyArgs.verbose = CSSM_TRUE;
				break;
			case 'q':
				vfyArgs.quiet = CSSM_TRUE;
				break;
			case 's':
				vfyArgs.useSystemAnchors = CSSM_TRUE;
				break;
			case 'g':
				vfyArgs.useTrustSettings = CSSM_TRUE;
				break;
			case 'i':
				vfyArgs.implicitAnchors = CSSM_TRUE;
				break;
			case 'a':
				vfyArgs.allowUnverified = CSSM_TRUE;
				break;
			case 'e':
				vfyArgs.expectedErrStr = &argp[3];
				break;
			case 'n':
				vfyArgs.crlNetFetchEnable = CSSM_FALSE;
				break;
			case 'N':
				vfyArgs.certNetFetchEnable = CSSM_FALSE;
				break;
			case 'f':
				vfyArgs.leafCertIsCA = CSSM_TRUE;
				break;
			case 'd':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				certDbName = argv[arg];
				break;
			case 'D':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				crlDbName = argv[arg];
				break;
			case 'S':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				scriptFile = argv[arg];
				break;
			case 'h':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				vfyArgs.sslHost= argv[arg];
				vfyArgs.vfyPolicy = CVP_SSL;
				break;
			case 'E':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				if(vfyArgs.vfyPolicy == CVP_Basic) {
					/* user hasn't specified; now default to SMIME - still 
					 * can override (e.g., for iChat) */
					vfyArgs.vfyPolicy = CVP_SMIME;
				}
				vfyArgs.senderEmail = argv[arg];
				break;
			case 'k':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				vfyArgs.intendedKeyUse = hexToBin(argv[arg]);
				break;
			case 't':
				vfyArgs.sslClient = CSSM_TRUE;
				vfyArgs.vfyPolicy = CVP_SSL;
				break;
			case 'y':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				argp = argv[arg];
				if(parsePolicyString(argp, &vfyArgs.vfyPolicy)) {
					printf("Bogus policyValue (%s)\n", argp);
					printPolicyStrings();
					exit(1);
				}
				break;
			case 'R':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				argp = argv[arg];
				if(!strcmp(argp, "none")) {
					vfyArgs.revokePolicy = CRP_None;
				}
				else if(!strcmp(argp, "crl")) {
					vfyArgs.revokePolicy = CRP_CRL;
				}
				else if(!strcmp(argp, "ocsp")) {
					vfyArgs.revokePolicy = CRP_OCSP;
				}
				else if(!strcmp(argp, "both")) {
					vfyArgs.revokePolicy = CRP_CRL_OCSP;
				}
				else {
					usage(argv);
				}
				break;
			case 'u':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				vfyArgs.responderURI = argv[arg];
				/* no implied policy yet - could be CRP_OCSP or CRP_CRL_OCSP */
				break;
			case 'U':
				if(readFile(argv[arg], (unsigned char **)vfyArgs.responderCert, 
					&vfyArgs.responderCertLen)) {
					printf("***Error reading responderCert from %s. Aborting.\n", 
						argv[arg]);
					exit(1);
				}
				/* no implied policy yet - could be CRP_OCSP or CRP_CRL_OCSP */
				break;
			case 'H':
				vfyArgs.disableCache = CSSM_TRUE;
				break;
			case 'W':
				vfyArgs.disableOcspNet = CSSM_TRUE;
				break;
			case 'Q':
				vfyArgs.requireOcspIfPresent = CSSM_TRUE;
				break;
			case '5':
				vfyArgs.requireOcspForAll = CSSM_TRUE;
				break;
			case 'o':
				vfyArgs.generateOcspNonce = CSSM_TRUE;
				break;
			case 'O':
				vfyArgs.requireOcspRespNonce = CSSM_TRUE;
				break;
			case 'A':
				vfyArgs.requireCrlIfPresent = CSSM_TRUE;
				break;
			case '4':
				vfyArgs.requireCrlForAll = CSSM_TRUE;
				break;
			case 'T':
				arg++;
				if(arg == argc) {
					usage(argv);
				}
				vfyArgs.vfyTime = argv[arg];
				break;
			case 'p':
				printScriptVars();
				exit(0);
			case 'P':
				scriptPause = CSSM_TRUE;
				break;
			case 'L':
				silent = CSSM_TRUE;				// inhibits start banner
				vfyArgs.quiet = CSSM_TRUE;		// inhibits stdout from certVerify
				break;
			default:
				usage(argv);
		}
	}
	
	if((vfyArgs.responderCert != NULL) || (vfyArgs.responderURI != NULL)) {
		switch(vfyArgs.revokePolicy) {
			case CRP_None:
				vfyArgs.revokePolicy = CRP_OCSP;
				break;
			case CRP_OCSP:
			case CRP_CRL_OCSP:
				break;
			case CRP_CRL:
				printf("*** OCSP options (responderURI, responderCert) only valid "
					"with OCSP policy\n");
				usage(argv);
		}
	}
	
	vfyArgs.clHand = clStartup();
	if(vfyArgs.clHand == CSSM_INVALID_HANDLE) {
		return 1;
	}
	vfyArgs.tpHand = tpStartup();
	if(vfyArgs.tpHand == CSSM_INVALID_HANDLE) {
		return 1;
	}
	vfyArgs.cspHand = cspStartup();
	if(vfyArgs.cspHand == CSSM_INVALID_HANDLE) {
		return 1;
	}
	dlHand = dlStartup();
	if(dlHand == CSSM_INVALID_HANDLE) {
		return 1;
	}
	
	if(!silent) {
		testStartBanner("certcrl", argc, argv);
	}

	if(scriptFile) {
		ScriptVars vars;
		vars.allowUnverified		= vfyArgs.allowUnverified;
		vars.requireCrlIfPresent	= vfyArgs.requireCrlIfPresent;
		vars.requireOcspIfPresent	= vfyArgs.requireOcspIfPresent;
		vars.crlNetFetchEnable		= vfyArgs.crlNetFetchEnable;
		vars.certNetFetchEnable		= vfyArgs.certNetFetchEnable;
		vars.useSystemAnchors		= vfyArgs.useSystemAnchors;
		vars.useTrustSettings		= vfyArgs.useTrustSettings;
		vars.leafCertIsCA			= vfyArgs.leafCertIsCA;
		vars.cacheDisable			= vfyArgs.disableCache;
		vars.ocspNetFetchDisable	= vfyArgs.disableOcspNet;
		vars.requireCrlForAll		= vfyArgs.requireCrlForAll;
		vars.requireOcspForAll		= vfyArgs.requireOcspForAll;
		return runScript(scriptFile, vfyArgs.tpHand, vfyArgs.clHand, 
			vfyArgs.cspHand, dlHand,
			&vars, vfyArgs.quiet, vfyArgs.verbose, scriptPause);
	}
	
	/* open DlDbs if enabled */
	dlDbList.NumHandles = 0;
	dlDbList.DLDBHandle = &dlDbHandles[0];
	dlDbList.DLDBHandle[0].DLHandle = dlHand;
	dlDbList.DLDBHandle[1].DLHandle = dlHand;
	if(certDbName != NULL) {
		crtn = CSSM_DL_DbOpen(dlHand,
			certDbName, 
			NULL,			// DbLocation
			CSSM_DB_ACCESS_READ,
			NULL, 			// CSSM_ACCESS_CREDENTIALS *AccessCred
			NULL,			// void *OpenParameters
			&dlDbList.DLDBHandle[0].DBHandle);
		if(crtn) {
			printError("CSSM_DL_DbOpen", crtn);
			printf("***Error opening DB %s. Aborting.\n", certDbName);
			return 1;
		}
		dlDbList.NumHandles++;
		vfyArgs.dlDbList = &dlDbList;
	}
	if(crlDbName != NULL) {
		vfyArgs.crlDlDb = &dlDbList.DLDBHandle[dlDbList.NumHandles];
		crtn = CSSM_DL_DbOpen(dlHand,
			crlDbName, 
			NULL,			// DbLocation
			CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE,
			NULL, 			// CSSM_ACCESS_CREDENTIALS *AccessCred
			NULL,			// void *OpenParameters
			&crlDbHandPtr->DBHandle);
		if(crtn) {
			printError("CSSM_DL_DbOpen", crtn);
			printf("***Error opening DB %s. Aborting.\n", crlDbName);
			return 1;
		}
		dlDbList.NumHandles++;
		vfyArgs.dlDbList = &dlDbList;
	}
	for(loop=0; loop<loops; loop++) {
		rtn = certVerify(&vfyArgs);
		if(rtn) {
			break;
		}

		if(loops != 1) {
			fpurge(stdin);
			printf("CR to continue, q to quit: ");
			char c = getchar();
			if(c == 'q') {
				break;
			}
		}
	}
	return rtn;
}
示例#13
0
int main(int argc, char **argv) {
	dongleHandle dongle;
	unsigned char in[260];
	unsigned char out[260];
	unsigned char encodedKey[100];
	unsigned char hash[32];
	unsigned char signature[100];
	int encodedKeyLength;
	int hashLength;
	int signatureLength;
	int result;
	int sw;
	int apduSize;		

	if (argc < 4) {
		fprintf(stderr, "Usage : %s [uncompressed public key hex] [hash to sign hex] [signature to verify hex]\n", argv[0]);
		return 0;
	}
	encodedKeyLength = hexToBin(argv[1], encodedKey, sizeof(encodedKey));
	if (encodedKeyLength < 0) {
		fprintf(stderr, "Invalid encoded key\n");
		return 0;
	}
	hashLength = hexToBin(argv[2], hash, sizeof(hash));
	if (hashLength < 0) {
		fprintf(stderr, "Invalid hash length\n");
		return 0;
	}
	signatureLength = hexToBin(argv[3], signature, sizeof(signature));
	if (signatureLength < 0) {
		fprintf(stderr, "Invalid signature\n");
		return 0;
	}	
	initDongle();
	dongle = getFirstDongle();
	if (dongle == NULL) {
		fprintf(stderr, "No dongle found\n");
		return 0;
	}	
	apduSize = 0;
	in[apduSize++] = BTCHIP_CLA;
	in[apduSize++] = BTCHIP_INS_SIGNVERIFY_IMMEDIATE;
	in[apduSize++] = 0x80;
	in[apduSize++] = 0x00;
	in[apduSize++] = 0x00;
	in[apduSize++] = encodedKeyLength;
	memcpy(in + apduSize, encodedKey, encodedKeyLength);
	apduSize += encodedKeyLength;	
	in[apduSize++] = hashLength;
	memcpy(in + apduSize, hash, hashLength);	
	apduSize += hashLength;	
	memcpy(in + apduSize, signature, signatureLength);	
	apduSize += signatureLength;		
	in[OFFSET_CDATA] = (apduSize - 5);
	result = sendApduDongle(dongle, in, apduSize, out, sizeof(out), &sw);
	exitDongle();
	if (result < 0) {
		fprintf(stderr, "I/O error\n");
		return 0;
	}
	if (sw != SW_OK) {
		fprintf(stderr, "Dongle application error : %.4x\n", sw);
		return 0;
	}	
	printf("Signature verified.\n");
	return 1;
}
示例#14
0
/* Parses one AVA, starting at *pbp.  Stops at endptr.
 * Advances *pbp past parsed AVA and trailing separator (if present).
 * On any error, returns NULL and *pbp is undefined.
 * On success, returns CERTAVA allocated from arena, and (*pbp)[-1] was
 * the last character parsed.  *pbp is either equal to endptr or
 * points to first character after separator.
 */
static CERTAVA *
ParseRFC1485AVA(PRArenaPool *arena, char **pbp, char *endptr)
{
    CERTAVA *a;
    const NameToKind *n2k;
    char *bp;
    int       vt = -1;
    int       valLen;
    SECOidTag kind  = SEC_OID_UNKNOWN;
    SECStatus rv    = SECFailure;
    SECItem   derOid = { 0, NULL, 0 };
    SECItem   derVal = { 0, NULL, 0};
    char      sep   = 0;

    char tagBuf[32];
    char valBuf[384];

    PORT_Assert(arena);
    if (SECSuccess != scanTag(pbp, endptr, tagBuf, sizeof tagBuf) ||
            !(valLen    = scanVal(pbp, endptr, valBuf, sizeof valBuf))) {
        goto loser;
    }

    bp = *pbp;
    if (bp < endptr) {
        sep = *bp++; /* skip over separator */
    }
    *pbp = bp;
    /* if we haven't finished, insist that we've stopped on a separator */
    if (sep && sep != ',' && sep != ';' && sep != '+') {
        goto loser;
    }

    /* is this a dotted decimal OID attribute type ? */
    if (!PL_strncasecmp("oid.", tagBuf, 4)) {
        rv = SEC_StringToOID(arena, &derOid, tagBuf, strlen(tagBuf));
    } else {
        for (n2k = name2kinds; n2k->name; n2k++) {
            SECOidData *oidrec;
            if (PORT_Strcasecmp(n2k->name, tagBuf) == 0) {
                kind = n2k->kind;
                vt   = n2k->valueType;
                oidrec = SECOID_FindOIDByTag(kind);
                if (oidrec == NULL)
                    goto loser;
                derOid = oidrec->oid;
                break;
            }
        }
    }
    if (kind == SEC_OID_UNKNOWN && rv != SECSuccess)
        goto loser;

    /* Is this a hex encoding of a DER attribute value ? */
    if ('#' == valBuf[0]) {
        /* convert attribute value from hex to binary */
        rv = hexToBin(arena, &derVal, valBuf + 1, valLen - 1);
        if (rv)
            goto loser;
        a = CERT_CreateAVAFromRaw(arena, &derOid, &derVal);
    } else {
        if (kind == SEC_OID_UNKNOWN)
            goto loser;
        if (kind == SEC_OID_AVA_COUNTRY_NAME && valLen != 2)
            goto loser;
        if (vt == SEC_ASN1_PRINTABLE_STRING &&
                !IsPrintable((unsigned char*) valBuf, valLen))
            goto loser;
        if (vt == SEC_ASN1_DS) {
            /* RFC 4630: choose PrintableString or UTF8String */
            if (IsPrintable((unsigned char*) valBuf, valLen))
                vt = SEC_ASN1_PRINTABLE_STRING;
            else
                vt = SEC_ASN1_UTF8_STRING;
        }

        derVal.data = (unsigned char*) valBuf;
        derVal.len  = valLen;
        a = CERT_CreateAVAFromSECItem(arena, kind, vt, &derVal);
    }
    return a;

loser:
    /* matched no kind -- invalid tag */
    PORT_SetError(SEC_ERROR_INVALID_AVA);
    return 0;
}
int main(int argc, char **argv) {
	dongleHandle dongle = NULL;
	unsigned char in[260];
	unsigned char out[260];
	int result;
	int sw;
	int apduSize;		
	uint32_t signingIndex;
	unsigned char newTransaction;
	bitcoinTransaction **transactions = NULL;
	prevout *prevouts = NULL;
	int transactionsNumber = 0;
	int status = 0;
	int i;

	initDongle();
	if (argc < 5) {
		fprintf(stderr, "Usage : %s [NEW for a new transaction|CONTINUE to keep on signing inputs in a previous transaction] [index of input to sign] [redeem script to use or empty to use the default one] [list of transactions output to use in this transaction]\n", argv[0]);
		fprintf(stderr, "Transaction outputs are coded as [hex transaction:output index] to generate a trusted input, or [-hex transaction:output index] to use the prevout directly for an output you don't own (relaxed wallet mode)\n");		
		goto cleanup;
	}
	if (strcasecmp(argv[1], "new") == 0) {
		newTransaction = 0x01;
	}
	else
	if (strcasecmp(argv[1], "continue") == 0) {
		newTransaction = 0x00;
	}
	else {
		fprintf(stderr, "Invalid transaction usage %s\n", argv[1]);
		goto cleanup;
	}
	result = strtol(argv[2], NULL, 10);
	if (result < 0) {
		fprintf(stderr, "Invalid input to sign index\n");
		goto cleanup;
	}
	signingIndex = result;
	transactionsNumber = argc - 1 - 3;
	transactions = (bitcoinTransaction**)malloc(sizeof(bitcoinTransaction*) * transactionsNumber);
	if (transactions == NULL) {
		fprintf(stderr, "Couldn't allocate transactions list\n");
		goto cleanup;
	}
	for (i=0; i<transactionsNumber; i++) {
		transactions[i] = NULL;
	}
	prevouts = (prevout*)malloc(sizeof(prevout) * transactionsNumber);
	if (prevouts == NULL) {
		fprintf(stderr, "Couldn't allocate prevouts list\n");
		goto cleanup;
	}
	dongle = getFirstDongle();
	if (dongle == NULL) {
		fprintf(stderr, "No dongle found\n");
		return 0;
	}	
	// Parse each provided transaction, get the associated trusted input when necessary
	for (i=0; i<transactionsNumber; i++) {
		uint32_t index;
		unsigned char untrusted;
		untrusted = (argv[4 + i][0] == '-');
		transactions[i] = parseTransactionStringWithIndex(argv[4 + i] + (untrusted ? 1 : 0), &index);
		if (transactions[i] == NULL) {
			fprintf(stderr, "Invalid transaction %d\n", i + 1);
			goto cleanup;
		}
		if (untrusted) {
			fprintf(stderr, "Untrusted mode not supported\n");
			goto cleanup;
		}
		else {
			result = getTrustedInput(dongle, transactions[i], index, prevouts[i].prevout, sizeof(prevouts[i].prevout));
			if (result < 0) {
				fprintf(stderr, "Error getting trusted input %d\n", i + 1);
				goto cleanup;
			}
			prevouts[i].isTrusted = 1;
			printf("Trusted input #%d\n", (i + 1));
			displayBinary(prevouts[i].prevout, result);
		}
		prevouts[i].outputIndex = index;
	}
	// Then start building a fake transaction with the inputs we want
	apduSize = 0;
	in[apduSize++] = BTCHIP_CLA;
	in[apduSize++] = BTCHIP_INS_HASH_INPUT_START;
	in[apduSize++] = 0x00;
	in[apduSize++] = (newTransaction ? 0x00 : 0x80);
	in[apduSize++] = 0x00;
	memcpy(in + apduSize, DEFAULT_VERSION, sizeof(DEFAULT_VERSION));
	apduSize += sizeof(DEFAULT_VERSION);
	apduSize += writeVarint(transactionsNumber, (in + apduSize), (sizeof(in) - apduSize));
	in[OFFSET_CDATA] = (apduSize - 5);
	result = sendApduDongle(dongle, in, apduSize, out, sizeof(out), &sw);
	if (result < 0) {
		fprintf(stderr, "I/O error\n");
		return 0;
	}
	if (sw != SW_OK) {
		fprintf(stderr, "Dongle application error : %.4x\n", sw);
		return 0;
	}
	// Each input
	for (i=0; i<transactionsNumber; i++) {
		int scriptLength;
		unsigned char *script;			
		apduSize = 0;
		in[apduSize++] = BTCHIP_CLA;
		in[apduSize++] = BTCHIP_INS_HASH_INPUT_START;
		in[apduSize++] = 0x80;
		in[apduSize++] = 0x00;
		in[apduSize++] = 0x00;
		if (prevouts[i].isTrusted) {
			in[apduSize++] = 0x01;
			in[apduSize++] = sizeof(prevouts[i].prevout);
			memcpy(in + apduSize, prevouts[i].prevout, sizeof(prevouts[i].prevout));
			apduSize += sizeof(prevouts[i].prevout);
		}
		else {
			in[apduSize++] = 0x00;
			in[apduSize++] = PREVOUT_SIZE;
			memcpy(in + apduSize, prevouts[i].prevout, PREVOUT_SIZE);
			apduSize += PREVOUT_SIZE;
		}
		// Get the script length - use either the output script if signing the current index
		// Or a null script
		if (i == signingIndex) {
			if (strlen(argv[3]) != 0) {
				scriptLength = strlen(argv[3]) / 2;
				script = (unsigned char*)malloc(scriptLength);
				if (script == NULL) {
					fprintf(stderr, "Failed to allocate script\n");
					goto cleanup;
				}
				scriptLength = hexToBin(argv[3], script, scriptLength);
				if (scriptLength <= 0) {
					free(script);
					fprintf(stderr, "Invalid redeem script\n");
					goto cleanup;
				}
			}
			else {
				int j;
				bitcoinOutput *output = transactions[i]->outputs;
				for (j=0; j<prevouts[i].outputIndex; j++) {
					output = output->next;
				}
				scriptLength = output->scriptLength;
				script = output->script;
			}
		}
		else {
			scriptLength = 0;
			script = NULL;
		}
		apduSize += writeVarint(scriptLength, (in + apduSize), (sizeof(in) - apduSize));
		if (scriptLength != 0) {
			memcpy(in + apduSize, script, scriptLength);
			apduSize += scriptLength;
		}
		if (strlen(argv[3]) != 0) {
			free(script);
		}
		memcpy(in + apduSize, DEFAULT_SEQUENCE, sizeof(DEFAULT_SEQUENCE));
		apduSize += sizeof(DEFAULT_SEQUENCE);
		in[OFFSET_CDATA] = (apduSize - 5);
		result = sendApduDongle(dongle, in, apduSize, out, sizeof(out), &sw);
		if (result < 0) {
			fprintf(stderr, "I/O error\n");
			return 0;
		}
		if (sw != SW_OK) {
			fprintf(stderr, "Dongle application error : %.4x\n", sw);
			return 0;
		}
	}
	printf("Transaction submitted, waiting to be finalized\n");
	status = 1;

cleanup:
	if (dongle != NULL) {
		closeDongle(dongle);
	}
	exitDongle();

	if (transactions != NULL) {
		for (i = 0; i < transactionsNumber; i++) {
			if (transactions[i] != NULL) {
				freeTransaction(transactions[i]);
			}
		}
	}
	if (prevouts != NULL) {
		free(prevouts);
	}

	return status;
}
int main(int argc, char **argv) {
	bitcoinTransaction *transaction;
	int offset = 0;
	int result;
	int version = DEFAULT_VERSION;
	int lockTime = DEFAULT_LOCKTIME;
	int i;
	int currentIndex = 1;
	bitcoinInput *lastInput = NULL;
	unsigned char *buffer;


	if (argc < 6) {
		fprintf(stderr, "Usage : %s [version (or empty for default)] [locktime (or empty for default)] [dongle output data] [trusted input 1] [input script 1] ... [last trusted input] [last input script]\n", argv[0]);
		return 0;
	}
	if (((argc - 4) % 2) != 0) {
		fprintf(stderr, "Invalid number of trusted input / input script parameters\n");
		return 0;
	}
	if (strlen(argv[1]) != 0) {
		version = strtol(argv[1], NULL, 10);
		if (version < 0) {
			fprintf(stderr, "Invalid version\n");
			return 0;
		}
	}
	if (strlen(argv[2]) != 0) {
		lockTime = strtol(argv[2], NULL, 10);
		if (lockTime < 0) {
			fprintf(stderr, "Invalid lockTime\n");
			return 0;
		}
	}	
	transaction = (bitcoinTransaction*)malloc(sizeof(bitcoinTransaction));
	if (transaction == NULL) {
		fprintf(stderr, "Failed to allocate transaction\n");
		return 0;
	}
	memset(transaction, 0, sizeof(bitcoinTransaction));
	writeUint32LE(transaction->version, version);
	for (i=4; i<argc; i += 2) {
		unsigned char trustedInput[56];
		bitcoinInput *input;
		input = (bitcoinInput*)malloc(sizeof(bitcoinInput));
		if (input == NULL) {
			fprintf(stderr, "Failed to allocate input\n");
			freeTransaction(transaction);
			return 0;
		}
		memset(input, 0, sizeof(bitcoinInput));
		result = hexToBin(argv[i], trustedInput, sizeof(trustedInput));
		if (result <= 0) {
			fprintf(stderr, "Invalid trustedInput %d\n", currentIndex);
			freeTransaction(transaction);
			free(input);
			return 0;
		}
		if (lastInput == NULL) {
			transaction->inputs = input;
		}
		else {
			lastInput->next = input;
		}
		input->scriptLength = (strlen(argv[i + 1]) / 2);
		input->script = (unsigned char*)malloc(input->scriptLength);
		if (input->script == NULL) {
			fprintf(stderr, "Failed to allocate script\n");
			freeTransaction(transaction);
			free(input);			
			return 0;
		}
		result = hexToBin(argv[i + 1], input->script, input->scriptLength);
		if (result <= 0) {
			fprintf(stderr, "Invalid script %d\n", currentIndex);
			freeTransaction(transaction);
			free(input);			
			return 0;
		}
		memcpy(input->prevOut, trustedInput + 4, sizeof(input->prevOut));
		memset(input->sequence, DEFAULT_SEQUENCE, sizeof(input->sequence));
		lastInput = input;
		currentIndex++;
	}	
	buffer = (unsigned char*)malloc(BUFFER_SIZE);
	if (buffer == NULL) {
		fprintf(stderr, "Failed to allocate output buffer\n");
		freeTransaction(transaction);
	}
	offset = writeTransactionWithoutOutputLocktime(transaction, buffer, BUFFER_SIZE);
	freeTransaction(transaction);
	result = hexToBin(argv[3], buffer + offset, BUFFER_SIZE - offset);
	if (result <= 0) {
		fprintf(stderr, "Invalid output\n");
		freeTransaction(transaction);
		free(buffer);
	}
	offset += result;
	writeUint32LE(buffer + offset, lockTime);
	offset += 4;
	printf("Transaction : ");
	displayBinary(buffer, offset);
	free(buffer);
	return 1;
}
static int vfyCertStatus(
	const CSSM_TP_VERIFY_CONTEXT_RESULT *vfyResult, 
	unsigned numCertStatus,
	const char **certStatus,	// e.g., "1:0x18", leading 0x optional
	CSSM_BOOL quiet)
{
	if(numCertStatus == 0) {
		return 0;
	}
	if(vfyResult->NumberOfEvidences != 3) {
		printf("***vfyCertStatus: NumberOfEvidences is %u, expect 3\n",
			(unsigned)vfyResult->NumberOfEvidences);
		return 1;
	}
	
	/* numCerts from evidence[1] */
	const CSSM_EVIDENCE *ev = &vfyResult->Evidence[1];
	const CSSM_CERTGROUP *grp = (const CSSM_CERTGROUP *)ev->Evidence;
	unsigned numCerts = grp->NumCerts;
	/* array of Apple-specific info from evidence[2] */
	ev = &vfyResult->Evidence[2];
	const CSSM_TP_APPLE_EVIDENCE_INFO *info = 
				(const CSSM_TP_APPLE_EVIDENCE_INFO *)ev->Evidence;
	int ourRtn = 0;
	
	for(unsigned dex=0; dex<numCertStatus; dex++) {
		const char *str = certStatus[dex];
		char buf[8];
		unsigned i;
		
		/* 
		 * Format is certNum:status_in_hex
		 * first get the cert number 
		 */
		for(i=0; *str != '\0'; i++, str++) {
			if(*str == ':') {
				break;
			}
			buf[i] = *str;
		}
		if(*str != ':') {
			printf("***Bad certstatus value, format is certNum:status_in_hex\n");
			return 1;
		}
		buf[i] = '\0';
		unsigned certNum = atoi(buf);
		if(certNum > (numCerts-1)) {
			printf("***certerror specified for cert %u, but only %u certs"
				" available\n", certNum, numCerts);
			return 1;
		}
		str++;			// pts to actual desired status string now
		unsigned certStat = hexToBin(str);
		const CSSM_TP_APPLE_EVIDENCE_INFO *thisInfo = &info[certNum];
		if(certStat == thisInfo->StatusBits) {
			if(!quiet) {
				printf("...0x%x per-cert status received as expected\n", certStat);
			}
		}
		else {
			printf("***Expected per cert status 0x%x, got 0x%x\n",
				(unsigned)certStat, (unsigned)thisInfo->StatusBits);
			ourRtn = 1;
		}
	}
	return ourRtn;
}
示例#18
0
int main(int argv, char** argc) {
    if (argv == 1) {
        std::cerr << "Must provide a command and arguments! Try parse, rewrite, compile, assemble\n";
        return 0;
    }
    std::string flag = "";
    std::string command = argc[1];
    std::string input;
    std::string secondInput;
    if (std::string(argc[1]) == "-s") {
        flag = command.substr(1);
        command = argc[2];
        input = "";
        std::string line;
        while (std::getline(std::cin, line)) {
            input += line + "\n";
        }
        secondInput = argv == 3 ? "" : argc[3];
    }
    else {
        if (argv == 2) {
            std::cerr << "Not enough arguments for serpent cmdline\n";
            throw(0);
        }
        input = argc[2];
        secondInput = argv == 3 ? "" : argc[3];
    }
    bool haveSec = secondInput.length() > 0;
    if (command == "parse" || command == "parse_serpent") {
        std::cout << printAST(parseSerpent(input), haveSec) << "\n";
    }
    else if (command == "rewrite") {
        std::cout << printAST(rewrite(parseLLL(input, true)), haveSec) << "\n";
    }
    else if (command == "compile_to_lll") {
        std::cout << printAST(compileToLLL(input), haveSec) << "\n";
    }
    else if (command == "build_fragtree") {
        std::cout << printAST(buildFragmentTree(parseLLL(input, true))) << "\n";
    }
    else if (command == "compile_lll") {
        std::cout << binToHex(compileLLL(parseLLL(input, true))) << "\n";
    }
    else if (command == "dereference") {
        std::cout << printAST(dereference(parseLLL(input, true)), haveSec) <<"\n";
    }
    else if (command == "pretty_assemble") {
        std::cout << printTokens(prettyAssemble(parseLLL(input, true))) <<"\n";
    }
    else if (command == "pretty_compile_lll") {
        std::cout << printTokens(prettyCompileLLL(parseLLL(input, true))) << "\n";
    }
    else if (command == "pretty_compile") {
        std::cout << printTokens(prettyCompile(input)) << "\n";
    }
    else if (command == "assemble") {
        std::cout << assemble(parseLLL(input, true)) << "\n";
    }
    else if (command == "serialize") {
        std::cout << binToHex(serialize(tokenize(input, Metadata(), false))) << "\n";
    }
    else if (command == "flatten") {
        std::cout << printTokens(flatten(parseLLL(input, true))) << "\n";
    }
    else if (command == "deserialize") {
        std::cout << printTokens(deserialize(hexToBin(input))) << "\n";
    }
    else if (command == "compile") {
        std::cout << binToHex(compile(input)) << "\n";
    }
    else if (command == "encode_datalist") {
        std::vector<Node> tokens = tokenize(input);
        std::vector<std::string> o;
        for (int i = 0; i < (int)tokens.size(); i++) {
            o.push_back(tokens[i].val);
        }
        std::cout << binToHex(encodeDatalist(o)) << "\n";
    }
    else if (command == "decode_datalist") {
        std::vector<std::string> o = decodeDatalist(hexToBin(input));
        std::vector<Node> tokens;
        for (int i = 0; i < (int)o.size(); i++)
            tokens.push_back(token(o[i]));
        std::cout << printTokens(tokens) << "\n";
    }
    else if (command == "tokenize") {
        std::cout << printTokens(tokenize(input));
    }
    else if (command == "biject") {
        if (argv == 3)
             std::cerr << "Not enough arguments for biject\n";
        int pos = decimalToUnsigned(secondInput);
        std::vector<Node> n = prettyCompile(input);
        if (pos >= (int)n.size())
             std::cerr << "Code position too high\n";
        Metadata m = n[pos].metadata;
        std::cout << "Opcode: " << n[pos].val << ", file: " << m.file << 
             ", line: " << m.ln << ", char: " << m.ch << "\n";
    }
}
示例#19
0
int main(int argc, char * argv []) {

  long address;
  int loadstore, icount;
  char marker;
  long IC = 0;
  long programIC = 0;
  int i = 0;
  int j = 1;
  int dirty_eviction = 0;
  int load_hits = 0;
  int load_misses = 0;
  int store_hits = 0;
  int store_misses = 0;
  int load = 0;
  int store = 0;
  long et = 0;
  

  // Process the command line arguments
  while (j < argc) {
    if (strcmp ("-a", argv [j]) == 0) {
      j++;
      if (j >= argc)
        print_usage ();
      associativity = atoi (argv [j]);
      j++;
    } else if (strcmp ("-l", argv [j]) == 0) {
      j++;
      if (j >= argc)
        print_usage ();
      blocksize_bytes = atoi (argv [j]);
      j++;
    } else if (strcmp ("-s", argv [j]) == 0) {
      j++;
      if (j >= argc)
        print_usage ();
      cachesize_kb = atoi (argv [j]);
      j++;
    } else if (strcmp ("-mp", argv [j]) == 0) {
      j++;
      if (j >= argc)
        print_usage ();
      miss_penalty = atoi (argv [j]);
      j++;
    } else {
      print_usage ();
    }
  }

  // print out cache configuration
  printf("Cache parameters:\n");
  printf ("Cache Size (KB)\t\t\t%d\n", cachesize_kb);
  printf ("Cache Associativity\t\t%d\n", associativity);
  printf ("Cache Block Size (bytes)\t%d\n", blocksize_bytes);
  printf ("Miss penalty (cyc)\t\t%d\n", miss_penalty);
  printf ("\n");

  //Calculate the tag, index, block offset bits
  int blockOffsetBits = (int)(log(blocksize_bytes)/log(2));
  int set = (int)((cachesize_kb*1024)/(blocksize_bytes*associativity));
  int indexBits = (int)(log(set)/log(2)); 
  int tagBits = 32 - indexBits - blockOffsetBits;
  
  char input[32];
  char output[32];
  char tagBin[32];
  char index[32];
  char blockOffset[32];

  cache newCache[set];
  
  //Initializing cache = null
  for (i=0; i < set; i++)
  {
    for (j=0; j<associativity; j++)
    {
      newCache[i].tag[j] = -1;
      newCache[i].lru[j] = -1;
      newCache[i].dirty[j] = 0;
    }
    newCache[i].valid = 0;
  }


  while (scanf("%c %d %lx %d\n",&marker,&loadstore,&address,&icount) != EOF) {

    //here is where you will want to process your memory accesses  
    //convert address to binary
    sprintf(input, "%lx", address);
    hexToBin(input, output); 
        
    //tag = output[0 - (tagBits-1)];
    //index = output[tagBits -> (tagBits+index-1)];
    for (i = 0; i<tagBits; i++)
    {
      tagBin[i] = output[i];
    }
    tagBin[i] = '\0';

    for (i = 0; i<indexBits; i++)
    {
      index[i] = output[tagBits+i];
    }
    index[i] = '\0';

    //Convert index to dec (indexDec)
    int indexDec = 0;
    int indexi = 0;
    int d = 1;

    for (i= strlen(index) - 1; i>=0; i--)
    {
      indexi = index[i] - '0'; 
      indexDec = indexDec + (d*indexi);
      d = 2 * d;
    }
    
    //Convert tagBin to dec (tagDec)
    int tagDec = 0;
    int tagi = 0;
    d = 1;
    for (i= strlen(tagBin) - 1; i>=0; i--)
    {
      tagi = tagBin[i] - '0'; 
      tagDec = tagDec + (d*tagi);
      d = 2 * d;
    }
    
    //Compare tag
    if (newCache[indexDec].valid == 0)
    {
      newCache[indexDec].valid = 1;
      newCache[indexDec].tag[0] = tagDec;
      newCache[indexDec].lru[0] = 0;

      et = et + miss_penalty;

      if (loadstore == 0)
      {
        //load
        load++;
        load_misses++;
        
      } else {
        //store
        store++;
        store_misses++; 
        newCache[indexDec].dirty[0] = 1;
      }
    }
    else if (newCache[indexDec].valid == 1)
    {
      int hit = 0;
      for (i = 0; i<associativity; i++) 
      {
        if (newCache[indexDec].tag[i] == tagDec)
        {
          // HIT!!!
          hit = 1;
          //update lru
          for (j = 0; j < associativity; j++)
          {
            if ((newCache[indexDec].lru[j] != -1) && (newCache[indexDec].lru[j] < newCache[indexDec].lru[i]))
              newCache[indexDec].lru[j] = newCache[indexDec].lru[j] + 1;
          }
          newCache[indexDec].lru[i] = 0;

          if (loadstore == 0)
          {
            //load
            load++;
            load_hits++;
            
          } else {
            //store
            store++;
            store_hits++;
            newCache[indexDec].dirty[i] = 1;
          }
          break;
        }  
      }

      if (hit == 0)
      {
        // MISS!!!!
        et = et + miss_penalty;

        int found = 0;
        //find the lru block in cache
        for (i = 0; i<associativity; i++)
        {
          if (newCache[indexDec].lru[i] == -1)
          {
            found = 1;
            newCache[indexDec].tag[i] = tagDec;
            //update lru
            for (j = 0; j < i; j++)
            {
                newCache[indexDec].lru[j] = newCache[indexDec].lru[j] + 1;
            }
            newCache[indexDec].lru[i] = 0;
            
            if (loadstore == 0) {
              //load
              load++;
              load_misses++;

            } else {
              //store
              store++;
              store_misses++;
              newCache[indexDec].dirty[i] = 1;
            }  
            break;
          }
        }

        if (found == 0) 
        {
          // all blocks are in use. 
          // replace the highest lru
          int lru1 = 0;
          for (j = 0; j<associativity; j++)
          {
            if (newCache[indexDec].lru[j] == (associativity - 1))
            {
              lru1 = j;
              break;
            }
          }

          newCache[indexDec].tag[lru1] = tagDec;

          for (j = 0; j < associativity; j++)
          {
            newCache[indexDec].lru[j] = newCache[indexDec].lru[j] + 1;
          }
          newCache[indexDec].lru[lru1] = 0;

          if (loadstore == 0) {
            //load
            load++;
            load_misses++;

            if (newCache[indexDec].dirty[lru1] == 1)
            {
              dirty_eviction++;
              et = et+ 2;
              newCache[indexDec].dirty[lru1] = 0;
            } 

          } else {
            //store
            store++;
            store_misses++;
            if (newCache[indexDec].dirty[lru1] == 1)
            {
              dirty_eviction++;
              et = et + 2;
            } else {
                newCache[indexDec].dirty[lru1] = 1;
            }
          }  
        }
      }
    } 
    IC++;
    programIC = programIC + icount;
  }
  
  // Here is where you want to print out stats

  float overall_miss_rate = ((float)load_misses+store_misses)/IC;
  float read_miss_rate = ((float)load_misses)/load;
  float write_miss_rate = ((float)store_misses/store);
  float memory_CPI = ((miss_penalty)*(load_misses+store_misses))/ ((float)programIC);
  float total_CPI = 1 + memory_CPI;
  float AMAT = overall_miss_rate*miss_penalty;

  printf("Simulation results:\n");
  
  //  Use your simulator to output the following statistics.  The 
  //  print statements are provided, just replace the question marks with
  //  your calcuations.
  
  printf("\texecution time %ld cycles\n", et+programIC);
  printf("\tinstructions %ld\n", programIC);
  printf("\tmemory accesses %ld\n", IC);
  printf("\toverall miss rate %.2f\n", overall_miss_rate);
  printf("\tread miss rate %.2f\n", read_miss_rate);
  printf("\tmemory CPI %.2f\n", memory_CPI);
  printf("\ttotal CPI %.2f\n", total_CPI);
  printf("\taverage memory access time %.2f cycles\n",  AMAT);
  printf("dirty evictions %d\n", dirty_eviction);
  printf("load_misses %d\n", load_misses);
  printf("store_misses %d\n", store_misses);
  printf("load_hits %d\n", load_hits);
  printf("store_hits %d\n", store_hits);
}