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

📄 pgpp11key.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 4 页
字号:
	if( IsPGPError( err ) )
		goto error;

	if (progress && IsPGPError( err = progress(arg, '*') ) )
		goto error;

	if (progress && IsPGPError( err = progress(arg, ' ') ) )
		goto error;

	if (progress && IsPGPError( err = progress(arg, '*') ) )
		goto error;

	bnInsertBigBytes( &mod, modbuf, 0, modlen );
	bnInsertBigBytes( &exp, pubexpbuf, 0, pubexplen );
	PGPFreeData( modbuf ); modbuf = NULL;

	pubbuflen = 2 + bnBytes(&mod) + 2 + bnBytes(&exp);
	pubbuf = PGPNewData( mgr, pubbuflen, 0 );

	off = pgpBnPutFormatted(&mod, pubbuf, bnBytes(&mod),
						  kPGPPublicKeyMessageFormat_PGP);
	pgpBnPutFormatted(&exp, pubbuf+off, bnBytes(&exp),
						  kPGPPublicKeyMessageFormat_PGP);
	bnEnd( &mod );
	bnEnd( &exp );
	
	seckey = p11SecFromBuf( context, pubbuf, pubbuflen, FALSE, tok, error );
	PGPFreeData( pubbuf ); pubbuf = NULL;
	pgpAssert( IsntNull( seckey ) );

	pgpCopyMemory( tmpkeyid, seckey->keyID, sizeof(seckey->keyID) );
	
	return seckey;

 error:

	if( IsntNull( modbuf ) )
		PGPFreeData( modbuf );
	if( IsntNull( pubexpbuf ) )
		PGPFreeData( pubexpbuf );
	if( IsntNull( pubbuf ) )
		PGPFreeData( pubbuf );
	bnEnd( &mod );
	bnEnd( &exp );

	*error = err;
	return NULL;

#else
	(void) context;
	(void) pkalg;
	(void) bits;
	(void) fastgen;
	(void) v3;
	(void) progress;
	(void) arg;
	(void) tokptr;
	(void) passphrase;
	(void) passphraseLength;
	(void) genMaster;
	(void) error;
	return NULL;
#endif
}


