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

📄 pgpdecode.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if( IsOp( op )  && IsntNull( op.subOptions ) ) {
			setupOp = op.subOptions;
		} else {
			err = kPGPError_DetachedSignatureFound;
			goto error;
		}
		freshOpList = s->newOptionList;
	}

	/* Set up input file or buffer */
	err = pgpSetupInput( s->context, setupOp, NULL, NULL, TRUE, TRUE,
						 &detFileRef, &pfrdet, &inFileDataType, &detBufPtr,
						 &detBufLength );
	if( IsPGPError( err ) )
		goto error;
	
	/* Now pump the sig-check data through the pipes */
	if( detFileRef ) {
		/* File input */
		pgpFileReadSetCallBack( pfrdet, decodeLocalCallBack, s );
		err = pgpFileReadPump( pfrdet, head );
		pgpFileReadDestroy( pfrdet );
		if( IsPGPError( err ) )
			goto error;
	} else {
		/* Buffer input */
		if( IsPGPError( err = pgpPumpMem( head, detBufPtr,
						detBufLength, NULL, NULL ) ) )
			goto error;
	}
	err = kPGPError_NoErr;
	/* Fall through */
error:
	/* Discard after one usage */
	if( PGPOptionListRefIsValid( freshOpList ) ) {
		pgpFreeOptionList( freshOpList );
	}
	
	s->newOptionList = kInvalidPGPOptionListRef;
	
	return err;
}


/*
 * Given the signature structure, sig, verify it against the hash
 * to see if this signature is valid.  This requires looking up the
 * public key in the keyring and validating the key.
 *
 * Returns 0 on success or an error code.
 */
	static PGPError
