⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tokencommon.c

📁 cryptoboot is set of tools for disk encryption on Unix. It is especially suited to encrypt root par
💻 C
字号:
#include "all.h"#include <stdio.h>#include <readline/readline.h>#include <readline/history.h>#include <stdlib.h>#include "shell.h"#include "util.h"#include "globalvars.h"voidfillUserTab(out_tab, doc)	xmlNodePtr** out_tab;	xmlDocPtr doc;{	xmlNodePtr user, cur, root;	xmlNodePtr* tab;	int i;		/* Count elements */	root = xmlDocGetRootElement(doc);	i = 0;	for (cur = root->xmlChildrenNode; cur != NULL; cur = cur->next)	{		if (0 == xmlStrcmp(cur->name, "users"))		{			for (user = cur->xmlChildrenNode; user != NULL; user = user->next)				if (0 == xmlStrcmp(user->name, "user"))					i++;			break;		}	}	tab = malloc(sizeof(xmlNodePtr) * (i + 1));		i = 0;	for (cur = root->xmlChildrenNode; cur != NULL; cur = cur->next)	{		if (0 == xmlStrcmp(cur->name, "users"))		{			for (user = cur->xmlChildrenNode; user != NULL; user = user->next)				if (0 == xmlStrcmp(user->name, "user"))				{					tab[i]= user;					i++;				}			break;		}	}		tab[i] = (xmlNodePtr) NULL;		*out_tab = tab;		return;}/* If count not null, function puts in it iteration count */intgetUserTokenKey(out_key, out_count, userNode, passphrase)	u_int8_t** out_key;	unsigned long* out_count;	xmlNodePtr userNode;	char* passphrase;{	u_int8_t* pkey; /* passphrase derived key */	u_int8_t* ukey; /* decrypted, userTokenKey */	u_int8_t* ekey; /* encrypted, userTokenKey */	u_int8_t* salt;	u_int8_t* emagicStored;	u_int8_t* emagicComputed;	xmlChar* saltText;	xmlChar* ekeyText;	xmlChar* emagicTextStored;	int saltlen;	int iterationCount;	xmlChar* iterationCountText;	xmlNodePtr cur, bcur;	int ret;	AES_KEY ik;	int result;	result = -1;		/* Get pbkdf2 arguments and key from xml node */	/* Find pbkdf2 tag */	for (bcur = userNode->xmlChildrenNode; bcur != NULL; bcur= bcur->next)	{		if (0 == xmlStrcmp(bcur->name, (const xmlChar*) "pbkdf2"))		{			/* Get iteration count */			iterationCountText = xmlGetProp(bcur, "iterations");			iterationCount = atoi(iterationCountText);			xmlFree(iterationCountText);			/* Get salt and salt length in bytes */			for (cur = bcur->xmlChildrenNode; cur != NULL; cur = cur->next)			{				if (0 == xmlStrcmp(cur->name, (const xmlChar*) "salt"))				{					saltText=xmlNodeListGetString(ctoken,cur->xmlChildrenNode,1);					cleanWhiteSpace((char**)(&saltText));					/* Salt is in hex-string format, so its length					 * in bytes is two times smaller. XML Schema's job					 * is to warn if salt is in bad format					 */									saltlen = strlen(saltText) / 2;					/* Convert salt to byte tab */					hex2byte(&salt, saltText, saltlen);					xmlFree(saltText);					break;				}			}		}		else if (0 == xmlStrcmp(bcur->name, (const xmlChar*) "userkey"))		{			for (cur = bcur->xmlChildrenNode; cur != NULL; cur = cur->next)			{				if (0 == xmlStrcmp(cur->name, (const xmlChar*) "key128"))				{					ekeyText = xmlNodeListGetString(ctoken,				 																  cur->xmlChildrenNode, 1);					cleanWhiteSpace((char**)(&ekeyText));					/* Convert key to byte tab */					hex2byte(&ekey, ekeyText, 128/8);					xmlFree(ekeyText);				}				else if (0 == xmlStrcmp(cur->name, (const xmlChar*) "encmagic"))				{					emagicTextStored = xmlNodeListGetString(ctoken,				 																  cur->xmlChildrenNode, 1);					cleanWhiteSpace((char**)(&emagicTextStored));					/* Convert key to byte tab */					hex2byte(&emagicStored, emagicTextStored, 128/8);					xmlFree(emagicTextStored);				}			}		}	}	/* Transform passphrase, salt and interation count into pkey	 * using pbkdf2 as key derivation function */	ret = pkcs5_pbkdf2(&pkey, 128/8, passphrase, strlen(passphrase),										 salt, saltlen, iterationCount);	free(salt);	if (ret != 0)	{		printf("pbkdf2 error.\n");		exit(1);	}	else	{		ukey = (u_int8_t*) malloc(128/8);		/* Dekrypt userTokenKey using pkey as a key */		AES_set_decrypt_key(pkey, 128, &ik);		/* FIXME: current implementation decrypts data only		 * 				one-block long - if user wants longer data		 * 				it will not work.		 */		AES_ecb_encrypt(ekey, ukey, &ik, AES_DECRYPT);		free(ekey);		free(pkey);		/* Encrypt magic string with ukey to see if passphrase is correct */		emagicComputed = (u_int8_t*) malloc(128/8);		AES_set_encrypt_key(ukey, 128, &ik);		AES_ecb_encrypt(MAGIC_STRING, emagicComputed, &ik, AES_ENCRYPT);		if (0 == memcmp(emagicComputed, emagicStored, 128/8))		{			*out_key = ukey;			if (NULL != out_count)				*out_count = iterationCount;			result = 1;		}		free(emagicStored);		free(emagicComputed);	}		return result;}/* Returns 1 if correct token detected, 0 if not, -1 if fatal error */intgetTokenConfig(dev, type, mnt, filename, out_result)	char* dev;	char* type;	char* mnt;	char* filename;	char** out_result;{	char* name;	char* tmpname;	xmlDocPtr tmpDoc;	int ret, fd, result;	/* Construct full name of token config file */	xstrcat(&tmpname, mnt, "/");	xstrcat(&name, tmpname, filename);	free(tmpname);	/* Try to open device to see if it is inserted */	fd = open(dev, O_RDONLY);	if (fd == -1)	{		result = 0;		if (errno == EACCES)			*out_result = "permission denied";		else			*out_result = "not detected";	}	else	{		ret = close(fd);		if (-1 == ret)		{			*out_result = "closing device failed";			result = -1;		}		else		{			/* Try to mount device readonly using given fstype */			ret = mount(dev, mnt, type, 0xC0ED0000 | MS_RDONLY, NULL);			if (ret == -1)			{				*out_result = "mounting error";				result = 0;			}			else			{				/* Check existence of token config file */				fd = open(name, O_RDONLY);				if (fd == -1) 				{					ret = umount(mnt);					if (ret == -1)					{						*out_result = "umounting error";						result = -1;					}					else					{						*out_result = "config file not found";						result = 0;					}				}				else				{					ret = close(fd);					if (-1 == ret)					{						*out_result = "closing file failed";						result = -1;					}					else					{						/* Parse token config file */						tmpDoc = xmlParseFile(name);						if (NULL == tmpDoc)						{							ret = umount(mnt);							if (ret == -1)							{								*out_result = "umounting error";								result = -1;							}							else							{								*out_result = "config file parsing error";								return 0;							}						}						else						{							/* Umount fs */							ret = umount(mnt);							if (-1 == ret)							{								*out_result = "umounting error";								result = -1;							}							else							{								/* Return xmlDocPtr */								ctoken = tmpDoc;								*out_result = "detected";								result = 1;							}						}					}				}			}		}	}	free(name);	return result;}/* Joins tokenTab with diskTab on encmagic */intjoinUNodeTabs(out_tTab, out_dTab, tokenTab, diskTab)	xmlNodePtr** out_tTab;	xmlNodePtr** out_dTab;	xmlNodePtr* tokenTab;	xmlNodePtr* diskTab;{	xmlChar* temagic;	xmlChar* demagic;	int i;	int j;	int tokenCount, diskCount, tabIndex;	xmlNodePtr* ttab;	xmlNodePtr* dtab;	xmlNodePtr cur;	size_t tabMaxSize;			for (i = 0; NULL != tokenTab[i]; i++);	tokenCount = i;	for (i = 0; NULL != diskTab[i]; i++);	diskCount = i;	tabMaxSize = sizeof(xmlNodePtr) * (tokenCount + diskCount + 1);		ttab = (xmlNodePtr*) malloc(tabMaxSize);	dtab = (xmlNodePtr*) malloc(tabMaxSize);	tabIndex = 0;	for (i = 0; NULL != tokenTab[i]; i++)		for (j = 0; NULL != diskTab[j]; j++)		{			for (cur = tokenTab[i]->xmlChildrenNode;					 NULL != cur; cur = cur->next)			{				if (0 == xmlStrcmp(cur->name, "userkey"))				{					for (cur = cur->xmlChildrenNode;							 NULL != cur; cur = cur->next)					{						if (0 == xmlStrcmp(cur->name, "encmagic"))						{							temagic = xmlNodeListGetString(ctoken,												cur->xmlChildrenNode, 1);							break;						}					}					break;				}			}						for (cur = diskTab[j]->xmlChildrenNode;					 NULL != cur; cur = cur->next)			{				if (0 == xmlStrcmp(cur->name, "encmagic"))				{					demagic = xmlNodeListGetString(ctab,										cur->xmlChildrenNode, 1);					break;				}			}			cleanWhiteSpace((char**) (&temagic));			cleanWhiteSpace((char**) (&demagic));			if (0 == xmlStrcmp(temagic, demagic))			{				ttab[tabIndex] = tokenTab[i];				dtab[tabIndex] = diskTab[j];				tabIndex++;			}			xmlFree(temagic);			xmlFree(demagic);		}		ttab = (xmlNodePtr*) realloc(ttab, sizeof(xmlNodePtr) * tabIndex);	dtab = (xmlNodePtr*) realloc(dtab, sizeof(xmlNodePtr) * tabIndex);		*out_tTab = ttab;	*out_dTab = dtab;		return tabIndex;}/* We do not verify encmagic in <user> node, because it is * the same as in token. It is verified in getUserTokenKey. * Last but not least - users with encmagic mismatch are not * listed in user select window. */intdecryptMasterKey(out_masterKey, userTokenKey, userNode)	u_int8_t** out_masterKey;	u_int8_t* userTokenKey;	xmlNodePtr userNode;{	u_int8_t* mkey;	u_int8_t* ekey;	u_int8_t* emagicStored;	u_int8_t* emagicCurrent;	xmlChar* ekeyText;	xmlChar* emagicStoredText;	AES_KEY ik;	xmlNodePtr cur, root;	int ret;	int fresult = -1;		/* Get encrypted master key */	for (cur = userNode->xmlChildrenNode; cur != NULL; cur=cur->next)	{		if (0 == xmlStrcmp(cur->name, "key128"))		{			ekeyText = xmlNodeListGetString(ctab, cur->xmlChildrenNode, 1);			cleanWhiteSpace((char**)(&ekeyText));			ret = hex2byte(&ekey, ekeyText, 128/8);			if (ret == -1)			{				printf("Internal error.\n");				exit(1);			}			else			{				/* Decrypt master key using userTokenKey */				AES_set_decrypt_key(userTokenKey, 128, &ik);					mkey = malloc(128/8);								/* FIXME: current implementation decrypts data only				 * 				one-block long - if user wants longer data				 * 				it will not work.				 */				AES_ecb_encrypt(ekey, mkey, &ik, AES_DECRYPT);				free(ekey);							/* Check encmagic for master key */				root = xmlDocGetRootElement(ctab);				for (cur = root->xmlChildrenNode; NULL != cur; cur = cur->next)				{					if (0 == xmlStrcmp(cur->name, "encmagic"))					{						emagicStoredText = xmlNodeListGetString(ctab,															 cur->xmlChildrenNode, 1);						cleanWhiteSpace((char**) (&emagicStoredText));						emagicStored = (u_int8_t*) malloc(128/8);						hex2byte(&emagicStored, emagicStoredText, 128/8);						xmlFree(emagicStoredText);												emagicCurrent = (u_int8_t*) malloc(128/8);						AES_set_encrypt_key(mkey, 128, &ik);						AES_ecb_encrypt(MAGIC_STRING,emagicCurrent,&ik,AES_ENCRYPT);												if (0 == memcmp(emagicCurrent, emagicStored, 128/8))						{							(*out_masterKey) = mkey;							fresult = 1;						}						free(emagicCurrent);						free(emagicStored);						break;					}				}			}			xmlFree(ekeyText);			break;		}	}		return fresult;}/* When out_dUserNode is NULL then user will choose from token * users - even if these users are not it ctab; * of course no ctab node will be returned in out_dUserNode then */intpromptForUser(out_tUserNode, out_dUserNode)	xmlNodePtr* out_tUserNode;	xmlNodePtr* out_dUserNode;{	xmlNodePtr* tokenTab;	xmlNodePtr* diskTab;	xmlNodePtr* dUNodeTab;	xmlNodePtr* tUNodeTab;	int ret, i, userCount;	int result = -1;	xmlChar* name;	unsigned long sel;	char* selText;			fillUserTab(&tokenTab, ctoken);	fillUserTab(&diskTab, ctab);	if (NULL != out_dUserNode)	{		userCount = joinUNodeTabs(&tUNodeTab,&dUNodeTab,tokenTab,diskTab);	}	else	{		for (i = 0; NULL != tokenTab[i]; i++);		userCount = i;		fillUserTab(&dUNodeTab, ctoken);		fillUserTab(&tUNodeTab, ctoken);	}			if (0 == userCount)	{		for (i = 0; NULL != tokenTab[i]; i++);		if (0 == i)		{			printf("No users on token found.\n");		}		else		{			printf("No user on token is allowed to access this machine.\n");		}		result = -1;	}	else if (1 == userCount)	{		name = xmlGetProp(tUNodeTab[0], "name");		printf("User '%s' found.\n", name);		xmlFree(name);		*out_tUserNode = tUNodeTab[0];		if (NULL != out_dUserNode)			*out_dUserNode = dUNodeTab[0];		result = 1;	}	else	{		printf("  #\tUser\n");		for (i = 0; i < userCount; i++)		{			name = xmlGetProp(tUNodeTab[i], "name");			printf(" %2d\t%s\n", i, name);			xmlFree(name);		}		selText = readline("Select user: ");		if (NULL != selText)		{			ret = str2num(&sel, selText);			if (-1 != ret)			{				if ((sel < userCount) && (sel >= 0))				{					*out_tUserNode = tUNodeTab[sel];					if (NULL != out_dUserNode)						*out_dUserNode = dUNodeTab[sel];					name = xmlGetProp(tUNodeTab[sel], "name");					printf("You have selected '%s'.\n", name);					xmlFree(name);					result = 1;				}				else					printf("No such user.\n");			}			else				printf("Bad index '%s'.\n", selText);			free(selText);		}		else			printf("\n");	}		free(diskTab);	free(tokenTab);	free(dUNodeTab);	free(tUNodeTab);	return result;}/* Prints index and user name from node tab entry given by this index *//* If user name is empty prints "-" (usefull, when someone don't want * to save user names in cryptotab) */voidprintUserLine(index, node)	int index;	xmlNodePtr node;{	xmlChar* name;	name = xmlGetProp(node, "name");	if (NULL != name)	{		printf(" %2d\t%s\n", index, name);		xmlFree(name);	}	else		printf(" %2d\t%s\n", index, "-");			return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -