Beispiel #1
0
INT
CLNewKeyserver (HWND hWndParent, HWND hWndTree)
{
	PKEYSERVERSTRUCT pkss;

	pkss = (PKEYSERVERSTRUCT)clAlloc (sizeof(KEYSERVERSTRUCT));
	if (!pkss) return 1;

	pkss->hWndTree = hWndTree;
	pkss->bEdit = FALSE;

	pkss->szServer[0] = '\0';
	pkss->iPort = 0;
	pkss->iType = kPGPKeyServerType_LDAP;
	LoadString (g_hInst, IDS_UNKNOWNKEY, pkss->szUserIDAuth, 
					sizeof(pkss->szUserIDAuth));
	pkss->szDomain[0] = '\0';
	pkss->bListed = TRUE;
	pkss->bRoot = FALSE;
	pkss->authAlg = kPGPPublicKeyAlgorithm_Invalid;
	pkss->pOrigStruct = NULL;

	if (!DialogBoxParam (g_hInst, MAKEINTRESOURCE(IDD_NEWSERVER), hWndParent, 
				sEditServerDlgProc, (LPARAM)pkss)) {
		clFree (pkss);
		SetFocus (hWndTree);
		return 0;
	}

	sSetOneKSItem (hWndTree, pkss); 
	InvalidateRect (hWndTree, NULL, TRUE);

	++uNumberOfServers;

	EnableWindow (GetDlgItem (hWndParent, IDC_REMOVEKEYSERVER), 
						FALSE);
	EnableWindow (GetDlgItem (hWndParent, IDC_EDITKEYSERVER),
						FALSE);
	EnableWindow (GetDlgItem (hWndParent, IDC_SETASROOT),
						FALSE);

	return 0;
}
static int calculateCertStorage( const PKCS15_INFO *pkcs15infoPtr,
								 OUT_PTR void **newCertDataPtr, 
								 OUT_LENGTH_SHORT_Z int *newCertDataSize,
								 IN_LENGTH_SHORT const int certAttributeSize,
								 IN_LENGTH_SHORT const int certSize )
	{
	void *newCertData;

	assert( isReadPtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) );
	assert( isWritePtr( newCertDataPtr, sizeof( void * ) ) );
	assert( isWritePtr( newCertDataSize, sizeof( int ) ) ); 

	REQUIRES( certAttributeSize > 0 && \
			  certAttributeSize < MAX_INTLENGTH_SHORT );
	REQUIRES( certSize > 0 && certSize < MAX_INTLENGTH_SHORT );

	/* Calculate the new certificate data size */
#ifdef USE_PKCS15V12_FORM
	*newCertDataSize = sizeofObject( certAttributeSize + \
									 sizeofObject( \
									   sizeofObject( \
										 sizeofObject( certSize ) ) ) );
#else
	*newCertDataSize = sizeofObject( certAttributeSize + \
									 sizeofObject( \
									   sizeofObject( certSize ) ) );
#endif /* USE_PKCS15V12_FORM */
	ENSURES( *newCertDataSize > 0 && *newCertDataSize < MAX_INTLENGTH );

	/* If the new data will fit into the existing storage, we're done */
	if( *newCertDataSize <= pkcs15infoPtr->certDataSize )
		return( CRYPT_OK );

	/* Allocate storage for the new data */
	newCertData = clAlloc( "calculateCertStorage", *newCertDataSize );
	if( newCertData == NULL )
		return( CRYPT_ERROR_MEMORY );
	*newCertDataPtr = newCertData;

	return( CRYPT_OK );
	}
Beispiel #3
0
static int calculatePubkeyStorage( const PKCS15_INFO *pkcs15infoPtr,
								   INOUT_PTR void **newPubKeyDataPtr, 
								   OUT_LENGTH_SHORT_Z int *newPubKeyDataSize, 
								   IN_LENGTH_SHORT const int pubKeySize,
								   IN_LENGTH_SHORT const int pubKeyAttributeSize,
								   IN_LENGTH_SHORT const int extraDataSize )
	{
	void *newPubKeyData;

	assert( isReadPtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) );
	assert( isWritePtr( newPubKeyDataPtr, sizeof( void * ) ) );
	assert( isWritePtr( newPubKeyDataSize, sizeof( int ) ) ); 

	REQUIRES( pubKeySize > 0 && pubKeySize < MAX_INTLENGTH_SHORT );
	REQUIRES( pubKeyAttributeSize > 0 && \
			  pubKeyAttributeSize < MAX_INTLENGTH_SHORT );
	REQUIRES( extraDataSize >= 0 && extraDataSize < MAX_INTLENGTH_SHORT );

	/* Calculate the new private-key data size */
	*newPubKeyDataSize = sizeofObject( \
							pubKeyAttributeSize + \
							sizeofObject( \
								sizeofObject( \
									sizeofObject( pubKeySize ) + \
									extraDataSize ) ) );
	ENSURES( *newPubKeyDataSize > 0 && \
			 *newPubKeyDataSize < MAX_BUFFER_SIZE );

	/* If the new data will fit into the existing storage, we're done */
	if( *newPubKeyDataSize <= pkcs15infoPtr->pubKeyDataSize )
		return( CRYPT_OK );

	/* Allocate storage for the new data */
	newPubKeyData = clAlloc( "calculatePubkeyStorage", *newPubKeyDataSize );
	if( newPubKeyData == NULL )
		return( CRYPT_ERROR_MEMORY );
	*newPubKeyDataPtr = newPubKeyData;

	return( CRYPT_OK );
	}
