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

📄 decrypt.c

📁 可以实现对邮件的加密解密以及签名
💻 C
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: decrypt.c,v 1.6 2002/08/06 20:11:09 dallen Exp $
____________________________________________________________________________*/

/*
 *  Author: Michael Elkins <michael_elkins@nai.com>
 *  Last Edit: December 9, 1999
 */

#include <math.h>
#include <stdlib.h>
#include "libpkcs7.h"

/* converts a DER encoding ASN.1 object-identifier into dot-string format */
/* FOO - possible buffer overflow if the input string generates and encoded ASN.1 longer than 256 bytes */
char *
sm_OIDToString (PKIOBJECT_ID *id, PKICONTEXT *ctx)
{
    char buf[1024];
    unsigned int ioff;
    unsigned int ibeg;
    int a1;
    int t;
    char *result;
    
    if (id->val[0] < 40)
	    a1 = 0;
    else if (id->val[0] < 80)
	    a1 = 1;
    else
	    a1 = 2;

    sprintf (buf, "%d.%d", a1, id->val[0] - 40 * a1);
    
    for (ioff = 1; ioff < id->len; ioff++)
    {
	    ibeg = ioff;
	    while (id->val[ioff] & 0x80 && ioff < id->len)
	        ioff++;
	    for (t = 0; ibeg <= ioff; ibeg++)
	        t += (int)((id->val[ibeg] & 0x7f)) * (int) (pow (128.0, ioff - ibeg));
	    sprintf (buf + strlen (buf), ".%d", t);
    }
    result = PKIAlloc (ctx->memMgr, strlen (buf) + 1);
    strcpy (result, buf);
    return (result);
}

int
sm_CompareIssuerAndSerialNumber (
	PKIIssuerAndSerialNumber	*a,	/* [IN] */
	PKIIssuerAndSerialNumber	*b,	/* [IN] */
	PKICONTEXT			*ctx	/* [IN] */
)
{
    unsigned char	*da, *db;
    size_t		la, lb;
    int			e = 0;
    int			result = 0;

    la = PKISizeofIssuerAndSerialNumber (ctx, a, 1);
    lb = PKISizeofIssuerAndSerialNumber (ctx, b, 1);

    if (la == lb)
    {
	da = PKIAlloc (ctx->memMgr, la);
	PKIPackIssuerAndSerialNumber (ctx, da, la, a, &e);

	db = PKIAlloc (ctx->memMgr, lb);
	PKIPackIssuerAndSerialNumber (ctx, db, lb, b, &e);

	result = (memcmp (da, db, la) == 0);

	PKIFree (ctx->memMgr, da);
	PKIFree (ctx->memMgr, db);
    }

    return (result);
}

/* Returns the index if the specified certificate is listed as a recipent of the
   encrypted message, other -1 is returned */
static int sm_CertIsRecipient (
	PKICertificate		*cert,		/* [IN] cert to check for */
	PKIEnvelopedData	*envelope,	/* [IN] message to check */
	PKICONTEXT		*ctx		/* [IN] */
)
{
    PKIIssuerAndSerialNumber	*is;
    int				i;
    int				result = -1;

    /* if cert is NULL, return the first recipent by default */
    if (!cert)
    {
	/* ensure there is at least one recipient */
	return (envelope->recipientInfos.n > 0 ? 0 : -1);
    }

    is = PKINewIssuerAndSerialNumber (ctx);
    sm_CopyIssuerAndSerialNumber (is, cert, ctx);

    for (i = 0; i < envelope->recipientInfos.n; i++)
	if (sm_CompareIssuerAndSerialNumber (is, &envelope->recipientInfos.elt[i]->issuerAndSerialNumber, ctx))
	{
	    result = i;
	    break;
	}
    PKIFreeIssuerAndSerialNumber (ctx, is);
    return (result);
}

int
sm_DecryptMessage (
	unsigned char		**msg,	  /* [OUT] decrypted message */
	size_t			*msglen,  /* [OUT] decrypted message length */
	PKIEnvelopedData	*envelope,/* [IN] encrypted message */
	PKICertificate		*cert,	  /* [IN] cert to decrypt for */
	DecryptCallback		*callback,/* [IN] decrypt callback function */
	void	    		*data,	  /* [IN] callback data (optional) */
	PKICONTEXT		*ctx
)
{
    int     result;
    int     recip = 0;
    char    *contentEncryptionAlg = NULL;
    char    *keyEncryptionAlg = NULL;

    recip = sm_CertIsRecipient (cert, envelope, ctx);
    if (recip < 0)
	return (-1);
    contentEncryptionAlg = sm_OIDToString (&envelope->encryptedContentInfo.contentEncryptionAlgorithm.algorithm, ctx);
    keyEncryptionAlg = sm_OIDToString (&envelope->recipientInfos.elt[recip]->keyEncryptionAlgorithm.algorithm, ctx);

    result = callback (
	    msg,
	    msglen,
	    contentEncryptionAlg,
	    envelope->encryptedContentInfo.contentEncryptionAlgorithm.parameters,
	    envelope->encryptedContentInfo.encryptedContent,
	    keyEncryptionAlg,
	    &envelope->recipientInfos.elt[recip]->encryptedKey,
	    cert,
	    data,
	    ctx);

    if (contentEncryptionAlg)
    {
        PKIFree (ctx->memMgr, contentEncryptionAlg);
        contentEncryptionAlg = NULL;
    }
    if (keyEncryptionAlg)
    {
        PKIFree (ctx->memMgr, keyEncryptionAlg);
        keyEncryptionAlg = NULL;
    }

    return (result);
}

⌨️ 快捷键说明

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