p7common.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 739 行 · 第 1/2 页
C
739 行
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * PKCS7 implementation -- the exported parts that are used whether * creating or decoding. * * $Id: p7common.c,v 1.1 2000/03/31 19:16:04 relyea%netscape.com Exp $ */#include "p7local.h"#include "cert.h"#include "secitem.h"#include "secoid.h"#include "secpkcs5.h"#include "pk11func.h"/* * Find out (saving pointer to lookup result for future reference) * and return the inner content type. */SECOidTagSEC_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. */voidSEC_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.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:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?