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

📄 dbx_misc.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
	assert( ( keyIDtype == CRYPT_CERTINFO_FINGERPRINT_SHA || \
			  keyIDtype == CRYPT_IATTRIBUTE_AUTHCERTID ) || \
			( keyIDtype == CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER || \
			  keyIDtype == CRYPT_IATTRIBUTE_ISSUER || \
			  keyIDtype == CRYPT_IATTRIBUTE_SUBJECT || \
			  keyIDtype == CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER || \
			  keyIDtype == CRYPT_IATTRIBUTE_SPKI ) );

	/* Get the attribute from the cert and hash it, unless it's already a
	   hash */
	if( keyIDtype == CRYPT_CERTINFO_FINGERPRINT_SHA || \
		keyIDtype == CRYPT_IATTRIBUTE_AUTHCERTID )
		{
		RESOURCE_DATA msgData;

		setMessageData( &msgData, hashBuffer, CRYPT_MAX_HASHSIZE );
		status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, keyIDtype );
		if( cryptStatusError( status ) )
			return( status );
		assert( msgData.length == KEYID_SIZE );
		}
	else
		{
		DYNBUF idDB;
		HASHFUNCTION hashFunction;
		int hashSize;

		/* Get the attribute data and hash it to get the ID */
		status = dynCreate( &idDB, cryptHandle, keyIDtype );
		if( cryptStatusError( status ) )
			return( status );
		getHashParameters( CRYPT_ALGO_SHA, &hashFunction, &hashSize );
		hashFunction( NULL, hashBuffer, dynData( idDB ), dynLength( idDB ),
					  HASH_ALL );
		assert( hashSize == KEYID_SIZE );
		dynDestroy( &idDB );
		}

	return( makeKeyID( keyIDbuffer, DBXKEYID_BUFFER_SIZE,
					   CRYPT_IKEYID_CERTID, hashBuffer, KEYID_SIZE ) );
	}

/* Get a keyID for a certificate */

int getCertKeyID( char *keyID, const CRYPT_CERTIFICATE iCryptCert )
	{
	int status;

	/* Certificate keyID handling isn't quite as simple as just reading an
	   attribute from the certificate since the subjectKeyIdentifier (if
	   present) may not be the same as the keyID if the cert has come from
	   a CA that does strange things with the sKID.  To resolve this we try
	   and build the key ID from the sKID, if this isn't present we use the
	   keyID (the sKID may have a nonstandard length since it's possible to
	   stuff anything in there, getKeyID() will hash it to the standard size
	   if the length is wrong) */
	status = getKeyID( keyID, iCryptCert,
					   CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER );
	if( !cryptStatusError( status ) )
		return( status );

	/* There's no subjectKeyIdentifier, use the keyID.  Note that we can't
	   just read the CRYPT_IATTRIBUTE_KEYID attribute directly since this
	   may be a data-only cert (either a standalone cert or one from the
	   middle of a chain), so we have to generate it indirectly by hashing
	   the SubjectPublicKeyInfo, which is equivalent to the keyID and is
	   always present in a cert */
	return( getKeyID( keyID, iCryptCert, CRYPT_IATTRIBUTE_SPKI ) );
	}

/* Some internal actions set extended error codes as a result of their 
   operation that the user shouldn't really see.  For example performing a 
   cert cleanup will return a no-data-found error once the last cert is
   reached, which will be read by the user the next time they read the
   CRYPT_ATTRIBUTE_INT_ERRORCODE/CRYPT_ATTRIBUTE_INT_ERRORMESSAGE, even 
   though the error came from a previous internal operation.  To avoid
   this problem, we clean up the error status info when it's been set by
   an internal operation */

int resetErrorInfo( DBMS_INFO *dbmsInfo )
	{
	dbmsInfo->errorCode = 0;
	memset( dbmsInfo->errorMessage, 0, MAX_ERRMSG_SIZE );
	return( CRYPT_OK );
	}

/* Get names and IDs for various items */

char *getKeyName( const CRYPT_KEYID_TYPE keyIDtype )
	{
	switch( keyIDtype )
		{
		case CRYPT_KEYID_NAME:
			return( "CN" );

		case CRYPT_KEYID_URI:
			return( "email" );

		case CRYPT_IKEYID_KEYID:
			return( "keyID" );

		case CRYPT_IKEYID_ISSUERID:
			return( "issuerID" );

		case CRYPT_IKEYID_CERTID:
			return( "certID" );
		}

	assert( NOTREACHED );
	return( "XXXX" );		/* Get rid of compiler warning */
	}

char *getTableName( const KEYMGMT_ITEM_TYPE itemType )
	{
	switch( itemType )
		{
		case KEYMGMT_ITEM_REQUEST:
			return( "certRequests" );

		case KEYMGMT_ITEM_PKIUSER:
			return( "pkiUsers" );

		case KEYMGMT_ITEM_PUBLICKEY:
			return( "certificates" );

		case KEYMGMT_ITEM_REVOCATIONINFO:
			return( "CRLs" );
		}

	assert( NOTREACHED );
	return( "XXXX" );		/* Get rid of compiler warning */
	}

/****************************************************************************
*																			*
*							Database Access Functions						*
*																			*
****************************************************************************/

/* Create a new key database */