pgpDecodeVerifySig(
	void				*arg,
	PGPSig const		*sig,
	PGPByte const		*hash
	)
{
#if PGP_VERIFY_DISABLE /* [ */

	(void)arg;
	(void)sig;
	(void)hash;
	return kPGPError_FeatureNotAvailable;

#else /* PGP_VERIFY_DISABLE */  /* ]  [ */

	PGPDecodeJob		*s;				/* Parameters for callbacks */
	PGPKeyRef			 signKey;		/* Signing key as PGPKey */
	PGPKeySetRef		 alternateKeySet; /* Extra keyset to try lookup */
	RingObject			*ringKey;		/* Public key ring object */
	RingSet const		*ringSet;		/* Set holding ringKey */
	PGPPubKey			*pubkey;		/* Public key for verify */
	PGPKeyID			keyid;			/* KeyID from signature */
	PGPPublicKeyAlgorithm	pkalg;		/* Public key alg from signature */
	PGPTime				 timeStamp;		/* Issuance time of sig */
	PGPValidity			 failValidity,	/* Fail on keys less valid */
						 warnValidity;	/* Warn on keys less valid */
	PGPBoolean			 fRevoked=FALSE,/* Status of signing key */
						 fExpired=FALSE,
						 fDisabled=FALSE,
						 fValidityThreshold=TRUE;
	PGPValidity			 keyValidity=kPGPValidity_Unknown;
	PGPError			 err;			/* Error code */
	
	s = (PGPDecodeJob *) arg;
	pubkey = NULL;
	alternateKeySet = NULL;

	if( IsNull( s->func ) ) {
		/* If can't report results, don't bother to do anything */
		err = kPGPError_NoErr;
		goto error;
	}

	/* Get info about sig */
	err	= pgpGetSigKeyID ( sig, &keyid );
	if ( IsPGPError( err ) )
		goto error;
		
	pkalg = (PGPPublicKeyAlgorithm)pgpSigPKAlg (sig);

	timeStamp = pgpSigTimestamp (sig);

retrykeyset:

	if (pkalg >= kPGPPublicKeyAlgorithm_First &&
					pkalg <= kPGPPublicKeyAlgorithm_Last) {
		if( IsNull( s->keySet ) ) {
			err = kPGPError_MissingKeySet;
		} else {
			err = PGPGetKeyByKeyID ( s->keySet, &keyid, pkalg, &signKey);
		}
		if( IsPGPError( err ) && IsntNull( alternateKeySet ) ) {
			err = PGPGetKeyByKeyID ( alternateKeySet, &keyid, pkalg, &signKey);
		}
	}

	if( IsPGPError( err ) ||
			pkalg < kPGPPublicKeyAlgorithm_First ||
			pkalg > kPGPPublicKeyAlgorithm_Last) {
		/* Don't have signing key; notify him */
		err = pgpEventSignature( s->context, &s->newOptionList,
							  s->func, s->userValue, &keyid, NULL,
							  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
							  keyValidity, timeStamp );
		if( IsntNull( alternateKeySet ) )
			PGPFreeKeySet (alternateKeySet);
		pgpSetupKeySet (s->newOptionList, &alternateKeySet);
		if( IsntNull( alternateKeySet ) ) {
			PGPIncKeySetRefCount( alternateKeySet );
			pgpCleanupOptionList( &s->newOptionList );
			goto retrykeyset;
		}
		pgpCleanupOptionList( &s->newOptionList );
		goto error;
	}

	if( IsPGPError( err = pgpGetKeyRingObject( signKey, FALSE, &ringKey ) ) )
		goto error;
	if( IsPGPError( err = pgpGetKeyRingSet( signKey, FALSE, &ringSet ) ) )
		goto error;
	
	pubkey = ringKeyPubKey( ringSet, ringKey, PGP_PKUSE_SIGN );

	if (pubkey && !pubkey->verify) {
		/* Make sure we can use this key */
		pgpPubKeyDestroy (pubkey);
		pubkey = NULL;
	}
	
	if (!pubkey) {
		/* Can't verify for some reason... notify him */
		err = pgpEventSignature( s->context, &s->newOptionList,
							  s->func, s->userValue, &keyid, signKey,
							  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
							  keyValidity, timeStamp );
		if( IsntNull( alternateKeySet ) )
			PGPFreeKeySet (alternateKeySet);
		pgpSetupKeySet (s->newOptionList, &alternateKeySet);
		if( IsntNull( alternateKeySet ) ) {
			PGPIncKeySetRefCount( alternateKeySet );
			pgpCleanupOptionList( &s->newOptionList );
			goto retrykeyset;
		}
		pgpCleanupOptionList( &s->newOptionList );
		goto error;
	}
	
	/* Determine validity of signing key */
	if( IsPGPError( err = pgpGetMinValidity( s->optionList,
					&failValidity, &warnValidity ) ) )
		goto error;
	err = pgpCheckKeyValidity( s->context, s->optionList,
					signKey, ringSet, failValidity, warnValidity, NULL,
					&keyValidity );

	if( err == kPGPError_KeyInvalid ) {
		fValidityThreshold = FALSE;
	} else if( err == kPGPError_KeyRevoked ||
			   err == kPGPError_KeyExpired ||
			   err == kPGPError_KeyDisabled ) {
		fValidityThreshold = FALSE;
		if( IsPGPError( err = PGPGetKeyBoolean( signKey, kPGPKeyPropIsRevoked,
												&fRevoked ) ) )
			goto error;
		if( IsPGPError( err = PGPGetKeyBoolean( signKey, kPGPKeyPropIsDisabled,
												&fDisabled ) ) )
			goto error;
		if( IsPGPError( err = PGPGetKeyBoolean( signKey, kPGPKeyPropIsExpired,
												&fExpired ) ) )
			goto error;
	} else if( err != kPGPError_NoErr ) {
		goto error;
	}

	/* Check signature, returns 1 if OK */
	err = pgpSigCheck (sig, pubkey, hash);
	pgpPubKeyDestroy (pubkey);
	pubkey = NULL;
	if( err != 1 ) {
		if( IsPGPError( err ) )
			goto error;
		/* Notify of bad signature and exit */
		err = pgpEventSignature( s->context, &s->newOptionList,
							  s->func, s->userValue, &keyid, signKey,
							  TRUE, FALSE, fDisabled, fRevoked, fExpired,
							  fValidityThreshold, keyValidity, timeStamp );
		pgpCleanupOptionList( &s->newOptionList );
		goto error;
	}
		
	err = pgpEventSignature( s->context, &s->newOptionList,
						  s->func, s->userValue, &keyid, signKey,
						  TRUE, TRUE, fDisabled, fRevoked, fExpired,
						  fValidityThreshold, keyValidity, timeStamp );
	pgpCleanupOptionList( &s->newOptionList );

	/* Fall through */
error:
	if ( IsntNull( pubkey ) )
		pgpPubKeyDestroy( pubkey );
	if ( IsntNull( alternateKeySet ) )
		PGPFreeKeySet( alternateKeySet );
	return err;

#endif /* PGP_VERIFY_DISABLE */ /* ] */
}