Beispiel #4
0
	struct addrinfo *addrInfoPtr;
	struct sockaddr_in *sockAddrPtr;

	assert( prevAddrInfoPtr == NULL || \
			isWritePtr( prevAddrInfoPtr, sizeof( struct addrinfo ) ) );
	assert( isWritePtr( addrInfoPtrPtr, sizeof( struct addrinfo * ) ) );
	assert( isReadPtr( address, addrLen ) );
	
	REQUIRES( addrLen == IP_ADDR_SIZE );
	REQUIRES( port >= 22 && port < 65536L );

	/* Clear return value */
	*addrInfoPtrPtr = NULL;

	/* Allocate the new element, clear it, and set fixed fields for IPv4 */
	addrInfoPtr = clAlloc( "addAddrInfo", sizeof( struct addrinfo ) );
	sockAddrPtr = clAlloc( "addAddrInfo", sizeof( struct sockaddr_in ) );
	if( addrInfoPtr == NULL || sockAddrPtr == NULL )
		{
		if( addrInfoPtr != NULL )
			clFree( "addAddrInfo", addrInfoPtr );
		if( sockAddrPtr != NULL )
			clFree( "addAddrInfo", sockAddrPtr );
		return( -1 );
		}
	memset( addrInfoPtr, 0, sizeof( struct addrinfo ) );
	memset( sockAddrPtr, 0, sizeof( struct sockaddr_in ) );
	if( prevAddrInfoPtr != NULL )
		prevAddrInfoPtr->ai_next = addrInfoPtr;
	addrInfoPtr->ai_family = PF_INET;
	addrInfoPtr->ai_socktype = SOCK_STREAM;