static int createDatabase( DBMS_INFO *dbmsInfo, 
						   const BOOLEAN hasPermissions )
	{
	int updateProgress = 0, status;

	/* Create tables for certs, CRLs, cert requests, PKI users, and CA logs.
	   We use CHAR rather than VARCHAR for the ID fields since these always
	   have a fixed length and CHAR is faster than VARCHAR.  In addition we
	   make as many columns as possible NOT NULL since these fields should
	   always be present, and because this is faster for most databases.  The
	   BLOB type is nonstandard, this is rewritten by the database interface
	   layer to the type which is appropriate for the database */
	status = dbmsStaticUpdate(
			"CREATE TABLE certificates ("
				"C CHAR(2), "
				"SP VARCHAR(64), "
				"L VARCHAR(64), "
				"O VARCHAR(64), "
				"OU VARCHAR(64), "
				"CN VARCHAR(64), "
				"email VARCHAR(64), "
				"validTo DATETIME NOT NULL, "
				"nameID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"issuerID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"keyID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"certID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"certData BLOB NOT NULL)" );
	if( cryptStatusError( status ) )
		return( status );
	if( isCertStore( dbmsInfo ) )
		/* The cert store contains in addition to the other CRL fields the
		   certificate expiry time which is used to remove the entry from
		   the CRL table once the certificate has expired anyway, the nameID
		   which is used to force clustering of entries for each CA, and the
		   ID of the cert being revoked, which isn't available if we're
		   creating it from a raw CRL */
		status = dbmsStaticUpdate(
			"CREATE TABLE CRLs ("
				"expiryDate DATETIME NOT NULL, "
				"nameID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"issuerID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL,"
				"certID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"certData BLOB NOT NULL)" );
	else
		status = dbmsStaticUpdate(
			"CREATE TABLE CRLs ("
				"issuerID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL,"
				"certData BLOB NOT NULL)" );
	if( cryptStatusOK( status ) && isCertStore( dbmsInfo ) )
		{
		updateProgress++;
		status = dbmsStaticUpdate(
			"CREATE TABLE pkiUsers ("
				"C CHAR(2), "
				"SP VARCHAR(64), "
				"L VARCHAR(64), "
				"O VARCHAR(64), "
				"OU VARCHAR(64), "
				"CN VARCHAR(64), "
				"nameID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"keyID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"certID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"certData BLOB NOT NULL)" );
		}
	if( cryptStatusOK( status ) && isCertStore( dbmsInfo ) )
		{
		updateProgress++;
		status = dbmsStaticUpdate(
			"CREATE TABLE certRequests ("
				"type SMALLINT NOT NULL, "
				"C CHAR(2), "
				"SP VARCHAR(64), "
				"L VARCHAR(64), "
				"O VARCHAR(64), "
				"OU VARCHAR(64), "
				"CN VARCHAR(64), "
				"email VARCHAR(64), "
				"certID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"certData BLOB NOT NULL)" );
		}
	if( cryptStatusOK( status ) && isCertStore( dbmsInfo ) )
		{
		updateProgress++;
		status = dbmsStaticUpdate(
			"CREATE TABLE certLog ("
				"action SMALLINT NOT NULL, "
				"actionTime DATETIME NOT NULL, "
				"certID CHAR(" TEXT_DBXKEYID_SIZE ") NOT NULL, "
				"reqCertID CHAR(" TEXT_DBXKEYID_SIZE "), "
				"subjCertID CHAR(" TEXT_DBXKEYID_SIZE "), "
				"certData BLOB)" );
		}
	if( cryptStatusError( status ) )
		{
		/* Undo the previous table creations */
		dbmsStaticUpdate( "DROP TABLE certificates" );
		if( updateProgress > 0 )
			dbmsStaticUpdate( "DROP TABLE CRLs" );
		if( updateProgress > 1 )
			dbmsStaticUpdate( "DROP TABLE pkiUsers" );
		if( updateProgress > 2 )
			dbmsStaticUpdate( "DROP TABLE certRequests" );
		return( status );
		}

	/* Create an index for the email address, nameID, issuerID, keyID, and
	   certID in the certificates table, the issuerID and certID in the CRLs
	   table (the CRL nameID isn't indexed since we only use it for linear
	   scans), the nameID and keyID in the PKI users table (the former isn't 
	   used but is made a UNIQUE INDEX to ensure that the same entry can't 
	   be added more than once) and the certID in the cert log (this also 
	   isn't used but is made a UNIQUE INDEX to ensure that the same entry 
	   can't be added more than once).  We have to give these unique names 
	   since some databases don't allow two indexes to have the same name, 
	   even if they're in a different table.  Since most of the fields in 
	   the tables are supposed to be unique, we can specify this for the 
	   indexes we're creating, however we can't do it for the email address 
	   or the nameID in the certs table since there could be multiple certs 
	   present that differ only in key usage.  We don't index the other 
	   tables since indexes consume space and we don't expect to access any
	   of these much */
	status = dbmsStaticUpdate(
			"CREATE INDEX emailIdx ON certificates(email)" );
	if( cryptStatusOK( status ) )
		status = dbmsStaticUpdate(
			"CREATE INDEX nameIDIdx ON certificates(nameID)" );
	if( cryptStatusOK( status ) )
		status = dbmsStaticUpdate(
			"CREATE UNIQUE INDEX issuerIDIdx ON certificates(issuerID)" );
	if( cryptStatusOK( status ) )
		status = dbmsStaticUpdate(
			"CREATE UNIQUE INDEX keyIDIdx ON certificates(keyID)" );

⌨️ 快捷键说明

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