/*
 * Remove any subkeys which don't have their keyids on the list
 */
	static PGPError
sRemoveUnlistedSubkeys( PGPKeySetRef keyset, PGPKeyID *keyids,
						PGPUInt32 nkeyids )
{
	PGPKeyListRef	klist;
	PGPKeyIterRef	kiter;
	PGPKeyID		skid;
	PGPKeyRef		key;
	PGPSubKeyRef	subkey;
	PGPUInt32		i;
	PGPError		err = kPGPError_NoErr;

	/* Skip if we have no keys (i.e. passphrase only) */
	if( IsNull( keyset ) )
		return err;

	PGPOrderKeySet( keyset, kPGPUserIDOrdering, &klist );
	PGPNewKeyIter( klist, &kiter );
	while( IsntPGPError( PGPKeyIterNext( kiter, &key ) ) ) {
		while( IsntPGPError( PGPKeyIterNextSubKey( kiter, &subkey ) ) ) {
			if( IsPGPError( err = PGPGetKeyIDFromSubKey( subkey, &skid ) ) )
				goto error;
			/* See if subkey id skid matches one on the list */
			for( i = 0; i < nkeyids; ++i ) {
				if( PGPCompareKeyIDs( &skid, keyids+i ) == 0 )
					break;
			}
			if( i == nkeyids ) {
				/* No match, must remove subkey */
				if( IsPGPError( err = PGPRemoveSubKey( subkey ) ) )
					goto error;
			}
		}
	}

 error:
	PGPFreeKeyIter( kiter );
	PGPFreeKeyList( klist );

	return err;
}


/*
 * given a list of Encrypted Session Keys (esklist), try to decrypt
 * them to get the session key.  Fills in keylen with the length of
 * the session key buffer.
 *
 * Returns 0 on success or PGPANN_PARSER_EATIT on failure.
 */
	static PGPError