static PGPError
sTokenCopyPrivKeyToToken( PGPContextRef context, PGPKeyDBObjRef key,
						PGPBoolean isMaster,
						PGPByte const *passphrase, PGPSize passphraseLength,
						PGPBoolean hashedPhrase, PGPByte const *PIN,
						PGPSize PINlength, PGPUInt32 toknumber )
{
#if PGP_WIN32
	PGPToken *tok;
	PGPByte pkalg;
	PGPKeyID keyid;
	PGPByte *keyidbytes;
	PGPMemoryMgrRef		mgr	= NULL;
	BigNum mod, exp, decexp, p1, p2, coef, decp1, decp2;
	PGPByte *modbuf, *expbuf, *decexpbuf, *p1buf, *p2buf, *coefbuf,
		*decp1buf, *decp2buf;
	PGPSize modlen, explen;
	PGPPubKey *pub;
	PGPSecKey *sec;
	PGPError err = kPGPError_NoErr;

	pgpAssert( OBJISKEY( key ) );

	tok = F.pgpGetNthTokenObject( toknumber );
	mgr	= PGPPeekContextMemoryMgr( context );

	pgpKeyID8( key, &pkalg, &keyid );
	if( pkalg != kPGPPublicKeyAlgorithm_RSA )
		return kPGPError_PublicKeyUnimplemented;

	keyidbytes = (PGPByte *)pgpGetKeyIDBytes( &keyid );

	bnBegin( &mod, mgr, FALSE );
	bnBegin( &exp, mgr, FALSE );
	bnBegin( &decexp, mgr, TRUE );
	bnBegin( &p1, mgr, TRUE );
	bnBegin( &p2, mgr, TRUE );
	bnBegin( &coef, mgr, TRUE );
	bnBegin( &decp1, mgr, TRUE );
	bnBegin( &decp2, mgr, TRUE );

	sec = pgpSecSecKey( key, 0 );
	pub = pgpSecKeyPubkey( sec );
	pgpPubKeyParams( pub, &mod, &exp, NULL, NULL, NULL, NULL, NULL, NULL );
	pgpPubKeyDestroy( pub );
	err = pgpSecKeyUnlock( sec, passphrase, passphraseLength, hashedPhrase );
	if( err <= 0 )
		return kPGPError_BadPassphrase;
	pgpSecKeyParams( sec, &decexp, &p2, &p1, &coef, NULL, NULL, NULL, NULL );
	pgpSecKeyDestroy( sec );

	bnSubQ( &p1, 1 );
	bnMod( &decp1, &decexp, &p1 );
	bnAddQ( &p1, 1 );
	bnSubQ( &p2, 1 );
	bnMod( &decp2, &decexp, &p2 );
	bnAddQ( &p2, 1 );

	modlen = bnBytes( &mod );
	explen = bnBytes( &exp );

	if( modlen % 2 != 0 )
		++modlen;
	
	modbuf = PGPNewData( mgr, modlen, 0 );
	expbuf = PGPNewData( mgr, explen, 0 );
	decexpbuf = PGPNewSecureData( mgr, modlen, 0 );
	p1buf = PGPNewSecureData( mgr, modlen/2, 0 );
	p2buf = PGPNewSecureData( mgr, modlen/2, 0 );
	decp1buf = PGPNewSecureData( mgr, modlen/2, 0 );
	decp2buf = PGPNewSecureData( mgr, modlen/2, 0 );
	coefbuf = PGPNewSecureData( mgr, modlen/2, 0 );

	bnExtractBigBytes( &mod, modbuf, 0, modlen );
	bnExtractBigBytes( &exp, expbuf, 0, explen );
	bnExtractBigBytes( &decexp, decexpbuf, 0, modlen );
	bnExtractBigBytes( &p1, p1buf, 0, modlen/2 );
	bnExtractBigBytes( &p2, p2buf, 0, modlen/2 );
	bnExtractBigBytes( &decp1, decp1buf, 0, modlen/2 );
	bnExtractBigBytes( &decp2, decp2buf, 0, modlen/2 );
	bnExtractBigBytes( &coef, coefbuf, 0, modlen/2 );

	bnEnd( &mod );
	bnEnd( &exp );
	bnEnd( &decexp );
	bnEnd( &p1 );
	bnEnd( &p2 );
	bnEnd( &decp1 );
	bnEnd( &decp2 );
	bnEnd( &coef );

	/* Unlock token */
	err = pgpTokenObjAuth( tok, (IsNull(PIN)?passphrase:PIN),
						   (IsNull(PIN)?passphraseLength:PINlength) );
	if( err != 0 )
		return kPGPError_BadPassphrase;

	err = pgpTokenObjPutPrivKey ( tok, isMaster, keyidbytes, modbuf, modlen,
								  expbuf, explen, decexpbuf, modlen,
								  p1buf, modlen/2, p2buf, modlen/2,
								  decp1buf, modlen/2, decp2buf, modlen/2,
								  coefbuf, modlen/2 );
	
	PGPFreeData( modbuf );
	PGPFreeData( expbuf );
	PGPFreeData( decexpbuf );
	PGPFreeData( p1buf );
	PGPFreeData( p2buf );
	PGPFreeData( decp1buf );
	PGPFreeData( decp2buf );
	PGPFreeData( coefbuf );

	if( IsntPGPError( err ) )
	{
		pgpSyncTokenToKeyDB( context, NULL, TRUE );
	}

	return err;
#else
	(void) context;
	(void) key;
	(void) toknumber;
	(void) isMaster;
	(void) passphrase;
	(void) passphraseLength;
	(void) hashedPhrase;
	(void) PIN;
	(void) PINlength;
	return kPGPError_PublicKeyUnimplemented;
#endif
}

	PGPError
pgpTokenCopyPrivKeyToToken( 
	PGPContextRef context, PGPKeyDBObjRef key,
	PGPBoolean isMaster,
	PGPByte const *passphrase, PGPSize passphraseLength,
	PGPBoolean hashedPhrase, PGPByte const *PIN, PGPSize PINlength,
	PGPUInt32 tokNumber )
{
	PGPKeyDBObjRef keyToUse = key;	

	if( !isMaster && pgpKeyVersion(key) == PGPVERSION_4 )  {
		PGPError err = PGPGetKeyForUsage( 
			key, kPGPKeyPropertyFlags_UsageEncrypt, &keyToUse );

		if( IsPGPError(err) )
			return err;
	}

	return sTokenCopyPrivKeyToToken( context, keyToUse, isMaster, 
		passphrase, passphraseLength, hashedPhrase, PIN, PINlength,tokNumber );
}

#if PGP_WIN32
/*
    Exports all identities with signatures into the certblob, 
	excluding the public key itself. 
	Caller must free the certblob.
 */
