| Index: mozilla/security/nss/lib/pkcs7/p7common.c
|
| ===================================================================
|
| --- mozilla/security/nss/lib/pkcs7/p7common.c (revision 191424)
|
| +++ mozilla/security/nss/lib/pkcs7/p7common.c (working copy)
|
| @@ -1,693 +0,0 @@
|
| -/* This Source Code Form is subject to the terms of the Mozilla Public
|
| - * License, v. 2.0. If a copy of the MPL was not distributed with this
|
| - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
| -
|
| -/*
|
| - * PKCS7 implementation -- the exported parts that are used whether
|
| - * creating or decoding.
|
| - *
|
| - * $Id: p7common.c,v 1.9 2012/04/25 14:50:06 gerv%gerv.net Exp $
|
| - */
|
| -
|
| -#include "p7local.h"
|
| -
|
| -#include "cert.h"
|
| -#include "secitem.h"
|
| -#include "secoid.h"
|
| -#include "pk11func.h"
|
| -
|
| -/*
|
| - * Find out (saving pointer to lookup result for future reference)
|
| - * and return the inner content type.
|
| - */
|
| -SECOidTag
|
| -SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo)
|
| -{
|
| - if (cinfo->contentTypeTag == NULL)
|
| - cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
|
| -
|
| - if (cinfo->contentTypeTag == NULL)
|
| - return SEC_OID_UNKNOWN;
|
| -
|
| - return cinfo->contentTypeTag->offset;
|
| -}
|
| -
|
| -
|
| -/*
|
| - * Destroy a PKCS7 contentInfo and all of its sub-pieces.
|
| - */
|
| -void
|
| -SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *cinfo)
|
| -{
|
| - SECOidTag kind;
|
| - CERTCertificate **certs;
|
| - CERTCertificateList **certlists;
|
| - SEC_PKCS7SignerInfo **signerinfos;
|
| - SEC_PKCS7RecipientInfo **recipientinfos;
|
| -
|
| - PORT_Assert (cinfo->refCount > 0);
|
| - if (cinfo->refCount <= 0)
|
| - return;
|
| -
|
| - cinfo->refCount--;
|
| - if (cinfo->refCount > 0)
|
| - return;
|
| -
|
| - certs = NULL;
|
| - certlists = NULL;
|
| - recipientinfos = NULL;
|
| - signerinfos = NULL;
|
| -
|
| - kind = SEC_PKCS7ContentType (cinfo);
|
| - switch (kind) {
|
| - case SEC_OID_PKCS7_ENVELOPED_DATA:
|
| - {
|
| - SEC_PKCS7EnvelopedData *edp;
|
| -
|
| - edp = cinfo->content.envelopedData;
|
| - if (edp != NULL) {
|
| - recipientinfos = edp->recipientInfos;
|
| - }
|
| - }
|
| - break;
|
| - case SEC_OID_PKCS7_SIGNED_DATA:
|
| - {
|
| - SEC_PKCS7SignedData *sdp;
|
| -
|
| - sdp = cinfo->content.signedData;
|
| - if (sdp != NULL) {
|
| - certs = sdp->certs;
|
| - certlists = sdp->certLists;
|
| - signerinfos = sdp->signerInfos;
|
| - }
|
| - }
|
| - break;
|
| - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
|
| - {
|
| - SEC_PKCS7SignedAndEnvelopedData *saedp;
|
| -
|
| - saedp = cinfo->content.signedAndEnvelopedData;
|
| - if (saedp != NULL) {
|
| - certs = saedp->certs;
|
| - certlists = saedp->certLists;
|
| - recipientinfos = saedp->recipientInfos;
|
| - signerinfos = saedp->signerInfos;
|
| - if (saedp->sigKey != NULL)
|
| - PK11_FreeSymKey (saedp->sigKey);
|
| - }
|
| - }
|
| - break;
|
| - default:
|
| - /* XXX Anything else that needs to be "manually" freed/destroyed? */
|
| - break;
|
| - }
|
| -
|
| - if (certs != NULL) {
|
| - CERTCertificate *cert;
|
| -
|
| - while ((cert = *certs++) != NULL) {
|
| - CERT_DestroyCertificate (cert);
|
| - }
|
| - }
|
| -
|
| - if (certlists != NULL) {
|
| - CERTCertificateList *certlist;
|
| -
|
| - while ((certlist = *certlists++) != NULL) {
|
| - CERT_DestroyCertificateList (certlist);
|
| - }
|
| - }
|
| -
|
| - if (recipientinfos != NULL) {
|
| - SEC_PKCS7RecipientInfo *ri;
|
| -
|
| - while ((ri = *recipientinfos++) != NULL) {
|
| - if (ri->cert != NULL)
|
| - CERT_DestroyCertificate (ri->cert);
|
| - }
|
| - }
|
| -
|
| - if (signerinfos != NULL) {
|
| - SEC_PKCS7SignerInfo *si;
|
| -
|
| - while ((si = *signerinfos++) != NULL) {
|
| - if (si->cert != NULL)
|
| - CERT_DestroyCertificate (si->cert);
|
| - if (si->certList != NULL)
|
| - CERT_DestroyCertificateList (si->certList);
|
| - }
|
| - }
|
| -
|
| - if (cinfo->poolp != NULL) {
|
| - PORT_FreeArena (cinfo->poolp, PR_FALSE); /* XXX clear it? */
|
| - }
|
| -}
|
| -
|
| -
|
| -/*
|
| - * Return a copy of the given contentInfo. The copy may be virtual
|
| - * or may be real -- either way, the result needs to be passed to
|
| - * SEC_PKCS7DestroyContentInfo later (as does the original).
|
| - */
|
| -SEC_PKCS7ContentInfo *
|
| -SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *cinfo)
|
| -{
|
| - if (cinfo == NULL)
|
| - return NULL;
|
| -
|
| - PORT_Assert (cinfo->refCount > 0);
|
| -
|
| - if (cinfo->created) {
|
| - /*
|
| - * Want to do a real copy of these; otherwise subsequent
|
| - * changes made to either copy are likely to be a surprise.
|
| - * XXX I suspect that this will not actually be called for yet,
|
| - * which is why the assert, so to notice if it is...
|
| - */
|
| - PORT_Assert (0);
|
| - /*
|
| - * XXX Create a new pool here, and copy everything from
|
| - * within. For cert stuff, need to call the appropriate
|
| - * copy functions, etc.
|
| - */
|
| - }
|
| -
|
| - cinfo->refCount++;
|
| - return cinfo;
|
| -}
|
| -
|
| -
|
| -/*
|
| - * Return a pointer to the actual content. In the case of those types
|
| - * which are encrypted, this returns the *plain* content.
|
| - * XXX Needs revisiting if/when we handle nested encrypted types.
|
| - */
|
| -SECItem *
|
| -SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo)
|
| -{
|
| - SECOidTag kind;
|
| -
|
| - kind = SEC_PKCS7ContentType (cinfo);
|
| - switch (kind) {
|
| - case SEC_OID_PKCS7_DATA:
|
| - return cinfo->content.data;
|
| - case SEC_OID_PKCS7_DIGESTED_DATA:
|
| - {
|
| - SEC_PKCS7DigestedData *digd;
|
| -
|
| - digd = cinfo->content.digestedData;
|
| - if (digd == NULL)
|
| - break;
|
| - return SEC_PKCS7GetContent (&(digd->contentInfo));
|
| - }
|
| - case SEC_OID_PKCS7_ENCRYPTED_DATA:
|
| - {
|
| - SEC_PKCS7EncryptedData *encd;
|
| -
|
| - encd = cinfo->content.encryptedData;
|
| - if (encd == NULL)
|
| - break;
|
| - return &(encd->encContentInfo.plainContent);
|
| - }
|
| - case SEC_OID_PKCS7_ENVELOPED_DATA:
|
| - {
|
| - SEC_PKCS7EnvelopedData *envd;
|
| -
|
| - envd = cinfo->content.envelopedData;
|
| - if (envd == NULL)
|
| - break;
|
| - return &(envd->encContentInfo.plainContent);
|
| - }
|
| - case SEC_OID_PKCS7_SIGNED_DATA:
|
| - {
|
| - SEC_PKCS7SignedData *sigd;
|
| -
|
| - sigd = cinfo->content.signedData;
|
| - if (sigd == NULL)
|
| - break;
|
| - return SEC_PKCS7GetContent (&(sigd->contentInfo));
|
| - }
|
| - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
|
| - {
|
| - SEC_PKCS7SignedAndEnvelopedData *saed;
|
| -
|
| - saed = cinfo->content.signedAndEnvelopedData;
|
| - if (saed == NULL)
|
| - break;
|
| - return &(saed->encContentInfo.plainContent);
|
| - }
|
| - default:
|
| - PORT_Assert(0);
|
| - break;
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -
|
| -/*
|
| - * XXX Fix the placement and formatting of the
|
| - * following routines (i.e. make them consistent with the rest of
|
| - * the pkcs7 code -- I think some/many belong in other files and
|
| - * they all need a formatting/style rehaul)
|
| - */
|
| -
|
| -/* retrieve the algorithm identifier for encrypted data.
|
| - * the identifier returned is a copy of the algorithm identifier
|
| - * in the content info and needs to be freed after being used.
|
| - *
|
| - * cinfo is the content info for which to retrieve the
|
| - * encryption algorithm.
|
| - *
|
| - * if the content info is not encrypted data or an error
|
| - * occurs NULL is returned.
|
| - */
|
| -SECAlgorithmID *
|
| -SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo)
|
| -{
|
| - SECAlgorithmID *alg = 0;
|
| - switch (SEC_PKCS7ContentType(cinfo))
|
| - {
|
| - case SEC_OID_PKCS7_ENCRYPTED_DATA:
|
| - alg = &cinfo->content.encryptedData->encContentInfo.contentEncAlg;
|
| - break;
|
| - case SEC_OID_PKCS7_ENVELOPED_DATA:
|
| - alg = &cinfo->content.envelopedData->encContentInfo.contentEncAlg;
|
| - break;
|
| - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
|
| - alg = &cinfo->content.signedAndEnvelopedData
|
| - ->encContentInfo.contentEncAlg;
|
| - break;
|
| - default:
|
| - alg = 0;
|
| - break;
|
| - }
|
| -
|
| - return alg;
|
| -}
|
| -
|
| -/* set the content of the content info. For data content infos,
|
| - * the data is set. For encrytped content infos, the plainContent
|
| - * is set, and is expected to be encrypted later.
|
| - *
|
| - * cinfo is the content info where the data will be set
|
| - *
|
| - * buf is a buffer of the data to set
|
| - *
|
| - * len is the length of the data being set.
|
| - *
|
| - * in the event of an error, SECFailure is returned. SECSuccess
|
| - * indicates the content was successfully set.
|
| - */
|
| -SECStatus
|
| -SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo,
|
| - const char *buf,
|
| - unsigned long len)
|
| -{
|
| - SECOidTag cinfo_type;
|
| - SECStatus rv;
|
| - SECItem content;
|
| - SECOidData *contentTypeTag = NULL;
|
| -
|
| - content.type = siBuffer;
|
| - content.data = (unsigned char *)buf;
|
| - content.len = len;
|
| -
|
| - cinfo_type = SEC_PKCS7ContentType(cinfo);
|
| -
|
| - /* set inner content */
|
| - switch(cinfo_type)
|
| - {
|
| - case SEC_OID_PKCS7_SIGNED_DATA:
|
| - if(content.len > 0) {
|
| - /* we "leak" the old content here, but as it's all in the pool */
|
| - /* it does not really matter */
|
| -
|
| - /* create content item if necessary */
|
| - if (cinfo->content.signedData->contentInfo.content.data == NULL)
|
| - cinfo->content.signedData->contentInfo.content.data = SECITEM_AllocItem(cinfo->poolp, NULL, 0);
|
| - rv = SECITEM_CopyItem(cinfo->poolp,
|
| - cinfo->content.signedData->contentInfo.content.data,
|
| - &content);
|
| - } else {
|
| - cinfo->content.signedData->contentInfo.content.data->data = NULL;
|
| - cinfo->content.signedData->contentInfo.content.data->len = 0;
|
| - rv = SECSuccess;
|
| - }
|
| - if(rv == SECFailure)
|
| - goto loser;
|
| -
|
| - break;
|
| - case SEC_OID_PKCS7_ENCRYPTED_DATA:
|
| - /* XXX this forces the inner content type to be "data" */
|
| - /* do we really want to override without asking or reason? */
|
| - contentTypeTag = SECOID_FindOIDByTag(SEC_OID_PKCS7_DATA);
|
| - if(contentTypeTag == NULL)
|
| - goto loser;
|
| - rv = SECITEM_CopyItem(cinfo->poolp,
|
| - &(cinfo->content.encryptedData->encContentInfo.contentType),
|
| - &(contentTypeTag->oid));
|
| - if(rv == SECFailure)
|
| - goto loser;
|
| - if(content.len > 0) {
|
| - rv = SECITEM_CopyItem(cinfo->poolp,
|
| - &(cinfo->content.encryptedData->encContentInfo.plainContent),
|
| - &content);
|
| - } else {
|
| - cinfo->content.encryptedData->encContentInfo.plainContent.data = NULL;
|
| - cinfo->content.encryptedData->encContentInfo.encContent.data = NULL;
|
| - cinfo->content.encryptedData->encContentInfo.plainContent.len = 0;
|
| - cinfo->content.encryptedData->encContentInfo.encContent.len = 0;
|
| - rv = SECSuccess;
|
| - }
|
| - if(rv == SECFailure)
|
| - goto loser;
|
| - break;
|
| - case SEC_OID_PKCS7_DATA:
|
| - cinfo->content.data = (SECItem *)PORT_ArenaZAlloc(cinfo->poolp,
|
| - sizeof(SECItem));
|
| - if(cinfo->content.data == NULL)
|
| - goto loser;
|
| - if(content.len > 0) {
|
| - rv = SECITEM_CopyItem(cinfo->poolp,
|
| - cinfo->content.data, &content);
|
| - } else {
|
| - /* handle case with NULL content */
|
| - rv = SECSuccess;
|
| - }
|
| - if(rv == SECFailure)
|
| - goto loser;
|
| - break;
|
| - default:
|
| - goto loser;
|
| - }
|
| -
|
| - return SECSuccess;
|
| -
|
| -loser:
|
| -
|
| - return SECFailure;
|
| -}
|
| -
|
| -/* the content of an encrypted data content info is encrypted.
|
| - * it is assumed that for encrypted data, that the data has already
|
| - * been set and is in the "plainContent" field of the content info.
|
| - *
|
| - * cinfo is the content info to encrypt
|
| - *
|
| - * key is the key with which to perform the encryption. if the
|
| - * algorithm is a password based encryption algorithm, the
|
| - * key is actually a password which will be processed per
|
| - * PKCS #5.
|
| - *
|
| - * in the event of an error, SECFailure is returned. SECSuccess
|
| - * indicates a success.
|
| - */
|
| -SECStatus
|
| -SEC_PKCS7EncryptContents(PRArenaPool *poolp,
|
| - SEC_PKCS7ContentInfo *cinfo,
|
| - SECItem *key,
|
| - void *wincx)
|
| -{
|
| - SECAlgorithmID *algid = NULL;
|
| - SECItem * result = NULL;
|
| - SECItem * src;
|
| - SECItem * dest;
|
| - SECItem * blocked_data = NULL;
|
| - void * mark;
|
| - void * cx;
|
| - PK11SymKey * eKey = NULL;
|
| - PK11SlotInfo * slot = NULL;
|
| -
|
| - CK_MECHANISM_TYPE cryptoMechType;
|
| - int bs;
|
| - SECStatus rv = SECFailure;
|
| - SECItem *c_param = NULL;
|
| -
|
| - if((cinfo == NULL) || (key == NULL))
|
| - return SECFailure;
|
| -
|
| - if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
|
| - return SECFailure;
|
| -
|
| - algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
|
| - if(algid == NULL)
|
| - return SECFailure;
|
| -
|
| - if(poolp == NULL)
|
| - poolp = cinfo->poolp;
|
| -
|
| - mark = PORT_ArenaMark(poolp);
|
| -
|
| - src = &cinfo->content.encryptedData->encContentInfo.plainContent;
|
| - dest = &cinfo->content.encryptedData->encContentInfo.encContent;
|
| - dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64));
|
| - dest->len = (src->len + 64);
|
| - if(dest->data == NULL) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - slot = PK11_GetInternalKeySlot();
|
| - if(slot == NULL) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
|
| - if(eKey == NULL) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key);
|
| - if (cryptoMechType == CKM_INVALID_MECHANISM) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - /* block according to PKCS 8 */
|
| - bs = PK11_GetBlockSize(cryptoMechType, c_param);
|
| - rv = SECSuccess;
|
| - if(bs) {
|
| - char pad_char;
|
| - pad_char = (char)(bs - (src->len % bs));
|
| - if(src->len % bs) {
|
| - rv = SECSuccess;
|
| - blocked_data = PK11_BlockData(src, bs);
|
| - if(blocked_data) {
|
| - PORT_Memset((blocked_data->data + blocked_data->len
|
| - - (int)pad_char),
|
| - pad_char, (int)pad_char);
|
| - } else {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| - } else {
|
| - blocked_data = SECITEM_DupItem(src);
|
| - if(blocked_data) {
|
| - blocked_data->data = (unsigned char*)PORT_Realloc(
|
| - blocked_data->data,
|
| - blocked_data->len + bs);
|
| - if(blocked_data->data) {
|
| - blocked_data->len += bs;
|
| - PORT_Memset((blocked_data->data + src->len), (char)bs, bs);
|
| - } else {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| - } else {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| - }
|
| - } else {
|
| - blocked_data = SECITEM_DupItem(src);
|
| - if(!blocked_data) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| - }
|
| -
|
| - cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT,
|
| - eKey, c_param);
|
| - if(cx == NULL) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len),
|
| - (int)(src->len + 64), blocked_data->data,
|
| - (int)blocked_data->len);
|
| - PK11_DestroyContext((PK11Context*)cx, PR_TRUE);
|
| -
|
| -loser:
|
| - /* let success fall through */
|
| - if(blocked_data != NULL)
|
| - SECITEM_ZfreeItem(blocked_data, PR_TRUE);
|
| -
|
| - if(result != NULL)
|
| - SECITEM_ZfreeItem(result, PR_TRUE);
|
| -
|
| - if(rv == SECFailure)
|
| - PORT_ArenaRelease(poolp, mark);
|
| - else
|
| - PORT_ArenaUnmark(poolp, mark);
|
| -
|
| - if(eKey != NULL)
|
| - PK11_FreeSymKey(eKey);
|
| -
|
| - if(slot != NULL)
|
| - PK11_FreeSlot(slot);
|
| -
|
| - if(c_param != NULL)
|
| - SECITEM_ZfreeItem(c_param, PR_TRUE);
|
| -
|
| - return rv;
|
| -}
|
| -
|
| -/* the content of an encrypted data content info is decrypted.
|
| - * it is assumed that for encrypted data, that the data has already
|
| - * been set and is in the "encContent" field of the content info.
|
| - *
|
| - * cinfo is the content info to decrypt
|
| - *
|
| - * key is the key with which to perform the decryption. if the
|
| - * algorithm is a password based encryption algorithm, the
|
| - * key is actually a password which will be processed per
|
| - * PKCS #5.
|
| - *
|
| - * in the event of an error, SECFailure is returned. SECSuccess
|
| - * indicates a success.
|
| - */
|
| -SECStatus
|
| -SEC_PKCS7DecryptContents(PRArenaPool *poolp,
|
| - SEC_PKCS7ContentInfo *cinfo,
|
| - SECItem *key,
|
| - void *wincx)
|
| -{
|
| - SECAlgorithmID *algid = NULL;
|
| - SECStatus rv = SECFailure;
|
| - SECItem *result = NULL, *dest, *src;
|
| - void *mark;
|
| -
|
| - PK11SymKey *eKey = NULL;
|
| - PK11SlotInfo *slot = NULL;
|
| - CK_MECHANISM_TYPE cryptoMechType;
|
| - void *cx;
|
| - SECItem *c_param = NULL;
|
| - int bs;
|
| -
|
| - if((cinfo == NULL) || (key == NULL))
|
| - return SECFailure;
|
| -
|
| - if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA)
|
| - return SECFailure;
|
| -
|
| - algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo);
|
| - if(algid == NULL)
|
| - return SECFailure;
|
| -
|
| - if(poolp == NULL)
|
| - poolp = cinfo->poolp;
|
| -
|
| - mark = PORT_ArenaMark(poolp);
|
| -
|
| - src = &cinfo->content.encryptedData->encContentInfo.encContent;
|
| - dest = &cinfo->content.encryptedData->encContentInfo.plainContent;
|
| - dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64));
|
| - dest->len = (src->len + 64);
|
| - if(dest->data == NULL) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - slot = PK11_GetInternalKeySlot();
|
| - if(slot == NULL) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx);
|
| - if(eKey == NULL) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key);
|
| - if (cryptoMechType == CKM_INVALID_MECHANISM) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT,
|
| - eKey, c_param);
|
| - if(cx == NULL) {
|
| - rv = SECFailure;
|
| - goto loser;
|
| - }
|
| -
|
| - rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len),
|
| - (int)(src->len + 64), src->data, (int)src->len);
|
| - PK11_DestroyContext((PK11Context *)cx, PR_TRUE);
|
| -
|
| - bs = PK11_GetBlockSize(cryptoMechType, c_param);
|
| - if(bs) {
|
| - /* check for proper badding in block algorithms. this assumes
|
| - * RC2 cbc or a DES cbc variant. and the padding is thus defined
|
| - */
|
| - if(((int)dest->data[dest->len-1] <= bs) &&
|
| - ((int)dest->data[dest->len-1] > 0)) {
|
| - dest->len -= (int)dest->data[dest->len-1];
|
| - } else {
|
| - rv = SECFailure;
|
| - /* set an error ? */
|
| - }
|
| - }
|
| -
|
| -loser:
|
| - /* let success fall through */
|
| - if(result != NULL)
|
| - SECITEM_ZfreeItem(result, PR_TRUE);
|
| -
|
| - if(rv == SECFailure)
|
| - PORT_ArenaRelease(poolp, mark);
|
| - else
|
| - PORT_ArenaUnmark(poolp, mark);
|
| -
|
| - if(eKey != NULL)
|
| - PK11_FreeSymKey(eKey);
|
| -
|
| - if(slot != NULL)
|
| - PK11_FreeSlot(slot);
|
| -
|
| - if(c_param != NULL)
|
| - SECITEM_ZfreeItem(c_param, PR_TRUE);
|
| -
|
| - return rv;
|
| -}
|
| -
|
| -SECItem **
|
| -SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo)
|
| -{
|
| - switch(SEC_PKCS7ContentType(cinfo))
|
| - {
|
| - case SEC_OID_PKCS7_SIGNED_DATA:
|
| - return cinfo->content.signedData->rawCerts;
|
| - break;
|
| - default:
|
| - return NULL;
|
| - break;
|
| - }
|
| -}
|
| -
|
| -
|
| -int
|
| -SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo)
|
| -{
|
| - if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA)
|
| - return cinfo->content.envelopedData->encContentInfo.keysize;
|
| - else
|
| - return 0;
|
| -}
|
| -
|
|
|