pgpDecodeDecryptESK(
	void				*arg,
	PGPESK const		*esklist,
	PGPByte				*key,
	PGPSize				*keylen,
	int				   (*tryKey)(void *arg, PGPByte const *key, PGPSize keylen),
	void				*tryarg
	)
{
#if PGP_DECRYPT_DISABLE /* [ */

	(void) arg;
	(void) esklist;
	(void) key;
	(void) keylen;
	(void) tryKey;
	(void) tryarg;
	return kPGPError_FeatureNotAvailable;

#else /* PGP_DECRYPT_DISABLE */  /* ]  [ */

	PGPDecodeJob		*s;				/* Parameters for callbacks */
	PGPESK const		*esk;			/* ESK being tested */
	PGPKeyRef			 decKey;		/* PGPKey for decryption key */
	PGPKeySet			*decKeySet1;	/* Keyset with just decKey */
	PGPKeySet			*decKeySet;		/* Keyset with all decryption keys */
	RingObject			*ringKey;		/* Secret key ring object */
	RingSet const		*ringSet;		/* Lowlevel keyring set for key */
	PGPSecKey			*seckey;		/* Secret key */
	PGPPublicKeyAlgorithm	 pkalg;			/* Pubkey algorithm from ESK */
	PGPBoolean			 success;		/* True if had a successful decrypt */
	PGPInt32			 klen;			/* Return code from key func */
	PGPError			 err;			/* Error from pgplib */
	PGPUInt32			 passPhraseCount; /* Count of possible pphrases */
	PGPUInt32			 keyIDCount;	/* # deckeys unavail */
	PGPKeyID			*keyIDArray;	/* Array of ptrs to keyids */
	PGPCipherAlgorithm	 cipheralg;		/* Decryption algorithm */
	PGPBoolean			 firstpass;		/* of passphrase checking */

	s = (PGPDecodeJob *) arg;
	decKeySet = NULL;
	decKeySet1 = NULL;
	seckey = NULL;
	keyIDArray = NULL;
	
	/* First loop over all ESK's to set up recipient list */
	passPhraseCount = 0;
	keyIDCount = 0;
	if( IsntNull( s->keySet ) ) {
		if( IsPGPError( err = PGPNewKeySet( s->context, &decKeySet ) ) )
			goto error;
	}
	for( esk = esklist; IsntNull( esk ); esk = pgpEskNext( esk ) ) {
		switch( pgpEskType( esk ) ) {
		case PGP_ESKTYPE_PASSPHRASE:
			passPhraseCount += 1;
			break;
		case PGP_ESKTYPE_PUBKEY:
		{
			PGPKeyID			keyid;			/* Key ID from ESK */
			void *				vKeyIDArray;
	
			err	= pgpGetEskKeyID( esk, &keyid);
			if ( IsPGPError( err ) )
				goto error;

			/* Save keyids in list */
			vKeyIDArray = keyIDArray;
			err = pgpContextMemRealloc( s->context,
				   &vKeyIDArray,
				   (keyIDCount+1) * sizeof(keyIDArray[ 0 ]), 0 );
			if( IsPGPError( err ) )
				goto error;
			keyIDArray = (PGPKeyID *)vKeyIDArray;
			keyIDArray[keyIDCount++] = keyid;
				
			pkalg = (PGPPublicKeyAlgorithm)pgpEskPKAlg (esk);

			decKey = NULL;
			if( IsntNull( s->keySet ) &&
						pkalg >= kPGPPublicKeyAlgorithm_First &&
						pkalg <= kPGPPublicKeyAlgorithm_Last) {
				(void)PGPGetKeyByKeyID ( s->keySet, &keyid, pkalg, &decKey);
			}

			if( IsNull( decKey ) ) {
				/* We don't have the decryption key */
			} else {
				/* Accumulate into recipient key set */
				if( IsPGPError( err = PGPNewSingletonKeySet( decKey,
											&decKeySet1 ) ) )
					goto error;
				if( IsPGPError( err = PGPAddKeys(decKeySet1, decKeySet ) ) )
					goto error;
				PGPFreeKeySet( decKeySet1 );
				decKeySet1 = NULL;
			}
			break;
		}
		
		default:
			pgpAssert(0);
			break;
		}
	}

	/* Remove any irrelevant subkeys from key we added */
	if( IsPGPError( err = sRemoveUnlistedSubkeys( decKeySet, keyIDArray,
												  keyIDCount ) ) )
		goto error;

	/* Notify user about decryption keys */
	if( IsPGPError( err = pgpEventRecipients( s->context, &s->newOptionList,
						  s->func, s->userValue, decKeySet, keyIDArray,
						  passPhraseCount, keyIDCount ) ) )
		goto error;
	pgpCleanupOptionList( &s->newOptionList );
	if( IsntNull( decKeySet ) ) {
		PGPFreeKeySet( decKeySet );
		decKeySet = NULL;
	}

	/* Loop over all ESK's trying to find one we can decrypt */
	/* decKeySet will hold decryption keys that we have secrets for */
	success = FALSE;
	if( IsntNull( s->keySet ) ) {
		if( IsPGPError( err = PGPNewKeySet( s->context, &decKeySet ) ) )
			goto error;
	}

	firstpass = TRUE;
	while( !success ) {
		for( esk = esklist; IsntNull( esk ) && !success;
			 								esk = pgpEskNext( esk ) ) {
			switch( pgpEskType( esk ) ) {
			case PGP_ESKTYPE_PASSPHRASE:
				/* Try the pass phrase */
				if (s->passPhraseIsSessionKey) {
					*keylen = pgpMin( *keylen, s->passLength );
					pgpCopyMemory( s->passPhrase, key, *keylen );
				} else {
					klen = pgpEskConvDecrypt (esk, s->env,
								(char *)s->passPhrase, s->passLength, key);
					if( klen < 0 ) {

⌨️ 快捷键说明

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