static PGPError 
sPgpKeyToMem( PGPContextRef context, PGPMemoryMgrRef mgr,
			    PGPKeyDBObjRef key, 
				PGPByte **certblob, PGPSize *certbloblen,
				PGPKeyDBObjProperty prop )
{
	PGPError err = kPGPError_NoErr;
	PGPKeySetRef oneset;
	PGPFilterRef filter;
	PGPKeySetRef filteredSet;
	PGPFile *pfile;

	*certblob = NULL;
	*certbloblen = 0;

	PGPNewOneKeySet( key, &oneset );
	if( prop != kPGPKeyDBObjProperty_Invalid )  {
		PGPKeyID keyid;
		PGPByte pkalg_notused;

		pgpKeyID8( key, &pkalg_notused, &keyid );

		PGPNewKeyDBObjDataFilter( context, prop,
							  &keyid, sizeof(keyid),
							  kPGPMatchCriterion_Equal, &filter );
		PGPFilterChildObjects( filter, TRUE );
		PGPFilterKeySet( oneset, filter, &filteredSet );
		PGPFreeKeySet( oneset );
	}
	else  {
		filteredSet = oneset;
	}
	pfile = pgpFileMemOpen( context, NULL, 0 );
	pgpExportToPGPFile( filteredSet, pfile, 
		                FALSE, FALSE, FALSE, FALSE /*includepubkey*/ );
	PGPFreeKeySet( filteredSet );
	*certbloblen = (PGPSize)pgpFileTell (pfile );
	*certblob = (PGPByte *)PGPNewData( mgr, *certbloblen, 0 );
	pgpFileSeek( pfile, 0, SEEK_SET );
	pgpFileRead( *certblob, *certbloblen, pfile );
	pgpFileClose( pfile );

	return err;
}

	static PGPError
sPutPubData(
	PGPToken		*tok, 
	PGPByte			*keyid,
	PGPByte			*data,
	PGPSize			size, 
	PGPUInt32		keyCrTime_netorder,
	PGPByte			v )  
{
	pgpTokenDataInfo di = { { 0 } };

	di.pubKeyStub.creationtime = keyCrTime_netorder;

	pgpAssert(v >= 0 && v <= PGPVERSION_4); 
	if( v < PGPVERSION_3 )
	    v = PGPVERSION_3;
	di.pubKeyStub.flags = v & 0xf;

	return pgpTokenObjPutPubKeyData ( tok, keyid, data, size, &di );
}
#endif


	PGPError
pgpTokenCopyPubKeyToToken(
	PGPContextRef		context,
	PGPKeyDBObjRef		key,
	PGPUInt32			toknumber, 
	PGPToken			*tok )
{
#if PGP_WIN32
	PGPByte				pkalg;
	PGPKeyID			keyid;
	PGPByte				*keyidbytes;
	PGPMemoryMgrRef		mgr	= NULL;
	PGPByte				*certblob;
	PGPSize				certbloblen;
	PGPUInt32			keyCrTime_netorder;
	PGPError			err = kPGPError_NoErr;
	PGPByte				v;

	pgpAssert( OBJISKEY( key ) );
	pgpAssert( (toknumber == -1 && tok) ||
			   (toknumber != -1 && tok && 
				     tok == F.pgpGetNthTokenObject(toknumber)) ||
			   (toknumber != -1 && !tok ) );

	if( !tok )
		tok = F.pgpGetNthTokenObject( toknumber );
	mgr	= PGPPeekContextMemoryMgr( context );

	pgpKeyID8( key, &pkalg, &keyid );
	if( pkalg != kPGPPublicKeyAlgorithm_RSA )
		return kPGPError_PublicKeyUnimplemented;

	keyidbytes = (PGPByte *)pgpGetKeyIDBytes( &keyid );
	v = pgpKeyVersion( key );

	/* Extract certificate without the Public key - only child Objects. 
	   Public key will be reconstructed from other objects on the token.
	   We only need key creation time (since it is hashed in PGP certs) 
	   and packet version.
	*/
	PGPUInt32ToEndian(pgpKeyCreation( key ), kPGPBigEndian, (PGPByte*)&keyCrTime_netorder);
	err = sPgpKeyToMem( context, mgr, key, 
		&certblob, &certbloblen, 
		kPGPKeyDBObjProperty_Invalid );
	
    if( IsntPGPError( err ) ) 
		err = sPutPubData( tok, keyidbytes, certblob, certbloblen, 
							keyCrTime_netorder, v );
	
	PGPFreeData( certblob );
	certblob = NULL;

	if( IsPGPError( err ) )
	{
		/* Try again, using only self signatures */
		err = sPgpKeyToMem( context, mgr, key, 
							&certblob, &certbloblen, 
							kPGPSigProperty_KeyID );

		if( IsntPGPError( err ) )  {
			err = sPutPubData( tok, keyidbytes, certblob, certbloblen, 
                               keyCrTime_netorder, v );
		}

		PGPFreeData( certblob );
		certblob = NULL;
	}
	
	return err;
#else
	(void) context;
	(void) key;
	(void) toknumber;
	(void) tok;
	return kPGPError_PublicKeyUnimplemented;
#endif
}