Beispiel #5
0
static int getCapabilities( DEVICE_INFO *deviceInfo,
							const PKCS11_MECHANISM_INFO *mechanismInfoPtr, 
							const int maxMechanisms )
	{
	CAPABILITY_INFO_LIST *capabilityInfoListTail = \
				( CAPABILITY_INFO_LIST * ) deviceInfo->capabilityInfoList;
	int i;

	assert( isWritePtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
	assert( isReadPtr( mechanismInfoPtr, \
					   maxMechanisms * sizeof( PKCS11_MECHANISM_INFO ) ) );

	static_assert( sizeof( CAPABILITY_INFO ) == sizeof( VARIABLE_CAPABILITY_INFO ),
				   "Variable capability-info-struct" );

	/* Find the end of the list to add new capabilities */
	if( capabilityInfoListTail != NULL )
		{
		while( capabilityInfoListTail->next != NULL )
			capabilityInfoListTail = capabilityInfoListTail->next;
		}

	/* Add capability information for each recognised mechanism type */
	for( i = 0; i < maxMechanisms && \
				mechanismInfoPtr[ i ].mechanism != CKM_NONE; i++ )
		{
		CAPABILITY_INFO_LIST *newCapabilityList;
		CAPABILITY_INFO *newCapability;
		const CRYPT_ALGO_TYPE cryptAlgo = mechanismInfoPtr[ i ].cryptAlgo;

		/* If the assertion below triggers then the PKCS #11 driver is 
		   broken since it's returning inconsistent information such as 
		   illegal key length data, conflicting algorithm information, etc 
		   etc.  This assertion is included here to detect buggy drivers 
		   early on rather than forcing users to step through the PKCS #11 
		   glue code to find out why an operation is failing.
		   
		   Because some tinkertoy implementations support only the bare 
		   minimum functionality (e.g.RSA private key ops and nothing else),
		   we allow asymmetric functionality for PKCs */
		newCapability = getCapability( deviceInfo, &mechanismInfoPtr[ i ],
									   maxMechanisms - i );
		if( newCapability == NULL )
			continue;
		REQUIRES( sanityCheckCapability( newCapability ) );
		if( ( newCapabilityList = \
						clAlloc( "getCapabilities", \
								 sizeof( CAPABILITY_INFO_LIST ) ) ) == NULL )
			{
			clFree( "getCapabilities", newCapability );
			continue;
			}
		newCapabilityList->info = newCapability;
		newCapabilityList->next = NULL;
		if( deviceInfo->capabilityInfoList == NULL )
			deviceInfo->capabilityInfoList = newCapabilityList;
		else
			capabilityInfoListTail->next = newCapabilityList;
		capabilityInfoListTail = newCapabilityList;

		/* Since there may be alternative mechanisms to the current one 
		   defined, we have to skip mechanisms until we find a ones for a
		   new algorithm */
		while( mechanismInfoPtr[ i + 1 ].cryptAlgo == cryptAlgo && \
			   i < maxMechanisms )
			i++;
		ENSURES( i < maxMechanisms );
		}
	ENSURES( i < maxMechanisms );

	return( ( deviceInfo->capabilityInfoList == NULL ) ? CRYPT_ERROR : CRYPT_OK );
	}
Beispiel #6
0
static CAPABILITY_INFO *getCapability( const DEVICE_INFO *deviceInfo,
									   const PKCS11_MECHANISM_INFO *mechanismInfoPtr,
									   const int maxMechanisms )
	{
	VARIABLE_CAPABILITY_INFO *capabilityInfo;
	CK_MECHANISM_INFO pMechanism;
	CK_RV status;
	const CRYPT_ALGO_TYPE cryptAlgo = mechanismInfoPtr->cryptAlgo;
	const BOOLEAN isPKC = isPkcAlgo( cryptAlgo ) ? TRUE : FALSE;
	const CK_FLAGS keyGenFlag = isPKC ? CKF_GENERATE_KEY_PAIR : CKF_GENERATE;
	PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11;
	int hardwareOnly, i, iterationCount;

	assert( isReadPtr( deviceInfo, sizeof( DEVICE_INFO ) ) );
	assert( isReadPtr( mechanismInfoPtr, \
					   maxMechanisms * sizeof( PKCS11_MECHANISM_INFO ) ) );

	/* Set up canary values for the mechanism information in case the driver
	   blindly reports success for every mechanism that we ask for */
	memset( &pMechanism, 0, sizeof( CK_MECHANISM_INFO ) );
	pMechanism.ulMinKeySize = 0xA5A5;
	pMechanism.ulMaxKeySize = 0x5A5A;

	/* Get the information for this mechanism.  Since many PKCS #11 drivers
	   implement some of their capabilities using God knows what sort of 
	   software implementation, we provide the option to skip emulated 
	   mechanisms if required */
	status = C_GetMechanismInfo( pkcs11Info->slotID, 
								 mechanismInfoPtr->mechanism,
								 &pMechanism );
	if( status != CKR_OK )
		return( NULL );
	if( pMechanism.ulMinKeySize == 0xA5A5 && \
		pMechanism.ulMaxKeySize == 0x5A5A )
		{
		/* The driver reported that this mechanism is available but didn't
		   update the mechanism information, it's lying */
		DEBUG_DIAG(( "Driver reports that mechanism %X is available even "
					 "though it isn't", mechanismInfoPtr->mechanism ));
		assert( DEBUG_WARN );
		return( NULL );
		}
	status = krnlSendMessage( deviceInfo->ownerHandle, IMESSAGE_GETATTRIBUTE, 
							  &hardwareOnly, 
							  CRYPT_OPTION_DEVICE_PKCS11_HARDWAREONLY );
	if( cryptStatusOK( status ) && hardwareOnly && \
		!( pMechanism.flags & CKF_HW ) )
		{
		DEBUG_DIAG(( "Skipping mechanism %X, which is only available in "
					 "software emulation", mechanismInfoPtr->mechanism ));
		return( NULL );
		}
	if( mechanismInfoPtr->requiredFlags != CKF_NONE )
		{
		/* Make sure that the driver flags indicate support for the specific 
		   functionality that we require */
		if( ( mechanismInfoPtr->requiredFlags & \
			  pMechanism.flags ) != mechanismInfoPtr->requiredFlags )
			{
			DEBUG_DIAG(( "Driver reports that mechanism %X only has "
						 "capabilities %lX when we require %lX", 
						 mechanismInfoPtr->mechanism, 
						 mechanismInfoPtr->requiredFlags & pMechanism.flags,
						 mechanismInfoPtr->requiredFlags ));
//////////////////////////////////
// Kludge to allow it to be used
//////////////////////////////////
//			assert( DEBUG_WARN );
//			return( NULL );
			}
		}

	/* Copy across the template for this capability */
	if( ( capabilityInfo = clAlloc( "getCapability", \
									sizeof( CAPABILITY_INFO ) ) ) == NULL )
		return( NULL );
	for( i = 0; capabilityTemplates[ i ].cryptAlgo != cryptAlgo && \
				capabilityTemplates[ i ].cryptAlgo != CRYPT_ERROR && \
				i < FAILSAFE_ARRAYSIZE( capabilityTemplates, CAPABILITY_INFO ); 
		 i++ );
	ENSURES_N( i < FAILSAFE_ARRAYSIZE( capabilityTemplates, CAPABILITY_INFO ) );
	ENSURES_N( capabilityTemplates[ i ].cryptAlgo != CRYPT_ERROR );
	memcpy( capabilityInfo, &capabilityTemplates[ i ],
			sizeof( CAPABILITY_INFO ) );

	/* Set up the keysize information if there's anything useful available */
	if( keysizeValid( cryptAlgo ) )
		{
		int minKeySize = ( int ) pMechanism.ulMinKeySize;
		int maxKeySize = ( int ) pMechanism.ulMaxKeySize;

		/* Adjust the key size to bytes and make sure that all values are 
		   consistent.  Some implementations report silly bounds (e.g. 1-bit 
		   RSA, "You naughty minKey" or alternatively 4Gbit RSA) so we 
		   adjust them to a sane value if necessary.  We also limit the 
		   maximum key size to match the cryptlib native maximum key size, 
		   both for consistency and because cryptlib performs buffer 
		   allocation based on the maximum native buffer size */
		if( pMechanism.ulMinKeySize < 0 || \
			pMechanism.ulMinKeySize >= 10000L )
			{
			DEBUG_DIAG(( "Driver reports invalid minimum key size %lu for "
						 "%s algorithm", pMechanism.ulMinKeySize,
						 capabilityInfo->algoName ));
			assert( DEBUG_WARN );
			minKeySize = 0;
			}
		if( pMechanism.ulMaxKeySize < 0 || \
			pMechanism.ulMaxKeySize >= 100000L )
			{
			DEBUG_DIAG(( "Driver reports invalid maximum key size %lu for "
						 "%s algorithm", pMechanism.ulMaxKeySize,
						 capabilityInfo->algoName ));
			assert( DEBUG_WARN );
			maxKeySize = 0;
			}
		if( !keysizeInBytes( cryptAlgo ) )
			{
			minKeySize = bitsToBytes( minKeySize );
			maxKeySize = bitsToBytes( maxKeySize );
			}
		if( minKeySize > capabilityInfo->minKeySize )
			capabilityInfo->minKeySize = minKeySize;
		if( capabilityInfo->keySize < capabilityInfo->minKeySize )
			capabilityInfo->keySize = capabilityInfo->minKeySize;
		capabilityInfo->maxKeySize = min( maxKeySize, 
										  capabilityInfo->maxKeySize );
		if( capabilityInfo->maxKeySize < capabilityInfo->minKeySize )
			{
			/* Serious braindamage in the driver, we'll just have to make
			   a sensible guess */
			DEBUG_DIAG(( "Driver reports maximum key size %d < minimum key "
						 "size %d for %s algorithm", 
						 capabilityInfo->maxKeySize, 
						 capabilityInfo->minKeySize, 
						 capabilityInfo->algoName ));
			assert( DEBUG_WARN );
			if( isPKC )
				{
				capabilityInfo->maxKeySize = \
					max( capabilityInfo->minKeySize, bitsToBytes( 2048 ) );
				}
			else
				capabilityInfo->maxKeySize = 16;
			}
		if( capabilityInfo->keySize > capabilityInfo->maxKeySize )
			capabilityInfo->keySize = capabilityInfo->maxKeySize;
		capabilityInfo->endFunction = genericEndFunction;
		}

	/* Set up the device-specific handlers */
	capabilityInfo->selfTestFunction = selfTestFunction;
	capabilityInfo->getInfoFunction = getDefaultInfo;
	if( !isPKC )
		capabilityInfo->initParamsFunction = initGenericParams;
	capabilityInfo->endFunction = mechanismInfoPtr->endFunction;
	capabilityInfo->initKeyFunction = mechanismInfoPtr->initKeyFunction;
	if( pMechanism.flags & keyGenFlag )
		capabilityInfo->generateKeyFunction = \
									mechanismInfoPtr->generateKeyFunction;
	if( pMechanism.flags & CKF_SIGN )
		{
		/* cryptlib treats hashing as an encrypt/decrypt operation while 
		   PKCS #11 treats it as a sign/verify operation, so we have to
		   juggle the function pointers based on the underlying algorithm
		   type */
		if( isPKC )
			capabilityInfo->signFunction = mechanismInfoPtr->signFunction;
		else
			capabilityInfo->encryptFunction = mechanismInfoPtr->encryptFunction;
		}
	if( pMechanism.flags & CKF_VERIFY )
		{
		/* See comment above */
		if( isPKC )
			capabilityInfo->sigCheckFunction = mechanismInfoPtr->sigCheckFunction;
		else
			capabilityInfo->decryptFunction = mechanismInfoPtr->decryptFunction;
		}
	if( pMechanism.flags & CKF_ENCRYPT )
		{
		/* Not all devices implement all modes, so we have to be careful to 
		   set up the pointer for the exact mode that's supported */
		switch( mechanismInfoPtr->cryptMode )
			{
			case CRYPT_MODE_CBC:
				capabilityInfo->encryptCBCFunction = mechanismInfoPtr->encryptFunction;
				break;

			case CRYPT_MODE_CFB:
				capabilityInfo->encryptCFBFunction = mechanismInfoPtr->encryptFunction;
				break;

			case CRYPT_MODE_GCM:
				capabilityInfo->encryptGCMFunction = mechanismInfoPtr->encryptFunction;
				break;

			default:	/* ECB or a PKC */
				capabilityInfo->encryptFunction = mechanismInfoPtr->encryptFunction;
				break;
			}
		}
	if( pMechanism.flags & CKF_DECRYPT )
		{
		/* Not all devices implement all modes, so we have to be careful to 
		   set up the pointer for the exact mode that's supported */
		switch( mechanismInfoPtr->cryptMode )
			{
			case CRYPT_MODE_CBC:
				capabilityInfo->decryptCBCFunction = mechanismInfoPtr->decryptFunction;
				break;

			case CRYPT_MODE_CFB:
				capabilityInfo->decryptCFBFunction = mechanismInfoPtr->decryptFunction;
				break;

			case CRYPT_MODE_GCM:
				capabilityInfo->decryptGCMFunction = mechanismInfoPtr->decryptFunction;
				break;

			default:	/* ECB or a PKC */
				capabilityInfo->decryptFunction = mechanismInfoPtr->decryptFunction;
				break;
			}
		}
	if( cryptAlgo == CRYPT_ALGO_DH && pMechanism.flags & CKF_DERIVE )
		{
		/* DH is a special-case that doesn't really have an encrypt function 
		   and where "decryption" is actually a derivation */
		capabilityInfo->encryptFunction = mechanismInfoPtr->encryptFunction;
		capabilityInfo->decryptFunction = mechanismInfoPtr->decryptFunction;
		}

	/* Keygen capabilities are generally present as separate mechanisms,
	   sometimes CKF_GENERATE/CKF_GENERATE_KEY_PAIR is set for the main 
	   mechanism and sometimes it's set for the separate one so if it isn't 
	   present in the main one we check the alternative one */
	if( !( pMechanism.flags & keyGenFlag ) && \
		( mechanismInfoPtr->keygenMechanism != CKM_NONE ) )
		{
		status = C_GetMechanismInfo( pkcs11Info->slotID, 
									 mechanismInfoPtr->keygenMechanism,
									 &pMechanism );
		if( status == CKR_OK && ( pMechanism.flags & keyGenFlag ) && \
			( !hardwareOnly || ( pMechanism.flags & CKF_HW ) ) )
			{
			/* Some tinkertoy tokens don't implement key generation in 
			   hardware but instead do it on the host PC (!!!) and load the
			   key into the token afterwards, so we have to perform another 
			   check here to make sure that they're doing things right */
			capabilityInfo->generateKeyFunction = \
									mechanismInfoPtr->generateKeyFunction;
			}
		}

	/* Record mechanism-specific parameters if required */
	if( isConvAlgo( cryptAlgo ) || isMacAlgo( cryptAlgo ) )
		{
		capabilityInfo->paramKeyType = mechanismInfoPtr->keyType;
		capabilityInfo->paramKeyGen = mechanismInfoPtr->keygenMechanism;
		capabilityInfo->paramDefaultMech = mechanismInfoPtr->defaultMechanism;
		}

	/* Some drivers report bizarre combinations of capabilities like (for 
	   RSA) sign, verify, and decrypt but not encrypt, which will fail later 
	   sanity checks.  If we run into one of these we force the capabilities 
	   to be consistent by disabling any for which only partial capabilities
	   are supported */
	if( isPkcAlgo( cryptAlgo ) )
		{
		if( capabilityInfo->decryptFunction != NULL && \
			capabilityInfo->encryptFunction == NULL )
			{
			DEBUG_DIAG(( "Driver reports decryption but not encryption "
						 "capability for %s algorithm, disabling "
						 "encryption", capabilityInfo->algoName ));
			capabilityInfo->decryptFunction = NULL;
			}
		if( capabilityInfo->signFunction != NULL && \
			capabilityInfo->sigCheckFunction == NULL )
			{
			DEBUG_DIAG(( "Driver reports signature-generation but not "
						 "signature-verification capability for %s "
						 "algorithm, disabling signing", 
						 capabilityInfo->algoName ));
//////////////////////////////////
// Kludge to allow it to be used
//////////////////////////////////
if( cryptAlgo == CRYPT_ALGO_ECDSA )
capabilityInfo->sigCheckFunction = capabilityInfo->signFunction;
else
			capabilityInfo->signFunction = NULL;
			}

		/* If we've now disabled all capabilities, we can't use this 
		   algorithm */
		if( capabilityInfo->decryptFunction == NULL && \
			capabilityInfo->signFunction == NULL )
			{
			DEBUG_DIAG(( "Use of algorithm %s disabled since no consistent "
						 "set of capabilities is available", 
						 capabilityInfo->algoName ));
			clFree( "getCapability", capabilityInfo );
			assert( DEBUG_WARN );
			return( NULL );
			}
		}

	/* If it's not a conventional encryption algo, we're done */
	if( !isConvAlgo( cryptAlgo ) )
		return( ( CAPABILITY_INFO * ) capabilityInfo );

	/* PKCS #11 handles encryption modes by defining a separate mechanism for
	   each one.  In order to enumerate all the modes available for a 
	   particular algorithm we check for each mechanism in turn and set up 
	   the appropriate function pointers if it's available */
	for( mechanismInfoPtr++, iterationCount = 0; 
		 mechanismInfoPtr->cryptAlgo == cryptAlgo && \
			iterationCount < maxMechanisms; 
		 mechanismInfoPtr++, iterationCount++ )
		{
		/* There's a different form of the existing mechanism available,
		   check whether the driver implements it */
		status = C_GetMechanismInfo( pkcs11Info->slotID, 
									 mechanismInfoPtr->mechanism,
									 &pMechanism );
		if( status != CKR_OK )
			continue;

		/* Set up the pointer for the appropriate encryption mode */
		switch( mechanismInfoPtr->cryptMode )
			{
			case CRYPT_MODE_CBC:
				if( pMechanism.flags & CKF_ENCRYPT )
					capabilityInfo->encryptCBCFunction = \
										mechanismInfoPtr->encryptFunction;
				if( pMechanism.flags & CKF_DECRYPT )
					capabilityInfo->decryptCBCFunction = \
										mechanismInfoPtr->decryptFunction;
				break;
			case CRYPT_MODE_CFB:
				if( pMechanism.flags & CKF_ENCRYPT )
					capabilityInfo->encryptCFBFunction = \
										mechanismInfoPtr->encryptFunction;
				if( pMechanism.flags & CKF_DECRYPT )
					capabilityInfo->decryptCFBFunction = \
										mechanismInfoPtr->decryptFunction;
				break;
			case CRYPT_MODE_GCM:
				if( pMechanism.flags & CKF_ENCRYPT )
					capabilityInfo->encryptGCMFunction = \
										mechanismInfoPtr->encryptFunction;
				if( pMechanism.flags & CKF_DECRYPT )
					capabilityInfo->decryptGCMFunction = \
										mechanismInfoPtr->decryptFunction;
				break;

			default:
				retIntError_Null();
			}
		}
	ENSURES_N( iterationCount < maxMechanisms );

	return( ( CAPABILITY_INFO * ) capabilityInfo );
	}
Beispiel #7
0
static INT
sFillTreeList (
		PGPPrefRef		PrefRef, 
		PGPContextRef	context, 
		HWND			hWndTree,
		PGPKeySetRef	keysetMain) 
{
	PGPKeyServerEntry*	keyserverList;
	PGPKeyRef			key;
	PGPUInt32			u, u2;
	PGPError			err;
	PKEYSERVERSTRUCT	pkss;
	PGPKeyID			keyid;

	// load keyserverprefs
	err = PGPGetKeyServerPrefs (PrefRef, &keyserverList, &uNumberOfServers);
	if (IsPGPError (err)) 
		uNumberOfServers = 0;

	for (u=0; u<uNumberOfServers; u++) {

		pkss = clAlloc (sizeof(KEYSERVERSTRUCT));
		if (pkss) {
			pkss->hWndTree = hWndTree;
			pkss->bEdit = FALSE;
			lstrcpy (pkss->szServer, keyserverList[u].serverDNS);
			pkss->iPort = keyserverList[u].serverPort;
			pkss->iType = keyserverList[u].protocol;
			lstrcpy (pkss->szDomain, keyserverList[u].domain);
			pkss->bListed = (keyserverList[u].flags & kKeyServerListed);
			pkss->authAlg = keyserverList[u].authAlg;
			pkss->bRoot = (keyserverList[u].flags & kKeyServerIsRoot);

			// get auth key userid
			pkss->szUserIDAuth[0] = '\0';
			if ((pkss->authAlg != kPGPPublicKeyAlgorithm_Invalid) &&
					keyserverList[u].authKeyIDString[0]) {
				lstrcpy (pkss->szKeyIDAuth, 
								keyserverList[u].authKeyIDString);
				err = PGPGetKeyIDFromString (
						keyserverList[u].authKeyIDString, &keyid);
				if (IsntPGPError (err)) {
					err = PGPGetKeyByKeyID (keysetMain, &keyid, 
								keyserverList[u].authAlg, &key);
					if (IsntPGPError (err)) {
						PGPGetPrimaryUserIDNameBuffer (key, 
									sizeof(pkss->szUserIDAuth), 
									pkss->szUserIDAuth, &u2);
					}
					else {
						lstrcpy (pkss->szUserIDAuth, 
								keyserverList[u].authKeyIDString);
					}
				}
			}
			if (pkss->szUserIDAuth[0] == '\0') {
				LoadString (g_hInst, IDS_UNKNOWNKEY, pkss->szUserIDAuth, 
							sizeof(pkss->szUserIDAuth));
			}

			sSetOneKSItem (hWndTree, pkss); 
		}
	}

	if (keyserverList) PGPDisposePrefData (PrefRef, keyserverList);

	return 0;
}
Beispiel #8
0
INT
CLSaveKeyserverPrefs (PGPPrefRef PrefRef, HWND hWndParent, HWND hWndTree)
{
	TL_TREEITEM			tlI;
	HTLITEM				hTServer;
	PGPKeyServerEntry*	keyserverList;
	INT					iServer, iServerCount;
	PKEYSERVERSTRUCT	pkss;

	// count number of servers
	iServerCount = 0;
	hTServer = TreeList_GetFirstItem (hWndTree);
	while (hTServer) {
		++iServerCount;
		tlI.hItem = hTServer;
		tlI.mask = TLIF_NEXTHANDLE;
		TreeList_GetItem (hWndTree, &tlI);
		hTServer = tlI.hItem;
	}

	keyserverList = clAlloc (iServerCount * sizeof(PGPKeyServerEntry));
	if (!keyserverList) return kPGPError_OutOfMemory;

	iServer = 0;
	hTServer = TreeList_GetFirstItem (hWndTree);
	while (hTServer) {
		// get server structure
		tlI.hItem = hTServer;
		tlI.mask = TLIF_PARAM | TLIF_NEXTHANDLE;
		TreeList_GetItem (hWndTree, &tlI);

		pkss = (PKEYSERVERSTRUCT)(tlI.lParam);

		keyserverList[iServer].protocol = pkss->iType;
		lstrcpy (keyserverList[iServer].domain, pkss->szDomain);
		lstrcpy (keyserverList[iServer].serverDNS, pkss->szServer);
		keyserverList[iServer].serverPort = pkss->iPort;

		// authentication key
		if (pkss->authAlg != kPGPPublicKeyAlgorithm_Invalid) {
			keyserverList[iServer].authAlg = pkss->authAlg;
			lstrcpy (keyserverList[iServer].authKeyIDString, 
						pkss->szKeyIDAuth);
		}
		else {
			keyserverList[iServer].authAlg = kPGPPublicKeyAlgorithm_Invalid;
			keyserverList[iServer].authKeyIDString[0] = '\0';
		}

		// listed flag
		keyserverList[iServer].flags = 0;
		if (pkss->bListed) 
			keyserverList[iServer].flags |= kKeyServerListed;
		if (pkss->bRoot) 
			keyserverList[iServer].flags |= kKeyServerIsRoot;

		// step to next server
		++iServer;
		hTServer = tlI.hItem;
	}

	// done, set preferences
	PGPSetKeyServerPrefs (PrefRef, keyserverList, iServerCount);

	clFree (keyserverList);

	return 0;
}
Beispiel #9
0
static int activateConnection( INOUT SESSION_INFO *sessionInfoPtr )
	{
	CRYPT_ATTRIBUTE_TYPE errorAttribute;
	int status;

	assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );

	/* Make sure that everything is set up ready to go */
	errorAttribute = isServer( sessionInfoPtr ) ? \
					 checkServerParameters( sessionInfoPtr ) : \
					 checkClientParameters( sessionInfoPtr );
	if( errorAttribute != CRYPT_ATTRIBUTE_NONE )
		{
		setErrorInfo( sessionInfoPtr, errorAttribute, 
					  CRYPT_ERRTYPE_ATTR_ABSENT );
		return( CRYPT_ERROR_NOTINITED );
		}
	ENSURES( isServer( sessionInfoPtr ) || \
			 findSessionInfo( sessionInfoPtr->attributeList, 
							  CRYPT_SESSINFO_SERVER_NAME ) != NULL || \
			 sessionInfoPtr->networkSocket != CRYPT_ERROR );
	ENSURES( findSessionInfo( sessionInfoPtr->attributeList,
							  CRYPT_SESSINFO_SERVER_PORT ) != NULL || \
			 sessionInfoPtr->protocolInfo->port > 0 );

	/* Allocate the send and receive buffers if necessary.  The send buffer
	   isn't used for request-response session types that use the receive
	   buffer for both outgoing and incoming data so we only allocate it if
	   it's actually required */
	if( sessionInfoPtr->sendBuffer == NULL )
		{
		REQUIRES( sessionInfoPtr->receiveBufSize >= MIN_BUFFER_SIZE && \
				  sessionInfoPtr->receiveBufSize < MAX_BUFFER_SIZE );
		REQUIRES( ( sessionInfoPtr->sendBufSize >= MIN_BUFFER_SIZE && \
					sessionInfoPtr->sendBufSize < MAX_BUFFER_SIZE ) || \
				  sessionInfoPtr->sendBufSize == CRYPT_UNUSED );

		if( ( sessionInfoPtr->receiveBuffer = \
						clAlloc( "activateConnection", \
								 sessionInfoPtr->receiveBufSize + 8 ) ) == NULL )
			return( CRYPT_ERROR_MEMORY );
		if( sessionInfoPtr->sendBufSize != CRYPT_UNUSED )
			{
			/* When allocating the send buffer we use the size given for the
			   receive buffer since the user may have overridden the default
			   buffer size */
			if( ( sessionInfoPtr->sendBuffer = \
						clAlloc( "activateConnection", \
								 sessionInfoPtr->receiveBufSize + 8 ) ) == NULL )
				{
				clFree( "activateConnection", sessionInfoPtr->receiveBuffer );
				sessionInfoPtr->receiveBuffer = NULL;
				return( CRYPT_ERROR_MEMORY );
				}
			sessionInfoPtr->sendBufSize = sessionInfoPtr->receiveBufSize;
			}
		}
	ENSURES( sessionInfoPtr->receiveBuffer != NULL && \
			 sessionInfoPtr->receiveBufSize >= MIN_BUFFER_SIZE && \
			 sessionInfoPtr->receiveBufSize < MAX_BUFFER_SIZE );
	ENSURES( sessionInfoPtr->sendBufSize == CRYPT_UNUSED || \
			 sessionInfoPtr->sendBuffer != NULL );

	/* Set timeouts if they're not set yet.  If there's an error then we use
	   the default value rather than aborting the entire session because of 
	   a minor difference in timeout values, although we also warn the 
	   caller in debug mode */
	if( sessionInfoPtr->connectTimeout == CRYPT_ERROR )
		{
		int timeout;

		status = krnlSendMessage( sessionInfoPtr->ownerHandle,
								  IMESSAGE_GETATTRIBUTE, &timeout,
								  CRYPT_OPTION_NET_CONNECTTIMEOUT );
		if( cryptStatusOK( status ) )
			sessionInfoPtr->connectTimeout = timeout;
		else
			{
			DEBUG_DIAG(( "Couldn't get connect timeout config value" ));
			assert( DEBUG_WARN );
			sessionInfoPtr->connectTimeout = 30;
			}
		}
	if( sessionInfoPtr->readTimeout == CRYPT_ERROR )
		{
		int timeout;

		status = krnlSendMessage( sessionInfoPtr->ownerHandle,
								  IMESSAGE_GETATTRIBUTE, &timeout,
								  CRYPT_OPTION_NET_READTIMEOUT );
		if( cryptStatusOK( status ) )
			sessionInfoPtr->readTimeout = timeout;
		else
			{
			DEBUG_DIAG(( "Couldn't get read timeout config value" ));
			assert( DEBUG_WARN );
			sessionInfoPtr->readTimeout = 30;
			}
		}
	if( sessionInfoPtr->writeTimeout == CRYPT_ERROR )
		{
		int timeout;

		status = krnlSendMessage( sessionInfoPtr->ownerHandle,
								  IMESSAGE_GETATTRIBUTE, &timeout,
								  CRYPT_OPTION_NET_WRITETIMEOUT );
		if( cryptStatusOK( status ) )
			sessionInfoPtr->writeTimeout = timeout;
		else
			{
			DEBUG_DIAG(( "Couldn't get write timeout config value" ));
			assert( DEBUG_WARN );
			sessionInfoPtr->writeTimeout = 30;
			}
		}

	/* Wait for any async driver binding to complete.  We can delay this
	   until this very late stage because no networking functionality is
	   used until this point */
	if( !krnlWaitSemaphore( SEMAPHORE_DRIVERBIND ) )
		{
		/* The kernel is shutting down, bail out */
		return( CRYPT_ERROR_PERMISSION );
		}

	/* If this is the first time that we've got here, activate the session */
	if( !( sessionInfoPtr->flags & SESSION_PARTIALOPEN ) )
		{
		REQUIRES( !( sessionInfoPtr->flags & SESSION_ISOPEN ) )

		status = sessionInfoPtr->connectFunction( sessionInfoPtr );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* If it's a secure data transport session, complete the session state
	   setup.  Note that some sessions dynamically change the protocol 
	   information during the handshake to accommodate parameters negotiated 
	   during the handshake so we can only access the protocol information 
	   after the handshake has completed */
	if( !sessionInfoPtr->protocolInfo->isReqResp )
		{
		/* Complete the session handshake to set up the secure state */
		status = sessionInfoPtr->transactFunction( sessionInfoPtr );
		if( cryptStatusError( status ) )
			{
			/* If we need feedback from the user before we can complete the 
			   handshake (for example checking a user name and password or 
			   certificate supplied by the other side) we remain in the 
			   handshake state so that the user can re-activate the session 
			   after confirming (or denying) the check */
			if( status == CRYPT_ENVELOPE_RESOURCE )
				sessionInfoPtr->flags |= SESSION_PARTIALOPEN;

			return( status );
			}

		/* Notify the kernel that the session key context is attached to the
		   session object.  Note that we increment its reference count even
		   though it's an internal object used only by the session because
		   otherwise it'll be automatically destroyed by the kernel as a
		   zero-reference dependent object when the session object is
		   destroyed (but before the session object itself since the context 
		   is just a dependent object).  This automatic cleanup could cause 
		   problems for lower-level session management code that tries to 
		   work with the (apparently still-valid) handle, for example 
		   protocols that need to encrypt a close-channel message on session 
		   shutdown */
		krnlSendMessage( sessionInfoPtr->objectHandle, IMESSAGE_SETDEPENDENT,
						 &sessionInfoPtr->iCryptInContext,
						 SETDEP_OPTION_INCREF );

		/* Set up the buffer management variables */
		sessionInfoPtr->receiveBufPos = sessionInfoPtr->receiveBufEnd = 0;
		sessionInfoPtr->sendBufPos = sessionInfoPtr->sendBufStartOfs;

		/* For data transport sessions, partial reads and writes (that is,
		   sending and receiving partial packets in the presence of 
		   timeouts) are permitted */
		sioctlSet( &sessionInfoPtr->stream, STREAM_IOCTL_PARTIALREAD, TRUE );
		sioctlSet( &sessionInfoPtr->stream, STREAM_IOCTL_PARTIALWRITE, TRUE );
		}

	/* The handshake has been completed, switch from the handshake timeout
	   to the data transfer timeout and remember that the session has been
	   successfully established */
	sioctlSet( &sessionInfoPtr->stream, STREAM_IOCTL_HANDSHAKECOMPLETE, TRUE );
	sessionInfoPtr->flags &= ~SESSION_PARTIALOPEN;
	sessionInfoPtr->flags |= SESSION_ISOPEN;

	return( CRYPT_OK );
	}