/* Used internally for cleanup only. 
   This function doesn't try to track dependencies between keys */
		PGPError
pgpDeleteKeyOnToken(
	PGPContextRef		context,
	const PGPKeyID		*keyID,
	PGPUInt32			toknumber )
{
#if PGP_WIN32
	PGPToken			*tok;
	PGPByte				*keyidbytes;
	PGPError			err = kPGPError_NoErr;

	/* Don't allow "ANY" token in this call */
	pgpAssert( toknumber != -1 );	

	tok = F.pgpGetNthTokenObject( toknumber );
	if( !tok )
		return kPGPError_SmartCardKeyNotFound;

	keyidbytes = (PGPByte *)pgpGetKeyIDBytes( keyID );
	return pgpTokenObjDeleteKey( tok, keyidbytes, TRUE );
#else
	(void) context;
	(void) keyID;
	(void) toknumber;
	return kPGPError_PublicKeyUnimplemented;
#endif
}



	PGPToken *
pgpTokenFromKeyID(
	const PGPByte *keyid )
{
#if PGP_WIN32
	sLoadTCL();
	if( IsNull( hTCL ) )
		return NULL;
	return F.pgpGetTokenObjectByPrivKeyID( keyid );
#else
	(void)keyid;
	return NULL;
#endif
}

	PGPToken *
pgpTokenGetIndexed(
	PGPUInt32	tokenNum )
{
#if PGP_WIN32
	sLoadTCL();
	if( IsNull( hTCL ) )
		return NULL;
	return F.pgpGetNthTokenObject( tokenNum );
#else
	(void)tokenNum;
	return NULL;
#endif
}

	PGPUInt32
pgpTokenGetCount ( )
{
#if PGP_WIN32
	sLoadTCL();
	if( IsNull( hTCL ) )
		return 0;
	return F.pgpCountTokenObjects( );
#else
	return 0;
#endif
}

	PGPError
pgpGetTokenInfo(
	PGPUInt32		toknumber,
	PGPTokenInfo	*tokenInfo )
{
#if PGP_WIN32
	PGPError		err;
	PGPToken		*tok;

	sLoadTCL();
	if( IsNull( hTCL ) )
		return 0;

	tok = F.pgpGetNthTokenObject( toknumber );
	if( IsNull( tok ) )  {
	    memset( tokenInfo, 0, sizeof(*tokenInfo) );
	    return kPGPError_PublicKeyUnimplemented;
	}

	err = pgpTokenObjGetInfo(tok, tokenInfo);
	return err;
#else
	(void) toknumber;
	memset( tokenInfo, 0, sizeof(*tokenInfo) );
	return 0;
#endif

}

	PGPError
pgpTokenWipe(
	PGPContextRef context, 
	PGPUInt32		toknumber,
	PGPByte const *	passphrase,
	PGPSize			passphraseLength )
{
#if PGP_WIN32
	PGPError		err;
	PGPToken		*tok;
	
	tok = F.pgpGetNthTokenObject( toknumber );
	if( IsNull( tok ) )
		return kPGPError_PublicKeyUnimplemented;
	/* Unlock token */
	err = pgpTokenObjAuth( tok, passphrase, passphraseLength );
	if( IsPGPError( err ) )
		return err;
	err = pgpTokenObjWipe( tok );
	(void)pgpTokenObjDeAuth( tok );
	
	if( IsntPGPError( err ) )
		pgpSyncTokenToKeyDB( context, NULL, TRUE );

	return err;
#else
	(void) context;
	(void) toknumber;
	(void) passphrase;
	(void) passphraseLength;
	return 0;

⌨️ 快捷键说明

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